aboutsummaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/ui/conversation_content_view/conversation_item_skeleton.vala26
-rw-r--r--main/src/ui/conversation_content_view/conversation_view.vala110
2 files changed, 106 insertions, 30 deletions
diff --git a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
index dbba2276..a87c8489 100644
--- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
@@ -22,7 +22,7 @@ public class ConversationItemSkeleton : EventBox {
private Box header_content_box = new Box(Orientation.VERTICAL, 0) { visible=true };
private ItemMetaDataHeader metadata_header;
- public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation, Plugins.MetaConversationItem item) {
+ public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation, Plugins.MetaConversationItem item, bool initial_item) {
this.stream_interactor = stream_interactor;
this.conversation = conversation;
this.item = item;
@@ -44,23 +44,17 @@ public class ConversationItemSkeleton : EventBox {
}
image_content_box.add(header_content_box);
- this.add(image_content_box);
-
- if (item.get_type().is_a(typeof(ContentMetaItem))) {
- this.motion_notify_event.connect((event) => {
- this.set_state_flags(StateFlags.PRELIGHT, false);
- return false;
- });
- this.enter_notify_event.connect((event) => {
- this.set_state_flags(StateFlags.PRELIGHT, false);
- return false;
- });
- this.leave_notify_event.connect((event) => {
- this.unset_state_flags(StateFlags.PRELIGHT);
- return false;
- });
+
+ if (initial_item) {
+ this.add(image_content_box);
+ } else {
+ Revealer revealer = new Revealer() { transition_duration=200, transition_type = RevealerTransitionType.SLIDE_UP, visible = true };
+ revealer.add_with_properties(image_content_box);
+ revealer.reveal_child = true;
+ this.add(revealer);
}
+
this.notify["show-skeleton"].connect(update_margin);
this.notify["last-group-item"].connect(update_margin);
diff --git a/main/src/ui/conversation_content_view/conversation_view.vala b/main/src/ui/conversation_content_view/conversation_view.vala
index 6c286fc0..f7f1faf2 100644
--- a/main/src/ui/conversation_content_view/conversation_view.vala
+++ b/main/src/ui/conversation_content_view/conversation_view.vala
@@ -1,5 +1,6 @@
using Gee;
using Gtk;
+using Gdk;
using Pango;
using Dino.Entities;
@@ -13,8 +14,11 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
[GtkChild] public ScrolledWindow scrolled;
[GtkChild] private Revealer notification_revealer;
+ [GtkChild] private Box message_menu_box;
[GtkChild] private Box notifications;
[GtkChild] private Box main;
+ [GtkChild] private EventBox main_event_box;
+ [GtkChild] private EventBox main_wrap_event_box;
[GtkChild] private Stack stack;
private StreamInteractor stream_interactor;
@@ -25,6 +29,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
private Gee.List<ConversationItemSkeleton> item_skeletons = new Gee.ArrayList<ConversationItemSkeleton>();
private ContentProvider content_populator;
private SubscriptionNotitication subscription_notification;
+ private bool enable_menu_box = false;
private double? was_value;
private double? was_upper;
@@ -35,6 +40,10 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
private bool firstLoad = true;
private bool at_current_content = true;
private bool reload_messages = true;
+ Widget currently_highlighted = null;
+ ContentItem current_highlighted_item = null;
+ bool mouse_inside = false;
+ int last_y_root = -1;
public ConversationView init(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
@@ -57,9 +66,89 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
}
return true;
});
+
+ main_wrap_event_box.events = EventMask.ENTER_NOTIFY_MASK;
+ main_wrap_event_box.events = EventMask.LEAVE_NOTIFY_MASK;
+ main_wrap_event_box.leave_notify_event.connect(on_leave_notify_event);
+ main_wrap_event_box.enter_notify_event.connect(on_enter_notify_event);
+ main_event_box.events = EventMask.POINTER_MOTION_MASK;
+ main_event_box.motion_notify_event.connect(on_motion_notify_event);
+
return this;
}
+ private bool on_enter_notify_event(Gdk.EventCrossing event) {
+ mouse_inside = true;
+ update_highlight((int)event.x_root, (int)event.y_root);
+ return false;
+ }
+
+ private bool on_leave_notify_event(Gdk.EventCrossing event) {
+ mouse_inside = false;
+ if (currently_highlighted != null) currently_highlighted.unset_state_flags(StateFlags.PRELIGHT);
+ message_menu_box.visible = false;
+ return false;
+ }
+
+ private bool on_motion_notify_event(Gdk.EventMotion event) {
+ mouse_inside = true;
+ update_highlight((int)event.x_root, (int)event.y_root);
+ return false;
+ }
+
+ private void update_highlight(int x_root, int y_root) {
+ if ((last_y_root - y_root).abs() <= 2) {
+ return;
+ }
+
+ last_y_root = y_root;
+ message_menu_box.visible = enable_menu_box;
+
+ // Get pointer location in main
+ int geometry_x, geometry_y, geometry_width, geometry_height, dest_x, dest_y;
+ Widget toplevel_widget = this.get_toplevel();
+ toplevel_widget.get_window().get_geometry(out geometry_x, out geometry_y, out geometry_width, out geometry_height);
+ toplevel_widget.translate_coordinates(main, x_root - geometry_x, y_root - geometry_y, out dest_x, out dest_y);
+
+ // Get widget under pointer
+ int h = 0;
+ bool @break = false;
+ Widget w = null;
+ main.@foreach((widget) => {
+ if (break) return;
+
+ h += widget.get_allocated_height();
+ w = widget;
+ if (h >= dest_y) {
+ @break = true;
+ return;
+ }
+ });
+
+ // Get widget coordinates in main
+ int widget_x, widget_y;
+ w.translate_coordinates(main, 0, 0, out widget_x, out widget_y);
+
+ // Get MessageItem
+ var iter = widgets.map_iterator();
+ while (iter.next()) {
+ if (iter.get_value() == w) {
+ Plugins.MetaConversationItem meta_item = iter.get_key();
+ var meta_content_item = meta_item as ContentMetaItem;
+ if (meta_content_item == null) return;
+ current_highlighted_item = meta_content_item.content_item;
+ }
+ }
+
+ // Highlight widget
+ if (currently_highlighted != null) currently_highlighted.unset_state_flags(StateFlags.PRELIGHT);
+ w.set_state_flags(StateFlags.PRELIGHT, true);
+ currently_highlighted = w;
+
+ // Move message menu
+ message_menu_box.margin_top = widget_y - 10;
+ }
+
public void initialize_for_conversation(Conversation? conversation) {
// Workaround for rendering issues
if (firstLoad) {
@@ -75,6 +164,8 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
initialize_for_conversation_(conversation);
display_latest();
stack.set_visible_child_name("main");
+
+ enable_menu_box = false;
}
public void initialize_around_message(Conversation conversation, ContentItem content_item) {
@@ -231,24 +322,15 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
Plugins.MetaConversationItem? lower_item = meta_items.lower(item);
// Fill datastructure
- ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation, item) { visible=true };
+ ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation, item, !animate) { visible=true };
item_item_skeletons[item] = item_skeleton;
int index = lower_item != null ? item_skeletons.index_of(item_item_skeletons[lower_item]) + 1 : 0;
item_skeletons.insert(index, item_skeleton);
// Insert widget
- Widget insert = item_skeleton;
- if (animate) {
- Revealer revealer = new Revealer() {transition_duration = 200, transition_type = RevealerTransitionType.SLIDE_UP, visible = true};
- revealer.add(item_skeleton);
- insert = revealer;
- main.add(insert);
- revealer.reveal_child = true;
- } else {
- main.add(insert);
- }
- widgets[item] = insert;
- main.reorder_child(insert, index);
+ widgets[item] = item_skeleton;
+ main.add(item_skeleton);
+ main.reorder_child(item_skeleton, index);
if (lower_item != null) {
if (can_merge(item, lower_item)) {
@@ -279,7 +361,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins
}
}
}
- return insert;
+ return item_skeleton;
}
private bool can_merge(Plugins.MetaConversationItem upper_item /*more recent, displayed below*/, Plugins.MetaConversationItem lower_item /*less recent, displayed above*/) {