From 2ba1fe874070fc372c1a522c5c5b97173fbe1459 Mon Sep 17 00:00:00 2001 From: frosty Date: Wed, 26 Aug 2026 15:01:29 -0400 Subject: feat: add tweaks page to preferences, as well as an option for avatar roundness --- libdino/src/entity/settings.vala | 20 ++++++++++++++++ main/data/gresource.xml | 1 + main/data/preferences_window/preferences_dialog.ui | 10 +++++++- .../preferences_window/tweaks_preferences_page.ui | 27 ++++++++++++++++++++++ main/meson.build | 1 + main/src/ui/widgets/avatar_picture.vala | 21 +++++++++++++++++ main/src/view_model/preferences_dialog.vala | 7 ++++++ .../preferences_window/preferences_dialog.vala | 3 ++- .../tweaks_preferences_page.vala | 27 ++++++++++++++++++++++ 9 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 main/data/preferences_window/tweaks_preferences_page.ui create mode 100644 main/src/windows/preferences_window/tweaks_preferences_page.vala diff --git a/libdino/src/entity/settings.vala b/libdino/src/entity/settings.vala index 8a3eb2fe..7d0f03c8 100644 --- a/libdino/src/entity/settings.vala +++ b/libdino/src/entity/settings.vala @@ -21,6 +21,7 @@ public class Settings : Object { notifications_connection_errors_ = col_to_bool_or_default("notifications_connection_errors", true); convert_utf8_smileys_ = col_to_bool_or_default("convert_utf8_smileys", true); check_spelling = col_to_bool_or_default("check_spelling", true); + avatar_roundness_ = col_to_int_or_default("avatar_roundness", 20).clamp(0, 100); } private bool col_to_bool_or_default(string key, bool def) { @@ -28,6 +29,12 @@ public class Settings : Object { return val != null ? bool.parse(val) : def; } + private int col_to_int_or_default(string key, int def) { + string? val = db.settings.select({db.settings.value}).with(db.settings.key, "=", key)[db.settings.value]; + int parsed = def; + return val != null && int.try_parse(val, out parsed) ? parsed : def; + } + private bool send_typing_; public bool send_typing { get { return send_typing_; } @@ -173,6 +180,19 @@ public class Settings : Object { } } + private int avatar_roundness_; + public int avatar_roundness { + get { return avatar_roundness_; } + set { + int clamped_value = value.clamp(0, 100); + db.settings.upsert() + .value(db.settings.key, "avatar_roundness", true) + .value(db.settings.value, clamped_value.to_string()) + .perform(); + avatar_roundness_ = clamped_value; + } + } + public Encryption get_default_encryption(Account account) { string? setting = db.account_settings.get_value(account.id, "default-encryption"); if (setting != null) { diff --git a/main/data/gresource.xml b/main/data/gresource.xml index b1dc2c40..8f23c48a 100644 --- a/main/data/gresource.xml +++ b/main/data/gresource.xml @@ -92,6 +92,7 @@ preferences_window/change_password_dialog.ui preferences_window/general_preferences_page.ui preferences_window/preferences_dialog.ui + preferences_window/tweaks_preferences_page.ui join_room_dialog.ui join_room_dialog1.ui diff --git a/main/data/preferences_window/preferences_dialog.ui b/main/data/preferences_window/preferences_dialog.ui index 3a35b63f..dae1ce7c 100644 --- a/main/data/preferences_window/preferences_dialog.ui +++ b/main/data/preferences_window/preferences_dialog.ui @@ -28,5 +28,13 @@ + + + Tweaks + tweaks + preferences-desktop-appearance-symbolic + + + - \ No newline at end of file + diff --git a/main/data/preferences_window/tweaks_preferences_page.ui b/main/data/preferences_window/tweaks_preferences_page.ui new file mode 100644 index 00000000..ae9b26e8 --- /dev/null +++ b/main/data/preferences_window/tweaks_preferences_page.ui @@ -0,0 +1,27 @@ + + + + + 0 + 100 + 1 + 10 + + + diff --git a/main/meson.build b/main/meson.build index 4959b7c5..e387914f 100644 --- a/main/meson.build +++ b/main/meson.build @@ -101,6 +101,7 @@ sources = files( 'src/windows/preferences_window/encryption_preferences_page.vala', 'src/windows/preferences_window/general_preferences_page.vala', 'src/windows/preferences_window/preferences_dialog.vala', + 'src/windows/preferences_window/tweaks_preferences_page.vala', 'src/windows/conversation_details.vala', ) sources += gnome.compile_resources( diff --git a/main/src/ui/widgets/avatar_picture.vala b/main/src/ui/widgets/avatar_picture.vala index 155c9440..18e4d02f 100644 --- a/main/src/ui/widgets/avatar_picture.vala +++ b/main/src/ui/widgets/avatar_picture.vala @@ -217,6 +217,13 @@ public class Dino.Ui.CompatAvatarDrawer { public int width_request { get; set; default = 35; } public string font_family { get; set; default = "Sans"; } + public CompatAvatarDrawer() { + Dino.Application? application = Dino.Application.get_default(); + if (application != null && application.settings != null) { + radius_percent = (float) application.settings.avatar_roundness / 100.0f; + } + } + public Cairo.ImageSurface draw_image_surface() { Cairo.ImageSurface surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width_request, height_request); draw_on_context(new Cairo.Context(surface)); @@ -337,12 +344,17 @@ public class Dino.Ui.AvatarPicture : Gtk.Widget { private ViewModel.AvatarPictureModel? old_model; private ulong model_tiles_items_changed_handler; + private Binding? avatar_roundness_binding; construct { height_request = 35; width_request = 35; set_css_name("picture"); add_css_class("avatar"); + Dino.Application? application = Dino.Application.get_default(); + if (application != null && application.settings != null) { + avatar_roundness_binding = application.settings.bind_property("avatar-roundness", this, "radius-percent", BindingFlags.SYNC_CREATE, avatar_roundness_to_radius_percent); + } notify["radius-percent"].connect(queue_draw); notify["model"].connect(on_model_changed); check_widget_leak(this); @@ -433,11 +445,20 @@ public class Dino.Ui.AvatarPicture : Gtk.Widget { } public override void dispose() { + if (avatar_roundness_binding != null) { + avatar_roundness_binding.unbind(); + avatar_roundness_binding = null; + } model = null; on_model_changed(); base.dispose(); } + private static bool avatar_roundness_to_radius_percent(Binding binding, Value from_value, ref Value to_value) { + to_value.set_float((float) from_value.get_int() / 100.0f); + return true; + } + private class Tile : Gtk.Widget { public ViewModel.AvatarPictureTileModel? model { get; set; } public Gdk.RGBA background_color { get; set; default = Gdk.RGBA(){ red = 1.0f, green = 1.0f, blue = 1.0f, alpha = 0.0f }; } diff --git a/main/src/view_model/preferences_dialog.vala b/main/src/view_model/preferences_dialog.vala index 5b5412f8..d7bad93a 100644 --- a/main/src/view_model/preferences_dialog.vala +++ b/main/src/view_model/preferences_dialog.vala @@ -14,6 +14,7 @@ public class Dino.Ui.ViewModel.PreferencesDialog : Object { public Database db; public GeneralPreferencesPage general_page { get; set; default=new GeneralPreferencesPage(); } + public TweaksPreferencesPage tweaks_page { get; set; default=new TweaksPreferencesPage(); } public void populate(Database db, StreamInteractor stream_interactor) { this.db = db; @@ -36,6 +37,7 @@ public class Dino.Ui.ViewModel.PreferencesDialog : Object { stream_interactor.account_removed.connect(update_data); bind_general_page(); + bind_tweaks_page(); update_data(); } @@ -119,6 +121,11 @@ public class Dino.Ui.ViewModel.PreferencesDialog : Object { settings.bind_property("notifications-connection-errors", general_page, "notifications-connection-errors", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); settings.bind_property("convert-utf8-smileys", general_page, "convert-emojis", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); } + + private void bind_tweaks_page() { + var settings = Dino.Application.get_default().settings; + settings.bind_property("avatar-roundness", tweaks_page, "avatar-roundness", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); + } } public class Dino.Ui.ViewModel.ChangePasswordDialog : Object { diff --git a/main/src/windows/preferences_window/preferences_dialog.vala b/main/src/windows/preferences_window/preferences_dialog.vala index 4baced96..a92575f0 100644 --- a/main/src/windows/preferences_window/preferences_dialog.vala +++ b/main/src/windows/preferences_window/preferences_dialog.vala @@ -10,6 +10,7 @@ public class Dino.Ui.PreferencesDialog : Adw.PreferencesDialog { [GtkChild] public unowned Dino.Ui.PreferencesWindowAccounts accounts_page; [GtkChild] public unowned Dino.Ui.PreferencesWindowEncryption encryption_page; [GtkChild] public unowned Dino.Ui.GeneralPreferencesPage general_page; + [GtkChild] public unowned Dino.Ui.TweaksPreferencesPage tweaks_page; [GtkChild] public unowned ViewModel.PreferencesDialog model { get; } @@ -24,4 +25,4 @@ public class Dino.Ui.PreferencesDialog : Adw.PreferencesDialog { this.push_subpage(account_page); }); } -} \ No newline at end of file +} diff --git a/main/src/windows/preferences_window/tweaks_preferences_page.vala b/main/src/windows/preferences_window/tweaks_preferences_page.vala new file mode 100644 index 00000000..6da43348 --- /dev/null +++ b/main/src/windows/preferences_window/tweaks_preferences_page.vala @@ -0,0 +1,27 @@ +using Gtk; + +public class Dino.Ui.ViewModel.TweaksPreferencesPage : Object { + public int avatar_roundness { get; set; } +} + +[GtkTemplate (ui = "/im/dino/Dino/preferences_window/tweaks_preferences_page.ui")] +public class Dino.Ui.TweaksPreferencesPage : Adw.PreferencesPage { + [GtkChild] private unowned Adw.SpinRow avatar_roundness_row; + + public ViewModel.TweaksPreferencesPage model { get; set; default = new ViewModel.TweaksPreferencesPage(); } + private Binding? avatar_roundness_binding; + + construct { + this.notify["model"].connect(on_model_changed); + } + + private void on_model_changed() { + if (avatar_roundness_binding != null) { + avatar_roundness_binding.unbind(); + avatar_roundness_binding = null; + } + if (model != null) { + avatar_roundness_binding = model.bind_property("avatar-roundness", avatar_roundness_row, "value", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); + } + } +} -- cgit v1.3