-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathButtonsContainer.vala
More file actions
146 lines (114 loc) · 5.43 KB
/
Copy pathButtonsContainer.vala
File metadata and controls
146 lines (114 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Copyright 2025 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*/
public class Notifications.ButtonsContainer : Gtk.Widget {
private const int SPACING = 6;
class construct {
set_css_name ("buttonbox");
}
construct {
layout_manager = new Gtk.CustomLayout (
(widget) => HEIGHT_FOR_WIDTH,
(widget, orientation, for_size, out minimum, out natural, out minimum_baseline, out natural_baseline) => {
minimum_baseline = -1;
natural_baseline = -1;
if (orientation == HORIZONTAL) {
var max_min_w = 0, sum_nat_w = 0, visible_count = 0;
for (unowned var child = widget.get_first_child (); child != null; child = child.get_next_sibling ()) {
if (!child.visible) {
continue;
}
visible_count++;
int child_min, child_nat;
child.measure (orientation, for_size, out child_min, out child_nat, null, null);
max_min_w = int.max (max_min_w, child_min);
sum_nat_w += child_nat;
}
sum_nat_w += SPACING * (visible_count - 1);
minimum = max_min_w;
natural = sum_nat_w;
} else {
// We need to compute total height after wrapping
// 'for_size' here is the available width for wrapping
minimum = compute_wrapped_size_height (widget, for_size, false);
natural = compute_wrapped_size_height (widget, for_size, true);
}
},
(widget, width, height, baseline) => {
var row_y = 0, row_height = 0, row_used_width = 0;
var row = new GLib.List<unowned Gtk.Widget> ();
for (unowned var child = widget.get_first_child (); child != null; child = child.get_next_sibling ()) {
if (!child.visible) {
continue;
}
int child_nat_w, child_nat_h;
child.measure (HORIZONTAL, -1, null, out child_nat_w, null, null);
child.measure (VERTICAL, -1, null, out child_nat_h, null, null);
if (row_used_width + child_nat_w + SPACING * (row.length () - 1) > width) {
allocate_row (row, width, row_y, baseline);
row_y += row_height + SPACING;
row_height = 0;
row_used_width = 0;
row = new GLib.List<unowned Gtk.Widget> ();
}
row.append (child);
row_used_width += child_nat_w + SPACING;
row_height = int.max (row_height, child_nat_h);
}
allocate_row (row, width, row_y, baseline);
}
);
}
public void append (Gtk.Widget child) {
child.insert_after (this, get_last_child ());
}
private static int compute_wrapped_size_height (Gtk.Widget widget, int width, bool natural) {
var row_used = 0, row_height = 0, total_height = 0;
for (unowned var child = widget.get_first_child (); child != null; child = child.get_next_sibling ()) {
if (!child.visible) {
continue;
}
int child_min_w, child_nat_w, child_min_h, child_nat_h;
child.measure (HORIZONTAL, -1, out child_min_w, out child_nat_w, null, null);
child.measure (VERTICAL, -1, out child_min_h, out child_nat_h, null, null);
var cw = natural ? child_nat_w : child_min_w;
var ch = natural ? child_nat_h : child_min_h;
var prospective = row_used == 0 ? cw : row_used + SPACING + cw;
// If the child doesn't fit in the current row and it's not the first in row -> wrap
if (row_used > 0 && prospective > width) {
total_height += row_height + SPACING;
row_used = 0;
row_height = 0;
}
if (row_used == 0) {
row_used = cw;
} else {
row_used += SPACING + cw;
}
row_height = int.max (row_height, ch);
}
total_height += row_height;
return total_height;
}
private static void allocate_row (GLib.List<unowned Gtk.Widget> row, int width, int row_y, int baseline) {
var total_row_width = 0;
foreach (var row_child in row) {
int nat_w;
row_child.measure (HORIZONTAL, -1, null, out nat_w, null, null);
total_row_width += nat_w <= width ? nat_w : width;
}
total_row_width += SPACING * ((int) row.length () - 1);
// Set starting x so the row is right-aligned
var row_x = width - total_row_width;
// Allocate children left-to-right
foreach (var row_child in row) {
int nat_w, nat_h;
row_child.measure (HORIZONTAL, -1, null, out nat_w, null, null);
row_child.measure (VERTICAL, -1, null, out nat_h, null, null);
var w = nat_w <= total_row_width ? nat_w : total_row_width;
row_child.allocate (w, nat_h, baseline, new Gsk.Transform ().translate ({ row_x, row_y }));
row_x += w + SPACING;
}
}
}