aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2022-05-14 14:45:59 +0200
committerfiaxh <git@lightrise.org>2022-07-27 20:34:20 +0200
commitf44cbe02c17df1f02ad49c63cd784fec0ea02d85 (patch)
tree4cab9b5f84d88769d19b0698e24b318f50b6144e /main/src/ui
parent2b3ce5fc95c63ed7d54e207db0585c8b8bbcd603 (diff)
downloaddino-f44cbe02c17df1f02ad49c63cd784fec0ea02d85.tar.gz
dino-f44cbe02c17df1f02ad49c63cd784fec0ea02d85.zip
Improve Gtk4 port
Diffstat (limited to 'main/src/ui')
-rw-r--r--main/src/ui/add_conversation/add_conference_dialog.vala53
-rw-r--r--main/src/ui/add_conversation/add_groupchat_dialog.vala2
-rw-r--r--main/src/ui/add_conversation/conference_list.vala17
-rw-r--r--main/src/ui/add_conversation/list_row.vala6
-rw-r--r--main/src/ui/add_conversation/roster_list.vala10
-rw-r--r--main/src/ui/add_conversation/select_contact_dialog.vala4
-rw-r--r--main/src/ui/add_conversation/select_jid_fragment.vala18
-rw-r--r--main/src/ui/application.vala13
-rw-r--r--main/src/ui/avatar_image.vala3
-rw-r--r--main/src/ui/call_window/audio_settings_popover.vala44
-rw-r--r--main/src/ui/call_window/call_bottom_bar.vala57
-rw-r--r--main/src/ui/call_window/call_connection_details_window.vala30
-rw-r--r--main/src/ui/call_window/call_encryption_button.vala28
-rw-r--r--main/src/ui/call_window/call_window.vala27
-rw-r--r--main/src/ui/call_window/call_window_controller.vala9
-rw-r--r--main/src/ui/call_window/participant_widget.vala31
-rw-r--r--main/src/ui/call_window/video_settings_popover.vala24
-rw-r--r--main/src/ui/chat_input/chat_text_view.vala26
-rw-r--r--main/src/ui/chat_input/encryption_button.vala54
-rw-r--r--main/src/ui/chat_input/view.vala20
-rw-r--r--main/src/ui/contact_details/blocking_provider.vala2
-rw-r--r--main/src/ui/contact_details/dialog.vala50
-rw-r--r--main/src/ui/contact_details/permissions_provider.vala2
-rw-r--r--main/src/ui/contact_details/settings_provider.vala4
-rw-r--r--main/src/ui/conversation_content/conversation_item_factory.vala36
-rw-r--r--main/src/ui/conversation_content_view/call_widget.vala16
-rw-r--r--main/src/ui/conversation_content_view/chat_state_populator.vala8
-rw-r--r--main/src/ui/conversation_content_view/conversation_item_skeleton.vala40
-rw-r--r--main/src/ui/conversation_content_view/conversation_view.vala9
-rw-r--r--main/src/ui/conversation_content_view/date_separator_populator.vala8
-rw-r--r--main/src/ui/conversation_content_view/file_default_widget.vala4
-rw-r--r--main/src/ui/conversation_content_view/file_image_widget.vala4
-rw-r--r--main/src/ui/conversation_content_view/file_widget.vala12
-rw-r--r--main/src/ui/conversation_content_view/message_item_widget.vala229
-rw-r--r--main/src/ui/conversation_content_view/message_widget.vala2
-rw-r--r--main/src/ui/conversation_content_view/subscription_notification.vala8
-rw-r--r--main/src/ui/conversation_list/conversation_list_item_factory.vala245
-rw-r--r--main/src/ui/conversation_list/conversation_list_model.vala141
-rw-r--r--main/src/ui/conversation_list/conversation_list_row.vala41
-rw-r--r--main/src/ui/conversation_selector/conversation_selector.vala50
-rw-r--r--main/src/ui/conversation_selector/conversation_selector_row.vala14
-rw-r--r--main/src/ui/conversation_titlebar/call_entry.vala1
-rw-r--r--main/src/ui/conversation_titlebar/conversation_titlebar.vala14
-rw-r--r--main/src/ui/conversation_view.vala4
-rw-r--r--main/src/ui/conversation_view_controller.vala149
-rw-r--r--main/src/ui/file_send_overlay.vala31
-rw-r--r--main/src/ui/global_search.vala24
-rw-r--r--main/src/ui/main_window.vala4
-rw-r--r--main/src/ui/main_window_controller.vala7
-rw-r--r--main/src/ui/manage_accounts/add_account_dialog.vala44
-rw-r--r--main/src/ui/manage_accounts/dialog.vala33
-rw-r--r--main/src/ui/occupant_menu/list.vala10
-rw-r--r--main/src/ui/occupant_menu/view.vala27
-rw-r--r--main/src/ui/util/data_forms.vala8
-rw-r--r--main/src/ui/util/label_hybrid.vala23
-rw-r--r--main/src/ui/util/scaling_image.vala14
-rw-r--r--main/src/ui/util/sizing_bin.vala5
57 files changed, 541 insertions, 1258 deletions
diff --git a/main/src/ui/add_conversation/add_conference_dialog.vala b/main/src/ui/add_conversation/add_conference_dialog.vala
index e078bc62..4b7364c7 100644
--- a/main/src/ui/add_conversation/add_conference_dialog.vala
+++ b/main/src/ui/add_conversation/add_conference_dialog.vala
@@ -10,7 +10,7 @@ namespace Dino.Ui {
public class AddConferenceDialog : Gtk.Dialog {
private Stack stack = new Stack();
- private Button cancel_button = new Button() { visible=true };
+ private Button cancel_button = new Button();
private Button ok_button;
private SelectJidFragment select_fragment;
@@ -70,12 +70,12 @@ public class AddConferenceDialog : Gtk.Dialog {
stack.transition_type = StackTransitionType.SLIDE_LEFT;
stack.set_visible_child_name("details");
-// animate_window_resize();
+ animate_window_resize(details_fragment);
}
private void setup_headerbar() {
- ok_button = new Button() { can_focus=true, visible=true };
- ok_button.get_style_context().add_class("suggested-action");
+ ok_button = new Button() { can_focus=true };
+ ok_button.add_css_class("suggested-action");
if (Util.use_csd()) {
HeaderBar header_bar = get_header_bar() as HeaderBar;
@@ -104,18 +104,18 @@ public class AddConferenceDialog : Gtk.Dialog {
stream_interactor.get_module(MucManager.IDENTITY).remove_bookmark(conference_row.account, conference_row.bookmark);
});
- Box wrap_box = new Box(Orientation.VERTICAL, 0) { visible=true };
+ Box wrap_box = new Box(Orientation.VERTICAL, 0);
wrap_box.append(select_fragment);
stack.add_named(wrap_box, "select");
if (!Util.use_csd()) {
- Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80, visible=true };
+ Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80 };
- Button ok_button = new Button.with_label(_("Next")) { sensitive=false, halign = Align.END, can_focus=true, visible=true };
- ok_button.get_style_context().add_class("suggested-action");
+ Button ok_button = new Button.with_label(_("Next")) { sensitive=false, halign = Align.END, can_focus=true };
+ ok_button.add_css_class("suggested-action");
ok_button.clicked.connect(on_next_button_clicked);
select_fragment.notify["done"].connect(() => { ok_button.sensitive = select_fragment.done; });
- Button cancel_button = new Button.with_label(_("Cancel")) { halign=Align.START, visible=true };
+ Button cancel_button = new Button.with_label(_("Cancel")) { halign=Align.START };
cancel_button.clicked.connect(on_cancel);
box.append(cancel_button);
box.append(ok_button);
@@ -129,18 +129,18 @@ public class AddConferenceDialog : Gtk.Dialog {
details_fragment = new ConferenceDetailsFragment(stream_interactor) { ok_button=ok_button };
details_fragment.joined.connect(() => this.close());
- Box wrap_box = new Box(Orientation.VERTICAL, 0) { visible=true };
+ Box wrap_box = new Box(Orientation.VERTICAL, 0);
wrap_box.append(details_fragment);
if (!Util.use_csd()) {
- Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80, visible=true };
+ Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80 };
- Button ok_button = new Button.with_label(_("Join")) { halign = Align.END, can_focus=true, visible=true };
- ok_button.get_style_context().add_class("suggested-action");
+ Button ok_button = new Button.with_label(_("Join")) { halign = Align.END, can_focus=true };
+ ok_button.add_css_class("suggested-action");
details_fragment.notify["done"].connect(() => { ok_button.sensitive = select_fragment.done; });
details_fragment.ok_button = ok_button;
- Button cancel_button = new Button.with_label(_("Back")) { halign=Align.START, visible=true };
+ Button cancel_button = new Button.with_label(_("Back")) { halign=Align.START };
cancel_button.clicked.connect(show_jid_add_view);
box.append(cancel_button);
box.append(ok_button);
@@ -180,23 +180,20 @@ public class AddConferenceDialog : Gtk.Dialog {
close();
}
- private void animate_window_resize() {
+ private void animate_window_resize(Widget widget) {
int curr_height = get_size(Orientation.VERTICAL);
- int curr_width = get_size(Orientation.HORIZONTAL);
- var natural_size = new Requisition();
- stack.get_preferred_size(null, out natural_size);
+ var natural_size = Requisition();
+ widget.get_preferred_size(null, out natural_size);
int difference = natural_size.height - curr_height;
Timer timer = new Timer();
- Timeout.add((int) (stack.transition_duration / 30),
- () => {
- ulong microsec;
- timer.elapsed(out microsec);
- ulong millisec = microsec / 1000;
- double partial = double.min(1, (double) millisec / stack.transition_duration);
- var a = this.list_toplevels().nth_data(0);
- set_size_request(curr_width, (int) (curr_height + difference * partial));
- return millisec < stack.transition_duration;
- });
+ Timeout.add((int) (stack.transition_duration / 30), () => {
+ ulong microsec;
+ timer.elapsed(out microsec);
+ ulong millisec = microsec / 1000;
+ double partial = double.min(1, (double) millisec / stack.transition_duration);
+ default_height = (int) (curr_height + difference * partial);
+ return millisec < stack.transition_duration;
+ });
}
}
diff --git a/main/src/ui/add_conversation/add_groupchat_dialog.vala b/main/src/ui/add_conversation/add_groupchat_dialog.vala
index 786c1a0b..a94b8c86 100644
--- a/main/src/ui/add_conversation/add_groupchat_dialog.vala
+++ b/main/src/ui/add_conversation/add_groupchat_dialog.vala
@@ -24,7 +24,7 @@ protected class AddGroupchatDialog : Gtk.Dialog {
Object(use_header_bar : 1);
this.stream_interactor = stream_interactor;
ok_button.label = _("Add");
- ok_button.get_style_context().add_class("suggested-action"); // TODO why doesn't it work in XML
+ ok_button.add_css_class("suggested-action"); // TODO why doesn't it work in XML
accounts_stack.set_visible_child_name("combobox");
account_combobox.initialize(stream_interactor);
diff --git a/main/src/ui/add_conversation/conference_list.vala b/main/src/ui/add_conversation/conference_list.vala
index a19630e4..181c6219 100644
--- a/main/src/ui/add_conversation/conference_list.vala
+++ b/main/src/ui/add_conversation/conference_list.vala
@@ -20,10 +20,6 @@ protected class ConferenceList {
public ConferenceList(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
-// list_box.set_filter_func(filter);
- list_box.set_header_func(header);
-// list_box.set_sort_func(sort);
-
stream_interactor.get_module(MucManager.IDENTITY).bookmarks_updated.connect((account, conferences) => {
lists[account] = conferences;
refresh_conferences();
@@ -57,7 +53,12 @@ protected class ConferenceList {
}
public void refresh_conferences() {
-// @foreach((widget) => { remove(widget); });
+ foreach (Account account in widgets.keys) {
+ foreach (Jid jid in widgets[account].keys) {
+ remove_conference(account, jid);
+ }
+ }
+
foreach (Account account in lists.keys) {
foreach (Conference conference in lists[account]) {
add_conference(account, conference);
@@ -74,12 +75,6 @@ protected class ConferenceList {
refresh_conferences();
}
- private void header(ListBoxRow row, ListBoxRow? before_row) {
- if (row.get_header() == null && before_row != null) {
- row.set_header(new Separator(Orientation.HORIZONTAL));
- }
- }
-
public ListBox get_list_box() {
return list_box;
}
diff --git a/main/src/ui/add_conversation/list_row.vala b/main/src/ui/add_conversation/list_row.vala
index 326dba98..a25ecbd3 100644
--- a/main/src/ui/add_conversation/list_row.vala
+++ b/main/src/ui/add_conversation/list_row.vala
@@ -24,7 +24,7 @@ public class ListRow : Widget {
via_label = (Label) builder.get_object("via_label");
this.layout_manager = new BinLayout();
- outer_grid.insert_after(this, null);
+ outer_grid.set_parent(this);
}
public ListRow() {}
@@ -47,6 +47,10 @@ public class ListRow : Widget {
name_label.label = display_name;
image.set_conversation(stream_interactor, conv);
}
+
+ public override void dispose() {
+ outer_grid.unparent();
+ }
}
}
diff --git a/main/src/ui/add_conversation/roster_list.vala b/main/src/ui/add_conversation/roster_list.vala
index a89d24e8..25827d67 100644
--- a/main/src/ui/add_conversation/roster_list.vala
+++ b/main/src/ui/add_conversation/roster_list.vala
@@ -20,10 +20,6 @@ protected class RosterList {
this.stream_interactor = stream_interactor;
this.accounts = accounts;
-// set_filter_func(filter);
- list_box.set_header_func(header);
-// set_sort_func(sort);
-
handler_ids += stream_interactor.get_module(RosterManager.IDENTITY).removed_roster_item.connect( (account, jid, roster_item) => {
if (accounts.contains(account)) {
on_removed_roster_item(account, jid, roster_item);
@@ -64,12 +60,6 @@ protected class RosterList {
}
}
- private void header(ListBoxRow row, ListBoxRow? before_row) {
- if (row.get_header() == null && before_row != null) {
- row.set_header(new Separator(Orientation.HORIZONTAL));
- }
- }
-
public ListBox get_list_box() {
return list_box;
}
diff --git a/main/src/ui/add_conversation/select_contact_dialog.vala b/main/src/ui/add_conversation/select_contact_dialog.vala
index 4bf5b193..09ac1636 100644
--- a/main/src/ui/add_conversation/select_contact_dialog.vala
+++ b/main/src/ui/add_conversation/select_contact_dialog.vala
@@ -40,7 +40,7 @@ public class SelectContactDialog : Gtk.Dialog {
cancel_button.visible = true;
ok_button = new Button();
- ok_button.get_style_context().add_class("suggested-action");
+ ok_button.add_css_class("suggested-action");
ok_button.sensitive = false;
ok_button.visible = true;
@@ -51,7 +51,7 @@ public class SelectContactDialog : Gtk.Dialog {
header_bar.pack_start(cancel_button);
header_bar.pack_end(ok_button);
} else {
- Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80, visible=true };
+ Box box = new Box(Orientation.HORIZONTAL, 5) { halign=Align.END, margin_bottom=15, margin_start=80, margin_end=80 };
cancel_button.halign = Align.START;
ok_button.halign = Align.END;
diff --git a/main/src/ui/add_conversation/select_jid_fragment.vala b/main/src/ui/add_conversation/select_jid_fragment.vala
index 58f019c1..a6cf0864 100644
--- a/main/src/ui/add_conversation/select_jid_fragment.vala
+++ b/main/src/ui/add_conversation/select_jid_fragment.vala
@@ -23,7 +23,7 @@ public class SelectJidFragment : Gtk.Box {
private StreamInteractor stream_interactor;
private Gee.List<Account> accounts;
- private ArrayList<AddListRow> added_rows = new ArrayList<AddListRow>();
+ private ArrayList<Widget> added_rows = new ArrayList<Widget>();
private ListBox list;
private string[]? filter_values;
@@ -39,6 +39,7 @@ public class SelectJidFragment : Gtk.Box {
list.set_sort_func(sort);
list.set_filter_func(filter);
+ list.set_header_func(header);
list.row_selected.connect(check_buttons_active);
list.row_selected.connect(() => { done = true; }); // just for notifying
entry.changed.connect(() => { set_filter(entry.text); });
@@ -49,7 +50,7 @@ public class SelectJidFragment : Gtk.Box {
public void set_filter(string str) {
if (entry.text != str) entry.text = str;
- foreach (AddListRow row in added_rows) list.remove(row);
+ foreach (Widget row in added_rows) list.remove(row);
added_rows.clear();
filter_values = str == "" ? null : str.split(" ");
@@ -59,9 +60,10 @@ public class SelectJidFragment : Gtk.Box {
Jid parsed_jid = new Jid(str);
if (parsed_jid != null && parsed_jid.localpart != null) {
foreach (Account account in accounts) {
- AddListRow row = new AddListRow(stream_interactor, parsed_jid, account);
- list.append(row);
- added_rows.add(row);
+ var list_row = new Gtk.ListBoxRow();
+ list_row.set_child(new AddListRow(stream_interactor, parsed_jid, account));
+ list.append(list_row);
+ added_rows.add(list_row);
}
}
} catch (InvalidJidError ignored) {
@@ -108,6 +110,12 @@ public class SelectJidFragment : Gtk.Box {
return true;
}
+ private void header(ListBoxRow row, ListBoxRow? before_row) {
+ if (row.get_header() == null && before_row != null) {
+ row.set_header(new Separator(Orientation.HORIZONTAL));
+ }
+ }
+
private class AddListRow : ListRow {
public AddListRow(StreamInteractor stream_interactor, Jid jid, Account account) {
diff --git a/main/src/ui/application.vala b/main/src/ui/application.vala
index f83e403b..2167145b 100644
--- a/main/src/ui/application.vala
+++ b/main/src/ui/application.vala
@@ -203,11 +203,6 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
Builder builder = new Builder.from_resource("/im/dino/Dino/shortcuts.ui");
ShortcutsWindow dialog = (ShortcutsWindow) builder.get_object("shortcuts-window");
if (!use_csd()) {
- // Hack to prevent CRITICAL in Gtk when trying to destroy non-existant headerbar
- Widget shortcuts_hack = dialog.get_titlebar();
-// dialog.destroy.connect_after(() => {
-// shortcuts_hack = null;
-// });
dialog.set_titlebar(null);
}
dialog.title = _("Keyboard Shortcuts");
@@ -292,12 +287,6 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
dialog.copyright = "Copyright © 2016-2022 - Dino Team";
dialog.license_type = License.GPL_3_0;
-// dialog.response.connect((response_id) => {
-// if (response_id == Gtk.ResponseType.CANCEL || response_id == Gtk.ResponseType.DELETE_EVENT) {
-// dialog.destroy();
-// }
-// });
-
if (!use_csd()) {
dialog.set_titlebar(null);
}
@@ -308,7 +297,7 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
Dialog dialog = new Dialog.with_buttons(_("Join Channel"), window, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.USE_HEADER_BAR, _("Join"), ResponseType.OK, _("Cancel"), ResponseType.CANCEL);
dialog.modal = true;
Button ok_button = dialog.get_widget_for_response(ResponseType.OK) as Button;
- ok_button.get_style_context().add_class("suggested-action");
+ ok_button.add_css_class("suggested-action");
ConferenceDetailsFragment conference_fragment = new ConferenceDetailsFragment(stream_interactor) { ok_button=ok_button };
conference_fragment.jid = jid;
if (account != null) {
diff --git a/main/src/ui/avatar_image.vala b/main/src/ui/avatar_image.vala
index a304f5a2..f348dd4b 100644
--- a/main/src/ui/avatar_image.vala
+++ b/main/src/ui/avatar_image.vala
@@ -24,7 +24,7 @@ public class AvatarImage : Widget {
public AvatarImage() {
can_focus = false;
- get_style_context().add_class("avatar");
+ add_css_class("avatar");
}
public override void dispose() {
@@ -51,7 +51,6 @@ public class AvatarImage : Widget {
}
public bool draw(Cairo.Context ctx_in) {
- if (conversation == null || jids == null) return false;
Cairo.Context ctx = ctx_in;
int width = this.width, height = this.height, base_factor = 1;
if (use_image_surface == -1) {
diff --git a/main/src/ui/call_window/audio_settings_popover.vala b/main/src/ui/call_window/audio_settings_popover.vala
index f5af90ff..f66c5eee 100644
--- a/main/src/ui/call_window/audio_settings_popover.vala
+++ b/main/src/ui/call_window/audio_settings_popover.vala
@@ -14,7 +14,7 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
private HashMap<ListBoxRow, Plugins.MediaDevice> row_speaker_device = new HashMap<ListBoxRow, Plugins.MediaDevice>();
public AudioSettingsPopover() {
- Box box = new Box(Orientation.VERTICAL, 15) { visible=true };
+ Box box = new Box(Orientation.VERTICAL, 15);
box.append(create_microphone_box());
box.append(create_speaker_box());
@@ -25,19 +25,19 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
Plugins.VideoCallPlugin call_plugin = Dino.Application.get_default().plugin_registry.video_call_plugin;
Gee.List<Plugins.MediaDevice> devices = call_plugin.get_devices("audio", false);
- Box micro_box = new Box(Orientation.VERTICAL, 10) { visible=true };
- micro_box.append(new Label("<b>" + _("Microphones") + "</b>") { use_markup=true, xalign=0, visible=true, can_focus=true /* grab initial focus*/ });
+ Box micro_box = new Box(Orientation.VERTICAL, 10);
+ micro_box.append(new Label("<b>" + _("Microphones") + "</b>") { use_markup=true, xalign=0, can_focus=true /* grab initial focus*/ });
if (devices.size == 0) {
micro_box.append(new Label(_("No microphone found.")));
} else {
- ListBox micro_list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE, visible=true };
+ ListBox micro_list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE };
micro_list_box.set_header_func(listbox_header_func);
- Frame micro_frame = new Frame(null) { visible=true };
+ Frame micro_frame = new Frame(null);
micro_frame.set_child(micro_list_box);
foreach (Plugins.MediaDevice device in devices) {
- Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
- Image image = new Image.from_icon_name("object-select-symbolic") { visible=true };
+ Label display_name_label = new Label(device.display_name) { xalign=0 };
+ Image image = new Image.from_icon_name("object-select-symbolic");
if (current_microphone_device == null || current_microphone_device.id != device.id) {
image.opacity = 0;
}
@@ -48,19 +48,19 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
image.opacity = 1;
}
});
- Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7, visible=true };
+ Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7 };
device_box.append(image);
- Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
+ Box label_box = new Box(Orientation.VERTICAL, 0);
label_box.append(display_name_label);
if (device.detail_name != null) {
- Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
- detail_name_label.get_style_context().add_class("dim-label");
+ Label detail_name_label = new Label(device.detail_name) { xalign=0 };
+ detail_name_label.add_css_class("dim-label");
detail_name_label.attributes = new Pango.AttrList();
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
label_box.append(detail_name_label);
}
device_box.append(label_box);
- ListBoxRow list_box_row = new ListBoxRow() { visible=true };
+ ListBoxRow list_box_row = new ListBoxRow();
list_box_row.set_child(device_box);
micro_list_box.append(list_box_row);
@@ -81,22 +81,22 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
Plugins.VideoCallPlugin call_plugin = Dino.Application.get_default().plugin_registry.video_call_plugin;
Gee.List<Plugins.MediaDevice> devices = call_plugin.get_devices("audio", true);
- Box speaker_box = new Box(Orientation.VERTICAL, 10) { visible=true };
- speaker_box.append(new Label("<b>" + _("Speakers") +"</b>") { use_markup=true, xalign=0, visible=true });
+ Box speaker_box = new Box(Orientation.VERTICAL, 10);
+ speaker_box.append(new Label("<b>" + _("Speakers") +"</b>") { use_markup=true, xalign=0 });
if (devices.size == 0) {
speaker_box.append(new Label(_("No speaker found.")));
} else {
- ListBox speaker_list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE, visible=true };
+ ListBox speaker_list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE };
speaker_list_box.set_header_func(listbox_header_func);
speaker_list_box.row_selected.connect((row) => {
});
- Frame speaker_frame = new Frame(null) { visible=true };
+ Frame speaker_frame = new Frame(null);
speaker_frame.set_child(speaker_list_box);
foreach (Plugins.MediaDevice device in devices) {
- Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
- Image image = new Image.from_icon_name("object-select-symbolic") { visible=true };
+ Label display_name_label = new Label(device.display_name) { xalign=0 };
+ Image image = new Image.from_icon_name("object-select-symbolic");
if (current_speaker_device == null || current_speaker_device.id != device.id) {
image.opacity = 0;
}
@@ -107,19 +107,19 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
image.opacity = 1;
}
});
- Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7, visible=true };
+ Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7 };
device_box.append(image);
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
label_box.append(display_name_label);
if (device.detail_name != null) {
- Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
- detail_name_label.get_style_context().add_class("dim-label");
+ Label detail_name_label = new Label(device.detail_name) { xalign=0 };
+ detail_name_label.add_css_class("dim-label");
detail_name_label.attributes = new Pango.AttrList();
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
label_box.append(detail_name_label);
}
device_box.append(label_box);
- ListBoxRow list_box_row = new ListBoxRow() { visible=true };
+ ListBoxRow list_box_row = new ListBoxRow();
list_box_row.set_child(device_box);
speaker_list_box.append(list_box_row);
diff --git a/main/src/ui/call_window/call_bottom_bar.vala b/main/src/ui/call_window/call_bottom_bar.vala
index ddc196f2..c30a86e9 100644
--- a/main/src/ui/call_window/call_bottom_bar.vala
+++ b/main/src/ui/call_window/call_bottom_bar.vala
@@ -11,52 +11,54 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
public string counterpart_display_name { get; set; }
- private Button audio_button = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START, visible=true };
- private Overlay audio_button_overlay = new Overlay() { visible=true };
+ private Button audio_button = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START };
+ private Overlay audio_button_overlay = new Overlay();
private Image audio_image = new Image() { pixel_size=22 };
- private MenuButton audio_settings_button = new MenuButton() { icon_name="go-up-symbolic", halign=Align.END, valign=Align.END };
+ private MenuButton audio_settings_button = new MenuButton() { halign=Align.END, valign=Align.END };
public AudioSettingsPopover? audio_settings_popover;
- private Button video_button = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START, visible=true };
- private Overlay video_button_overlay = new Overlay() { visible=true };
+ private Button video_button = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START };
+ private Overlay video_button_overlay = new Overlay();
private Image video_image = new Image() { pixel_size=22 };
- private MenuButton video_settings_button = new MenuButton() { icon_name="go-up-symbolic", halign=Align.END, valign=Align.END };
+ private MenuButton video_settings_button = new MenuButton() { halign=Align.END, valign=Align.END };
public VideoSettingsPopover? video_settings_popover;
- private Label label = new Label("") { halign=Align.CENTER, valign=Align.CENTER, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, visible=true };
- private Stack stack = new Stack() { visible=true };
+ private Label label = new Label("") { halign=Align.CENTER, valign=Align.CENTER, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true };
+ private Stack stack = new Stack();
public CallBottomBar() {
Object(orientation:Orientation.HORIZONTAL, spacing:0);
- Box main_buttons = new Box(Orientation.HORIZONTAL, 20) { margin_start=40, margin_end=40, margin_bottom=20, margin_top=20, halign=Align.CENTER, hexpand=true, visible=true };
+ Box main_buttons = new Box(Orientation.HORIZONTAL, 20) { margin_start=40, margin_end=40, margin_bottom=20, margin_top=20, halign=Align.CENTER, hexpand=true };
audio_button.set_child(audio_image);
- audio_button.get_style_context().add_class("call-button");
+ audio_button.add_css_class("call-button");
audio_button.clicked.connect(() => { audio_enabled = !audio_enabled; });
audio_button.margin_end = audio_button.margin_bottom = 5; // space for the small settings button
audio_button_overlay.set_child(audio_button);
audio_button_overlay.add_overlay(audio_settings_button);
- audio_settings_button.get_style_context().add_class("call-mediadevice-settings-button");
+ audio_settings_button.set_child(new Image.from_icon_name("go-up-symbolic") { pixel_size=10 });
+ audio_settings_button.add_css_class("call-mediadevice-settings-button");
main_buttons.append(audio_button_overlay);
video_button.set_child(video_image);
- video_button.get_style_context().add_class("call-button");
+ video_button.add_css_class("call-button");
video_button.clicked.connect(() => { video_enabled = !video_enabled; });
video_button.margin_end = video_button.margin_bottom = 5;
video_button_overlay.set_child(video_button);
video_button_overlay.add_overlay(video_settings_button);
- video_settings_button.get_style_context().add_class("call-mediadevice-settings-button");
+ video_settings_button.set_child(new Image.from_icon_name("go-up-symbolic") { pixel_size=10 });
+ video_settings_button.add_css_class("call-mediadevice-settings-button");
main_buttons.append(video_button_overlay);
- Button button_hang = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START, visible=true };
+ Button button_hang = new Button() { height_request=45, width_request=45, halign=Align.START, valign=Align.START };
button_hang.set_child(new Image() { icon_name="dino-phone-hangup-symbolic", pixel_size=22 });
- button_hang.get_style_context().add_class("call-button");
- button_hang.get_style_context().add_class("destructive-action");
+ button_hang.add_css_class("call-button");
+ button_hang.add_css_class("destructive-action");
button_hang.clicked.connect(() => hang_up());
main_buttons.append(button_hang);
- label.get_style_context().add_class("text-no-controls");
+ label.add_css_class("text-no-controls");
stack.add_named(main_buttons, "control-buttons");
stack.add_named(label, "label");
@@ -71,7 +73,7 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
on_audio_enabled_changed();
on_video_enabled_changed();
- this.get_style_context().add_class("call-bottom-bar");
+ this.add_css_class("call-bottom-bar");
}
public AudioSettingsPopover? show_audio_device_choices(bool show) {
@@ -112,25 +114,25 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
public void on_audio_enabled_changed() {
if (audio_enabled) {
audio_image.icon_name = "dino-microphone-symbolic";
- audio_button.get_style_context().add_class("white-button");
- audio_button.get_style_context().remove_class("transparent-white-button");
+ audio_button.add_css_class("white-button");
+ audio_button.remove_css_class("transparent-white-button");
} else {
audio_image.icon_name = "dino-microphone-off-symbolic";
- audio_button.get_style_context().remove_class("white-button");
- audio_button.get_style_context().add_class("transparent-white-button");
+ audio_button.remove_css_class("white-button");
+ audio_button.add_css_class("transparent-white-button");
}
}
public void on_video_enabled_changed() {
if (video_enabled) {
video_image.icon_name = "dino-video-symbolic";
- video_button.get_style_context().add_class("white-button");
- video_button.get_style_context().remove_class("transparent-white-button");
+ video_button.add_css_class("white-button");
+ video_button.remove_css_class("transparent-white-button");
} else {
video_image.icon_name = "dino-video-off-symbolic";
- video_button.get_style_context().remove_class("white-button");
- video_button.get_style_context().add_class("transparent-white-button");
+ video_button.remove_css_class("white-button");
+ video_button.add_css_class("transparent-white-button");
}
}
@@ -140,6 +142,7 @@ public class Dino.Ui.CallBottomBar : Gtk.Box {
}
public bool is_menu_active() {
- return video_settings_button.popover.visible || audio_settings_button.popover.visible; // TODO gtk4 does this work? check for null?
+ return (video_settings_button.popover != null && video_settings_button.popover.visible) ||
+ (audio_settings_button.popover != null && audio_settings_button.popover.visible);
}
} \ No newline at end of file
diff --git a/main/src/ui/call_window/call_connection_details_window.vala b/main/src/ui/call_window/call_connection_details_window.vala
index 0905908c..9e9e1b3a 100644
--- a/main/src/ui/call_window/call_connection_details_window.vala
+++ b/main/src/ui/call_window/call_connection_details_window.vala
@@ -4,10 +4,10 @@ namespace Dino.Ui {
public class CallConnectionDetailsWindow : Gtk.Window {
- public Box box = new Box(Orientation.VERTICAL, 15) { halign=Align.CENTER, valign=Align.CENTER, visible=true };
+ public Box box = new Box(Orientation.VERTICAL, 15) { halign=Align.CENTER, valign=Align.CENTER };
private bool video_added = false;
- private CallContentDetails audio_details = new CallContentDetails("Audio") { visible=true };
+ private CallContentDetails audio_details = new CallContentDetails("Audio");
private CallContentDetails video_details = new CallContentDetails("Video");
public CallConnectionDetailsWindow() {
@@ -36,24 +36,24 @@ namespace Dino.Ui {
public class CallContentDetails : Gtk.Grid {
- public Label rtp_title = new Label("RTP") { xalign=0, visible=true };
- public Label rtcp_title = new Label("RTCP") { xalign=0, visible=true };
- public Label target_recv_title = new Label("Target receive bitrate") { xalign=0, visible=true };
- public Label target_send_title = new Label("Target send bitrate") { xalign=0, visible=true };
+ public Label rtp_title = new Label("RTP") { xalign=0 };
+ public Label rtcp_title = new Label("RTCP") { xalign=0 };
+ public Label target_recv_title = new Label("Target receive bitrate") { xalign=0 };
+ public Label target_send_title = new Label("Target send bitrate") { xalign=0 };
- public Label rtp_ready = new Label("?") { xalign=0, visible=true };
- public Label rtcp_ready = new Label("?") { xalign=0, visible=true };
- public Label sent_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
- public Label recv_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
- public Label codec = new Label("?") { xalign=0, visible=true };
- public Label target_receive_bitrate = new Label("n/a") { use_markup=true, xalign=0, visible=true };
- public Label target_send_bitrate = new Label("n/a") { use_markup=true, xalign=0, visible=true };
+ public Label rtp_ready = new Label("?") { xalign=0 };
+ public Label rtcp_ready = new Label("?") { xalign=0 };
+ public Label sent_bps = new Label("?") { use_markup=true, xalign=0 };
+ public Label recv_bps = new Label("?") { use_markup=true, xalign=0 };
+ public Label codec = new Label("?") { xalign=0 };
+ public Label target_receive_bitrate = new Label("n/a") { use_markup=true, xalign=0 };
+ public Label target_send_bitrate = new Label("n/a") { use_markup=true, xalign=0 };
private PeerContentInfo? prev_info = null;
private int row_at = 0;
public CallContentDetails(string headline) {
- attach(new Label("<b>%s</b>".printf(headline)) { use_markup=true, xalign=0, visible=true }, 0, row_at++, 1, 1);
+ attach(new Label("<b>%s</b>".printf(headline)) { use_markup=true, xalign=0 }, 0, row_at++, 1, 1);
attach(rtp_title, 0, row_at, 1, 1);
attach(rtp_ready, 1, row_at++, 1, 1);
attach(rtcp_title, 0, row_at, 1, 1);
@@ -104,7 +104,7 @@ namespace Dino.Ui {
}
private void put_row(string label) {
- attach(new Label(label) { xalign=0, visible=true }, 0, row_at, 1, 1);
+ attach(new Label(label) { xalign=0 }, 0, row_at, 1, 1);
}
}
}
diff --git a/main/src/ui/call_window/call_encryption_button.vala b/main/src/ui/call_window/call_encryption_button.vala
index 095db2b4..1b586f28 100644
--- a/main/src/ui/call_window/call_encryption_button.vala
+++ b/main/src/ui/call_window/call_encryption_button.vala
@@ -2,7 +2,7 @@ using Dino.Entities;
using Gtk;
using Pango;
-public class Dino.Ui.CallEncryptionButtonController {
+public class Dino.Ui.CallEncryptionButtonController : Object {
private bool has_been_set = false;
public bool controls_active { get; set; default=false; }
@@ -21,10 +21,10 @@ public class Dino.Ui.CallEncryptionButtonController {
public void set_icon(bool encrypted, string? icon_name) {
if (encrypted) {
button.icon_name = icon_name ?? "changes-prevent-symbolic";
- button.get_style_context().remove_class("unencrypted");
+ button.remove_css_class("unencrypted");
} else {
button.icon_name = icon_name ?? "changes-allow-symbolic";
- button.get_style_context().add_class("unencrypted");
+ button.add_css_class("unencrypted");
}
has_been_set = true;
update_opacity();
@@ -35,23 +35,23 @@ public class Dino.Ui.CallEncryptionButtonController {
button.set_popover(popover);
if (audio_encryption == null) {
- popover.set_child(new Label("This call is unencrypted.") { visible=true } );
+ popover.set_child(new Label("This call is unencrypted.") );
return;
}
if (title != null && !show_keys) {
- popover.set_child(new Label(title) { use_markup=true, visible=true } );
+ popover.set_child(new Label(title) { use_markup=true } );
return;
}
- Box box = new Box(Orientation.VERTICAL, 10) { visible=true };
- box.append(new Label("<b>%s</b>".printf(title ?? "This call is end-to-end encrypted.")) { use_markup=true, xalign=0, visible=true });
+ Box box = new Box(Orientation.VERTICAL, 10);
+ box.append(new Label("<b>%s</b>".printf(title ?? "This call is end-to-end encrypted.")) { use_markup=true, xalign=0 });
if (video_encryption == null) {
box.append(create_media_encryption_grid(audio_encryption));
} else {
- box.append(new Label("<b>Audio</b>") { use_markup=true, xalign=0, visible=true });
+ box.append(new Label("<b>Audio</b>") { use_markup=true, xalign=0 });
box.append(create_media_encryption_grid(audio_encryption));
- box.append(new Label("<b>Video</b>") { use_markup=true, xalign=0, visible=true });
+ box.append(new Label("<b>Video</b>") { use_markup=true, xalign=0 });
box.append(create_media_encryption_grid(video_encryption));
}
popover.set_child(box);
@@ -62,14 +62,14 @@ public class Dino.Ui.CallEncryptionButtonController {
}
private Grid create_media_encryption_grid(Xmpp.Xep.Jingle.ContentEncryption? encryption) {
- Grid ret = new Grid() { row_spacing=3, column_spacing=5, visible=true };
+ Grid ret = new Grid() { row_spacing=3, column_spacing=5 };
if (encryption.peer_key.length > 0) {
- ret.attach(new Label("Peer call key") { xalign=0, visible=true }, 1, 2, 1, 1);
- ret.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.peer_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true, visible=true }, 2, 2, 1, 1);
+ ret.attach(new Label("Peer call key") { xalign=0 }, 1, 2, 1, 1);
+ ret.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.peer_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true }, 2, 2, 1, 1);
}
if (encryption.our_key.length > 0) {
- ret.attach(new Label("Your call key") { xalign=0, visible=true }, 1, 3, 1, 1);
- ret.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.our_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true, visible=true }, 2, 3, 1, 1);
+ ret.attach(new Label("Your call key") { xalign=0 }, 1, 3, 1, 1);
+ ret.attach(new Label("<span font_family='monospace'>" + format_fingerprint(encryption.our_key) + "</span>") { use_markup=true, max_width_chars=25, ellipsize=EllipsizeMode.MIDDLE, xalign=0, hexpand=true }, 2, 3, 1, 1);
}
return ret;
}
diff --git a/main/src/ui/call_window/call_window.vala b/main/src/ui/call_window/call_window.vala
index cd05848a..cf89d8e8 100644
--- a/main/src/ui/call_window/call_window.vala
+++ b/main/src/ui/call_window/call_window.vala
@@ -11,13 +11,13 @@ namespace Dino.Ui {
public CallWindowController controller;
- public Overlay overlay = new Overlay() { visible=true };
- public Grid grid = new Grid() { visible=true };
- public CallBottomBar bottom_bar = new CallBottomBar() { visible=true };
- public Revealer bottom_bar_revealer = new Revealer() { valign=Align.END, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200, visible=true };
- public HeaderBar header_bar = new HeaderBar() { valign=Align.START, halign=Align.END, show_title_buttons=true, visible=true, opacity=0.0 };
- public Revealer header_bar_revealer = new Revealer() { halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.SLIDE_LEFT, transition_duration=200, visible=true, reveal_child=false };
- public Box own_video_box = new Box(Orientation.HORIZONTAL, 0) { halign=Align.END, valign=Align.END, visible=true };
+ public Overlay overlay = new Overlay();
+ public Grid grid = new Grid();
+ public CallBottomBar bottom_bar = new CallBottomBar();
+ public Revealer bottom_bar_revealer = new Revealer() { valign=Align.END, transition_type=RevealerTransitionType.CROSSFADE, transition_duration=200 };
+ public HeaderBar header_bar = new HeaderBar() { valign=Align.START, halign=Align.END, show_title_buttons=true, opacity=0.0 };
+ public Revealer header_bar_revealer = new Revealer() { halign=Align.END, valign=Align.START, transition_type=RevealerTransitionType.SLIDE_LEFT, transition_duration=200, reveal_child=false };
+ public Box own_video_box = new Box(Orientation.HORIZONTAL, 0) { halign=Align.END, valign=Align.END };
private Widget? own_video = null;
private HashMap<string, ParticipantWidget> participant_widgets = new HashMap<string, ParticipantWidget>();
private ArrayList<string> participants = new ArrayList<string>();
@@ -32,14 +32,14 @@ namespace Dino.Ui {
public bool controls_active { get; set; default=true; }
construct {
- header_bar.get_style_context().add_class("call-header-bar");
+ header_bar.add_css_class("call-header-bar");
header_bar.title_widget = new Box(Orientation.VERTICAL, 0);
// header_bar.spacing = 0;
header_bar_revealer.set_child(header_bar);
bottom_bar_revealer.set_child(bottom_bar);
- own_video_box.get_style_context().add_class("own-video");
+ own_video_box.add_css_class("own-video");
- this.get_style_context().add_class("dino-call-window");
+ this.add_css_class("dino-call-window");
overlay.set_child(grid);
overlay.add_overlay(own_video_box);
@@ -64,7 +64,7 @@ namespace Dino.Ui {
this.notify["default-width"].connect(reposition_participant_widgets);
this.notify["default-height"].connect(reposition_participant_widgets);
- this.set_titlebar(new OutsideHeaderBar(this.header_bar) { visible=true });
+ this.set_titlebar(new OutsideHeaderBar(this.header_bar));
reveal_control_elements();
}
@@ -72,7 +72,7 @@ namespace Dino.Ui {
public void add_participant(string participant, ParticipantWidget participant_widget) {
participant_widget.visible = true;
this.bind_property("controls-active", participant_widget, "controls-active", BindingFlags.SYNC_CREATE);
- this.bind_property("controls-active", participant_widget.encryption_button, "controls-active", BindingFlags.SYNC_CREATE);
+ this.bind_property("controls-active", participant_widget.encryption_button_controller, "controls-active", BindingFlags.SYNC_CREATE);
participants.add(participant);
participant_widgets[participant] = participant_widget;
@@ -153,8 +153,9 @@ namespace Dino.Ui {
own_video = widget_;
if (own_video == null) {
- own_video = new Box(Orientation.HORIZONTAL, 0) { hexpand=true, vexpand=true };
+ own_video = new Box(Orientation.HORIZONTAL, 0);
}
+ own_video.hexpand = own_video.vexpand = true;
own_video.visible = true;
own_video_box.append(own_video);
}
diff --git a/main/src/ui/call_window/call_window_controller.vala b/main/src/ui/call_window/call_window_controller.vala
index e3f8b670..e0eca6dc 100644
--- a/main/src/ui/call_window/call_window_controller.vala
+++ b/main/src/ui/call_window/call_window_controller.vala
@@ -134,10 +134,11 @@ public class Dino.Ui.CallWindowController : Object {
warning("suspend inhibit request failed or unsupported");
}
- call_window.destroy.connect(() => {
+ call_window.close_request.connect(() => {
if (inhibit_cookie != 0) {
app.uninhibit(inhibit_cookie);
}
+ return false;
});
}
@@ -235,7 +236,7 @@ public class Dino.Ui.CallWindowController : Object {
ParticipantWidget participant_widget = new ParticipantWidget(participant_name);
participant_widget.may_show_invite_button = !participant_widgets.is_empty;
participant_widget.debug_information_clicked.connect(() => {
- var conn_details_window = new CallConnectionDetailsWindow() { title=participant_name, visible=true };
+ var conn_details_window = new CallConnectionDetailsWindow() { title=participant_name };
conn_details_window.update_content(peer_states[participant_id].get_info());
uint timeout_handle_id = Timeout.add_seconds(1, () => {
conn_details_window.update_content(peer_states[participant_id].get_info());
@@ -361,7 +362,9 @@ public class Dino.Ui.CallWindowController : Object {
public override void dispose() {
foreach (ulong handler_id in call_window_handler_ids) call_window.disconnect(handler_id);
foreach (ulong handler_id in bottom_bar_handler_ids) call_window.bottom_bar.disconnect(handler_id);
- participant_widgets.keys.@foreach((peer_id) => { remove_participant(peer_id); return true; });
+ foreach (string peer_id in participant_widgets.keys) {
+ remove_participant(peer_id);
+ }
call_window_handler_ids = bottom_bar_handler_ids = new ulong[0];
own_video.detach();
diff --git a/main/src/ui/call_window/participant_widget.vala b/main/src/ui/call_window/participant_widget.vala
index ecd6cbb3..180923f1 100644
--- a/main/src/ui/call_window/participant_widget.vala
+++ b/main/src/ui/call_window/participant_widget.vala
@@ -10,15 +10,15 @@ namespace Dino.Ui {
public Overlay overlay = new Overlay();
public Widget main_widget;
- public HeaderBar header_bar = new HeaderBar() { valign=Align.START, visible=true };
+ public HeaderBar header_bar = new HeaderBar() { valign=Align.START };
public Label title_label = new Label("");
public Label subtitle_label = new Label("");
- public Box inner_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=5, margin_top=5, hexpand=true, visible=true };
- public Box title_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER, hexpand=true, visible=true };
- public MenuButton encryption_button = new MenuButton() { opacity=0, has_frame=false, height_request=30, width_request=30, margin_end=5, visible=true };
+ public Box inner_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=5, margin_top=5, hexpand=true };
+ public Box title_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER, hexpand=true };
+ public MenuButton encryption_button = new MenuButton() { opacity=0, has_frame=false, height_request=30, width_request=30, margin_end=5 };
public CallEncryptionButtonController encryption_button_controller;
- public MenuButton menu_button = new MenuButton() { icon_name="open-menu-symbolic", has_frame=false, visible=true };
- public Button invite_button = new Button.from_icon_name("dino-account-plus") { has_frame=false, visible=true };
+ public MenuButton menu_button = new MenuButton() { icon_name="open-menu-symbolic", has_frame=false };
+ public Button invite_button = new Button.from_icon_name("dino-account-plus") { has_frame=false };
public bool shows_video = false;
public string? participant_name;
@@ -40,18 +40,19 @@ namespace Dino.Ui {
this.participant_name = participant_name;
Box titles_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER };
+ titles_box.add_css_class("titles");
title_label.attributes = new AttrList();
title_label.attributes.insert(Pango.attr_weight_new(Weight.BOLD));
titles_box.append(title_label);
subtitle_label.attributes = new AttrList();
subtitle_label.attributes.insert(Pango.attr_scale_new(Pango.Scale.SMALL));
- subtitle_label.get_style_context().add_class("dim-label");
+ subtitle_label.add_css_class("dim-label");
titles_box.append(subtitle_label);
header_bar.set_title_widget(titles_box);
title_label.label = participant_name;
- header_bar.get_style_context().add_class("participant-header-bar");
+ header_bar.add_css_class("participant-header-bar");
header_bar.pack_start(invite_button);
header_bar.pack_start(encryption_button);
header_bar.pack_end(menu_button);
@@ -73,14 +74,14 @@ namespace Dino.Ui {
header_bar.show_title_buttons = is_highest_row;
if (is_highest_row) {
- header_bar.get_style_context().add_class("call-header-background");
+ header_bar.add_css_class("call-header-background");
Gtk.Settings? gtk_settings = Gtk.Settings.get_default();
if (gtk_settings != null) {
string[] buttons = gtk_settings.gtk_decoration_layout.split(":");
header_bar.decoration_layout = (is_start ? buttons[0] : "") + ":" + (is_end && buttons.length == 2 ? buttons[1] : "");
}
} else {
- header_bar.get_style_context().remove_class("call-header-background");
+ header_bar.remove_css_class("call-header-background");
}
reveal_or_hide_controls();
}
@@ -93,9 +94,9 @@ namespace Dino.Ui {
public void set_placeholder(Conversation? conversation, StreamInteractor stream_interactor) {
shows_video = false;
- Box box = new Box(Orientation.HORIZONTAL, 0) { visible=true };
- box.get_style_context().add_class("video-placeholder-box");
- AvatarImage avatar = new AvatarImage() { allow_gray=false, hexpand=true, vexpand=true, halign=Align.CENTER, valign=Align.CENTER, height=100, width=100, visible=true };
+ Box box = new Box(Orientation.HORIZONTAL, 0);
+ box.add_css_class("video-placeholder-box");
+ AvatarImage avatar = new AvatarImage() { allow_gray=false, hexpand=true, vexpand=true, halign=Align.CENTER, valign=Align.CENTER, height=100, width=100 };
if (conversation != null) {
avatar.set_conversation(stream_interactor, conversation);
} else {
@@ -133,6 +134,10 @@ namespace Dino.Ui {
}
}
+ public bool is_menu_active() {
+ return false;
+ }
+
private void reveal_or_hide_controls() {
header_bar.opacity = controls_active ? 1.0 : 0.0;
invite_button.visible = may_show_invite_button && is_highest_row && is_start_row;
diff --git a/main/src/ui/call_window/video_settings_popover.vala b/main/src/ui/call_window/video_settings_popover.vala
index c931c466..58967bd2 100644
--- a/main/src/ui/call_window/video_settings_popover.vala
+++ b/main/src/ui/call_window/video_settings_popover.vala
@@ -11,7 +11,7 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover {
private HashMap<ListBoxRow, Plugins.MediaDevice> row_device = new HashMap<ListBoxRow, Plugins.MediaDevice>();
public VideoSettingsPopover() {
- Box box = new Box(Orientation.VERTICAL, 15) { visible=true };
+ Box box = new Box(Orientation.VERTICAL, 15);
box.append(create_camera_box());
this.set_child(box);
@@ -21,19 +21,19 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover {
Plugins.VideoCallPlugin call_plugin = Dino.Application.get_default().plugin_registry.video_call_plugin;
Gee.List<Plugins.MediaDevice> devices = call_plugin.get_devices("video", false);
- Box camera_box = new Box(Orientation.VERTICAL, 10) { visible=true };
- camera_box.append(new Label("<b>" + _("Cameras") + "</b>") { use_markup=true, xalign=0, visible=true, can_focus=true /* grab initial focus*/ });
+ Box camera_box = new Box(Orientation.VERTICAL, 10);
+ camera_box.append(new Label("<b>" + _("Cameras") + "</b>") { use_markup=true, xalign=0, can_focus=true /* grab initial focus*/ });
if (devices.size == 0) {
- camera_box.append(new Label(_("No camera found.")) { visible=true });
+ camera_box.append(new Label(_("No camera found.")));
} else {
- ListBox list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE, visible=true };
+ ListBox list_box = new ListBox() { activate_on_single_click=true, selection_mode=SelectionMode.SINGLE };
list_box.set_header_func(listbox_header_func);
- Frame frame = new Frame(null) { visible=true };
+ Frame frame = new Frame(null);
frame.set_child(list_box);
foreach (Plugins.MediaDevice device in devices) {
- Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
- Image image = new Image.from_icon_name("object-select-symbolic") { visible=true };
+ Label display_name_label = new Label(device.display_name) { xalign=0 };
+ Image image = new Image.from_icon_name("object-select-symbolic");
if (current_device == null || current_device.id != device.id) {
image.opacity = 0;
}
@@ -44,19 +44,19 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover {
image.opacity = 1;
}
});
- Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7, visible=true };
+ Box device_box = new Box(Orientation.HORIZONTAL, 0) { spacing=7 };
device_box.append(image);
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
label_box.append(display_name_label);
if (device.detail_name != null) {
- Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
- detail_name_label.get_style_context().add_class("dim-label");
+ Label detail_name_label = new Label(device.detail_name) { xalign=0 };
+ detail_name_label.add_css_class("dim-label");
detail_name_label.attributes = new Pango.AttrList();
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
label_box.append(detail_name_label);
}
device_box.append(label_box);
- ListBoxRow list_box_row = new ListBoxRow() { visible=true };
+ ListBoxRow list_box_row = new ListBoxRow();
list_box_row.set_child(device_box);
list_box.append(list_box_row);
diff --git a/main/src/ui/chat_input/chat_text_view.vala b/main/src/ui/chat_input/chat_text_view.vala
index b1f719b6..437950ea 100644
--- a/main/src/ui/chat_input/chat_text_view.vala
+++ b/main/src/ui/chat_input/chat_text_view.vala
@@ -26,7 +26,6 @@ public class ChatTextViewController : Object {
public void initialize_for_conversation(Conversation conversation) {
occupants_tab_completor.initialize_for_conversation(conversation);
- widget.initialize_for_conversation(conversation);
}
}
@@ -39,40 +38,31 @@ public class ChatTextView : Box {
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;
-// private SpellChecker spell_checker;
construct {
scrolled_window.set_child(text_view);
this.append(scrolled_window);
- smiley_converter = new SmileyConverter(text_view);
-
-// scrolled_window.get_vscrollbar().get_preferred_size(out vscrollbar_min_size, null);
- scrolled_window.vadjustment.notify["upper"].connect(on_upper_notify);
-
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);
+ smiley_converter = new SmileyConverter(text_view);
+
+ scrolled_window.vadjustment.changed.connect(on_upper_notify);
+
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) {
-// spell_checker.initialize_for_conversation(conversation);
- }
-
-// 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() {
- scrolled_window.vadjustment.value = scrolled_window.vadjustment.upper - scrolled_window.vadjustment.page_size;
+ // hack. otherwise the textview would only show the last row(s) when entering a new row on some systems.
+ if (text_view.get_height() < scrolled_window.max_content_height - 20) {
+ scrolled_window.vadjustment.page_size = scrolled_window.vadjustment.upper;
+ }
// hack for vscrollbar not requiring space and making textview higher //TODO doesn't resize immediately
scrolled_window.get_vscrollbar().visible = (scrolled_window.vadjustment.upper > scrolled_window.max_content_height - 2 * this.vscrollbar_min_height);
diff --git a/main/src/ui/chat_input/encryption_button.vala b/main/src/ui/chat_input/encryption_button.vala
index e5831802..ab463f44 100644
--- a/main/src/ui/chat_input/encryption_button.vala
+++ b/main/src/ui/chat_input/encryption_button.vala
@@ -15,16 +15,39 @@ public class EncryptionButton {
private Map<CheckButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<CheckButton, Plugins.EncryptionListEntry>();
private string? current_icon;
private StreamInteractor stream_interactor;
+ private SimpleAction action;
public EncryptionButton(StreamInteractor stream_interactor, MenuButton menu_button) {
this.stream_interactor = stream_interactor;
this.menu_button = menu_button;
- Builder builder = new Builder.from_resource("/im/dino/Dino/menu_encryption.ui");
- 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 CheckButton;
- button_unencrypted.toggled.connect(encryption_button_toggled);
+ // Build menu model including "Unencrypted" and all registered encryption entries
+ Menu menu_model = new Menu();
+
+ MenuItem unencrypted_item = new MenuItem(_("Unencrypted"), "enc.encryption");
+ unencrypted_item.set_action_and_target_value("enc.encryption", new Variant.int32(Encryption.NONE));
+ menu_model.append_item(unencrypted_item);
+
+ Application app = GLib.Application.get_default() as Application;
+ foreach (var e in app.plugin_registry.encryption_list_entries) {
+ MenuItem item = new MenuItem(e.name, "enc.encryption");
+ item.set_action_and_target_value("enc.encryption", new Variant.int32(e.encryption));
+ menu_model.append_item(item);
+ }
+
+ // Create action to act on menu selections (stateful => radio buttons)
+ SimpleActionGroup action_group = new SimpleActionGroup();
+ action = new SimpleAction.stateful("encryption", VariantType.INT32, new Variant.int32(Encryption.NONE));
+ action.activate.connect((parameter) => {
+ action.set_state(parameter);
+ this.conversation.encryption = (Encryption) parameter.get_int32();
+ });
+ action_group.insert(action);
+ menu_button.insert_action_group("enc", action_group);
+
+ // Create and set popover menu
+ Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu.from_model(menu_model);
+ menu_button.popover = popover_menu;
stream_interactor.get_module(MucManager.IDENTITY).room_info_updated.connect((account, muc_jid) => {
if (conversation != null && conversation.account.equals(account) && conversation.counterpart.equals(muc_jid)) {
@@ -32,15 +55,6 @@ public class EncryptionButton {
}
});
- Application app = GLib.Application.get_default() as Application;
- foreach (var e in app.plugin_registry.encryption_list_entries) {
- 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.prepend(btn);
- }
menu_button.activate.connect(update_encryption_menu_state);
}
@@ -61,16 +75,8 @@ public class EncryptionButton {
}
private void update_encryption_menu_state() {
- foreach (CheckButton e in encryption_radios.keys) {
- if (conversation.encryption == encryption_radios[e].encryption) {
- e.set_active(true);
- encryption_changed(encryption_radios[e]);
- }
- }
- if (conversation.encryption == Encryption.NONE) {
- button_unencrypted.set_active(true);
- encryption_changed(null);
- }
+ action.set_state(new Variant.int32(conversation.encryption));
+ action.change_state(new Variant.int32(conversation.encryption));
}
private void set_icon(string icon) {
diff --git a/main/src/ui/chat_input/view.vala b/main/src/ui/chat_input/view.vala
index 6524a825..81f2bd0f 100644
--- a/main/src/ui/chat_input/view.vala
+++ b/main/src/ui/chat_input/view.vala
@@ -66,28 +66,28 @@ public class View : Box {
public void set_input_state(Plugins.InputFieldStatus.MessageType message_type) {
switch (message_type) {
case Plugins.InputFieldStatus.MessageType.NONE:
- this.get_style_context().remove_class("dino-input-warning");
- this.get_style_context().remove_class("dino-input-error");
+ this.remove_css_class("dino-input-warning");
+ this.remove_css_class("dino-input-error");
break;
case Plugins.InputFieldStatus.MessageType.INFO:
- this.get_style_context().remove_class("dino-input-warning");
- this.get_style_context().remove_class("dino-input-error");
+ this.remove_css_class("dino-input-warning");
+ this.remove_css_class("dino-input-error");
break;
case Plugins.InputFieldStatus.MessageType.WARNING:
- this.get_style_context().add_class("dino-input-warning");
- this.get_style_context().remove_class("dino-input-error");
+ this.add_css_class("dino-input-warning");
+ this.remove_css_class("dino-input-error");
break;
case Plugins.InputFieldStatus.MessageType.ERROR:
- this.get_style_context().remove_class("dino-input-warning");
- this.get_style_context().add_class("dino-input-error");
+ this.remove_css_class("dino-input-warning");
+ this.add_css_class("dino-input-error");
break;
}
}
public void highlight_state_description() {
- chat_input_status.get_style_context().add_class("input-status-highlight-once");
+ chat_input_status.add_css_class("input-status-highlight-once");
Timeout.add_seconds(1, () => {
- chat_input_status.get_style_context().remove_class("input-status-highlight-once");
+ chat_input_status.remove_css_class("input-status-highlight-once");
return false;
});
}
diff --git a/main/src/ui/contact_details/blocking_provider.vala b/main/src/ui/contact_details/blocking_provider.vala
index 76e5d000..7e4a475d 100644
--- a/main/src/ui/contact_details/blocking_provider.vala
+++ b/main/src/ui/contact_details/blocking_provider.vala
@@ -19,7 +19,7 @@ public class BlockingProvider : Plugins.ContactDetailsProvider, Object {
if (stream_interactor.get_module(BlockingManager.IDENTITY).is_supported(conversation.account)) {
bool is_blocked = stream_interactor.get_module(BlockingManager.IDENTITY).is_blocked(conversation.account, conversation.counterpart);
- Switch sw = new Switch() { active=is_blocked, valign=Align.CENTER, visible=true };
+ Switch sw = new Switch() { active=is_blocked, valign=Align.CENTER };
sw.state_set.connect((state) => {
if (state) {
stream_interactor.get_module(BlockingManager.IDENTITY).block(conversation.account, conversation.counterpart);
diff --git a/main/src/ui/contact_details/dialog.vala b/main/src/ui/contact_details/dialog.vala
index b07ab9c9..36bef391 100644
--- a/main/src/ui/contact_details/dialog.vala
+++ b/main/src/ui/contact_details/dialog.vala
@@ -37,7 +37,18 @@ public class Dialog : Gtk.Dialog {
title = conversation.type_ == Conversation.Type.GROUPCHAT ? _("Conference Details") : _("Contact Details");
if (Util.use_csd()) {
// TODO get_header_bar directly returns a HeaderBar in vala > 0.48
-// ((HeaderBar) get_header_bar()).set_subtitle(Util.get_conversation_display_name(stream_interactor, conversation));
+ Box titles_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER };
+ var title_label = new Label(title);
+ title_label.attributes = new AttrList();
+ title_label.attributes.insert(Pango.attr_weight_new(Weight.BOLD));
+ titles_box.append(title_label);
+ var subtitle_label = new Label(Util.get_conversation_display_name(stream_interactor, conversation));
+ subtitle_label.attributes = new AttrList();
+ subtitle_label.attributes.insert(Pango.attr_scale_new(Pango.Scale.SMALL));
+ subtitle_label.add_css_class("dim-label");
+ titles_box.append(subtitle_label);
+
+ get_header_bar().set_title_widget(titles_box);
}
setup_top();
@@ -53,9 +64,10 @@ public class Dialog : Gtk.Dialog {
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4);
}
-// destroy.connect(() => {
-// contact_details.save();
-// });
+ close_request.connect(() => {
+ contact_details.save();
+ return false;
+ });
}
private void setup_top() {
@@ -83,16 +95,16 @@ public class Dialog : Gtk.Dialog {
Widget w = (Widget) wo;
add_category(category);
- ListBoxRow list_row = new ListBoxRow() { activatable=false, visible=true };
- Box row = new Box(Orientation.HORIZONTAL, 20) { margin_start=15, margin_end=15, margin_top=3, margin_bottom=3, visible=true };
+ ListBoxRow list_row = new ListBoxRow() { activatable=false };
+ Box row = new Box(Orientation.HORIZONTAL, 20) { margin_start=15, margin_end=15, margin_top=3, margin_bottom=3 };
list_row.set_child(row);
- Label label_label = new Label(label) { xalign=0, yalign=0.5f, hexpand=true, visible=true };
+ Label label_label = new Label(label) { xalign=0, yalign=0.5f, hexpand=true };
if (description != null && description != "") {
- Box box = new Box(Orientation.VERTICAL, 0) { visible=true };
+ Box box = new Box(Orientation.VERTICAL, 0);
box.append(label_label);
- Label desc_label = new Label("") { xalign=0, yalign=0.5f, hexpand=true, visible=true };
+ Label desc_label = new Label("") { xalign=0, yalign=0.5f, hexpand=true };
desc_label.set_markup("<span size='small'>%s</span>".printf(Markup.escape_text(description)));
- desc_label.get_style_context().add_class("dim-label");
+ desc_label.add_css_class("dim-label");
box.append(desc_label);
row.append(box);
} else {
@@ -101,11 +113,11 @@ public class Dialog : Gtk.Dialog {
Widget widget = w;
if (widget.get_type().is_a(typeof(Entry))) {
- Util.EntryLabelHybrid hybrid = new Util.EntryLabelHybrid.wrap(widget as Entry) { xalign=1, visible=true };
+ Util.EntryLabelHybrid hybrid = new Util.EntryLabelHybrid.wrap(widget as Entry) { xalign=1 };
hybrid_group.add(hybrid);
widget = hybrid;
} else if (widget.get_type().is_a(typeof(ComboBoxText))) {
- Util.ComboBoxTextLabelHybrid hybrid = new Util.ComboBoxTextLabelHybrid.wrap(widget as ComboBoxText) { xalign=1, visible=true };
+ Util.ComboBoxTextLabelHybrid hybrid = new Util.ComboBoxTextLabelHybrid.wrap(widget as ComboBoxText) { xalign=1 };
hybrid_group.add(hybrid);
widget = hybrid;
}
@@ -116,26 +128,26 @@ public class Dialog : Gtk.Dialog {
row.append(widget);
categories[category].append(list_row);
+ int width = get_content_area().get_width();
int pref_height, pref_width;
-// get_content_area().get_preferred_height(null, out pref_height);
-// get_preferred_width(out pref_width, null);
-// resize(pref_width, int.min(500, pref_height));
+ get_content_area().measure(Orientation.VERTICAL, width, null, out pref_height, null, null);
+ default_height = pref_height;
}
private void add_category(string category) {
if (!categories.has_key(category)) {
- ListBox list_box = new ListBox() { selection_mode=SelectionMode.NONE, visible=true };
+ ListBox list_box = new ListBox() { selection_mode=SelectionMode.NONE };
categories[category] = list_box;
list_box.set_header_func((row, before_row) => {
if (row.get_header() == null && before_row != null) {
row.set_header(new Separator(Orientation.HORIZONTAL));
}
});
- Box box = new Box(Orientation.VERTICAL, 5) { margin_top=12, margin_bottom=12, visible=true };
- Label category_label = new Label("") { xalign=0, visible=true };
+ Box box = new Box(Orientation.VERTICAL, 5) { margin_top=12, margin_bottom=12 };
+ Label category_label = new Label("") { xalign=0 };
category_label.set_markup(@"<b>$(Markup.escape_text(category))</b>");
box.append(category_label);
- Frame frame = new Frame(null) { visible=true };
+ Frame frame = new Frame(null);
frame.set_child(list_box);
box.append(frame);
main_box.append(box);
diff --git a/main/src/ui/contact_details/permissions_provider.vala b/main/src/ui/contact_details/permissions_provider.vala
index d87658ff..ed0756e8 100644
--- a/main/src/ui/contact_details/permissions_provider.vala
+++ b/main/src/ui/contact_details/permissions_provider.vala
@@ -20,7 +20,7 @@ public class PermissionsProvider : Plugins.ContactDetailsProvider, Object {
if (own_jid == null) return;
if (stream_interactor.get_module(MucManager.IDENTITY).get_role(own_jid, conversation.account) == Xmpp.Xep.Muc.Role.VISITOR){
- Button voice_request = new Button.with_label(_("Request")) { visible=true };
+ Button voice_request = new Button.with_label(_("Request"));
voice_request.clicked.connect(()=>stream_interactor.get_module(MucManager.IDENTITY).request_voice(conversation.account, conversation.counterpart));
contact_details.add(_("Permissions"), _("Request permission to send messages"), "", voice_request);
}
diff --git a/main/src/ui/contact_details/settings_provider.vala b/main/src/ui/contact_details/settings_provider.vala
index 42c690e5..140ebcab 100644
--- a/main/src/ui/contact_details/settings_provider.vala
+++ b/main/src/ui/contact_details/settings_provider.vala
@@ -39,7 +39,7 @@ public class SettingsProvider : Plugins.ContactDetailsProvider, Object {
combobox_notifications.active_id = get_notify_setting_id(conversation.notify_setting);
combobox_notifications.changed.connect(() => { conversation.notify_setting = get_notify_setting(combobox_notifications.active_id); } );
} else if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- ComboBoxText combobox = new ComboBoxText() { visible=true };
+ ComboBoxText combobox = new ComboBoxText();
combobox.append("default", get_notify_setting_string(Conversation.NotifySetting.DEFAULT, conversation.get_notification_default_setting(stream_interactor)));
combobox.append("highlight", get_notify_setting_string(Conversation.NotifySetting.HIGHLIGHT));
combobox.append("on", get_notify_setting_string(Conversation.NotifySetting.ON));
@@ -119,7 +119,7 @@ public class SettingsProvider : Plugins.ContactDetailsProvider, Object {
private ComboBoxText get_combobox(bool default_val) {
ComboBoxText combobox = new ComboBoxText();
- combobox = new ComboBoxText() { visible=true };
+ combobox = new ComboBoxText();
string default_setting = default_val ? _("On") : _("Off");
combobox.append("default", _("Default: %s").printf(default_setting) );
combobox.append("on", _("On"));
diff --git a/main/src/ui/conversation_content/conversation_item_factory.vala b/main/src/ui/conversation_content/conversation_item_factory.vala
deleted file mode 100644
index 29a83785..00000000
--- a/main/src/ui/conversation_content/conversation_item_factory.vala
+++ /dev/null
@@ -1,36 +0,0 @@
-using Gtk;
-
-namespace Dino.Ui {
-
- public static ListItemFactory get_item_factory() {
- SignalListItemFactory item_factory = new SignalListItemFactory();
- item_factory.setup.connect((list_item) => { on_setup(list_item); });
- item_factory.bind.connect((list_item) => { on_bind(list_item); });
- return item_factory;
- }
-
- public static void on_setup(ListItem listitem) {
- listitem.child = new ConversationItemWidget();
- }
-
- public static void on_bind(ListItem listitem) {
- MessageViewModel view_model = (MessageViewModel) listitem.get_item();
- ConversationItemWidget view = (ConversationItemWidget) listitem.get_child();
-
- view_model.bind_property("name", view.name_label, "label", BindingFlags.SYNC_CREATE);
- view_model.bind_property("time", view.time_label, "label", BindingFlags.SYNC_CREATE);
-
- Label? label = view.content_widget as Label;
- if (label == null) {
- label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, vexpand=true };
- view.set_content_widget(label);
- }
- view_model.bind_property("message", label, "label", BindingFlags.SYNC_CREATE);
-
- view_model.bind_property("encryption-icon-name", view.encrypted_image, "icon-name", BindingFlags.SYNC_CREATE);
- view_model.bind_property("encryption-icon-tooltip", view.encrypted_image, "tooltip-text", BindingFlags.SYNC_CREATE);
-
- view_model.bind_property("marked-icon-name", view.marked_image, "icon-name", BindingFlags.SYNC_CREATE);
- view_model.bind_property("marked-icon-tooltip", view.marked_image, "tooltip-text", BindingFlags.SYNC_CREATE);
- }
-} \ No newline at end of file
diff --git a/main/src/ui/conversation_content_view/call_widget.vala b/main/src/ui/conversation_content_view/call_widget.vala
index 645c31c1..df4b7386 100644
--- a/main/src/ui/conversation_content_view/call_widget.vala
+++ b/main/src/ui/conversation_content_view/call_widget.vala
@@ -20,7 +20,7 @@ namespace Dino.Ui {
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) {
CallItem call_item = content_item as CallItem;
CallState? call_state = stream_interactor.get_module(Calls.IDENTITY).call_states[call_item.call];
- return new CallWidget(stream_interactor, call_item.call, call_state, call_item.conversation) { visible=true };
+ return new CallWidget(stream_interactor, call_item.call, call_state, call_item.conversation);
}
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { return null; }
@@ -94,17 +94,17 @@ namespace Dino.Ui {
}
foreach (Jid counterpart in call.counterparts) {
- AvatarImage image = new AvatarImage() { force_gray=true, margin_top=2, visible=true };
+ AvatarImage image = new AvatarImage() { force_gray=true, margin_top=2 };
image.set_conversation_participant(stream_interactor, conversation, counterpart.bare_jid);
multiparty_peer_box.append(image);
multiparty_peer_widgets.add(image);
}
- AvatarImage image2 = new AvatarImage() { force_gray=true, margin_top=2, visible=true };
+ AvatarImage image2 = new AvatarImage() { force_gray=true, margin_top=2 };
image2.set_conversation_participant(stream_interactor, conversation, call.account.bare_jid);
multiparty_peer_box.append(image2);
multiparty_peer_widgets.add(image2);
- outer_additional_box.get_style_context().add_class("multiparty-participants");
+ outer_additional_box.add_css_class("multiparty-participants");
multiparty_peer_box.visible = true;
incoming_call_box.visible = false;
@@ -113,8 +113,8 @@ namespace Dino.Ui {
private void update_call_state() {
incoming_call_revealer.reveal_child = false;
- incoming_call_revealer.get_style_context().remove_class("incoming");
- outer_additional_box.get_style_context().remove_class("incoming-call-box");
+ incoming_call_revealer.remove_css_class("incoming");
+ outer_additional_box.remove_css_class("incoming-call-box");
// It doesn't make sense to display MUC calls as missed or declined by the whole MUC. Just display as ended.
// TODO: maybe not let them be missed/declined in first place.
@@ -139,8 +139,8 @@ namespace Dino.Ui {
subtitle_label.label = "Ring ring…!";
incoming_call_box.visible = true;
incoming_call_revealer.reveal_child = true;
- incoming_call_revealer.get_style_context().add_class("incoming");
- outer_additional_box.get_style_context().add_class("incoming-call-box");
+ incoming_call_revealer.add_css_class("incoming");
+ outer_additional_box.add_css_class("incoming-call-box");
} else {
subtitle_label.label = "Dependencies for call support not met";
}
diff --git a/main/src/ui/conversation_content_view/chat_state_populator.vala b/main/src/ui/conversation_content_view/chat_state_populator.vala
index 0665caac..803739c8 100644
--- a/main/src/ui/conversation_content_view/chat_state_populator.vala
+++ b/main/src/ui/conversation_content_view/chat_state_populator.vala
@@ -77,11 +77,11 @@ private class MetaChatStateItem : Plugins.MetaConversationItem {
}
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType widget_type) {
- label = new Label("") { xalign=0, vexpand=true, visible=true };
- label.get_style_context().add_class("dim-label");
- image = new AvatarImage() { margin_top=2, valign=Align.START, visible=true };
+ label = new Label("") { xalign=0, vexpand=true };
+ label.add_css_class("dim-label");
+ image = new AvatarImage() { margin_top=2, valign=Align.START };
- Box image_content_box = new Box(Orientation.HORIZONTAL, 8) { visible=true };
+ Box image_content_box = new Box(Orientation.HORIZONTAL, 8);
image_content_box.append(image);
image_content_box.append(label);
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 3e4ce88b..ae2d835f 100644
--- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
@@ -18,7 +18,12 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
public Widget? content_widget = null;
- public bool show_skeleton { get; set; default=false; }
+ private bool show_skeleton_ = false;
+ public bool show_skeleton {
+ get { return show_skeleton_; }
+ set {
+ show_skeleton_ = value && content_meta_item != null && content_meta_item.requires_header && content_meta_item.requires_avatar; }
+ }
public bool last_group_item { get; set; default=true; }
public StreamInteractor stream_interactor;
@@ -26,7 +31,7 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
public Plugins.MetaConversationItem item;
public bool item_in_edit_mode { get; set; }
public Entities.Message.Marked item_mark { get; set; }
- public ContentMetaItem? content_meta_item = null;
+ public ContentMetaItem content_meta_item = null;
public Widget? widget = null;
private uint time_update_timeout = 0;
@@ -40,7 +45,7 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
Builder builder = new Builder.from_resource("/im/dino/Dino/conversation_item_widget.ui");
main_grid = (Grid) builder.get_object("main_grid");
- main_grid.get_style_context().add_class("message-box");
+ main_grid.add_css_class("message-box");
name_label = (Label) builder.get_object("name_label");
time_label = (Label) builder.get_object("time_label");
avatar_image = (AvatarImage) builder.get_object("avatar_image");
@@ -65,7 +70,7 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
}
private void set_header() {
- if (!show_skeleton || !item.requires_header) return;
+ if (!show_skeleton) return;
update_name_label();
// name_label.style_updated.connect(update_name_label);
@@ -102,34 +107,32 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
encryption_image.visible = show_skeleton;
received_image.visible = show_skeleton;
- if (show_skeleton) {
- main_grid.get_style_context().add_class("has-skeleton");
+ if (show_skeleton || content_meta_item == null) {
+ main_grid.add_css_class("has-skeleton");
}
if (last_group_item) {
- main_grid.get_style_context().add_class("last-group-item");
+ main_grid.add_css_class("last-group-item");
}
}
private void update_edit_mode() {
if (item.in_edit_mode) {
- main_grid.get_style_context().add_class("edit-mode");
+ main_grid.add_css_class("edit-mode");
} else {
- main_grid.get_style_context().remove_class("edit-mode");
+ main_grid.remove_css_class("edit-mode");
}
}
private void update_error_mode() {
if (item_mark == Message.Marked.ERROR) {
- main_grid.get_style_context().add_class("error");
+ main_grid.add_css_class("error");
} else {
- main_grid.get_style_context().remove_class("error");
+ main_grid.remove_css_class("error");
}
}
private void update_encryption_icon() {
- encryption_image.visible = true;
-
Application app = GLib.Application.get_default() as Application;
ContentMetaItem ci = item as ContentMetaItem;
@@ -141,7 +144,8 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
break;
}
}
- encryption_image.icon_name = icon_name ?? "dino-changes-prevent-symbolic";
+ encryption_image.icon_name = icon_name ?? "changes-prevent-symbolic";
+ encryption_image.visible = true;
}
if (item.encryption == Encryption.NONE) {
@@ -149,6 +153,7 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
encryption_image.icon_name = "dino-changes-allowed-symbolic";
encryption_image.tooltip_text = _("Unencrypted");
Util.force_error_color(encryption_image);
+ encryption_image.visible = true;
} else if (conversation.encryption == Encryption.NONE) {
encryption_image.icon_name = null;
encryption_image.visible = false;
@@ -176,8 +181,11 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
case Message.Marked.READ: received_image.icon_name = "dino-double-tick-symbolic"; break;
case Message.Marked.WONTSEND:
received_image.icon_name = "dialog-warning-symbolic";
- received_image.icon_name = _("Unable to send message");
- // TODO error color on marked icon and time
+ Util.force_error_color(received_image);
+ Util.force_error_color(time_label);
+ string error_text = _("Unable to send message");
+ received_image.tooltip_text = error_text;
+ time_label.tooltip_text = error_text;
break;
default: received_image.icon_name = null; break;
}
diff --git a/main/src/ui/conversation_content_view/conversation_view.vala b/main/src/ui/conversation_content_view/conversation_view.vala
index 8d46281f..bfee3cbb 100644
--- a/main/src/ui/conversation_content_view/conversation_view.vala
+++ b/main/src/ui/conversation_content_view/conversation_view.vala
@@ -108,7 +108,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
private void on_leave_notify_event() {
if (currently_highlighted != null) {
- currently_highlighted.get_style_context().remove_class("highlight");
+ currently_highlighted.remove_css_class("highlight");
currently_highlighted = null;
}
message_menu_box.visible = false;
@@ -134,7 +134,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
}
};
- if (currently_highlighted != null) currently_highlighted.get_style_context().remove_class("highlight");
+ if (currently_highlighted != null) currently_highlighted.remove_css_class("highlight");
currently_highlighted = null;
current_meta_item = null;
@@ -160,7 +160,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
if (current_meta_item != null) {
// Highlight widget
currently_highlighted = w;
- currently_highlighted.get_style_context().add_class("highlight");
+ currently_highlighted.add_css_class("highlight");
// Move message menu
message_menu_box.margin_top = (int)(widget_y - 10);
@@ -233,7 +233,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
i++;
}
scrolled.vadjustment.value = h - scrolled.vadjustment.page_size * 1/3;
- w.get_style_context().add_class("highlight-once");
+ w.add_css_class("highlight-once");
reload_messages = true;
stack.set_visible_child_name("main");
return false;
@@ -414,6 +414,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
});
}
} else if (scrolled.vadjustment.value < scrolled.vadjustment.upper - scrolled.vadjustment.page_size - 1) {
+ print("move!\n");
scrolled.vadjustment.value = scrolled.vadjustment.upper - was_upper + scrolled.vadjustment.value; // stay at same content
}
was_upper = scrolled.vadjustment.upper;
diff --git a/main/src/ui/conversation_content_view/date_separator_populator.vala b/main/src/ui/conversation_content_view/date_separator_populator.vala
index 40bf0693..25ef7a51 100644
--- a/main/src/ui/conversation_content_view/date_separator_populator.vala
+++ b/main/src/ui/conversation_content_view/date_separator_populator.vala
@@ -83,12 +83,12 @@ public class DateSeparatorWidget : Box {
visible = true;
this.date = date;
- label = new Label("") { use_markup=true, halign=Align.CENTER, hexpand=false, visible=true };
- label.get_style_context().add_class("dim-label");
+ label = new Label("") { use_markup=true, halign=Align.CENTER, hexpand=false };
+ label.add_css_class("dim-label");
- this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true, visible=true });
+ this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true });
this.append(label);
- this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true, visible=true });
+ this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true });
update_time();
}
diff --git a/main/src/ui/conversation_content_view/file_default_widget.vala b/main/src/ui/conversation_content_view/file_default_widget.vala
index 3bd5842f..9efc130f 100644
--- a/main/src/ui/conversation_content_view/file_default_widget.vala
+++ b/main/src/ui/conversation_content_view/file_default_widget.vala
@@ -9,6 +9,7 @@ namespace Dino.Ui {
[GtkTemplate (ui = "/im/dino/Dino/file_default_widget.ui")]
public class FileDefaultWidget : Box {
+ public signal void clicked();
public signal void open_file();
public signal void save_file_as();
public signal void cancel_download();
@@ -35,6 +36,7 @@ public class FileDefaultWidget : Box {
this_motion_events.leave.connect(on_pointer_left_event);
GestureClick gesture_click_controller = new GestureClick();
+ gesture_click_controller.set_button(1); // listen for left clicks
this.add_controller(gesture_click_controller);
gesture_click_controller.pressed.connect((n_press, x, y) => {
// Check whether the click was inside the file menu. Otherwise, open the file.
@@ -42,7 +44,7 @@ public class FileDefaultWidget : Box {
this.translate_coordinates(file_menu, x, y, out x_button, out y_button);
if (file_menu.contains(x_button, y_button)) return;
- this.open_file();
+ this.clicked();
});
}
diff --git a/main/src/ui/conversation_content_view/file_image_widget.vala b/main/src/ui/conversation_content_view/file_image_widget.vala
index aad220e8..285e397e 100644
--- a/main/src/ui/conversation_content_view/file_image_widget.vala
+++ b/main/src/ui/conversation_content_view/file_image_widget.vala
@@ -15,7 +15,7 @@ public class FileImageWidget : Box {
public FileImageWidget() {
this.halign = Align.START;
- this.get_style_context().add_class("file-image-widget");
+ this.add_css_class("file-image-widget");
}
public async void load_from_file(File file, string file_name, int MAX_WIDTH=600, int MAX_HEIGHT=300) throws GLib.Error {
@@ -52,7 +52,7 @@ public class FileImageWidget : Box {
file_default_widget_controller = new FileDefaultWidgetController(file_default_widget);
file_default_widget_controller.set_file(file, file_name, mime_type);
- Overlay overlay = new Overlay() { visible=true };
+ Overlay overlay = new Overlay();
overlay.set_child(image);
overlay.add_overlay(file_default_widget);
overlay.set_measure_overlay(image, true);
diff --git a/main/src/ui/conversation_content_view/file_widget.vala b/main/src/ui/conversation_content_view/file_widget.vala
index 6378c298..8dbc3dc8 100644
--- a/main/src/ui/conversation_content_view/file_widget.vala
+++ b/main/src/ui/conversation_content_view/file_widget.vala
@@ -19,7 +19,7 @@ public class FileMetaItem : ConversationSummary.ContentMetaItem {
public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) {
FileItem file_item = content_item as FileItem;
FileTransfer transfer = file_item.file_transfer;
- return new FileWidget(stream_interactor, transfer) { visible=true };
+ return new FileWidget(stream_interactor, transfer);
}
public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { return null; }
@@ -70,7 +70,7 @@ public class FileWidget : SizeRequestBox {
FileImageWidget file_image_widget = null;
try {
- file_image_widget = new FileImageWidget() { visible=true };
+ file_image_widget = new FileImageWidget();
yield file_image_widget.load_from_file(file_transfer.get_file(), file_transfer.file_name);
// If the widget changed in the meanwhile, stop
@@ -86,7 +86,7 @@ public class FileWidget : SizeRequestBox {
if (state != State.DEFAULT) {
if (content != null) this.remove(content);
- FileDefaultWidget default_file_widget = new FileDefaultWidget() { visible=true };
+ FileDefaultWidget default_file_widget = new FileDefaultWidget();
default_widget_controller = new FileDefaultWidgetController(default_file_widget);
default_widget_controller.set_file_transfer(file_transfer, stream_interactor);
content = default_file_widget;
@@ -129,14 +129,10 @@ public class FileDefaultWidgetController : Object {
public FileDefaultWidgetController(FileDefaultWidget widget) {
this.widget = widget;
+ widget.clicked.connect(on_clicked);
widget.open_file.connect(open_file);
widget.save_file_as.connect(save_file);
widget.cancel_download.connect(cancel_download);
-
- var gesture_controller = new GestureClick();
- gesture_controller.set_button(1); // listen for left clicks
- gesture_controller.released.connect(on_clicked);
- widget.add_controller(gesture_controller);
}
public void set_file_transfer(FileTransfer file_transfer, StreamInteractor stream_interactor) {
diff --git a/main/src/ui/conversation_content_view/message_item_widget.vala b/main/src/ui/conversation_content_view/message_item_widget.vala
deleted file mode 100644
index 23a499d9..00000000
--- a/main/src/ui/conversation_content_view/message_item_widget.vala
+++ /dev/null
@@ -1,229 +0,0 @@
-using Dino.Entities;
-using Gtk;
-
-namespace Dino.Ui {
- public class MessageItemWidget : SizeRequestBin {
-
- public signal void edit_cancelled();
- public signal void edit_sent(string text);
-
- enum AdditionalInfo {
- NONE,
- PENDING,
- DELIVERY_FAILED
- }
-
- StreamInteractor stream_interactor;
- public ContentItem content_item;
- public Message.Marked marked { get; set; }
-
- Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, vexpand=true, visible=true };
- MessageItemEditMode? edit_mode = null;
- ChatTextViewController? controller = null;
- AdditionalInfo additional_info = AdditionalInfo.NONE;
-
- ulong realize_id = -1;
- ulong style_updated_id = -1;
- ulong marked_notify_handler_id = -1;
-
- construct {
- this.append(label);
- label.activate_link.connect(on_label_activate_link);
- this.size_request_mode = SizeRequestMode.HEIGHT_FOR_WIDTH;
- }
-
- public MessageItemWidget(StreamInteractor stream_interactor, ContentItem content_item) {
- this.stream_interactor = stream_interactor;
- this.content_item = content_item;
-
- Message message = ((MessageItem) content_item).message;
- if (message.direction == Message.DIRECTION_SENT && !(message.marked in Message.MARKED_RECEIVED)) {
- var binding = message.bind_property("marked", this, "marked");
- marked_notify_handler_id = this.notify["marked"].connect(() => {
- // Currently "pending", but not anymore
- if (additional_info == AdditionalInfo.PENDING &&
- message.marked != Message.Marked.SENDING && message.marked != Message.Marked.UNSENT) {
- update_label();
- }
-
- // Currently "error", but not anymore
- if (additional_info == AdditionalInfo.DELIVERY_FAILED && message.marked != Message.Marked.ERROR) {
- update_label();
- }
-
- // Currently not error, but should be
- if (additional_info != AdditionalInfo.DELIVERY_FAILED && message.marked == Message.Marked.ERROR) {
- update_label();
- }
-
- // Nothing bad can happen anymore
- if (message.marked in Message.MARKED_RECEIVED) {
- binding.unbind();
- this.disconnect(marked_notify_handler_id);
- }
- });
- }
-
- update_label();
- }
-
- public void set_edit_mode() {
-
- MessageItem message_item = content_item as MessageItem;
- Message message = message_item.message;
-
- if (edit_mode == null) {
- edit_mode = new MessageItemEditMode();
- controller = new ChatTextViewController(edit_mode.chat_text_view, stream_interactor);
- Conversation conversation = message_item.conversation;
- controller.initialize_for_conversation(conversation);
-
- edit_mode.cancelled.connect(() => {
- edit_cancelled();
- unset_edit_mode();
- });
- edit_mode.send.connect(() => {
- if (((MessageItem) content_item).message.body != edit_mode.chat_text_view.text_view.buffer.text) {
- edit_sent(edit_mode.chat_text_view.text_view.buffer.text);
- } else {
- edit_cancelled();
- }
- unset_edit_mode();
- });
- }
-
- edit_mode.chat_text_view.text_view.buffer.text = message.body;
-
- this.remove(label);
- this.append(edit_mode);
-
- edit_mode.chat_text_view.text_view.grab_focus();
- }
-
- public void unset_edit_mode() {
- this.remove(edit_mode);
- this.append(label);
- label.grab_focus();
- label.selectable = false;
- label.selectable = true;
- }
-
- public void update_label() {
- label.label = generate_markup_text(content_item);
- }
-
- private string generate_markup_text(ContentItem item) {
- MessageItem message_item = item as MessageItem;
- Conversation conversation = message_item.conversation;
- Message message = message_item.message;
-
- bool theme_dependent = false;
-
- string markup_text = message.body;
- if (markup_text.length > 10000) {
- markup_text = markup_text.substring(0, 10000) + " [" + _("Message too long") + "]";
- }
- if (message.body.has_prefix("/me ")) {
- markup_text = markup_text.substring(4);
- }
-
- if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- markup_text = Util.parse_add_markup_theme(markup_text, conversation.nickname, true, true, true, Util.is_dark_theme(this), ref theme_dependent);
- } else {
- markup_text = Util.parse_add_markup_theme(markup_text, null, true, true, true, Util.is_dark_theme(this), ref theme_dependent);
- }
-
- if (message.body.has_prefix("/me ")) {
- string display_name = Util.get_participant_display_name(stream_interactor, conversation, message.from);
- markup_text = @"<i><b>$(Markup.escape_text(display_name))</b> " + markup_text + "</i>";
- }
-
- int only_emoji_count = Util.get_only_emoji_count(markup_text);
- if (only_emoji_count != -1) {
- string size_str = only_emoji_count < 5 ? "xx-large" : "large";
- markup_text = @"<span size=\'$size_str\'>" + markup_text + "</span>";
- }
-
- string dim_color = Util.is_dark_theme(this) ? "#BDBDBD" : "#707070";
-
- if (message.edit_to != null) {
- markup_text += @" <span size='small' color='$dim_color'>(%s)</span>".printf(_("edited"));
- theme_dependent = true;
- }
-
- // Append message status info
- additional_info = AdditionalInfo.NONE;
- if (message.direction == Message.DIRECTION_SENT && (message.marked == Message.Marked.SENDING || message.marked == Message.Marked.UNSENT)) {
- // Append "pending..." iff message has not been sent yet
- if (message.time.compare(new DateTime.now_utc().add_seconds(-10)) < 0) {
- markup_text += @" <span size='small' color='$dim_color'>%s</span>".printf(_("pending…"));
- theme_dependent = true;
- additional_info = AdditionalInfo.PENDING;
- } else {
- int time_diff = (- (int) message.time.difference(new DateTime.now_utc()) / 1000);
- Timeout.add(10000 - time_diff, () => {
- update_label();
- return false;
- });
- }
- } else if (message.direction == Message.DIRECTION_SENT && message.marked == Message.Marked.ERROR) {
- // Append "delivery failed" if there was a server error
- string error_color = Util.rgba_to_hex(Util.get_label_pango_color(label, "@error_color"));
- markup_text += " <span size='small' color='%s'>%s</span>".printf(error_color, _("delivery failed"));
- theme_dependent = true;
- additional_info = AdditionalInfo.DELIVERY_FAILED;
- }
-
- if (theme_dependent && realize_id == -1) {
- realize_id = label.realize.connect(update_label);
- // style_updated_id = label.style_updated.connect(update_label);
- } else if (!theme_dependent && realize_id != -1) {
- label.disconnect(realize_id);
- label.disconnect(style_updated_id);
- }
- return markup_text;
- }
-
- public static bool on_label_activate_link(string uri) {
- // Always handle xmpp URIs with Dino
- if (!uri.has_prefix("xmpp:")) return false;
- File file = File.new_for_uri(uri);
- Dino.Application.get_default().open(new File[]{file}, "");
- return true;
- }
- }
-
- [GtkTemplate (ui = "/im/dino/Dino/message_item_widget_edit_mode.ui")]
- public class MessageItemEditMode : Box {
-
- public signal void cancelled();
- public signal void send();
-
- [GtkChild] public unowned MenuButton emoji_button;
- [GtkChild] public unowned ChatTextView chat_text_view;
- [GtkChild] public unowned Button cancel_button;
- [GtkChild] public unowned Button send_button;
- [GtkChild] public unowned Frame frame;
-
- construct {
- Util.force_css(frame, "* { border-radius: 3px; }");
-
- 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);
-
- chat_text_view.text_view.buffer.changed.connect_after(on_text_view_changed);
-
- cancel_button.clicked.connect(() => cancelled());
- send_button.clicked.connect(() => send());
- chat_text_view.cancel_input.connect(() => cancelled());
- chat_text_view.send_text.connect(() => send());
- }
-
- private void on_text_view_changed() {
- send_button.sensitive = chat_text_view.text_view.buffer.text != "";
- }
- }
-} \ No newline at end of file
diff --git a/main/src/ui/conversation_content_view/message_widget.vala b/main/src/ui/conversation_content_view/message_widget.vala
index 3ebce0ee..346a6f71 100644
--- a/main/src/ui/conversation_content_view/message_widget.vala
+++ b/main/src/ui/conversation_content_view/message_widget.vala
@@ -28,7 +28,7 @@ public class MessageMetaItem : ContentMetaItem {
ulong style_updated_id = -1;
ulong marked_notify_handler_id = -1;
- public Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, vexpand=true, can_focus=false };
+ public Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, hexpand=true, vexpand=true };
public MessageMetaItem(ContentItem content_item, StreamInteractor stream_interactor) {
base(content_item);
diff --git a/main/src/ui/conversation_content_view/subscription_notification.vala b/main/src/ui/conversation_content_view/subscription_notification.vala
index 1f0f39d8..b825f4ad 100644
--- a/main/src/ui/conversation_content_view/subscription_notification.vala
+++ b/main/src/ui/conversation_content_view/subscription_notification.vala
@@ -33,9 +33,9 @@ public class SubscriptionNotitication : Object {
}
private void show_notification() {
- Box box = new Box(Orientation.HORIZONTAL, 5) { visible=true };
- Button accept_button = new Button.with_label(_("Accept")) { visible=true };
- Button deny_button = new Button.with_label(_("Deny")) { visible=true };
+ Box box = new Box(Orientation.HORIZONTAL, 5);
+ Button accept_button = new Button.with_label(_("Accept"));
+ Button deny_button = new Button.with_label(_("Deny"));
GLib.Application app = GLib.Application.get_default();
accept_button.clicked.connect(() => {
app.activate_action("accept-subscription", conversation.id);
@@ -45,7 +45,7 @@ public class SubscriptionNotitication : Object {
app.activate_action("deny-subscription", conversation.id);
conversation_view.remove_notification(box);
});
- box.append(new Label(_("This contact would like to add you to their contact list")) { margin_end=10, visible=true });
+ box.append(new Label(_("This contact would like to add you to their contact list")) { margin_end=10 });
box.append(accept_button);
box.append(deny_button);
conversation_view.add_notification(box);
diff --git a/main/src/ui/conversation_list/conversation_list_item_factory.vala b/main/src/ui/conversation_list/conversation_list_item_factory.vala
deleted file mode 100644
index dc26d2f1..00000000
--- a/main/src/ui/conversation_list/conversation_list_item_factory.vala
+++ /dev/null
@@ -1,245 +0,0 @@
-using Gtk;
-using Dino.Entities;
-using Dino;
-using Gee;
-using Pango;
-using Xmpp;
-
-namespace Dino.Ui.ConversationList {
-
- public static ListItemFactory get_item_factory() {
- SignalListItemFactory item_factory = new SignalListItemFactory();
- item_factory.setup.connect((list_item) => { on_setup(list_item); });
- item_factory.bind.connect((list_item) => { on_bind(list_item); });
- return item_factory;
- }
-
- public static void on_setup(ListItem listitem) {
- listitem.child = new ConversationListRow();
- }
-
- public static void on_bind(ListItem listitem) {
- ConversationViewModel list_model = (ConversationViewModel) listitem.get_item();
- ConversationListRow view = (ConversationListRow) listitem.get_child();
- StreamInteractor stream_interactor = list_model.stream_interactor;
-
- list_model.bind_property("name", view.name_label, "label");
- list_model.notify["latest-content-item"].connect((obj, _) => {
- update_content_item(view, list_model.conversation, stream_interactor, ((ConversationViewModel) obj).latest_content_item);
- });
- list_model.notify["unread-count"].connect((obj, _) => {
- update_read(view, list_model.conversation, stream_interactor, (int) obj);
- });
-
- view.x_button.clicked.connect(() => list_model.closed() );
-
- ConversationViewModel view_model = (ConversationViewModel) listitem.get_item();
- view.name_label.label = view_model.name;
- if (view_model.latest_content_item != null) {
- update_content_item(view, view_model.conversation, stream_interactor, view_model.latest_content_item);
- }
- update_read(view, view_model.conversation, stream_interactor, view_model.unread_count);
- }
-
- private static void update_content_item(ConversationListRow view, Conversation conversation, StreamInteractor stream_interactor, ContentItem last_content_item) {
- view.time_label.label = get_relative_time(last_content_item.time.to_local());
- view.image.set_conversation(stream_interactor, conversation);
-
- Label nick_label = view.nick_label;
- Label message_label = view.message_label;
-
- switch (last_content_item.type_) {
- case MessageItem.TYPE:
- MessageItem message_item = last_content_item as MessageItem;
- Message last_message = message_item.message;
-
- string body = last_message.body;
- bool me_command = body.has_prefix("/me ");
-
- /* If we have a /me command, we always show the display
- * name, and we don't set me_is_me on
- * get_participant_display_name, since that will return
- * "Me" (internationalized), whereas /me commands expect to
- * be in the third person. We also omit the colon in this
- * case, and strip off the /me prefix itself. */
-
- if (conversation.type_ == Conversation.Type.GROUPCHAT || me_command) {
- nick_label.label = Util.get_participant_display_name(stream_interactor, conversation, last_message.from, !me_command);
- } else if (last_message.direction == Message.DIRECTION_SENT) {
- nick_label.label = _("Me");
- } else {
- nick_label.label = "";
- }
-
- if (me_command) {
- /* Don't slice off the space after /me */
- body = body.slice("/me".length, body.length);
- } else if (nick_label.label.length > 0) {
- /* TODO: Is this valid for RTL languages? */
- nick_label.label += ": ";
- }
-
- message_label.attributes.filter((attr) => attr.equal(attr_style_new(Pango.Style.ITALIC)));
- message_label.label = Util.summarize_whitespaces_to_space(body);
-
- break;
- case FileItem.TYPE:
- FileItem file_item = last_content_item as FileItem;
- FileTransfer transfer = file_item.file_transfer;
-
- if (conversation.type_ == Conversation.Type.GROUPCHAT) {
- // TODO properly display nick for oneself
- nick_label.label = Util.get_participant_display_name(stream_interactor, conversation, file_item.file_transfer.from, true) + ": ";
- } else {
- nick_label.label = transfer.direction == Message.DIRECTION_SENT ? _("Me") + ": " : "";
- }
-
- bool file_is_image = transfer.mime_type != null && transfer.mime_type.has_prefix("image");
- message_label.attributes.insert(attr_style_new(Pango.Style.ITALIC));
- if (transfer.direction == Message.DIRECTION_SENT) {
- message_label.label = (file_is_image ? _("Image sent") : _("File sent") );
- } else {
- message_label.label = (file_is_image ? _("Image received") : _("File received") );
- }
- break;
- case CallItem.TYPE:
- CallItem call_item = (CallItem) last_content_item;
- Call call = call_item.call;
-
- nick_label.label = call.direction == Call.DIRECTION_OUTGOING ? _("Me") + ": " : "";
- message_label.attributes.insert(attr_style_new(Pango.Style.ITALIC));
- message_label.label = call.direction == Call.DIRECTION_OUTGOING ? _("Outgoing call") : _("Incoming call");
- break;
- }
- nick_label.visible = true;
- message_label.visible = true;
- }
-
- private void update_read(ConversationListRow view, Conversation conversation, StreamInteractor stream_interactor, int num_unread) {
- Label unread_count_label = view.unread_count_label;
- Label name_label = view.name_label;
- Label time_label = view.time_label;
- Label nick_label = view.nick_label;
- Label message_label = view.message_label;
- if (num_unread == 0) {
- unread_count_label.visible = false;
-
- name_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
- time_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
- nick_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
- message_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));
- } else {
- unread_count_label.label = num_unread.to_string();
- unread_count_label.visible = true;
-
- if (conversation.get_notification_setting(stream_interactor) == Conversation.NotifySetting.ON) {
- unread_count_label.get_style_context().add_class("unread-count-notify");
- unread_count_label.get_style_context().remove_class("unread-count");
- } else {
- unread_count_label.get_style_context().add_class("unread-count");
- unread_count_label.get_style_context().remove_class("unread-count-notify");
- }
-
- name_label.attributes.insert(attr_weight_new(Weight.BOLD));
- time_label.attributes.insert(attr_weight_new(Weight.BOLD));
- nick_label.attributes.insert(attr_weight_new(Weight.BOLD));
- message_label.attributes.insert(attr_weight_new(Weight.BOLD));
- }
-
- name_label.label = name_label.label; // TODO initializes redrawing, which would otherwise not happen. nicer?
- time_label.label = time_label.label;
- nick_label.label = nick_label.label;
- message_label.label = message_label.label;
- }
-
- private Widget generate_tooltip(StreamInteractor stream_interactor, Conversation conversation) {
- Grid grid = new Grid() { row_spacing=5, column_homogeneous=false, column_spacing=5, margin_start=7, margin_end=7, margin_top=7, margin_bottom=7 };
-
- Label label = new Label(conversation.counterpart.to_string()) { valign=Align.START, xalign=0, visible=true };
- label.attributes = new AttrList();
- label.attributes.insert(attr_weight_new(Weight.BOLD));
-
- grid.attach(label, 0, 0, 2, 1);
-
- Gee.List<Jid>? full_jids = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(conversation.counterpart, conversation.account);
- if (full_jids == null) return grid;
-
- for (int i = 0; i < full_jids.size; i++) {
- Jid full_jid = full_jids[i];
- string? show = stream_interactor.get_module(PresenceManager.IDENTITY).get_last_show(full_jid, conversation.account);
- if (show == null) continue;
-
- int i_cache = i;
- stream_interactor.get_module(EntityInfo.IDENTITY).get_identity.begin(conversation.account, full_jid, (_, res) => {
- Xep.ServiceDiscovery.Identity? identity = stream_interactor.get_module(EntityInfo.IDENTITY).get_identity.end(res);
-
- Image image = new Image() { hexpand=false, valign=Align.CENTER, visible=true };
- if (identity != null && (identity.type_ == Xep.ServiceDiscovery.Identity.TYPE_PHONE || identity.type_ == Xep.ServiceDiscovery.Identity.TYPE_TABLET)) {
- image.set_from_icon_name("dino-device-phone-symbolic");
- } else {
- image.set_from_icon_name("dino-device-desktop-symbolic");
- }
-
- if (show == Presence.Stanza.SHOW_AWAY) {
- Util.force_color(image, "#FF9800");
- } else if (show == Presence.Stanza.SHOW_XA || show == Presence.Stanza.SHOW_DND) {
- Util.force_color(image, "#FF5722");
- } else {
- Util.force_color(image, "#4CAF50");
- }
-
- string? status = null;
- if (show == Presence.Stanza.SHOW_AWAY) {
- status = "away";
- } else if (show == Presence.Stanza.SHOW_XA) {
- status = "not available";
- } else if (show == Presence.Stanza.SHOW_DND) {
- status = "do not disturb";
- }
-
- var sb = new StringBuilder();
- if (identity != null && identity.name != null) {
- sb.append(identity.name);
- } else if (full_jid.resourcepart != null) {
- sb.append(full_jid.resourcepart);
- } else {
- return;
- }
- if (status != null) {
- sb.append(" <i>(").append(status).append(")</i>");
- }
-
- Label resource = new Label(sb.str) { use_markup=true, hexpand=true, xalign=0, visible=true };
-
- grid.attach(image, 0, i_cache + 1, 1, 1);
- grid.attach(resource, 1, i_cache + 1, 1, 1);
- });
- }
- return grid;
- }
-
- private static string get_relative_time(DateTime datetime) {
- DateTime now = new DateTime.now_local();
- TimeSpan timespan = now.difference(datetime);
- if (timespan > 365 * TimeSpan.DAY) {
- return datetime.get_year().to_string();
- } else if (timespan > 7 * TimeSpan.DAY) {
- // Day and month
- // xgettext:no-c-format
- return datetime.format(_("%b %d"));
- } else if (timespan > 2 * TimeSpan.DAY) {
- return datetime.format("%a");
- } else if (datetime.get_day_of_month() != now.get_day_of_month()) {
- return _("Yesterday");
- } else if (timespan > 9 * TimeSpan.MINUTE) {
- return datetime.format(Util.is_24h_format() ?
- /* xgettext:no-c-format */ /* Time in 24h format (w/o seconds) */ _("%H∶%M") :
- /* xgettext:no-c-format */ /* Time in 12h format (w/o seconds) */ _("%l∶%M %p"));
- } else if (timespan > 1 * TimeSpan.MINUTE) {
- ulong mins = (ulong) (timespan.abs() / TimeSpan.MINUTE);
- return n("%i min ago", "%i mins ago", mins).printf(mins);
- } else {
- return _("Just now");
- }
- }
-} \ No newline at end of file
diff --git a/main/src/ui/conversation_list/conversation_list_model.vala b/main/src/ui/conversation_list/conversation_list_model.vala
deleted file mode 100644
index 9412e64a..00000000
--- a/main/src/ui/conversation_list/conversation_list_model.vala
+++ /dev/null
@@ -1,141 +0,0 @@
-using Gtk;
-using Dino.Entities;
-using Dino;
-using Gee;
-using Xmpp;
-
-public class Dino.Ui.ConversationViewModel : Object {
- public signal void closed();
-
- public StreamInteractor stream_interactor { get; set; }
- public Conversation conversation { get; set; }
- public string name { get; set; }
- public ContentItem? latest_content_item { get; set; }
- public int unread_count { get; set; }
-}
-
-public class Dino.Ui.ConversationListModel : Object, ListModel {
-
- public signal void closed_conversation(Conversation conversation);
-
- private HashMap<Conversation, ConversationViewModel> conversation_view_model_hm = new HashMap<Conversation, ConversationViewModel>(Conversation.hash_func, Conversation.equals_func);
- private ArrayList<ConversationViewModel> view_models = new ArrayList<ConversationViewModel>();
- private StreamInteractor stream_interactor;
-
- public ConversationListModel(StreamInteractor stream_interactor) {
- this.stream_interactor = stream_interactor;
-
- stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect(add_conversation);
- stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect(remove_conversation);
- stream_interactor.get_module(ContentItemStore.IDENTITY).new_item.connect(on_content_item_received);
-
- foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations()) {
- var view_model = create_view_model(conversation);
- view_models.add(view_model);
- conversation_view_model_hm[conversation] = view_model;
- }
- view_models.sort(sort);
- items_changed(0, 0, get_n_items());
-
- stream_interactor.get_module(RosterManager.IDENTITY).updated_roster_item.connect((account, jid, roster_item) => {
- ConversationViewModel? view_model = get_view_model(account, jid, Conversation.Type.CHAT);
- if (view_model == null) return;
- view_model.name = Util.get_conversation_display_name(stream_interactor, view_model.conversation);
- });
- stream_interactor.get_module(MucManager.IDENTITY).room_info_updated.connect((account, jid) => {
- ConversationViewModel? view_model = get_view_model(account, jid, Conversation.Type.GROUPCHAT);
- if (view_model == null) return;
- view_model.name = Util.get_conversation_display_name(stream_interactor, view_model.conversation);
- // bubble color might have changed
- view_model.unread_count = stream_interactor.get_module(ChatInteraction.IDENTITY).get_num_unread(view_model.conversation);
- });
- stream_interactor.get_module(MucManager.IDENTITY).private_room_occupant_updated.connect((account, room, occupant) => {
- ConversationViewModel? view_model = get_view_model(account, room.bare_jid, Conversation.Type.GROUPCHAT);
- if (view_model == null) return;
- view_model.name = Util.get_conversation_display_name(stream_interactor, view_model.conversation);
- });
- }
-
- public GLib.Object? get_item (uint position) {
- if (position >= view_models.size) return null;
- return view_models[(int)position];
- }
-
- public GLib.Type get_item_type () {
- return GLib.Type.OBJECT;
- }
-
- public uint get_n_items () {
- return view_models.size;
- }
-
- private ConversationViewModel create_view_model(Conversation conversation) {
- var view_model = new ConversationViewModel();
- view_model.stream_interactor = stream_interactor;
- view_model.conversation = conversation;
- view_model.name = Util.get_conversation_display_name(stream_interactor, conversation);
- view_model.latest_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_latest(conversation);
- view_model.unread_count = stream_interactor.get_module(ChatInteraction.IDENTITY).get_num_unread(conversation);
- view_model.closed.connect(() => closed_conversation(conversation));
-
- return view_model;
- }
-
- private void add_conversation(Conversation conversation) {
- var view_model = create_view_model(conversation);
-
- view_models.add(view_model);
- conversation_view_model_hm[conversation] = view_model;
- view_models.sort(sort);
-
- int idx = view_models.index_of(view_model);
- items_changed(idx, 0, 1);
- }
-
- private async void remove_conversation(Conversation conversation) {
- ConversationViewModel? view_model = conversation_view_model_hm[conversation];
- if (view_model == null) return;
-
- int idx = view_models.index_of(view_model);
- view_models.remove(view_model);
- conversation_view_model_hm.unset(conversation);
- items_changed(idx, 1, 0);
- }
-
- private void on_content_item_received(ContentItem item, Conversation conversation) {
- ConversationViewModel? view_model = conversation_view_model_hm[conversation];
- if (view_model == null) return;
-
- view_model.latest_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_latest(conversation);
- view_model.unread_count = stream_interactor.get_module(ChatInteraction.IDENTITY).get_num_unread(conversation);
-
- view_models.sort(sort);
- items_changed(0, view_models.size, view_models.size); // TODO better
- }
-
- private ConversationViewModel? get_view_model(Account account, Jid jid, Conversation.Type? conversation_ty) {
- foreach (ConversationViewModel view_model in view_models) {
- Conversation conversation = view_model.conversation;
- if (conversation.account.equals(account) && conversation.counterpart.equals(jid)) {
- if (conversation_ty != null && conversation.type_ != conversation_ty) continue;
- return view_model;
- }
- }
- return null;
- }
-
- private int sort(ConversationViewModel vm1, ConversationViewModel vm2) {
- Conversation c1 = vm1.conversation;
- Conversation c2 = vm2.conversation;
-
- if (c1 == null || c2 == null) return 0;
- if (c1.last_active == null) return -1;
- if (c2.last_active == null) return 1;
-
- int comp = c2.last_active.compare(c1.last_active);
- if (comp != 0) return comp;
-
- return Util.get_conversation_display_name(stream_interactor, c1)
- .collate(Util.get_conversation_display_name(stream_interactor, c2));
- }
-} \ No newline at end of file
diff --git a/main/src/ui/conversation_list/conversation_list_row.vala b/main/src/ui/conversation_list/conversation_list_row.vala
deleted file mode 100644
index ab4e8cee..00000000
--- a/main/src/ui/conversation_list/conversation_list_row.vala
+++ /dev/null
@@ -1,41 +0,0 @@
-using Gee;
-using Gdk;
-using Gtk;
-using Pango;
-
-using Dino;
-using Dino.Entities;
-using Xmpp;
-
-[GtkTemplate (ui = "/im/dino/Dino/conversation_row.ui")]
-public class Dino.Ui.ConversationListRow : ListBoxRow {
-
- [GtkChild] public unowned AvatarImage image;
- [GtkChild] public unowned Label name_label;
- [GtkChild] public unowned Label time_label;
- [GtkChild] public unowned Label nick_label;
- [GtkChild] public unowned Label message_label;
- [GtkChild] public unowned Label unread_count_label;
- [GtkChild] public unowned Button x_button;
- [GtkChild] public unowned Revealer time_revealer;
- [GtkChild] public unowned Revealer xbutton_revealer;
- [GtkChild] public unowned Revealer unread_count_revealer;
- [GtkChild] public unowned Revealer main_revealer;
-
- construct {
- name_label.attributes = new AttrList();
- }
-
- public override void state_flags_changed(StateFlags flags) {
- StateFlags curr_flags = get_state_flags();
- if ((curr_flags & StateFlags.PRELIGHT) != 0) {
- time_revealer.set_reveal_child(false);
- unread_count_revealer.set_reveal_child(false);
- xbutton_revealer.set_reveal_child(true);
- } else {
- time_revealer.set_reveal_child(true);
- unread_count_revealer.set_reveal_child(true);
- xbutton_revealer.set_reveal_child(false);
- }
- }
-} \ No newline at end of file
diff --git a/main/src/ui/conversation_selector/conversation_selector.vala b/main/src/ui/conversation_selector/conversation_selector.vala
index 2e262bf1..609e1be1 100644
--- a/main/src/ui/conversation_selector/conversation_selector.vala
+++ b/main/src/ui/conversation_selector/conversation_selector.vala
@@ -1,3 +1,4 @@
+using Gdk;
using Gee;
using Gtk;
@@ -18,7 +19,7 @@ public class ConversationSelector : Widget {
public ConversationSelector init(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
- list_box.insert_after(this, null);
+ list_box.set_parent(this);
this.layout_manager = new BinLayout();
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect(add_conversation);
@@ -36,7 +37,7 @@ public class ConversationSelector : Widget {
}
construct {
- get_style_context().add_class("sidebar");
+ add_css_class("sidebar");
list_box.set_header_func(header);
list_box.set_sort_func(sort);
@@ -78,36 +79,29 @@ public class ConversationSelector : Widget {
rows[conversation] = row;
list_box.append(row);
row.main_revealer.set_reveal_child(true);
-// drag_dest_set(row, DestDefaults.MOTION, null, Gdk.DragAction.COPY);
-// drag_dest_set_track_motion(row, true);
-// row.drag_motion.connect(this.on_drag_motion);
-// row.drag_leave.connect(this.on_drag_leave);
+
+ // Set up drag motion behaviour (select conversation after timeout)
+ DropControllerMotion drop_motion_controller = new DropControllerMotion();
+ uint drag_timeout = 0;
+ drop_motion_controller.motion.connect((x, y) => {
+ if (drag_timeout != 0) return;
+ drag_timeout = Timeout.add(200, () => {
+ conversation_selected(conversation);
+ drag_timeout = 0;
+ return false;
+ });
+ });
+ drop_motion_controller.leave.connect(() => {
+ if (drag_timeout != 0) {
+ Source.remove(drag_timeout);
+ drag_timeout = 0;
+ }
+ });
+ row.add_controller(drop_motion_controller);
}
list_box.invalidate_sort();
}
- /*public bool on_drag_motion(Widget widget, Gdk.DragContext context,
- int x, int y, uint time) {
- if (this.drag_timeout != null)
- return false;
- this.drag_timeout = Timeout.add(200, () => {
- if (widget.get_type().is_a(typeof(ConversationSelectorRow))) {
- ConversationSelectorRow row = widget as ConversationSelectorRow;
- conversation_selected(row.conversation);
- }
- this.drag_timeout = null;
- return false;
- });
- return false;
- }
-
- public void on_drag_leave(Widget widget, Gdk.DragContext context, uint time) {
- if (this.drag_timeout != null) {
- Source.remove(this.drag_timeout);
- this.drag_timeout = null;
- }
- }*/
-
private void select_fallback_conversation(Conversation conversation) {
if (list_box.get_selected_row() == rows[conversation]) {
int index = rows[conversation].get_index();
diff --git a/main/src/ui/conversation_selector/conversation_selector_row.vala b/main/src/ui/conversation_selector/conversation_selector_row.vala
index f813ddfc..76cbabb3 100644
--- a/main/src/ui/conversation_selector/conversation_selector_row.vala
+++ b/main/src/ui/conversation_selector/conversation_selector_row.vala
@@ -229,11 +229,11 @@ public class ConversationSelectorRow : ListBoxRow {
unread_count_label.visible = true;
if (conversation.get_notification_setting(stream_interactor) == Conversation.NotifySetting.ON) {
- unread_count_label.get_style_context().add_class("unread-count-notify");
- unread_count_label.get_style_context().remove_class("unread-count");
+ unread_count_label.add_css_class("unread-count-notify");
+ unread_count_label.remove_css_class("unread-count");
} else {
- unread_count_label.get_style_context().add_class("unread-count");
- unread_count_label.get_style_context().remove_class("unread-count-notify");
+ unread_count_label.add_css_class("unread-count");
+ unread_count_label.remove_css_class("unread-count-notify");
}
name_label.attributes.insert(attr_weight_new(Weight.BOLD));
@@ -266,7 +266,7 @@ public class ConversationSelectorRow : ListBoxRow {
private Widget generate_tooltip() {
Grid grid = new Grid() { row_spacing=5, column_homogeneous=false, column_spacing=5, margin_start=7, margin_end=7, margin_top=7, margin_bottom=7 };
- Label label = new Label(conversation.counterpart.to_string()) { valign=Align.START, xalign=0, visible=true };
+ Label label = new Label(conversation.counterpart.to_string()) { valign=Align.START, xalign=0 };
label.attributes = new AttrList();
label.attributes.insert(attr_weight_new(Weight.BOLD));
@@ -284,7 +284,7 @@ public class ConversationSelectorRow : ListBoxRow {
stream_interactor.get_module(EntityInfo.IDENTITY).get_identity.begin(conversation.account, full_jid, (_, res) => {
Xep.ServiceDiscovery.Identity? identity = stream_interactor.get_module(EntityInfo.IDENTITY).get_identity.end(res);
- Image image = new Image() { hexpand=false, valign=Align.CENTER, visible=true };
+ Image image = new Image() { hexpand=false, valign=Align.CENTER };
if (identity != null && (identity.type_ == Xep.ServiceDiscovery.Identity.TYPE_PHONE || identity.type_ == Xep.ServiceDiscovery.Identity.TYPE_TABLET)) {
image.set_from_icon_name("dino-device-phone-symbolic");
} else {
@@ -322,7 +322,7 @@ public class ConversationSelectorRow : ListBoxRow {
sb.append(" <i>(").append(status).append(")</i>");
}
- Label resource = new Label(sb.str) { use_markup=true, hexpand=true, xalign=0, visible=true };
+ Label resource = new Label(sb.str) { use_markup=true, hexpand=true, xalign=0 };
grid.attach(image, 0, i_cache + 1, 1, 1);
grid.attach(resource, 1, i_cache + 1, 1, 1);
diff --git a/main/src/ui/conversation_titlebar/call_entry.vala b/main/src/ui/conversation_titlebar/call_entry.vala
index 72376126..0a658b10 100644
--- a/main/src/ui/conversation_titlebar/call_entry.vala
+++ b/main/src/ui/conversation_titlebar/call_entry.vala
@@ -73,7 +73,6 @@ namespace Dino.Ui {
}
public new void set_conversation(Conversation conversation) {
- print(@"set_conversation $(conversation.counterpart)\n");
this.conversation = conversation;
update_visibility.begin();
diff --git a/main/src/ui/conversation_titlebar/conversation_titlebar.vala b/main/src/ui/conversation_titlebar/conversation_titlebar.vala
index 0d13e48b..26fd9639 100644
--- a/main/src/ui/conversation_titlebar/conversation_titlebar.vala
+++ b/main/src/ui/conversation_titlebar/conversation_titlebar.vala
@@ -31,27 +31,27 @@ public class ConversationTitlebarNoCsd : ConversationTitlebar, Object {
}
}
- private Box widgets_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=15, valign=Align.END, visible=true };
- private Label title_label = new Label("") { ellipsize=EllipsizeMode.END, visible=true };
+ private Box widgets_box = new Box(Orientation.HORIZONTAL, 7) { margin_start=15, valign=Align.END };
+ private Label title_label = new Label("") { ellipsize=EllipsizeMode.END };
private Label subtitle_label = new Label("") { use_markup=true, ellipsize=EllipsizeMode.END, visible=false };
construct {
- Box content_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=15, margin_end=10, hexpand=true, visible=true };
+ Box content_box = new Box(Orientation.HORIZONTAL, 0) { margin_start=15, margin_end=10, hexpand=true };
main.append(content_box);
- Box titles_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER, hexpand=true, visible=true };
+ Box titles_box = new Box(Orientation.VERTICAL, 0) { valign=Align.CENTER, hexpand=true };
content_box.append(titles_box);
titles_box.append(title_label);
subtitle_label.attributes = new AttrList();
- subtitle_label.get_style_context().add_class("dim-label");
+ subtitle_label.add_css_class("dim-label");
titles_box.append(subtitle_label);
content_box.append(widgets_box);
}
public ConversationTitlebarNoCsd() {
- main.get_style_context().add_class("dino-header-right");
+ main.add_css_class("dino-header-right");
}
public void insert_button(Widget button) {
@@ -79,7 +79,7 @@ public class ConversationTitlebarCsd : ConversationTitlebar, Object {
titles_box.append(title_label);
subtitle_label.attributes = new AttrList();
subtitle_label.attributes.insert(Pango.attr_scale_new(Pango.Scale.SMALL));
- subtitle_label.get_style_context().add_class("dim-label");
+ subtitle_label.add_css_class("dim-label");
titles_box.append(subtitle_label);
header_bar.set_title_widget(titles_box);
diff --git a/main/src/ui/conversation_view.vala b/main/src/ui/conversation_view.vala
index a51b2381..6e07b0e8 100644
--- a/main/src/ui/conversation_view.vala
+++ b/main/src/ui/conversation_view.vala
@@ -34,7 +34,7 @@ public class ConversationView : Widget {
}
public void add_overlay_dialog(Widget widget) {
- Revealer revealer = new Revealer() { transition_type=RevealerTransitionType.CROSSFADE , transition_duration= 100, visible=true };
+ Revealer revealer = new Revealer() { transition_type=RevealerTransitionType.CROSSFADE , transition_duration= 100 };
revealer.set_child(widget);
overlay.add_overlay(revealer);
@@ -43,7 +43,7 @@ public class ConversationView : Widget {
white_revealer.visible = true;
white_revealer.reveal_child = true;
widget.destroy.connect(() => {
- revealer.destroy(); // GTK4: this.remove_overlay(revealer);
+ overlay.remove_overlay(revealer);
white_revealer.reveal_child = false;
chat_input.do_focus();
});
diff --git a/main/src/ui/conversation_view_controller.vala b/main/src/ui/conversation_view_controller.vala
index 759984c8..6786117c 100644
--- a/main/src/ui/conversation_view_controller.vala
+++ b/main/src/ui/conversation_view_controller.vala
@@ -6,15 +6,6 @@ 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 : Object {
public new string? conversation_display_name { get; set; }
@@ -26,6 +17,7 @@ public class ConversationViewController : Object {
private ConversationTitlebar titlebar;
public SearchMenuEntry search_menu_entry = new SearchMenuEntry();
public ListView list_view = new ListView(null, null);
+ private DropTarget drop_event_controller = new DropTarget(typeof(File), DragAction.COPY );
private ChatInputController chat_input_controller;
private StreamInteractor stream_interactor;
@@ -38,21 +30,29 @@ public class ConversationViewController : Object {
this.app = GLib.Application.get_default() as Application;
this.chat_input_controller = new ChatInputController(view.chat_input, stream_interactor);
-// chat_input_controller.activate_last_message_correction.connect(view.conversation_frame.activate_last_message_correction);
+ chat_input_controller.activate_last_message_correction.connect(view.conversation_frame.activate_last_message_correction);
chat_input_controller.file_picker_selected.connect(open_file_picker);
chat_input_controller.clipboard_pasted.connect(on_clipboard_paste);
view.conversation_frame.init(stream_interactor);
// drag 'n drop file upload
-// view.drag_data_received.connect(this.on_drag_data_received);
+ drop_event_controller.on_drop.connect(this.on_drag_data_received);
// forward key presses
-// view.chat_input.key_press_event.connect(forward_key_press_to_chat_input);
-// view.conversation_frame.key_press_event.connect(forward_key_press_to_chat_input);
-// titlebar.key_press_event.connect(forward_key_press_to_chat_input);
+ var key_controller = new EventControllerKey();
+ key_controller.key_pressed.connect((v, c, s) => forward_key_press_to_chat_input(key_controller, v, c, s));
+ view.conversation_frame.add_controller(key_controller);
+
+ var key_controller2 = new EventControllerKey();
+ key_controller2.key_pressed.connect((v, c, s) => forward_key_press_to_chat_input(key_controller2, v, c, s));
+ view.chat_input.add_controller(key_controller2);
+
+ var key_controller3 = new EventControllerKey();
+ key_controller3.key_pressed.connect((v, c, s) => forward_key_press_to_chat_input(key_controller3, v, c, s));
+ titlebar.get_widget().add_controller(key_controller3);
-// goto-end floating button
+// goto-end floating button
var vadjustment = view.conversation_frame.scrolled.vadjustment;
vadjustment.notify["value"].connect(() => {
bool button_active = vadjustment.value < vadjustment.upper - vadjustment.page_size;
@@ -102,17 +102,16 @@ public class ConversationViewController : Object {
titlebar.insert_button(button);
}
-// AccelGroup accel_group = new AccelGroup();
-// accel_group.connect(Gdk.Key.U, ModifierType.CONTROL_MASK, AccelFlags.VISIBLE, () => {
-// if (conversation == null) return false;
-// stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.begin(conversation, (_, res) => {
-// if (stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.end(res)) {
-// open_file_picker();
-// }
-// });
-// return false;
-// });
-// ((Gtk.Window)view.get_toplevel()).add_accel_group(accel_group);
+ Shortcut shortcut = new Shortcut(new KeyvalTrigger(Key.U, ModifierType.CONTROL_MASK), new CallbackAction(() => {
+ if (conversation == null) return false;
+ stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.begin(conversation, (_, res) => {
+ if (stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.end(res)) {
+ open_file_picker();
+ }
+ });
+ return false;
+ }));
+ ((Gtk.Window)view.get_root()).add_shortcut(shortcut);
}
public void select_conversation(Conversation? conversation, bool default_initialize_conversation) {
@@ -159,10 +158,14 @@ public class ConversationViewController : Object {
stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.begin(conversation, (_, res) => {
bool upload_available = stream_interactor.get_module(FileManager.IDENTITY).is_upload_available.end(res);
chat_input_controller.set_file_upload_active(upload_available);
- if (upload_available && overlay_dialog == null) {
-// Gtk.drag_dest_set(view, DestDefaults.ALL, target_list, Gdk.DragAction.COPY);
+ if (conversation.account.bare_jid.to_string().has_prefix("f")) {
+ if (drop_event_controller.widget == null) {
+ view.add_controller(drop_event_controller);
+ }
} else {
-// Gtk.drag_dest_unset(view);
+ if (drop_event_controller.widget != null) {
+ view.remove_controller(drop_event_controller);
+ }
}
});
}
@@ -186,48 +189,28 @@ public class ConversationViewController : Object {
}
}
- private void on_clipboard_paste() {
+ private async void on_clipboard_paste() {
Clipboard clipboard = view.get_clipboard();
-// if (clipboard.wait_is_image_available()) {
-// clipboard.request_image((_, pixbuf) => {
-// File file = File.new_for_path(Path.build_filename(FileManager.get_storage_dir(), Xmpp.random_uuid() + ".png"));
-// try {
-// FileOutputStream fos = file.create(FileCreateFlags.REPLACE_DESTINATION);
-// pixbuf.save_to_stream_async.begin(fos, "png", null, () => {
-// open_send_file_overlay(file);
-// });
-// } catch (Error e) {
-// warning("Could not create file to store pasted image in %s, %s", file.get_path(), e.message);
-// }
-// });
-// }
+ Gdk.Texture? texture = yield clipboard.read_texture_async(null); // TODO critical
+ var file_name = Path.build_filename(FileManager.get_storage_dir(), Xmpp.random_uuid() + ".png");
+ texture.save_to_png(file_name);
+ open_send_file_overlay(File.new_for_path(file_name));
}
-// private 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 now we only process the first dragged file
-// if (uris.length >= 1) {
-// try {
-// string file_path = Filename.from_uri(uris[0]);
-// open_send_file_overlay(File.new_for_path(file_path));
-// } catch (ConvertError e) {
-// warning("Could not handle dragged file %s, %s", uris[0], e.message);
-// }
-// }
-// break;
-// default:
-// break;
-// }
-// }
-// }
+ private bool on_drag_data_received(DropTarget target, Value val, double x, double y) {
+ if (val.type() == typeof(File)) {
+ open_send_file_overlay((File)val);
+ return true;
+ }
+ return false;
+ }
private void open_file_picker() {
FileChooserNative chooser = new FileChooserNative(_("Select file"), view.get_root() as Gtk.Window, FileChooserAction.OPEN, _("Select"), _("Cancel"));
- chooser.response.connect(() => {
- open_send_file_overlay(File.new_for_path(chooser.get_file().get_path()));
+ chooser.response.connect((response) => {
+ if (response == ResponseType.ACCEPT) {
+ open_send_file_overlay(File.new_for_path(chooser.get_file().get_path()));
+ }
});
chooser.show();
}
@@ -272,24 +255,22 @@ public class ConversationViewController : Object {
stream_interactor.get_module(FileManager.IDENTITY).send_file.begin(file, conversation);
}
-// private bool forward_key_press_to_chat_input(EventKey event) {
-// if (((Gtk.Window)view.get_toplevel()).get_focus() is TextView) {
-// return false;
-// }
-//
-// // 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;
-// }
-// if (view.chat_input.chat_text_view.text_view.key_press_event(event)) {
-// return true;
-// }
-// return false;
-// }
+ private bool forward_key_press_to_chat_input(EventControllerKey key_controller, uint keyval, uint keycode, Gdk.ModifierType state) {
+ if (view.get_root().get_focus() is TextView) {
+ return false;
+ }
+
+ // Don't forward / change focus on Control / Alt
+ if (keyval == Gdk.Key.Control_L || keyval == Gdk.Key.Control_R ||
+ keyval == Gdk.Key.Alt_L || keyval == Gdk.Key.Alt_R) {
+ return false;
+ }
+ // Don't forward / change focus on Control + ...
+ if ((state & ModifierType.CONTROL_MASK) > 0) {
+ return false;
+ }
+
+ return key_controller.forward(view.chat_input.chat_text_view.text_view);
+ }
}
}
diff --git a/main/src/ui/file_send_overlay.vala b/main/src/ui/file_send_overlay.vala
index ceb78818..11bd9a11 100644
--- a/main/src/ui/file_send_overlay.vala
+++ b/main/src/ui/file_send_overlay.vala
@@ -28,14 +28,11 @@ public class FileSendOverlay {
info_label = (Label) builder.get_object("info_label");
close_button.clicked.connect(() => {
- main_box.unparent();
- main_box.destroy();
+ do_close();
});
send_button.clicked.connect(() => {
send_file();
- this.close();
- main_box.unparent();
- main_box.destroy();
+ do_close();
});
load_file_widget.begin(file, file_info);
@@ -48,12 +45,14 @@ public class FileSendOverlay {
}
});
-// this.key_release_event.connect((event) => {
-// if (event.keyval == Gdk.Key.Escape) {
-// this.destroy();
-// }
-// return false;
-// });
+ var key_events = new EventControllerKey();
+ key_events.key_pressed.connect((keyval) => {
+ if (keyval == Gdk.Key.Escape) {
+ do_close();
+ }
+ return false;
+ });
+ this.main_box.add_controller(key_events);
}
private async void load_file_widget(File file, FileInfo file_info) {
@@ -72,7 +71,7 @@ public class FileSendOverlay {
Widget? widget = null;
if (is_image) {
- FileImageWidget image_widget = new FileImageWidget() { visible=true };
+ FileImageWidget image_widget = new FileImageWidget();
try {
yield image_widget.load_from_file(file, file_name);
widget = image_widget;
@@ -80,7 +79,7 @@ public class FileSendOverlay {
}
if (widget == null) {
- FileDefaultWidget default_widget = new FileDefaultWidget() { visible=true };
+ FileDefaultWidget default_widget = new FileDefaultWidget();
default_widget.name_label.label = file_name;
default_widget.update_file_info(mime_type, FileTransfer.State.COMPLETE, (long)file_info.get_size());
widget = default_widget;
@@ -96,6 +95,12 @@ public class FileSendOverlay {
can_send = false;
}
+ private void do_close() {
+ this.close();
+ main_box.unparent();
+ main_box.destroy();
+ }
+
public Widget get_widget() {
return main_box;
}
diff --git a/main/src/ui/global_search.vala b/main/src/ui/global_search.vala
index bee409fe..5a02aa28 100644
--- a/main/src/ui/global_search.vala
+++ b/main/src/ui/global_search.vala
@@ -185,7 +185,7 @@ public class GlobalSearch {
Gee.List<MessageItem> before_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages_before_message(item.conversation, item.message.time, item.message.id, 1);
Gee.List<MessageItem> after_message = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages_after_message(item.conversation, item.message.time, item.message.id, 1);
- Box context_box = new Box(Orientation.VERTICAL, 5) { visible=true };
+ Box context_box = new Box(Orientation.VERTICAL, 5);
if (before_message != null && before_message.size > 0) {
context_box.append(get_context_message_widget(before_message.first()));
}
@@ -197,16 +197,16 @@ public class GlobalSearch {
context_box.append(get_context_message_widget(after_message.first()));
}
- Label date_label = new Label(ConversationSummary.ConversationItemSkeleton.get_relative_time(item.time.to_local())) { xalign=0, visible=true };
- date_label.get_style_context().add_class("dim-label");
+ Label date_label = new Label(ConversationSummary.ConversationItemSkeleton.get_relative_time(item.time.to_local())) { xalign=0 };
+ date_label.add_css_class("dim-label");
string display_name = Util.get_conversation_display_name(stream_interactor, item.conversation);
string title = item.message.type_ == Message.Type.GROUPCHAT ? _("In %s").printf(display_name) : _("With %s").printf(display_name);
- Box header_box = new Box(Orientation.HORIZONTAL, 10) { margin_start=7, visible=true };
- header_box.append(new Label(@"<b>$(Markup.escape_text(title))</b>") { ellipsize=EllipsizeMode.END, xalign=0, use_markup=true, visible=true });
+ Box header_box = new Box(Orientation.HORIZONTAL, 10) { margin_start=7 };
+ header_box.append(new Label(@"<b>$(Markup.escape_text(title))</b>") { ellipsize=EllipsizeMode.END, xalign=0, use_markup=true });
header_box.append(date_label);
- Box result_box = new Box(Orientation.VERTICAL, 7) { visible=true };
+ Box result_box = new Box(Orientation.VERTICAL, 7);
result_box.append(header_box);
result_box.append(context_box);
@@ -232,7 +232,7 @@ public class GlobalSearch {
text = text.substring(0, 25) + " … " + text.substring(index - 50, 50) + text.substring(index, 100) + " … " + text.substring(text.length - 25, 25);
}
}
- Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, vexpand=true, visible=true };
+ Label label = new Label("") { use_markup=true, xalign=0, selectable=true, wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, vexpand=true };
// Build regex containing all keywords
string regex_str = "(";
@@ -269,7 +269,7 @@ public class GlobalSearch {
label.label = markup_text;
grid.attach(label, 1, 1, 1, 1);
- Button button = new Button() { has_frame=false, visible=true };
+ Button button = new Button() { has_frame=false };
button.clicked.connect(() => {
selected_item(item);
});
@@ -280,20 +280,20 @@ public class GlobalSearch {
private Grid get_context_message_widget(MessageItem item) {
Grid grid = get_skeleton(item);
grid.margin_start = 7;
- Label label = new Label(item.message.body.replace("\n", "").replace("\r", "")) { ellipsize=EllipsizeMode.MIDDLE, xalign=0, visible=true };
+ Label label = new Label(item.message.body.replace("\n", "").replace("\r", "")) { ellipsize=EllipsizeMode.MIDDLE, xalign=0 };
grid.attach(label, 1, 1, 1, 1);
grid.opacity = 0.55;
return grid;
}
private Grid get_skeleton(MessageItem item) {
- AvatarImage image = new AvatarImage() { height=32, width=32, margin_end=7, valign=Align.START, visible=true, allow_gray = false };
+ AvatarImage image = new AvatarImage() { height=32, width=32, margin_end=7, valign=Align.START, allow_gray = false };
image.set_conversation_participant(stream_interactor, item.conversation, item.jid);
- Grid grid = new Grid() { row_homogeneous=false, visible=true };
+ Grid grid = new Grid() { row_homogeneous=false };
grid.attach(image, 0, 0, 1, 2);
string display_name = Util.get_participant_display_name(stream_interactor, item.conversation, item.jid);
- Label name_label = new Label(display_name) { ellipsize=EllipsizeMode.END, xalign=0, visible=true };
+ Label name_label = new Label(display_name) { ellipsize=EllipsizeMode.END, xalign=0 };
name_label.attributes = new AttrList();
name_label.attributes.insert(attr_weight_new(Weight.BOLD));
grid.attach(name_label, 1, 0, 1, 1);
diff --git a/main/src/ui/main_window.vala b/main/src/ui/main_window.vala
index a7e78b5d..1f1a7688 100644
--- a/main/src/ui/main_window.vala
+++ b/main/src/ui/main_window.vala
@@ -49,7 +49,7 @@ public class MainWindow : Gtk.Window {
this.title = "Dino";
- this.get_style_context().add_class("dino-main");
+ this.add_css_class("dino-main");
Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect(set_window_buttons);
((Widget)this).realize.connect(set_window_buttons);
@@ -77,7 +77,7 @@ public class MainWindow : Gtk.Window {
search_frame.set_child(global_search.get_widget());
Image conversation_list_placeholder_image = (Image) builder.get_object("conversation_list_placeholder_image");
- conversation_list_placeholder_image.set_from_pixbuf(new Pixbuf.from_resource("/im/dino/Dino/icons/dino-conversation-list-placeholder-arrow.svg"));
+ conversation_list_placeholder_image.set_from_pixbuf(new Pixbuf.from_resource("/im/dino/Dino/icons/scalable/ui/dino-conversation-list-placeholder-arrow.svg"));
}
private void setup_headerbar() {
diff --git a/main/src/ui/main_window_controller.vala b/main/src/ui/main_window_controller.vala
index 7049aa40..38ebcc9c 100644
--- a/main/src/ui/main_window_controller.vala
+++ b/main/src/ui/main_window_controller.vala
@@ -111,13 +111,6 @@ public class MainWindowController : Object {
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect(() => update_stack_state());
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect(() => update_stack_state());
update_stack_state();
-
-// AccelGroup accel_group = new AccelGroup();
-// accel_group.connect(Gdk.Key.F, ModifierType.CONTROL_MASK, AccelFlags.VISIBLE, () => {
-// window.search_revealer.reveal_child = true;
-// return false;
-// });
-// window.add_accel_group(accel_group);
}
public void select_conversation(Conversation? conversation, bool do_reset_search = true, bool default_initialize_conversation = true) {
diff --git a/main/src/ui/manage_accounts/add_account_dialog.vala b/main/src/ui/manage_accounts/add_account_dialog.vala
index d3dbf390..daff3abf 100644
--- a/main/src/ui/manage_accounts/add_account_dialog.vala
+++ b/main/src/ui/manage_accounts/add_account_dialog.vala
@@ -109,8 +109,8 @@ public class AddAccountDialog : Gtk.Dialog {
login_button.clicked.connect(show_sign_in_jid);
foreach (string server in server_list) {
- ListBoxRow list_box_row = new ListBoxRow() { visible=true };
- list_box_row.set_child(new Label(server) { xalign=0, margin_start=7, margin_end=7, visible=true });
+ ListBoxRow list_box_row = new ListBoxRow();
+ list_box_row.set_child(new Label(server) { xalign=0, margin_start=7, margin_end=7 });
list_box_jids[list_box_row] = server;
server_list_box.append(list_box_row);
}
@@ -338,8 +338,8 @@ public class AddAccountDialog : Gtk.Dialog {
register_title.label = _("Register on %s").printf(server.to_string());
if (form.oob != null) {
- form_box.append(new Label(_("The server requires to sign up through a website")){ visible=true } );
- form_box.append(new Label(@"<a href=\"$(form.oob)\">$(form.oob)</a>") { use_markup=true, visible=true });
+ form_box.append(new Label(_("The server requires to sign up through a website")));
+ form_box.append(new Label(@"<a href=\"$(form.oob)\">$(form.oob)</a>") { use_markup=true });
register_form_continue_label.label = _("Open website");
register_form_continue.visible = true;
register_form_continue.grab_focus();
@@ -347,23 +347,23 @@ public class AddAccountDialog : Gtk.Dialog {
if (form.instructions != null && form.instructions != "") {
string markup_instructions = Util.parse_add_markup(form.instructions, null, true, false);
form_box.append(new Label(markup_instructions) { use_markup=true, halign=Align.CENTER, xalign=0, margin_top=7,
- wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, visible=true });
+ wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR });
}
foreach (Xep.DataForms.DataForm.Field field in form.fields) {
Widget? field_widget = Util.get_data_form_field_widget(field);
if (field.label != null && field.label != "" && field_widget != null) {
- form_box.append(new Label(field.label) { xalign=0, margin_top=7, visible=true });
+ form_box.append(new Label(field.label) { xalign=0, margin_top=7 });
form_box.append(field_widget);
} else if (field.type_ == Xep.DataForms.DataForm.Type.FIXED && field.get_value_string() != "") {
string markup_fixed_field = Util.parse_add_markup(field.get_value_string(), null, true, false);
form_box.append(new Label(markup_fixed_field) { use_markup=true, xalign=0, margin_top=7,
- wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR, visible=true });
+ wrap=true, wrap_mode=Pango.WrapMode.WORD_CHAR });
}
}
register_form_continue.visible = true;
register_form_continue_label.label = _("Register");
} else {
- form_box.append(new Label(_("Check %s for information on how to sign up").printf(@"<a href=\"http://$(server)\">$(server)</a>")) { use_markup=true, visible=true });
+ form_box.append(new Label(_("Check %s for information on how to sign up").printf(@"<a href=\"http://$(server)\">$(server)</a>")) { use_markup=true });
register_form_continue.visible = false;
}
}
@@ -423,21 +423,19 @@ public class AddAccountDialog : Gtk.Dialog {
}
private void animate_window_resize(Widget widget) { // TODO code duplication
-// int def_height, curr_width, curr_height;
-// get_size(out curr_width, out curr_height);
-// widget.get_preferred_height(null, out def_height);
-// def_height += 5;
-// int difference = def_height - curr_height;
-// Timer timer = new Timer();
-// Timeout.add((int) (stack.transition_duration / 30),
-// () => {
-// ulong microsec;
-// timer.elapsed(out microsec);
-// ulong millisec = microsec / 1000;
-// double partial = double.min(1, (double) millisec / stack.transition_duration);
-// resize(curr_width, (int) (curr_height + difference * partial));
-// return millisec < stack.transition_duration;
-// });
+ int curr_height = widget.get_size(Orientation.VERTICAL);
+ var natural_size = Requisition();
+ stack.get_preferred_size(null, out natural_size);
+ int difference = natural_size.height + 5 - curr_height;
+ Timer timer = new Timer();
+ Timeout.add((int) (stack.transition_duration / 30), () => {
+ ulong microsec;
+ timer.elapsed(out microsec);
+ ulong millisec = microsec / 1000;
+ double partial = double.min(1, (double) millisec / stack.transition_duration);
+ default_height = (int) (curr_height + difference * partial);
+ return millisec < stack.transition_duration;
+ });
}
}
diff --git a/main/src/ui/manage_accounts/dialog.vala b/main/src/ui/manage_accounts/dialog.vala
index 88dc7485..efeff046 100644
--- a/main/src/ui/manage_accounts/dialog.vala
+++ b/main/src/ui/manage_accounts/dialog.vala
@@ -58,8 +58,8 @@ public class Dialog : Gtk.Dialog {
Widget? widget = e.get_widget(Plugins.WidgetType.GTK4) as Widget;
if (widget == null) continue;
- Label label = new Label(e.name) { xalign=1, yalign=0, visible=true };
- label.get_style_context().add_class("dim-label");
+ Label label = new Label(e.name) { xalign=1, yalign=0 };
+ label.add_css_class("dim-label");
label.margin_top = e.label_top_padding == -1 ? default_top_padding : e.label_top_padding;
settings_list.attach(label, 0, row_index);
@@ -117,18 +117,21 @@ public class Dialog : Gtk.Dialog {
msg.secondary_text = "You won't be able to access your conversation history anymore."; // TODO remove history!
Button ok_button = msg.get_widget_for_response(ResponseType.OK) as Button;
ok_button.label = _("Remove");
- ok_button.get_style_context().add_class("destructive-action");
- if (/*msg.run() == Gtk.ResponseType.OK*/ true) {
- account_list.remove(account_item);
- if (account_item.account.enabled) account_disabled(account_item.account);
- account_item.account.remove();
- if (account_list.get_row_at_index(0) != null) {
- account_list.select_row(account_list.get_row_at_index(0));
- } else {
- main_stack.set_visible_child_name("no_accounts");
+ ok_button.add_css_class("destructive-action");
+ msg.response.connect((response) => {
+ if (response == ResponseType.OK) {
+ account_list.remove(account_item);
+ if (account_item.account.enabled) account_disabled(account_item.account);
+ account_item.account.remove();
+ if (account_list.get_row_at_index(0) != null) {
+ account_list.select_row(account_list.get_row_at_index(0));
+ } else {
+ main_stack.set_visible_child_name("no_accounts");
+ }
}
- }
- msg.close();
+ msg.close();
+ });
+ msg.present();
}
private void on_account_list_row_selected(ListBoxRow? row) {
@@ -205,7 +208,7 @@ public class Dialog : Gtk.Dialog {
ConnectionManager.ConnectionError? error = stream_interactor.connection_manager.get_error(account);
if (error != null) {
state_label.label = get_connection_error_description(error);
- state_label.get_style_context().add_class("is_error");
+ state_label.add_css_class("is_error");
} else {
ConnectionManager.ConnectionState state = stream_interactor.connection_manager.get_state(account);
switch (state) {
@@ -216,7 +219,7 @@ public class Dialog : Gtk.Dialog {
case ConnectionManager.ConnectionState.DISCONNECTED:
state_label.label = _("Disconnected"); break;
}
- state_label.get_style_context().remove_class("is_error");
+ state_label.remove_css_class("is_error");
}
}
diff --git a/main/src/ui/occupant_menu/list.vala b/main/src/ui/occupant_menu/list.vala
index 20a98cf6..b9a4a74f 100644
--- a/main/src/ui/occupant_menu/list.vala
+++ b/main/src/ui/occupant_menu/list.vala
@@ -122,16 +122,16 @@ public class List : Box {
if (aff == affiliation) count++;
}
- Label title_label = new Label("") { margin_start=10, xalign=0, visible=true };
+ Label title_label = new Label("") { margin_start=10, xalign=0 };
title_label.set_markup(@"<b>$(Markup.escape_text(aff_str))</b>");
- Label count_label = new Label(@"$count") { xalign=0, margin_end=7, hexpand=true, visible=true };
- count_label.get_style_context().add_class("dim-label");
+ Label count_label = new Label(@"$count") { xalign=0, margin_end=7, hexpand=true };
+ count_label.add_css_class("dim-label");
- Grid grid = new Grid() { margin_top=top?5:15, column_spacing=5, hexpand=true, visible=true };
+ Grid grid = new Grid() { margin_top=top?5:15, column_spacing=5, hexpand=true };
grid.attach(title_label, 0, 0, 1, 1);
grid.attach(count_label, 1, 0, 1, 1);
- grid.attach(new Separator(Orientation.HORIZONTAL) { hexpand=true, vexpand=true, visible=true }, 0, 1, 2, 1);
+ grid.attach(new Separator(Orientation.HORIZONTAL) { hexpand=true, vexpand=true }, 0, 1, 2, 1);
return grid;
}
diff --git a/main/src/ui/occupant_menu/view.vala b/main/src/ui/occupant_menu/view.vala
index 35aa95f4..08e1e9ed 100644
--- a/main/src/ui/occupant_menu/view.vala
+++ b/main/src/ui/occupant_menu/view.vala
@@ -10,10 +10,10 @@ public class View : Popover {
private StreamInteractor stream_interactor;
private Conversation conversation;
- private Stack stack = new Stack() { vhomogeneous=false, visible=true };
- private Box list_box = new Box(Orientation.VERTICAL, 1) { visible=true };
+ private Stack stack = new Stack() { vhomogeneous=false };
+ private Box list_box = new Box(Orientation.VERTICAL, 1);
private List? list = null;
- private ListBox invite_list = new ListBox() { visible=true };
+ private ListBox invite_list = new ListBox();
private Box? jid_menu = null;
private Jid? selected_jid;
@@ -25,6 +25,7 @@ public class View : Popover {
this.show.connect(initialize_list);
invite_list.append(new ListRow.label("+", _("Invite")).get_widget());
+ invite_list.can_focus = false;
list_box.append(invite_list);
invite_list.row_activated.connect(on_invite_clicked);
@@ -44,7 +45,7 @@ public class View : Popover {
private void initialize_list() {
if (list == null) {
- list = new List(stream_interactor, conversation) { visible=true };
+ list = new List(stream_interactor, conversation);
list_box.prepend(list);
list.list_box.row_activated.connect((row) => {
@@ -68,17 +69,17 @@ public class View : Popover {
Jid? real_jid = stream_interactor.get_module(MucManager.IDENTITY).get_real_jid(jid, conversation.account);
if (real_jid != null) name += "\n<span font=\'8\'>%s</span>".printf(Markup.escape_text(real_jid.bare_jid.to_string()));
- Box header_box = new Box(Orientation.HORIZONTAL, 5) { visible=true };
- header_box.append(new Image.from_icon_name("pan-start-symbolic") { visible=true });
- header_box.append(new Label(name) { xalign=0, use_markup=true, hexpand=true, visible=true });
- Button header_button = new Button() { has_frame=false, visible=true };
+ Box header_box = new Box(Orientation.HORIZONTAL, 5);
+ header_box.append(new Image.from_icon_name("pan-start-symbolic"));
+ header_box.append(new Label(name) { xalign=0, use_markup=true, hexpand=true });
+ Button header_button = new Button() { has_frame=false };
header_button.child = header_box;
- Box outer_box = new Box(Orientation.VERTICAL, 5) { visible=true };
+ Box outer_box = new Box(Orientation.VERTICAL, 5);
outer_box.append(header_button);
header_button.clicked.connect(show_list);
- Button private_button = new Button.with_label(_("Start private conversation")) { visible=true };
+ Button private_button = new Button.with_label(_("Start private conversation")) ;
outer_box.append(private_button);
private_button.clicked.connect(private_conversation_button_clicked);
@@ -86,19 +87,19 @@ public class View : Popover {
Xmpp.Xep.Muc.Role? role = stream_interactor.get_module(MucManager.IDENTITY).get_role(own_jid, conversation.account);
if (role == Xmpp.Xep.Muc.Role.MODERATOR && stream_interactor.get_module(MucManager.IDENTITY).kick_possible(conversation.account, jid)) {
- Button kick_button = new Button.with_label(_("Kick")) { visible=true };
+ Button kick_button = new Button.with_label(_("Kick")) ;
outer_box.append(kick_button);
kick_button.clicked.connect(kick_button_clicked);
}
if (stream_interactor.get_module(MucManager.IDENTITY).is_moderated_room(conversation.account, conversation.counterpart) && role == Xmpp.Xep.Muc.Role.MODERATOR){
if (stream_interactor.get_module(MucManager.IDENTITY).get_role(selected_jid, conversation.account) == Xmpp.Xep.Muc.Role.VISITOR) {
- Button voice_button = new Button.with_label(_("Grant write permission")) { visible=true };
+ Button voice_button = new Button.with_label(_("Grant write permission")) ;
outer_box.append(voice_button);
voice_button.clicked.connect(() =>
voice_button_clicked("participant"));
}
else if (stream_interactor.get_module(MucManager.IDENTITY).get_role(selected_jid, conversation.account) == Xmpp.Xep.Muc.Role.PARTICIPANT){
- Button voice_button = new Button.with_label(_("Revoke write permission")) { visible=true };
+ Button voice_button = new Button.with_label(_("Revoke write permission")) ;
outer_box.append(voice_button);
voice_button.clicked.connect(() =>
voice_button_clicked("visitor"));
diff --git a/main/src/ui/util/data_forms.vala b/main/src/ui/util/data_forms.vala
index 53439149..af8789a7 100644
--- a/main/src/ui/util/data_forms.vala
+++ b/main/src/ui/util/data_forms.vala
@@ -11,7 +11,7 @@ public static Widget? get_data_form_field_widget(DataForms.DataForm.Field field)
switch (field.type_) {
case DataForms.DataForm.Type.BOOLEAN:
DataForms.DataForm.BooleanField boolean_field = field as DataForms.DataForm.BooleanField;
- Switch sw = new Switch() { active=boolean_field.value, halign=Align.START, valign=Align.CENTER, visible=true };
+ Switch sw = new Switch() { active=boolean_field.value, halign=Align.START, valign=Align.CENTER };
sw.state_set.connect((state) => {
boolean_field.value = state;
return false;
@@ -21,7 +21,7 @@ public static Widget? get_data_form_field_widget(DataForms.DataForm.Field field)
return null;
case DataForms.DataForm.Type.LIST_SINGLE:
DataForms.DataForm.ListSingleField list_single_field = field as DataForms.DataForm.ListSingleField;
- ComboBoxText combobox = new ComboBoxText() { valign=Align.CENTER, visible=true };
+ ComboBoxText combobox = new ComboBoxText() { valign=Align.CENTER };
for (int i = 0; i < list_single_field.options.size; i++) {
DataForms.DataForm.Option option = list_single_field.options[i];
combobox.append(option.value, option.label);
@@ -35,7 +35,7 @@ public static Widget? get_data_form_field_widget(DataForms.DataForm.Field field)
return null;
case DataForms.DataForm.Type.TEXT_PRIVATE:
DataForms.DataForm.TextPrivateField text_private_field = field as DataForms.DataForm.TextPrivateField;
- Entry entry = new Entry() { text=text_private_field.value ?? "", valign=Align.CENTER, visible=true, visibility=false };
+ Entry entry = new Entry() { text=text_private_field.value ?? "", valign=Align.CENTER, visibility=false };
var entry_key_events = new EventControllerKey();
entry_key_events.key_released.connect(() => {
text_private_field.value = entry.text;
@@ -44,7 +44,7 @@ public static Widget? get_data_form_field_widget(DataForms.DataForm.Field field)
return entry;
case DataForms.DataForm.Type.TEXT_SINGLE:
DataForms.DataForm.TextSingleField text_single_field = field as DataForms.DataForm.TextSingleField;
- Entry entry = new Entry() { text=text_single_field.value ?? "", valign=Align.CENTER, visible=true };
+ Entry entry = new Entry() { text=text_single_field.value ?? "", valign=Align.CENTER };
var entry_key_events = new EventControllerKey();
entry_key_events.key_released.connect(() => {
text_single_field.value = entry.text;
diff --git a/main/src/ui/util/label_hybrid.vala b/main/src/ui/util/label_hybrid.vala
index d880ba6f..53f0fbca 100644
--- a/main/src/ui/util/label_hybrid.vala
+++ b/main/src/ui/util/label_hybrid.vala
@@ -6,12 +6,12 @@ namespace Dino.Ui.Util {
public class LabelHybrid : Widget {
public Stack stack = new Stack();
- public Label label = new Label("") { visible=true, max_width_chars=1, ellipsize=Pango.EllipsizeMode.END };
- protected Button button = new Button() { has_frame=false, visible=true };
+ public Label label = new Label("") { max_width_chars=1, ellipsize=Pango.EllipsizeMode.END };
+ protected Button button = new Button() { has_frame=false };
internal virtual void init(Widget widget) {
this.layout_manager = new BinLayout();
- stack.insert_after(this, null);
+ stack.set_parent(this);
button.child = label;
stack.add_named(button, "label");
stack.add_named(widget, "widget");
@@ -29,6 +29,10 @@ public class LabelHybrid : Widget {
public void show_label() {
stack.visible_child_name = "label";
}
+
+ public override void dispose() {
+ stack.unparent();
+ }
}
public class EntryLabelHybrid : LabelHybrid {
@@ -58,7 +62,7 @@ public class EntryLabelHybrid : LabelHybrid {
public Entry entry {
get {
if (entry_ == null) {
- entry_ = new Entry() { visible=true };
+ entry_ = new Entry();
init(entry_);
}
return entry_;
@@ -71,10 +75,11 @@ public class EntryLabelHybrid : LabelHybrid {
}
internal override void init(Widget widget) {
- Entry? e = widget as Entry; if (e == null) return;
+ Entry? e = widget as Entry;
+ if (e == null) return;
entry = e;
base.init(entry);
- update_label();
+ set_label_label(entry.text);
var key_events = new EventControllerKey();
key_events.key_released.connect(on_key_released);
@@ -106,10 +111,6 @@ public class EntryLabelHybrid : LabelHybrid {
label.label = filler;
}
}
-
- private void update_label() {
- text = text;
- }
}
public class ComboBoxTextLabelHybrid : LabelHybrid {
@@ -128,7 +129,7 @@ public class ComboBoxTextLabelHybrid : LabelHybrid {
public ComboBoxText combobox {
get {
if (combobox_ == null) {
- combobox_ = new ComboBoxText() { visible=true };
+ combobox_ = new ComboBoxText();
init(combobox_);
}
return combobox_;
diff --git a/main/src/ui/util/scaling_image.vala b/main/src/ui/util/scaling_image.vala
index 3dd3221f..20ff6718 100644
--- a/main/src/ui/util/scaling_image.vala
+++ b/main/src/ui/util/scaling_image.vala
@@ -177,20 +177,6 @@ class ScalingImage : Widget {
minimum_baseline = natural_baseline = -1;
}
-// public override void get_preferred_height_for_width(int width, out int minimum_height, out int natural_height) {
-// double exact_width = width, exact_height = -1;
-// calculate_size(ref exact_width, ref exact_height);
-// natural_height = (int) Math.ceil(exact_height);
-// minimum_height = natural_height;
-// }
-//
-// public override void get_preferred_width_for_height(int height, out int minimum_width, out int natural_width) {
-// double exact_width = -1, exact_height = height;
-// calculate_size(ref exact_width, ref exact_height);
-// natural_width = (int) Math.ceil(exact_width);
-// minimum_width = natural_width;
-// }
-
public override SizeRequestMode get_request_mode() {
return SizeRequestMode.HEIGHT_FOR_WIDTH;
}
diff --git a/main/src/ui/util/sizing_bin.vala b/main/src/ui/util/sizing_bin.vala
index 939022a1..c17cb3cc 100644
--- a/main/src/ui/util/sizing_bin.vala
+++ b/main/src/ui/util/sizing_bin.vala
@@ -33,5 +33,10 @@ public class SizingBin : Widget {
natural = int.max(natural, minimum);
}
}
+
+ public override void dispose() {
+ var child = this.get_first_child();
+ if (child != null) child.unparent();
+ }
}
}