aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/widgets')
-rw-r--r--main/src/ui/widgets/fixed_ratio_picture.vala88
-rw-r--r--main/src/ui/widgets/natural_size_increase.vala59
2 files changed, 147 insertions, 0 deletions
diff --git a/main/src/ui/widgets/fixed_ratio_picture.vala b/main/src/ui/widgets/fixed_ratio_picture.vala
new file mode 100644
index 00000000..79c60141
--- /dev/null
+++ b/main/src/ui/widgets/fixed_ratio_picture.vala
@@ -0,0 +1,88 @@
+using Gdk;
+using Gtk;
+
+class Dino.Ui.FixedRatioPicture : Gtk.Widget {
+ public int min_width { get; set; default = -1; }
+ public int max_width { get; set; default = int.MAX; }
+ public int min_height { get; set; default = -1; }
+ public int max_height { get; set; default = int.MAX; }
+ public File file { get { return inner.file; } set { inner.file = value; } }
+ public Gdk.Paintable paintable { get { return inner.paintable; } set { inner.paintable = value; } }
+#if GTK_4_8 && VALA_0_58
+ public Gtk.ContentFit content_fit { get { return inner.content_fit; } set { inner.content_fit = value; } }
+#endif
+ private Gtk.Picture inner = new Gtk.Picture();
+
+ construct {
+ set_css_name("picture");
+ add_css_class("fixed-ratio");
+ inner.insert_after(this, null);
+ this.notify.connect(queue_resize);
+ }
+
+ private void measure_target_size(out int width, out int height) {
+ if (width_request != -1 && height_request != -1) {
+ width = width_request;
+ height = height_request;
+ return;
+ }
+ width = min_width;
+ height = min_height;
+
+ if (inner.should_layout()) {
+ int child_min = 0, child_nat = 0, child_min_baseline = -1, child_nat_baseline = -1;
+ inner.measure(Orientation.HORIZONTAL, -1, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
+ width = int.max(child_nat, width);
+ }
+ width = int.min(width, max_width);
+
+ if (inner.should_layout()) {
+ int child_min = 0, child_nat = 0, child_min_baseline = -1, child_nat_baseline = -1;
+ inner.measure(Orientation.VERTICAL, width, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
+ height = int.max(child_nat, height);
+ }
+
+ if (height > max_height) {
+ height = max_height;
+ width = min_width;
+
+ if (inner.should_layout()) {
+ int child_min = 0, child_nat = 0, child_min_baseline = -1, child_nat_baseline = -1;
+ inner.measure(Orientation.HORIZONTAL, max_height, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
+ width = int.max(child_nat, width);
+ }
+ width = int.min(width, max_width);
+ }
+ }
+
+ public override void measure(Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) {
+ minimum_baseline = -1;
+ natural_baseline = -1;
+ int width, height;
+ measure_target_size(out width, out height);
+ if (orientation == Orientation.HORIZONTAL) {
+ minimum = min_width;
+ natural = width;
+ } else if (for_size == -1) {
+ minimum = min_height;
+ natural = height;
+ } else {
+ minimum = natural = height * for_size / width;
+ }
+ }
+
+ public override void size_allocate(int width, int height, int baseline) {
+ if (inner.should_layout()) {
+ inner.allocate(width, height, baseline, null);
+ }
+ }
+
+ public override SizeRequestMode get_request_mode() {
+ return SizeRequestMode.HEIGHT_FOR_WIDTH;
+ }
+
+ public override void dispose() {
+ inner.unparent();
+ base.dispose();
+ }
+} \ No newline at end of file
diff --git a/main/src/ui/widgets/natural_size_increase.vala b/main/src/ui/widgets/natural_size_increase.vala
new file mode 100644
index 00000000..2b04d748
--- /dev/null
+++ b/main/src/ui/widgets/natural_size_increase.vala
@@ -0,0 +1,59 @@
+using Gtk;
+
+public class Dino.Ui.NaturalSizeIncrease : Gtk.Widget {
+ public int min_natural_height { get; set; default = -1; }
+ public int min_natural_width { get; set; default = -1; }
+
+ construct {
+ this.notify.connect(queue_resize);
+ }
+
+ public override void measure(Orientation orientation, int for_size, out int minimum, out int natural, out int minimum_baseline, out int natural_baseline) {
+ minimum = 0;
+ if (orientation == Orientation.HORIZONTAL) {
+ natural = min_natural_width;
+ } else {
+ natural = min_natural_height;
+ }
+ natural = int.max(0, natural);
+ minimum_baseline = -1;
+ natural_baseline = -1;
+ Widget child = get_first_child();
+ while (child != null) {
+ if (child.should_layout()) {
+ int child_min = 0;
+ int child_nat = 0;
+ int child_min_baseline = -1;
+ int child_nat_baseline = -1;
+ child.measure(orientation, -1, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
+ minimum = int.max(minimum, child_min);
+ natural = int.max(natural, child_nat);
+ if (child_min_baseline > 0) {
+ minimum_baseline = int.max(minimum_baseline, child_min_baseline);
+ }
+ if (child_nat_baseline > 0) {
+ natural_baseline = int.max(natural_baseline, child_nat_baseline);
+ }
+ }
+ child = child.get_next_sibling();
+ }
+ }
+
+ public override void size_allocate(int width, int height, int baseline) {
+ Widget child = get_first_child();
+ while (child != null) {
+ if (child.should_layout()) {
+ child.allocate(width, height, baseline, null);
+ }
+ child = child.get_next_sibling();
+ }
+ }
+
+ public override SizeRequestMode get_request_mode() {
+ Widget child = get_first_child();
+ if (child != null) {
+ return child.get_request_mode();
+ }
+ return SizeRequestMode.CONSTANT_SIZE;
+ }
+} \ No newline at end of file