From 7e7dcedaf31ee35499875491c9f569c575d28435 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 14 Feb 2022 14:55:59 +0100 Subject: Port from GTK3 to GTK4 --- main/src/ui/util/data_forms.vala | 10 ++-- main/src/ui/util/helper.vala | 45 ++++++++--------- main/src/ui/util/label_hybrid.vala | 66 +++++++++++++++---------- main/src/ui/util/scaling_image.vala | 89 ++++++++++++++++++++-------------- main/src/ui/util/size_request_box.vala | 6 ++- main/src/ui/util/sizing_bin.vala | 38 ++++++++------- 6 files changed, 146 insertions(+), 108 deletions(-) (limited to 'main/src/ui/util') diff --git a/main/src/ui/util/data_forms.vala b/main/src/ui/util/data_forms.vala index b36012de..53439149 100644 --- a/main/src/ui/util/data_forms.vala +++ b/main/src/ui/util/data_forms.vala @@ -36,18 +36,20 @@ public static Widget? get_data_form_field_widget(DataForms.DataForm.Field field) 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.key_release_event.connect(() => { + var entry_key_events = new EventControllerKey(); + entry_key_events.key_released.connect(() => { text_private_field.value = entry.text; - return false; }); + entry.add_controller(entry_key_events); 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.key_release_event.connect(() => { + var entry_key_events = new EventControllerKey(); + entry_key_events.key_released.connect(() => { text_single_field.value = entry.text; - return false; }); + entry.add_controller(entry_key_events); return entry; default: return null; diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala index 427c2d3a..98abb48e 100644 --- a/main/src/ui/util/helper.vala +++ b/main/src/ui/util/helper.vala @@ -134,29 +134,30 @@ public static string get_occupant_display_name(StreamInteractor stream_interacto return Dino.get_occupant_display_name(stream_interactor, conversation, jid, me_is_me ? _("Me") : null); } -public static void image_set_from_scaled_pixbuf(Image image, Gdk.Pixbuf pixbuf, int scale = 0, int width = 0, int height = 0) { - if (scale == 0) scale = image.scale_factor; - Cairo.Surface surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, image.get_window()); - if (height == 0 && width != 0) { - height = (int) ((double) width / pixbuf.width * pixbuf.height); - } else if (height != 0 && width == 0) { - width = (int) ((double) height / pixbuf.height * pixbuf.width); - } - if (width != 0) { - Cairo.Surface surface_new = new Cairo.Surface.similar_image(surface, Cairo.Format.ARGB32, width, height); - Cairo.Context context = new Cairo.Context(surface_new); - context.scale((double) width * scale / pixbuf.width, (double) height * scale / pixbuf.height); - context.set_source_surface(surface, 0, 0); - context.get_source().set_filter(Cairo.Filter.BEST); - context.paint(); - surface = surface_new; - } - image.set_from_surface(surface); -} +// TODO this has no usages? +//public static void image_set_from_scaled_pixbuf(Image image, Gdk.Pixbuf pixbuf, int scale = 0, int width = 0, int height = 0) { +// if (scale == 0) scale = image.scale_factor; +// Cairo.Surface surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, image.get_window()); +// if (height == 0 && width != 0) { +// height = (int) ((double) width / pixbuf.width * pixbuf.height); +// } else if (height != 0 && width == 0) { +// width = (int) ((double) height / pixbuf.height * pixbuf.width); +// } +// if (width != 0) { +// Cairo.Surface surface_new = new Cairo.Surface.similar_image(surface, Cairo.Format.ARGB32, width, height); +// Cairo.Context context = new Cairo.Context(surface_new); +// context.scale((double) width * scale / pixbuf.width, (double) height * scale / pixbuf.height); +// context.set_source_surface(surface, 0, 0); +// context.get_source().set_filter(Cairo.Filter.BEST); +// context.paint(); +// surface = surface_new; +// } +// image.set_from_surface(surface); +//} public static Gdk.RGBA get_label_pango_color(Label label, string css_color) { Gtk.CssProvider provider = force_color(label, css_color); - Gdk.RGBA color_rgba = label.get_style_context().get_color(StateFlags.NORMAL); + Gdk.RGBA color_rgba = label.get_style_context().get_color(); label.get_style_context().remove_provider(provider); return color_rgba; } @@ -176,7 +177,7 @@ private const string force_color_css = "%s { color: %s; }"; public static Gtk.CssProvider force_css(Gtk.Widget widget, string css) { var p = new Gtk.CssProvider(); try { - p.load_from_data(css); + p.load_from_data(css.data); widget.get_style_context().add_provider(p, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } catch (GLib.Error err) { // handle err @@ -197,7 +198,7 @@ public static void force_error_color(Gtk.Widget widget, string selector = "*") { } public static bool is_dark_theme(Gtk.Widget widget) { - Gdk.RGBA bg = widget.get_style_context().get_color(StateFlags.NORMAL); + Gdk.RGBA bg = widget.get_style_context().get_color(); return (bg.red > 0.5 && bg.green > 0.5 && bg.blue > 0.5); } diff --git a/main/src/ui/util/label_hybrid.vala b/main/src/ui/util/label_hybrid.vala index b992f169..d880ba6f 100644 --- a/main/src/ui/util/label_hybrid.vala +++ b/main/src/ui/util/label_hybrid.vala @@ -3,15 +3,18 @@ using Gtk; namespace Dino.Ui.Util { -public class LabelHybrid : Stack { +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() { relief=ReliefStyle.NONE, visible=true }; + protected Button button = new Button() { has_frame=false, visible=true }; internal virtual void init(Widget widget) { - button.add(label); - add_named(button, "label"); - add_named(widget, "widget"); + this.layout_manager = new BinLayout(); + stack.insert_after(this, null); + button.child = label; + stack.add_named(button, "label"); + stack.add_named(widget, "widget"); button.clicked.connect(() => { show_widget(); @@ -19,12 +22,12 @@ public class LabelHybrid : Stack { } public void show_widget() { - visible_child_name = "widget"; - get_child_by_name("widget").grab_focus(); + stack.visible_child_name = "widget"; + stack.get_child_by_name("widget").grab_focus(); } public void show_label() { - visible_child_name = "label"; + stack.visible_child_name = "label"; } } @@ -73,18 +76,25 @@ public class EntryLabelHybrid : LabelHybrid { base.init(entry); update_label(); - entry.key_release_event.connect((event) => { - if (event.keyval == Gdk.Key.Return) { - show_label(); - } else { - set_label_label(entry.text); - } - return false; - }); - entry.focus_out_event.connect(() => { + var key_events = new EventControllerKey(); + key_events.key_released.connect(on_key_released); + entry.add_controller(key_events); + + var focus_events = new EventControllerFocus(); + focus_events.leave.connect(on_focus_leave); + entry.add_controller(focus_events); + } + + private void on_key_released(uint keyval) { + if (keyval == Gdk.Key.Return) { show_label(); - return false; - }); + } else { + set_label_label(entry.text); + } + } + + private void on_focus_leave() { + show_label(); } private void set_label_label(string value) { @@ -143,14 +153,18 @@ public class ComboBoxTextLabelHybrid : LabelHybrid { update_label(); show_label(); }); - combobox.focus_out_event.connect(() => { - update_label(); - show_label(); - return false; - }); button.clicked.connect(() => { combobox.popup(); }); + + var focus_events = new EventControllerFocus(); + focus_events.leave.connect(on_focus_leave); + combobox.add_controller(focus_events); + } + + private void on_focus_leave() { + update_label(); + show_label(); } private void update_label() { @@ -166,10 +180,10 @@ public class LabelHybridGroup { hybrids.add(hybrid); hybrid.notify["visible-child-name"].connect(() => { - if (hybrid.visible_child_name == "label") return; + if (hybrid.stack.visible_child_name == "label") return; foreach (LabelHybrid h in hybrids) { if (h != hybrid) { - h.set_visible_child_name("label"); + h.stack.set_visible_child_name("label"); } } }); diff --git a/main/src/ui/util/scaling_image.vala b/main/src/ui/util/scaling_image.vala index 477432c5..3dd3221f 100644 --- a/main/src/ui/util/scaling_image.vala +++ b/main/src/ui/util/scaling_image.vala @@ -2,7 +2,7 @@ using Gdk; using Gtk; namespace Dino.Ui { -class ScalingImage : Misc { +class ScalingImage : Widget { public int min_width { get; set; default = -1; } public int target_width { get; set; default = -1; } public int max_width { get; set; default = -1; } @@ -65,23 +65,28 @@ class ScalingImage : Misc { if (exact_height < min_height) exact_height = min_height; } - public override void size_allocate(Allocation allocation) { - if (max_width != -1) allocation.width = int.min(allocation.width, max_width); - if (max_height != -1) allocation.height = int.min(allocation.height, max_height); - allocation.height = int.max(allocation.height, min_height); - allocation.width = int.max(allocation.width, min_width); - double exact_width = allocation.width, exact_height = allocation.height; + public override void size_allocate(int width, int height, int baseline) { + if (max_width != -1) width = int.min(width, max_width); + if (max_height != -1) height = int.min(height, max_height); + height = int.max(height, min_height); + width = int.max(width, min_width); + double exact_width = width, exact_height = height; calculate_size(ref exact_width, ref exact_height); - base.size_allocate(allocation); - if (last_allocation_height != allocation.height || last_allocation_width != allocation.width || last_scale_factor != scale_factor) { - last_allocation_height = allocation.height; - last_allocation_width = allocation.width; + base.size_allocate(width, height, baseline); + if (last_allocation_height != height || last_allocation_width != width || last_scale_factor != scale_factor) { + last_allocation_height = height; + last_allocation_width = width; last_scale_factor = scale_factor; cached_surface = null; } } - public override bool draw(Cairo.Context ctx_in) { + public override void snapshot(Gtk.Snapshot snapshot) { + Cairo.Context context = snapshot.append_cairo(Graphene.Rect.alloc().init(0, 0, get_allocated_width(), get_allocated_height())); + draw(context); + } + + public bool draw(Cairo.Context ctx_in) { if (image == null) return false; Cairo.Context ctx = ctx_in; int width = this.get_allocated_width(), height = this.get_allocated_height(), base_factor = 1; @@ -148,33 +153,43 @@ class ScalingImage : Misc { return buffer; } - public override void get_preferred_width(out int minimum_width, out int natural_width) { - minimum_width = int.max(0, min_width); - double exact_width = -1, exact_height = -1; - calculate_size(ref exact_width, ref exact_height); - natural_width = (int) Math.ceil(exact_width); - } - - public override void get_preferred_height(out int minimum_height, out int natural_height) { - minimum_height = int.max(0, min_height); - double exact_width = -1, exact_height = -1; - calculate_size(ref exact_width, ref exact_height); - natural_height = (int) Math.ceil(exact_height); - } - - 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 measure(Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) { + double natural_width = -1, natural_height = -1; + calculate_size(ref natural_width, ref natural_height); + if (orientation == Orientation.HORIZONTAL) { + natural = (int) Math.ceil(natural_width); + } else { + natural = (int) Math.ceil(natural_height); + } + if (for_size == -1) { + minimum = 0; + } else { + if (orientation == Orientation.HORIZONTAL) { + double exact_width = -1, exact_height = for_size; + calculate_size(ref exact_width, ref exact_height); + minimum = int.max((int)Math.floor(exact_width), min_width); + } else { + double exact_width = for_size, exact_height = -1; + calculate_size(ref exact_width, ref exact_height); + minimum = int.max((int)Math.floor(exact_height), min_height); + } + } + minimum_baseline = natural_baseline = -1; } - 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 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/size_request_box.vala b/main/src/ui/util/size_request_box.vala index a2828262..7d7b6185 100644 --- a/main/src/ui/util/size_request_box.vala +++ b/main/src/ui/util/size_request_box.vala @@ -9,9 +9,13 @@ public class SizeRequestBox : Box { } } -public class SizeRequestBin : Bin { +public class SizeRequestBin : Widget { public SizeRequestMode size_request_mode { get; set; default = SizeRequestMode.CONSTANT_SIZE; } + construct { + this.layout_manager = new BinLayout(); + } + public override Gtk.SizeRequestMode get_request_mode() { return size_request_mode; } diff --git a/main/src/ui/util/sizing_bin.vala b/main/src/ui/util/sizing_bin.vala index 9c5ff4c7..939022a1 100644 --- a/main/src/ui/util/sizing_bin.vala +++ b/main/src/ui/util/sizing_bin.vala @@ -1,7 +1,7 @@ using Gtk; namespace Dino.Ui { -public class SizingBin : Bin { +public class SizingBin : Widget { public int min_width { get; set; default = -1; } public int target_width { get; set; default = -1; } public int max_width { get; set; default = -1; } @@ -9,27 +9,29 @@ public class SizingBin : Bin { public int target_height { get; set; default = -1; } public int max_height { get; set; default = -1; } - public override void size_allocate(Allocation allocation) { - if (max_height != -1) allocation.height = int.min(allocation.height, max_height); - if (max_width != -1) allocation.width = int.min(allocation.width, max_width); - base.size_allocate(allocation); + construct { + layout_manager = new BinLayout(); } - public override void get_preferred_width(out int minimum_width, out int natural_width) { - base.get_preferred_width(out minimum_width, out natural_width); - if (min_width != -1) minimum_width = int.max(minimum_width, min_width); - if (max_width != -1) natural_width = int.min(natural_width, max_width); - if (target_width != -1) natural_width = int.max(natural_width, target_width); - natural_width = int.max(natural_width, minimum_width); + public override void size_allocate(int width, int height, int baseline) { + if (max_height != -1) height = int.min(height, max_height); + if (max_width != -1) width = int.min(width, max_width); + base.size_allocate(width, height, baseline); } - public override void get_preferred_height_for_width(int width, out int minimum_height, out int natural_height) { - base.get_preferred_height_for_width(width, out minimum_height, out natural_height); - if (min_height != -1) minimum_height = int.max(minimum_height, min_height); - if (max_height != -1) natural_height = int.min(natural_height, max_height); - if (target_height != -1) natural_height = int.max(natural_height, target_height); - natural_height = int.max(natural_height, minimum_height); + public override void measure(Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) { + base.measure(orientation, for_size, out minimum, out natural, out minimum_baseline, out natural_baseline); + if (orientation == Orientation.HORIZONTAL) { + if (min_width != -1) minimum = int.max(minimum, min_width); + if (max_width != -1) natural = int.min(natural, max_width); + if (target_width != -1) natural = int.max(natural, target_width); + natural = int.max(natural, minimum); + } else { + if (min_height != -1) minimum = int.max(minimum, min_height); + if (max_height != -1) natural = int.min(natural, max_height); + if (target_height != -1) natural = int.max(natural, target_height); + natural = int.max(natural, minimum); + } } - } } -- cgit v1.2.3-70-g09d2