diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index d5414084..56344eab 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -43,6 +43,7 @@ set(RESOURCE_LIST contact_details_dialog.ui conversation_list_titlebar.ui conversation_list_titlebar_csd.ui + conversation_view.ui emojichooser.ui global_search.ui conversation_selector/chat_row_tooltip.ui @@ -97,6 +98,8 @@ SOURCES src/ui/chat_input_controller.vala src/ui/conversation_list_titlebar.vala src/ui/conversation_list_titlebar_csd.vala + src/ui/conversation_view.vala + src/ui/conversation_view_controller.vala src/ui/global_search.vala src/ui/notifications.vala src/ui/settings_dialog.vala diff --git a/main/data/conversation_view.ui b/main/data/conversation_view.ui new file mode 100644 index 00000000..df9df7e0 --- /dev/null +++ b/main/data/conversation_view.ui @@ -0,0 +1,54 @@ + + + + diff --git a/main/data/unified_main_content.ui b/main/data/unified_main_content.ui index 25faf0fa..03c206c1 100644 --- a/main/data/unified_main_content.ui +++ b/main/data/unified_main_content.ui @@ -69,55 +69,8 @@ True - + True - - - vertical - True - - - - True - - - - - True - - - - - - - end - end - crossfade - True - 30 - 70 - - - False - end - end - True - - - - go-down-symbolic - 1 - True - - - - - - content diff --git a/main/src/ui/chat_input_controller.vala b/main/src/ui/chat_input_controller.vala index aafb40a3..59a2abb4 100644 --- a/main/src/ui/chat_input_controller.vala +++ b/main/src/ui/chat_input_controller.vala @@ -23,6 +23,8 @@ public class ChatInputController : Object { this.status_description_label = chat_input.chat_input_status; this.stream_interactor = stream_interactor; + chat_input.init(stream_interactor); + reset_input_field_status(); chat_input.text_input.buffer.changed.connect(on_text_input_changed); @@ -40,6 +42,7 @@ public class ChatInputController : Object { reset_input_field_status(); + chat_input.initialize_for_conversation(conversation); chat_input.occupants_tab_completor.initialize_for_conversation(conversation); chat_input.edit_history.initialize_for_conversation(conversation); chat_input.encryption_widget.set_conversation(conversation); diff --git a/main/src/ui/conversation_selector/conversation_selector.vala b/main/src/ui/conversation_selector/conversation_selector.vala index ac087183..4c7e6b8d 100644 --- a/main/src/ui/conversation_selector/conversation_selector.vala +++ b/main/src/ui/conversation_selector/conversation_selector.vala @@ -56,7 +56,6 @@ public class ConversationSelector : ListBox { if (!rows.has_key(conversation)) { add_conversation(conversation); } - rows[conversation].grab_focus(); this.select_row(rows[conversation]); } @@ -86,8 +85,8 @@ public class ConversationSelector : ListBox { if (this.drag_timeout != null) return false; this.drag_timeout = Timeout.add(200, () => { - if (widget.get_type().is_a(typeof(ConversationRow))) { - ConversationRow row = widget as ConversationRow; + if (widget.get_type().is_a(typeof(ConversationSelectorRow))) { + ConversationSelectorRow row = widget as ConversationSelectorRow; conversation_selected(row.conversation); } this.drag_timeout = null; diff --git a/main/src/ui/conversation_summary/conversation_view.vala b/main/src/ui/conversation_summary/conversation_view.vala index 33980c09..92d94cd7 100644 --- a/main/src/ui/conversation_summary/conversation_view.vala +++ b/main/src/ui/conversation_summary/conversation_view.vala @@ -4,15 +4,6 @@ using Pango; using Dino.Entities; -enum Target { - URI_LIST, - STRING -} - -const TargetEntry[] target_list = { - { "text/uri-list", 0, Target.URI_LIST }, -}; - namespace Dino.Ui.ConversationSummary { [GtkTemplate (ui = "/im/dino/Dino/conversation_summary/view.ui")] @@ -67,9 +58,12 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins return true; }); - drag_dest_unset(main); - drag_dest_set(scrolled, DestDefaults.ALL, target_list, Gdk.DragAction.COPY); - scrolled.drag_data_received.connect(this.on_drag_data_received); + const TargetEntry[] target_list = { + { "text/uri-list", 0, Target.URI_LIST } + }; +// drag_dest_unset(main); +// drag_dest_set(scrolled, DestDefaults.ALL, target_list, Gdk.DragAction.COPY); +// scrolled.drag_data_received.connect(() => print("a\n")); return this; } @@ -185,28 +179,6 @@ public class ConversationView : Box, Plugins.ConversationItemCollection, Plugins do_insert_item(item); } - public void on_drag_data_received(Widget widget, Gdk.DragContext context, - int x, int y, - SelectionData selection_data, - uint target_type, uint time) { - if ((selection_data != null) && (selection_data.get_length() >= 0)) { - switch (target_type) { - case Target.URI_LIST: - string[] uris = selection_data.get_uris(); - for (int i = 0; i < uris.length; i++) { - try { - string filename = Filename.from_uri(uris[i]); - stream_interactor.get_module(FileManager.IDENTITY).send_file(filename, conversation); - } catch (Error err) { - } - } - break; - default: - break; - } - } - } - public void do_insert_item(Plugins.MetaConversationItem item) { lock (meta_items) { insert_new(item); diff --git a/main/src/ui/conversation_view.vala b/main/src/ui/conversation_view.vala new file mode 100644 index 00000000..b521b5ad --- /dev/null +++ b/main/src/ui/conversation_view.vala @@ -0,0 +1,19 @@ +using Gee; +using Gdk; +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui { + +[GtkTemplate (ui = "/im/dino/Dino/conversation_view.ui")] +public class ConversationView : Gtk.Box { + + [GtkChild] public Revealer goto_end_revealer; + [GtkChild] public Button goto_end_button; + [GtkChild] public ChatInput.View chat_input; + [GtkChild] public ConversationSummary.ConversationView conversation_frame; + +} + +} diff --git a/main/src/ui/conversation_view_controller.vala b/main/src/ui/conversation_view_controller.vala new file mode 100644 index 00000000..1a0b2b07 --- /dev/null +++ b/main/src/ui/conversation_view_controller.vala @@ -0,0 +1,96 @@ +using Gee; +using Gdk; +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui { + +enum Target { + URI_LIST, + STRING +} + +const TargetEntry[] target_list = { + { "text/uri-list", 0, Target.URI_LIST } +}; + +public class ConversationViewController { + + private ConversationView widget; + + private ChatInputController chat_input_controller; + private StreamInteractor stream_interactor; + private Conversation? conversation; + + public ConversationViewController(ConversationView widget, StreamInteractor stream_interactor) { + this.widget = widget; + this.stream_interactor = stream_interactor; + + this.chat_input_controller = new ChatInputController(widget.chat_input, stream_interactor); + + widget.conversation_frame.init(stream_interactor); + + // drag 'n drop file upload + Gtk.drag_dest_unset(widget.chat_input.text_input); + Gtk.drag_dest_set(widget, DestDefaults.ALL, target_list, Gdk.DragAction.COPY); + widget.drag_data_received.connect(this.on_drag_data_received); + + // forward key presses + widget.chat_input.key_press_event.connect(forward_key_press_to_chat_input); + widget.conversation_frame.key_press_event.connect(forward_key_press_to_chat_input); + + // goto-end floating button + var vadjustment = widget.conversation_frame.scrolled.vadjustment; + vadjustment.notify["value"].connect(() => { + widget.goto_end_revealer.reveal_child = vadjustment.value < vadjustment.upper - vadjustment.page_size; + }); + widget.goto_end_button.clicked.connect(() => { + widget.conversation_frame.initialize_for_conversation(conversation); + }); + } + + public void select_conversation(Conversation? conversation, bool default_initialize_conversation) { + this.conversation = conversation; + + chat_input_controller.set_conversation(conversation); + + if (default_initialize_conversation) { + widget.conversation_frame.initialize_for_conversation(conversation); + } + } + + public void on_drag_data_received(Widget widget, Gdk.DragContext context, int x, int y, SelectionData selection_data, uint target_type, uint time) { + if ((selection_data != null) && (selection_data.get_length() >= 0)) { + switch (target_type) { + case Target.URI_LIST: + string[] uris = selection_data.get_uris(); + for (int i = 0; i < uris.length; i++) { + try { + string filename = Filename.from_uri(uris[i]); + stream_interactor.get_module(FileManager.IDENTITY).send_file.begin(filename, conversation); + } catch (Error err) {} + } + break; + default: + break; + } + } + } + + public bool forward_key_press_to_chat_input(EventKey event) { + // Don't forward / change focus on Control / Alt + if (event.keyval == Gdk.Key.Control_L || event.keyval == Gdk.Key.Control_R || + event.keyval == Gdk.Key.Alt_L || event.keyval == Gdk.Key.Alt_R) { + return false; + } + // Don't forward / change focus on Control + ... + if ((event.state & ModifierType.CONTROL_MASK) > 0) { + return false; + } + widget.chat_input.text_input.key_press_event(event); + widget.chat_input.text_input.grab_focus(); + return true; + } +} +} diff --git a/main/src/ui/unified_window.vala b/main/src/ui/unified_window.vala index 7cecceb5..9d9a870c 100644 --- a/main/src/ui/unified_window.vala +++ b/main/src/ui/unified_window.vala @@ -16,9 +16,8 @@ public class UnifiedWindow : Gtk.Window { public WelcomePlceholder welcome_placeholder = new WelcomePlceholder() { visible=true }; public NoAccountsPlaceholder accounts_placeholder = new NoAccountsPlaceholder() { visible=true }; public NoConversationsPlaceholder conversations_placeholder = new NoConversationsPlaceholder() { visible=true }; - public ChatInput.View chat_input; + public ConversationView conversation_view; public ConversationSelector conversation_selector; - public ConversationSummary.ConversationView conversation_frame; public ConversationTitlebar conversation_titlebar; public ConversationTitlebarCsd conversation_titlebar_csd; public ConversationListTitlebarCsd conversation_list_titlebar_csd; @@ -26,8 +25,6 @@ public class UnifiedWindow : Gtk.Window { public Box box = new Box(Orientation.VERTICAL, 0) { orientation=Orientation.VERTICAL, visible=true }; public Paned headerbar_paned = new Paned(Orientation.HORIZONTAL) { visible=true }; public Paned paned; - public Revealer goto_end_revealer; - public Button goto_end_button; public Revealer search_revealer; public SearchEntry search_entry; public GlobalSearch search_box; @@ -72,13 +69,8 @@ public class UnifiedWindow : Gtk.Window { box.add(paned); left_stack = (Stack) builder.get_object("left_stack"); right_stack = (Stack) builder.get_object("right_stack"); - chat_input = ((ChatInput.View) builder.get_object("chat_input")).init(stream_interactor); - chat_input.key_press_event.connect(forward_key_press_to_chat_input); - conversation_frame = ((ConversationSummary.ConversationView) builder.get_object("conversation_frame")).init(stream_interactor); - conversation_frame.key_press_event.connect(forward_key_press_to_chat_input); + conversation_view = (ConversationView) builder.get_object("conversation_view"); conversation_selector = ((ConversationSelector) builder.get_object("conversation_list")).init(stream_interactor); - goto_end_revealer = (Revealer) builder.get_object("goto_end_revealer"); - goto_end_button = (Button) builder.get_object("goto_end_button"); search_box = ((GlobalSearch) builder.get_object("search_box")).init(stream_interactor); search_revealer = (Revealer) builder.get_object("search_revealer"); search_entry = (SearchEntry) builder.get_object("search_entry"); @@ -103,7 +95,7 @@ public class UnifiedWindow : Gtk.Window { box.add(headerbar_paned); } - headerbar_paned.key_press_event.connect(forward_key_press_to_chat_input); +// headerbar_paned.key_press_event.connect(forward_key_press_to_chat_input); TODO } private void set_window_buttons() { @@ -153,21 +145,6 @@ public class UnifiedWindow : Gtk.Window { } } - private bool forward_key_press_to_chat_input(EventKey event) { - // Don't forward / change focus on Control / Alt - if (event.keyval == Gdk.Key.Control_L || event.keyval == Gdk.Key.Control_R || - event.keyval == Gdk.Key.Alt_L || event.keyval == Gdk.Key.Alt_R) { - return false; - } - // Don't forward / change focus on Control + ... - if ((event.state & ModifierType.CONTROL_MASK) > 0) { - return false; - } - chat_input.text_input.key_press_event(event); - chat_input.text_input.grab_focus(); - return true; - } - public void loop_conversations(bool backwards) { conversation_selector.loop_conversations(backwards); } diff --git a/main/src/ui/unified_window_controller.vala b/main/src/ui/unified_window_controller.vala index 9e41aff8..2ee1c452 100644 --- a/main/src/ui/unified_window_controller.vala +++ b/main/src/ui/unified_window_controller.vala @@ -19,7 +19,7 @@ public class UnifiedWindowController : Object { private SearchMenuEntry search_menu_entry = new SearchMenuEntry(); - private ChatInputController chat_input_controller; + private ConversationViewController conversation_view_controller; public UnifiedWindowController(Application application, StreamInteractor stream_interactor, Database db) { this.app = application; @@ -54,18 +54,15 @@ public class UnifiedWindowController : Object { public void set_window(UnifiedWindow window) { this.window = window; - this.chat_input_controller = new ChatInputController(window.chat_input, stream_interactor); + this.conversation_view_controller = new ConversationViewController(window.conversation_view, stream_interactor); this.bind_property("conversation-display-name", window, "title"); this.bind_property("conversation-topic", window, "subtitle"); search_menu_entry.search_button.bind_property("active", window.search_revealer, "reveal_child"); - window.goto_end_button.clicked.connect(() => { - window.conversation_frame.initialize_for_conversation(conversation); - }); window.search_revealer.notify["child-revealed"].connect(() => { if (window.search_revealer.child_revealed) { - if (window.conversation_frame.conversation != null && window.search_box.search_entry.text == "") { + if (window.conversation_view.conversation_frame.conversation != null && window.search_box.search_entry.text == "") { reset_search_entry(); } window.search_box.search_entry.grab_focus_without_selecting(); @@ -74,7 +71,7 @@ public class UnifiedWindowController : Object { }); window.search_box.selected_item.connect((item) => { select_conversation(item.conversation, false, false); - window.conversation_frame.initialize_around_message(item.conversation, item); + window.conversation_view.conversation_frame.initialize_around_message(item.conversation, item); close_search(); }); @@ -88,10 +85,6 @@ public class UnifiedWindowController : Object { window.conversations_placeholder.secondary_button.clicked.connect(() => { app.activate_action("add_conference", null); }); window.conversation_selector.conversation_selected.connect((conversation) => select_conversation(conversation)); - var vadjustment = window.conversation_frame.scrolled.vadjustment; - vadjustment.notify["value"].connect(() => { - window.goto_end_revealer.reveal_child = vadjustment.value < vadjustment.upper - vadjustment.page_size; - }); window.event.connect((event) => { if (event.type == EventType.BUTTON_PRESS) { int dest_x, dest_y; @@ -124,6 +117,8 @@ public class UnifiedWindowController : Object { public void select_conversation(Conversation? conversation, bool do_reset_search = true, bool default_initialize_conversation = true) { this.conversation = conversation; + conversation_view_controller.select_conversation(conversation, default_initialize_conversation); + update_conversation_display_name(); update_conversation_topic(); @@ -141,11 +136,6 @@ public class UnifiedWindowController : Object { if (do_reset_search) { reset_search_entry(); } - chat_input_controller.set_conversation(conversation); - window.chat_input.initialize_for_conversation(conversation); - if (default_initialize_conversation) { - window.conversation_frame.initialize_for_conversation(conversation); - } } private void check_unset_conversation() { @@ -188,7 +178,7 @@ public class UnifiedWindowController : Object { } private void reset_search_entry() { - if (window.conversation_frame.conversation != null) { + if (window.conversation_view.conversation_frame.conversation != null) { switch (conversation.type_) { case Conversation.Type.CHAT: case Conversation.Type.GROUPCHAT_PM: