mirror of https://github.com/TakeV-Lambda/dino.git
131 lines
5.0 KiB
Vala
131 lines
5.0 KiB
Vala
using Gdk;
|
|
using Gtk;
|
|
|
|
namespace Dino.Ui {
|
|
|
|
class FixedRatioLayout : Gtk.LayoutManager {
|
|
public int min_width { get; set; default = 0; }
|
|
public int target_width { get; set; default = -1; }
|
|
public int max_width { get; set; default = int.MAX; }
|
|
public int min_height { get; set; default = 0; }
|
|
public int target_height { get; set; default = -1; }
|
|
public int max_height { get; set; default = int.MAX; }
|
|
|
|
public FixedRatioLayout() {
|
|
this.notify.connect(layout_changed);
|
|
}
|
|
|
|
private void measure_target_size(Gtk.Widget widget, out int width, out int height) {
|
|
if (target_width != -1 && target_height != -1) {
|
|
width = target_width;
|
|
height = target_height;
|
|
return;
|
|
}
|
|
Widget child;
|
|
width = min_width;
|
|
height = min_height;
|
|
|
|
child = widget.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.HORIZONTAL, -1, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
|
|
width = int.max(child_nat, width);
|
|
}
|
|
child = child.get_next_sibling();
|
|
}
|
|
width = int.min(width, max_width);
|
|
|
|
child = widget.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.VERTICAL, width, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
|
|
height = int.max(child_nat, height);
|
|
}
|
|
child = child.get_next_sibling();
|
|
}
|
|
|
|
if (height > max_height) {
|
|
height = max_height;
|
|
width = min_width;
|
|
|
|
child = widget.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.HORIZONTAL, max_height, out child_min, out child_nat, out child_min_baseline, out child_nat_baseline);
|
|
width = int.max(child_nat, width);
|
|
}
|
|
child = child.get_next_sibling();
|
|
}
|
|
width = int.min(width, max_width);
|
|
}
|
|
}
|
|
|
|
public override void measure(Gtk.Widget widget, 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(widget, 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 allocate(Gtk.Widget widget, int width, int height, int baseline) {
|
|
Widget child = widget.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(Gtk.Widget widget) {
|
|
return SizeRequestMode.HEIGHT_FOR_WIDTH;
|
|
}
|
|
}
|
|
|
|
class FixedRatioPicture : Gtk.Widget {
|
|
public int min_width { get { return layout.min_width; } set { layout.min_width = value; } }
|
|
public int target_width { get { return layout.target_width; } set { layout.target_width = value; } }
|
|
public int max_width { get { return layout.max_width; } set { layout.max_width = value; } }
|
|
public int min_height { get { return layout.min_height; } set { layout.min_height = value; } }
|
|
public int target_height { get { return layout.target_height; } set { layout.target_height = value; } }
|
|
public int max_height { get { return layout.max_height; } set { layout.max_height = value; } }
|
|
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();
|
|
private FixedRatioLayout layout = new FixedRatioLayout();
|
|
|
|
public FixedRatioPicture() {
|
|
layout_manager = layout;
|
|
inner.insert_after(this, null);
|
|
}
|
|
|
|
public override void dispose() {
|
|
inner.unparent();
|
|
base.dispose();
|
|
}
|
|
}
|
|
} |