aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/chat_input
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2022-02-14 14:55:59 +0100
committerfiaxh <git@lightrise.org>2022-07-27 20:34:20 +0200
commit7e7dcedaf31ee35499875491c9f569c575d28435 (patch)
tree0c5fee2b28baf320775fbc92b3c252e97d9d054f /main/src/ui/chat_input
parentf25bfb00969a7e09996da2d5500e6718f4cc0148 (diff)
downloaddino-7e7dcedaf31ee35499875491c9f569c575d28435.tar.gz
dino-7e7dcedaf31ee35499875491c9f569c575d28435.zip
Port from GTK3 to GTK4
Diffstat (limited to 'main/src/ui/chat_input')
-rw-r--r--main/src/ui/chat_input/chat_input_controller.vala15
-rw-r--r--main/src/ui/chat_input/chat_text_view.vala55
-rw-r--r--main/src/ui/chat_input/edit_history.vala77
-rw-r--r--main/src/ui/chat_input/encryption_button.vala43
-rw-r--r--main/src/ui/chat_input/occupants_tab_completer.vala14
-rw-r--r--main/src/ui/chat_input/smiley_converter.vala8
-rw-r--r--main/src/ui/chat_input/view.vala30
7 files changed, 80 insertions, 162 deletions
diff --git a/main/src/ui/chat_input/chat_input_controller.vala b/main/src/ui/chat_input/chat_input_controller.vala
index d7a69c3d..41891519 100644
--- a/main/src/ui/chat_input/chat_input_controller.vala
+++ b/main/src/ui/chat_input/chat_input_controller.vala
@@ -34,9 +34,12 @@ public class ChatInputController : Object {
reset_input_field_status();
- chat_input.chat_text_view.text_view.buffer.changed.connect(on_text_input_changed);
- chat_input.chat_text_view.text_view.key_press_event.connect(on_text_input_key_press);
+ var text_input_key_events = new EventControllerKey();
+ text_input_key_events.key_pressed.connect(on_text_input_key_press);
+ chat_input.chat_text_view.text_view.add_controller(text_input_key_events);
+
chat_input.chat_text_view.text_view.paste_clipboard.connect(() => clipboard_pasted());
+ chat_input.chat_text_view.text_view.buffer.changed.connect(on_text_input_changed);
chat_text_view_controller.send_text.connect(send_text);
@@ -50,7 +53,7 @@ public class ChatInputController : Object {
status_description_label.activate_link.connect((uri) => {
if (uri == OPEN_CONVERSATION_DETAILS_URI){
ContactDetails.Dialog contact_details_dialog = new ContactDetails.Dialog(stream_interactor, conversation);
- contact_details_dialog.set_transient_for((Gtk.Window) chat_input.get_toplevel());
+ contact_details_dialog.set_transient_for((Gtk.Window) chat_input.get_root());
contact_details_dialog.present();
}
return true;
@@ -136,7 +139,7 @@ public class ChatInputController : Object {
case "/ping":
Xmpp.XmppStream? stream = stream_interactor.get_stream(conversation.account);
try {
- stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping.begin(stream, conversation.counterpart.with_resource(token[1]), null);
+ stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping.begin(stream, conversation.counterpart.with_resource(token[1]));
} catch (Xmpp.InvalidJidError e) {
warning("Could not ping invalid Jid: %s", e.message);
}
@@ -184,8 +187,8 @@ public class ChatInputController : Object {
}
}
- private bool on_text_input_key_press(EventKey event) {
- if (event.keyval == Gdk.Key.Up && chat_input.chat_text_view.text_view.buffer.text == "") {
+ private bool on_text_input_key_press(uint keyval, uint keycode, Gdk.ModifierType state) {
+ if (keyval == Gdk.Key.Up && chat_input.chat_text_view.text_view.buffer.text == "") {
activate_last_message_correction();
return true;
} else {
diff --git a/main/src/ui/chat_input/chat_text_view.vala b/main/src/ui/chat_input/chat_text_view.vala
index 2f8393d2..b1f719b6 100644
--- a/main/src/ui/chat_input/chat_text_view.vala
+++ b/main/src/ui/chat_input/chat_text_view.vala
@@ -30,61 +30,64 @@ public class ChatTextViewController : Object {
}
}
-public class ChatTextView : ScrolledWindow {
+public class ChatTextView : Box {
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 };
+ public ScrolledWindow scrolled_window = new ScrolledWindow() { propagate_natural_height=true, max_content_height=300 };
+ public TextView text_view = new TextView() { hexpand=true, wrap_mode=Gtk.WrapMode.WORD_CHAR, valign=Align.CENTER, margin_top=7, margin_bottom=7 };
private int vscrollbar_min_height;
private SmileyConverter smiley_converter;
- public EditHistory edit_history;
- private SpellChecker spell_checker;
+// private SpellChecker spell_checker;
construct {
- max_content_height = 300;
- propagate_natural_height = true;
- this.add(text_view);
+ scrolled_window.set_child(text_view);
+ this.append(scrolled_window);
smiley_converter = new SmileyConverter(text_view);
- edit_history = new EditHistory(text_view);
- spell_checker = new SpellChecker(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);
+// scrolled_window.get_vscrollbar().get_preferred_size(out vscrollbar_min_size, null);
+ scrolled_window.vadjustment.notify["upper"].connect(on_upper_notify);
- Gtk.drag_dest_unset(text_view);
+ var text_input_key_events = new EventControllerKey();
+ text_input_key_events.key_pressed.connect(on_text_input_key_press);
+ text_view.add_controller(text_input_key_events);
+
+ text_view.realize.connect(() => {
+ var minimum_size = new Requisition();
+ scrolled_window.get_preferred_size(out minimum_size, null);
+ vscrollbar_min_height = minimum_size.height;
+ });
+// Gtk.drag_dest_unset(text_view);
}
public void initialize_for_conversation(Conversation conversation) {
- edit_history.initialize_for_conversation(conversation);
- spell_checker.initialize_for_conversation(conversation);
+// spell_checker.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;
- }
+// public override void get_preferred_size(out Gtk.Requisition minimum_size, out Gtk.Requisition natural_size) {
+// 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;
+ scrolled_window.vadjustment.value = scrolled_window.vadjustment.upper - scrolled_window.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);
+ scrolled_window.get_vscrollbar().visible = (scrolled_window.vadjustment.upper > scrolled_window.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) {
+ private bool on_text_input_key_press(uint keyval, uint keycode, Gdk.ModifierType state) {
+ if (keyval in new uint[]{ Key.Return, Key.KP_Enter }) {
+ if ((state & ModifierType.SHIFT_MASK) > 0) {
text_view.buffer.insert_at_cursor("\n", 1);
} else if (text_view.buffer.text.strip() != "") {
send_text();
- edit_history.reset_history();
}
return true;
}
- if (event.keyval == Key.Escape) {
+ if (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
deleted file mode 100644
index 70f6d400..00000000
--- a/main/src/ui/chat_input/edit_history.vala
+++ /dev/null
@@ -1,77 +0,0 @@
-using Gdk;
-using Gee;
-using Gtk;
-
-using Dino.Entities;
-
-namespace Dino.Ui {
-
-public class EditHistory {
-
- private Conversation? conversation;
- private TextView text_input;
-
- private HashMap<Conversation, Gee.List<string>> histories = new HashMap<Conversation, Gee.List<string>>(Conversation.hash_func, Conversation.equals_func);
- private HashMap<Conversation, int> indices = new HashMap<Conversation, int>(Conversation.hash_func, Conversation.equals_func);
-
- public EditHistory(TextView text_input) {
- this.text_input = text_input;
-
- text_input.key_press_event.connect(on_text_input_key_press);
- text_input.cut_clipboard.connect_after(save_state);
- text_input.paste_clipboard.connect_after(save_state);
- text_input.move_cursor.connect_after(save_state);
- text_input.button_release_event.connect_after(() => { save_state(); return false; });
- }
-
- public void initialize_for_conversation(Conversation conversation) {
- this.conversation = conversation;
- if (!histories.has_key(conversation)) {
- reset_history();
- }
- }
-
- public bool on_text_input_key_press(EventKey event) {
- bool ctrl_pressed = (event.state & ModifierType.CONTROL_MASK) > 0;
- if (ctrl_pressed && event.keyval == Key.z) {
- undo();
- } else if (ctrl_pressed && (event.keyval in new uint[]{ Key.Z, Key.y } )) {
- redo();
- } else if (event.keyval in new uint[]{ Key.space, Key.Tab, Key.ISO_Left_Tab }) {
- save_state();
- }
- return false;
- }
-
- private void undo() {
- save_state();
- if (indices[conversation] > 0) {
- indices[conversation] = indices[conversation] - 1;
- text_input.buffer.text = histories[conversation][indices[conversation]];
- }
- }
-
- private void redo() {
- if (indices[conversation] < histories[conversation].size - 1) {
- indices[conversation] = indices[conversation] + 1;
- text_input.buffer.text = histories[conversation][indices[conversation]];
- }
- }
-
- private void save_state() {
- if (histories[conversation][indices[conversation]] == text_input.buffer.text) return;
- if (indices[conversation] < histories[conversation].size - 1) {
- histories[conversation] = histories[conversation].slice(0, indices[conversation] + 1);
- }
- histories[conversation].add(text_input.buffer.text);
- indices[conversation] = indices[conversation] + 1;
- }
-
- public void reset_history() {
- histories[conversation] = new ArrayList<string>();
- histories[conversation].add("");
- indices[conversation] = 0;
- }
-}
-
-}
diff --git a/main/src/ui/chat_input/encryption_button.vala b/main/src/ui/chat_input/encryption_button.vala
index 11466931..e5831802 100644
--- a/main/src/ui/chat_input/encryption_button.vala
+++ b/main/src/ui/chat_input/encryption_button.vala
@@ -5,27 +5,25 @@ using Dino.Entities;
namespace Dino.Ui {
-public class EncryptionButton : MenuButton {
+public class EncryptionButton {
public signal void encryption_changed(Plugins.EncryptionListEntry? encryption_entry);
+ private MenuButton menu_button;
private Conversation? conversation;
- private RadioButton? button_unencrypted;
- private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
+ private CheckButton? button_unencrypted;
+ private Map<CheckButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<CheckButton, Plugins.EncryptionListEntry>();
private string? current_icon;
private StreamInteractor stream_interactor;
- public EncryptionButton(StreamInteractor stream_interactor) {
+ public EncryptionButton(StreamInteractor stream_interactor, MenuButton menu_button) {
this.stream_interactor = stream_interactor;
-
- use_popover = true;
- image = new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON);
- get_style_context().add_class("flat");
+ this.menu_button = menu_button;
Builder builder = new Builder.from_resource("/im/dino/Dino/menu_encryption.ui");
- popover = builder.get_object("menu_encryption") as PopoverMenu;
+ menu_button.popover = builder.get_object("menu_encryption") as PopoverMenu;
Box encryption_box = builder.get_object("encryption_box") as Box;
- button_unencrypted = builder.get_object("button_unencrypted") as RadioButton;
+ button_unencrypted = builder.get_object("button_unencrypted") as CheckButton;
button_unencrypted.toggled.connect(encryption_button_toggled);
stream_interactor.get_module(MucManager.IDENTITY).room_info_updated.connect((account, muc_jid) => {
@@ -36,17 +34,18 @@ public class EncryptionButton : MenuButton {
Application app = GLib.Application.get_default() as Application;
foreach (var e in app.plugin_registry.encryption_list_entries) {
- RadioButton btn = new RadioButton.with_label(button_unencrypted.get_group(), e.name);
+ CheckButton btn = new CheckButton.with_label(e.name);
+ btn.set_group(button_unencrypted);
encryption_radios[btn] = e;
btn.toggled.connect(encryption_button_toggled);
btn.visible = true;
- encryption_box.pack_end(btn, false);
+ encryption_box.prepend(btn);
}
- clicked.connect(update_encryption_menu_state);
+ menu_button.activate.connect(update_encryption_menu_state);
}
private void encryption_button_toggled() {
- foreach (RadioButton e in encryption_radios.keys) {
+ foreach (CheckButton e in encryption_radios.keys) {
if (e.get_active()) {
conversation.encryption = encryption_radios[e].encryption;
encryption_changed(encryption_radios[e]);
@@ -62,7 +61,7 @@ public class EncryptionButton : MenuButton {
}
private void update_encryption_menu_state() {
- foreach (RadioButton e in encryption_radios.keys) {
+ foreach (CheckButton e in encryption_radios.keys) {
if (conversation.encryption == encryption_radios[e].encryption) {
e.set_active(true);
encryption_changed(encryption_radios[e]);
@@ -76,7 +75,7 @@ public class EncryptionButton : MenuButton {
private void set_icon(string icon) {
if (icon != current_icon) {
- image = new Image.from_icon_name(icon, IconSize.BUTTON);
+ menu_button.set_icon_name(icon);
current_icon = icon;
}
}
@@ -87,23 +86,23 @@ public class EncryptionButton : MenuButton {
private void update_visibility() {
if (conversation.encryption != Encryption.NONE) {
- visible = true;
+ menu_button.visible = true;
return;
}
switch (conversation.type_) {
case Conversation.Type.CHAT:
- visible = true;
+ menu_button.visible = true;
break;
case Conversation.Type.GROUPCHAT_PM:
- visible = false;
+ menu_button.visible = false;
break;
case Conversation.Type.GROUPCHAT:
- visible = stream_interactor.get_module(MucManager.IDENTITY).is_private_room(conversation.account, conversation.counterpart);
+ menu_button.visible = stream_interactor.get_module(MucManager.IDENTITY).is_private_room(conversation.account, conversation.counterpart);
break;
}
}
- public new void set_conversation(Conversation conversation) {
+ public void set_conversation(Conversation conversation) {
this.conversation = conversation;
update_encryption_menu_state();
update_encryption_menu_icon();
@@ -111,4 +110,4 @@ public class EncryptionButton : MenuButton {
}
}
-}
+} \ No newline at end of file
diff --git a/main/src/ui/chat_input/occupants_tab_completer.vala b/main/src/ui/chat_input/occupants_tab_completer.vala
index 6d2a7434..e50fe831 100644
--- a/main/src/ui/chat_input/occupants_tab_completer.vala
+++ b/main/src/ui/chat_input/occupants_tab_completer.vala
@@ -27,16 +27,18 @@ public class OccupantsTabCompletor {
this.stream_interactor = stream_interactor;
this.text_input = text_input;
- text_input.key_press_event.connect(on_text_input_key_press);
+ var text_input_key_events = new EventControllerKey();
+ text_input_key_events.key_pressed.connect(on_text_input_key_press);
+ text_input.add_controller(text_input_key_events);
}
public void initialize_for_conversation(Conversation conversation) {
this.conversation = conversation;
}
- public bool on_text_input_key_press(EventKey event) {
+ public bool on_text_input_key_press(uint keyval, uint keycode, Gdk.ModifierType state) {
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- if (event.keyval == Key.Tab || event.keyval == Key.ISO_Left_Tab) {
+ if (keyval == Key.Tab || keyval == Key.ISO_Left_Tab) {
string text = text_input.buffer.text;
int start_index = int.max(text.last_index_of(" "), text.last_index_of("\n")) + 1;
string word = text.substring(start_index);
@@ -51,11 +53,11 @@ public class OccupantsTabCompletor {
index = -1;
}
}
- if (event.keyval != Key.ISO_Group_Shift && active) {
- text_input.buffer.text = next_completion(event.keyval == Key.ISO_Left_Tab);
+ if (keyval != Key.ISO_Group_Shift && active) {
+ text_input.buffer.text = next_completion(keyval == Key.ISO_Left_Tab);
return true;
}
- } else if (event.keyval != Key.Shift_L && active) {
+ } else if (keyval != Key.Shift_L && active) {
active = false;
}
}
diff --git a/main/src/ui/chat_input/smiley_converter.vala b/main/src/ui/chat_input/smiley_converter.vala
index 8f4dee9a..fe280d99 100644
--- a/main/src/ui/chat_input/smiley_converter.vala
+++ b/main/src/ui/chat_input/smiley_converter.vala
@@ -33,11 +33,13 @@ class SmileyConverter {
public SmileyConverter(TextView text_input) {
this.text_input = text_input;
- text_input.key_press_event.connect(on_text_input_key_press);
+ var text_input_key_events = new EventControllerKey();
+ text_input_key_events.key_pressed.connect(on_text_input_key_press);
+ text_input.add_controller(text_input_key_events);
}
- public bool on_text_input_key_press(EventKey event) {
- if (event.keyval == Key.space || event.keyval == Key.Return) {
+ public bool on_text_input_key_press(uint keyval, uint keycode, Gdk.ModifierType state) {
+ if (keyval == Key.space || keyval == Key.Return) {
check_convert();
}
return false;
diff --git a/main/src/ui/chat_input/view.vala b/main/src/ui/chat_input/view.vala
index 5142eb10..6524a825 100644
--- a/main/src/ui/chat_input/view.vala
+++ b/main/src/ui/chat_input/view.vala
@@ -23,6 +23,8 @@ public class View : Box {
[GtkChild] public unowned ChatTextView chat_text_view;
[GtkChild] public unowned Box outer_box;
[GtkChild] public unowned Button file_button;
+ [GtkChild] public unowned MenuButton emoji_button;
+ [GtkChild] public unowned MenuButton encryption_button;
[GtkChild] public unowned Separator file_separator;
[GtkChild] public unowned Label chat_input_status;
@@ -31,29 +33,13 @@ public class View : Box {
public View init(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
- encryption_widget = new EncryptionButton(stream_interactor) { relief=ReliefStyle.NONE, margin_top=3, valign=Align.START, visible=true };
+ encryption_widget = new EncryptionButton(stream_interactor, encryption_button);
- file_button.get_style_context().add_class("dino-attach-button");
-
- encryption_widget.get_style_context().add_class("dino-chatinput-button");
-
- // Emoji button for emoji picker (recents don't work < 3.22.19, category icons don't work <3.23.2)
- if (Gtk.get_major_version() >= 3 && Gtk.get_minor_version() >= 24) {
- MenuButton emoji_button = new MenuButton() { relief=ReliefStyle.NONE, margin_top=3, valign=Align.START, visible=true };
- emoji_button.get_style_context().add_class("flat");
- emoji_button.get_style_context().add_class("dino-chatinput-button");
- emoji_button.image = new Image.from_icon_name("dino-emoticon-symbolic", IconSize.BUTTON) { visible=true };
-
- EmojiChooser chooser = new EmojiChooser();
- chooser.emoji_picked.connect((emoji) => {
- chat_text_view.text_view.buffer.insert_at_cursor(emoji, emoji.data.length);
- });
- emoji_button.set_popover(chooser);
-
- outer_box.add(emoji_button);
- }
-
- outer_box.add(encryption_widget);
+ EmojiChooser chooser = new EmojiChooser();
+ chooser.emoji_picked.connect((emoji) => {
+ chat_text_view.text_view.buffer.insert_at_cursor(emoji, emoji.data.length);
+ });
+ emoji_button.set_popover(chooser);
Util.force_css(frame, "* { border-radius: 3px; }");