From 871ff33ac79f3d17b0260b8bfcd27780038edd6d Mon Sep 17 00:00:00 2001 From: fiaxh Date: Fri, 3 Apr 2020 22:49:59 +0200 Subject: Add support for last message correction --- main/src/ui/chat_input/chat_input_controller.vala | 18 +++-- main/src/ui/chat_input/chat_text_view.vala | 91 ++++++++++++++++++++++ main/src/ui/chat_input/edit_history.vala | 4 +- .../src/ui/chat_input/occupants_tab_completer.vala | 2 +- main/src/ui/chat_input/smiley_converter.vala | 2 +- main/src/ui/chat_input/view.vala | 52 ++----------- 6 files changed, 113 insertions(+), 56 deletions(-) create mode 100644 main/src/ui/chat_input/chat_text_view.vala (limited to 'main/src/ui/chat_input') diff --git a/main/src/ui/chat_input/chat_input_controller.vala b/main/src/ui/chat_input/chat_input_controller.vala index f65da1e8..c0878c36 100644 --- a/main/src/ui/chat_input/chat_input_controller.vala +++ b/main/src/ui/chat_input/chat_input_controller.vala @@ -17,18 +17,20 @@ public class ChatInputController : Object { private StreamInteractor stream_interactor; private Plugins.InputFieldStatus input_field_status; + private ChatTextViewController chat_text_view_controller; public ChatInputController(ChatInput.View chat_input, StreamInteractor stream_interactor) { this.chat_input = chat_input; this.status_description_label = chat_input.chat_input_status; this.stream_interactor = stream_interactor; + this.chat_text_view_controller = new ChatTextViewController(chat_input.chat_text_view, stream_interactor); chat_input.init(stream_interactor); reset_input_field_status(); - chat_input.text_input.buffer.changed.connect(on_text_input_changed); - chat_input.send_text.connect(send_text); + chat_input.chat_text_view.text_view.buffer.changed.connect(on_text_input_changed); + chat_text_view_controller.send_text.connect(send_text); chat_input.encryption_widget.encryption_changed.connect(on_encryption_changed); @@ -40,10 +42,10 @@ 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); + + chat_input.initialize_for_conversation(conversation); + chat_text_view_controller.initialize_for_conversation(conversation); } private void on_encryption_changed(Plugins.EncryptionListEntry? encryption_entry) { @@ -81,8 +83,8 @@ public class ChatInputController : Object { return; } - string text = chat_input.text_input.buffer.text; - chat_input.text_input.buffer.text = ""; + string text = chat_input.chat_text_view.text_view.buffer.text; + chat_input.chat_text_view.text_view.buffer.text = ""; if (text.has_prefix("/")) { string[] token = text.split(" ", 2); switch(token[0]) { @@ -137,7 +139,7 @@ public class ChatInputController : Object { } private void on_text_input_changed() { - if (chat_input.text_input.buffer.text != "") { + if (chat_input.chat_text_view.text_view.buffer.text != "") { stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_entered(conversation); } else { stream_interactor.get_module(ChatInteraction.IDENTITY).on_message_cleared(conversation); diff --git a/main/src/ui/chat_input/chat_text_view.vala b/main/src/ui/chat_input/chat_text_view.vala new file mode 100644 index 00000000..1155d21d --- /dev/null +++ b/main/src/ui/chat_input/chat_text_view.vala @@ -0,0 +1,91 @@ +using Gdk; +using Gee; +using Gtk; + +using Dino.Entities; +using Xmpp; + +namespace Dino.Ui { + +public class ChatTextViewController : Object { + + public signal void send_text(); + + public OccupantsTabCompletor occupants_tab_completor; + + private ChatTextView widget; + + public ChatTextViewController(ChatTextView widget, StreamInteractor stream_interactor) { + this.widget = widget; + occupants_tab_completor = new OccupantsTabCompletor(stream_interactor, widget.text_view); + + widget.send_text.connect(() => { + send_text(); + }); + } + + public void initialize_for_conversation(Conversation conversation) { + occupants_tab_completor.initialize_for_conversation(conversation); + widget.initialize_for_conversation(conversation); + } +} + +public class ChatTextView : ScrolledWindow { + + public signal void send_text(); + public signal void cancel_input(); + + public TextView text_view = new TextView() { can_focus=true, hexpand=true, margin=8, wrap_mode=Gtk.WrapMode.WORD_CHAR, valign=Align.CENTER, visible=true }; + private int vscrollbar_min_height; + private SmileyConverter smiley_converter; + public EditHistory edit_history; + + construct { + max_content_height = 300; + propagate_natural_height = true; + this.add(text_view); + + smiley_converter = new SmileyConverter(text_view); + edit_history = new EditHistory(text_view); + + this.get_vscrollbar().get_preferred_height(out vscrollbar_min_height, null); + this.vadjustment.notify["upper"].connect_after(on_upper_notify); + text_view.key_press_event.connect(on_text_input_key_press); + + Gtk.drag_dest_unset(text_view); + } + + public void initialize_for_conversation(Conversation conversation) { + edit_history.initialize_for_conversation(conversation); + } + + public override void get_preferred_height(out int min_height, out int nat_height) { + base.get_preferred_height(out min_height, out nat_height); + min_height = nat_height; + } + + private void on_upper_notify() { + this.vadjustment.value = this.vadjustment.upper - this.vadjustment.page_size; + + // hack for vscrollbar not requiring space and making textview higher //TODO doesn't resize immediately + this.get_vscrollbar().visible = (this.vadjustment.upper > this.max_content_height - 2 * this.vscrollbar_min_height); + } + + private bool on_text_input_key_press(EventKey event) { + if (event.keyval in new uint[]{Key.Return, Key.KP_Enter}) { + if ((event.state & ModifierType.SHIFT_MASK) > 0) { + text_view.buffer.insert_at_cursor("\n", 1); + } else if (text_view.buffer.text != "") { + send_text(); + edit_history.reset_history(); + } + return true; + } + if (event.keyval == Key.Escape) { + cancel_input(); + } + return false; + } +} + +} diff --git a/main/src/ui/chat_input/edit_history.vala b/main/src/ui/chat_input/edit_history.vala index 1d179bb7..70f6d400 100644 --- a/main/src/ui/chat_input/edit_history.vala +++ b/main/src/ui/chat_input/edit_history.vala @@ -4,7 +4,7 @@ using Gtk; using Dino.Entities; -namespace Dino.Ui.ChatInput { +namespace Dino.Ui { public class EditHistory { @@ -14,7 +14,7 @@ public class EditHistory { private HashMap> histories = new HashMap>(Conversation.hash_func, Conversation.equals_func); private HashMap indices = new HashMap(Conversation.hash_func, Conversation.equals_func); - public EditHistory(TextView text_input, GLib.Application application) { + public EditHistory(TextView text_input) { this.text_input = text_input; text_input.key_press_event.connect(on_text_input_key_press); diff --git a/main/src/ui/chat_input/occupants_tab_completer.vala b/main/src/ui/chat_input/occupants_tab_completer.vala index 87db8986..ab1b75e0 100644 --- a/main/src/ui/chat_input/occupants_tab_completer.vala +++ b/main/src/ui/chat_input/occupants_tab_completer.vala @@ -5,7 +5,7 @@ using Gtk; using Dino.Entities; using Xmpp; -namespace Dino.Ui.ChatInput { +namespace Dino.Ui { /** * - With given prefix: Complete from occupant list (sorted lexicographically) diff --git a/main/src/ui/chat_input/smiley_converter.vala b/main/src/ui/chat_input/smiley_converter.vala index a25076ba..8f4dee9a 100644 --- a/main/src/ui/chat_input/smiley_converter.vala +++ b/main/src/ui/chat_input/smiley_converter.vala @@ -4,7 +4,7 @@ using Gtk; using Dino.Entities; -namespace Dino.Ui.ChatInput { +namespace Dino.Ui { class SmileyConverter { diff --git a/main/src/ui/chat_input/view.vala b/main/src/ui/chat_input/view.vala index 960e4e14..166ead2e 100644 --- a/main/src/ui/chat_input/view.vala +++ b/main/src/ui/chat_input/view.vala @@ -10,25 +10,17 @@ namespace Dino.Ui.ChatInput { [GtkTemplate (ui = "/im/dino/Dino/chat_input.ui")] public class View : Box { - public signal void send_text(); - public string text { - owned get { return text_input.buffer.text; } - set { text_input.buffer.text = value; } + owned get { return chat_text_view.text_view.buffer.text; } + set { chat_text_view.text_view.buffer.text = value; } } private StreamInteractor stream_interactor; private Conversation? conversation; private HashMap entry_cache = new HashMap(Conversation.hash_func, Conversation.equals_func); - private int vscrollbar_min_height; - - public OccupantsTabCompletor occupants_tab_completor; - private SmileyConverter smiley_converter; - public EditHistory edit_history; [GtkChild] public Frame frame; - [GtkChild] public ScrolledWindow scrolled; - [GtkChild] public TextView text_input; + [GtkChild] public ChatTextView chat_text_view; [GtkChild] public Box outer_box; [GtkChild] public Button file_button; [GtkChild] public Separator file_separator; @@ -39,9 +31,6 @@ public class View : Box { public View init(StreamInteractor stream_interactor) { this.stream_interactor = stream_interactor; - occupants_tab_completor = new OccupantsTabCompletor(stream_interactor, text_input); - smiley_converter = new SmileyConverter(text_input); - edit_history = new EditHistory(text_input, GLib.Application.get_default()); encryption_widget = new EncryptionButton(stream_interactor) { relief=ReliefStyle.NONE, margin_top=3, valign=Align.START, visible=true }; file_button.clicked.connect(() => { @@ -53,9 +42,6 @@ public class View : Box { }); file_button.get_style_context().add_class("dino-attach-button"); - scrolled.get_vscrollbar().get_preferred_height(out vscrollbar_min_height, null); - scrolled.vadjustment.notify["upper"].connect_after(on_upper_notify); - encryption_widget.get_style_context().add_class("dino-chatinput-button"); encryption_widget.encryption_changed.connect(update_file_transfer_availability); @@ -68,7 +54,7 @@ public class View : Box { EmojiChooser chooser = new EmojiChooser(); chooser.emoji_picked.connect((emoji) => { - text_input.buffer.insert_at_cursor(emoji, emoji.data.length); + chat_text_view.text_view.buffer.insert_at_cursor(emoji, emoji.data.length); }); emoji_button.set_popover(chooser); @@ -77,8 +63,6 @@ public class View : Box { outer_box.add(encryption_widget); - text_input.key_press_event.connect(on_text_input_key_press); - Util.force_css(frame, "* { border-radius: 3px; }"); return this; @@ -91,17 +75,17 @@ public class View : Box { } public void initialize_for_conversation(Conversation conversation) { - if (this.conversation != null) entry_cache[this.conversation] = text_input.buffer.text; + if (this.conversation != null) entry_cache[this.conversation] = chat_text_view.text_view.buffer.text; this.conversation = conversation; update_file_transfer_availability(); - text_input.buffer.text = ""; + chat_text_view.text_view.buffer.text = ""; if (entry_cache.has_key(conversation)) { - text_input.buffer.text = entry_cache[conversation]; + chat_text_view.text_view.buffer.text = entry_cache[conversation]; } - text_input.grab_focus(); + chat_text_view.text_view.grab_focus(); } public void set_input_state(Plugins.InputFieldStatus.MessageType message_type) { @@ -132,26 +116,6 @@ public class View : Box { return false; }); } - - private bool on_text_input_key_press(EventKey event) { - if (event.keyval in new uint[]{Key.Return, Key.KP_Enter}) { - if ((event.state & ModifierType.SHIFT_MASK) > 0) { - text_input.buffer.insert_at_cursor("\n", 1); - } else if (this.text != "") { - send_text(); - edit_history.reset_history(); - } - return true; - } - return false; - } - - private void on_upper_notify() { - scrolled.vadjustment.value = scrolled.vadjustment.upper - scrolled.vadjustment.page_size; - - // hack for vscrollbar not requiring space and making textview higher //TODO doesn't resize immediately - scrolled.get_vscrollbar().visible = (scrolled.vadjustment.upper > scrolled.max_content_height - 2 * vscrollbar_min_height); - } } } -- cgit v1.2.3-54-g00ecf