initial scaffolding for inverted, custom message list
This commit is contained in:
72
src/message-list/message-list-model.vala
Normal file
72
src/message-list/message-list-model.vala
Normal file
@@ -0,0 +1,72 @@
|
||||
using GLib;
|
||||
using Gee;
|
||||
|
||||
public class MessageListModel : Object, ListModel
|
||||
{
|
||||
public SortedSet<Message> messages {
|
||||
owned get { return _messages.read_only_view; }
|
||||
}
|
||||
|
||||
private string _conversation_guid;
|
||||
private SortedSet<Message> _messages;
|
||||
|
||||
public MessageListModel(string conversation_guid) {
|
||||
_messages = new TreeSet<Message>((a, b) => {
|
||||
// Sort by date in descending order (newest first)
|
||||
return (int)(b.date - a.date);
|
||||
});
|
||||
|
||||
Repository.get_instance().messages_updated.connect(got_messages_updated);
|
||||
_conversation_guid = conversation_guid;
|
||||
}
|
||||
|
||||
public void load_messages() {
|
||||
try {
|
||||
Message[] messages = Repository.get_instance().get_messages(_conversation_guid);
|
||||
|
||||
// Clear existing set
|
||||
uint old_count = _messages.size;
|
||||
_messages.clear();
|
||||
|
||||
// Notify of removal
|
||||
if (old_count > 0) {
|
||||
items_changed(0, old_count, 0);
|
||||
}
|
||||
|
||||
// Process each conversation
|
||||
uint position = 0;
|
||||
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
var message = messages[i];
|
||||
_messages.add(message);
|
||||
position++;
|
||||
}
|
||||
|
||||
// Notify of additions
|
||||
if (position > 0) {
|
||||
items_changed(0, 0, position);
|
||||
}
|
||||
} catch (Error e) {
|
||||
warning("Failed to load messages: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void got_messages_updated(string conversation_guid) {
|
||||
if (conversation_guid == _conversation_guid) {
|
||||
load_messages();
|
||||
}
|
||||
}
|
||||
|
||||
// ListModel implementation
|
||||
public Type get_item_type() {
|
||||
return typeof(Message);
|
||||
}
|
||||
|
||||
public uint get_n_items() {
|
||||
return _messages.size;
|
||||
}
|
||||
|
||||
public Object? get_item(uint position) {
|
||||
return _messages.to_array()[position];
|
||||
}
|
||||
}
|
||||
73
src/message-list/message-list-view.vala
Normal file
73
src/message-list/message-list-view.vala
Normal file
@@ -0,0 +1,73 @@
|
||||
using Adw;
|
||||
using Gtk;
|
||||
|
||||
public class MessageListView : Adw.Bin
|
||||
{
|
||||
private Adw.ToolbarView container;
|
||||
|
||||
private MessageDrawingArea message_drawing_area = new MessageDrawingArea();
|
||||
private ScrolledWindow scrolled_window = new ScrolledWindow();
|
||||
|
||||
public MessageListView(MessageListModel model) {
|
||||
container = new Adw.ToolbarView();
|
||||
set_child(container);
|
||||
|
||||
scrolled_window.set_child(message_drawing_area);
|
||||
scrolled_window.add_css_class("message-list-scroller");
|
||||
container.set_content(scrolled_window);
|
||||
|
||||
var header_bar = new Adw.HeaderBar();
|
||||
header_bar.set_title_widget(new Label("Messages"));
|
||||
container.add_top_bar(header_bar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class MessageDrawingArea : Widget {
|
||||
public MessageDrawingArea() {
|
||||
}
|
||||
|
||||
public override SizeRequestMode get_request_mode() {
|
||||
return SizeRequestMode.HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
public override void measure(Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) {
|
||||
GLib.message("Measure orientation: %s, for_size: %d", orientation.to_string(), for_size);
|
||||
|
||||
if (orientation == Orientation.HORIZONTAL) {
|
||||
// Horizontal, so we take up the full width provided
|
||||
minimum = 0;
|
||||
natural = for_size;
|
||||
} else {
|
||||
GLib.message("Vertical measure for width: %d", for_size);
|
||||
minimum = 1500;
|
||||
natural = 1500;
|
||||
}
|
||||
|
||||
minimum_baseline = -1;
|
||||
natural_baseline = -1;
|
||||
}
|
||||
|
||||
public override void snapshot(Snapshot snapshot) {
|
||||
var width = get_width();
|
||||
var height = get_height();
|
||||
|
||||
GLib.message("Snapshot width: %d, height: %d", width, height);
|
||||
|
||||
var rect = Graphene.Rect().init(0, 0, width, height);
|
||||
snapshot.append_color({1.0f, 0.0f, 0.0f, 1.0f}, rect);
|
||||
|
||||
// Create a text layout
|
||||
var layout = create_pango_layout("Hello World!");
|
||||
layout.set_width(width * Pango.SCALE);
|
||||
|
||||
// Set text attributes
|
||||
var font_desc = Pango.FontDescription.from_string("Sans 14");
|
||||
layout.set_font_description(font_desc);
|
||||
|
||||
// Draw the text in white
|
||||
snapshot.append_layout(layout, Gdk.RGBA() { red = 1.0f, green = 1.0f, blue = 1.0f, alpha = 1.0f });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user