Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions data/Application.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ icongroup {
padding-bottom: 0;
}

icongroup .icon-group-box {
icongroup .icon-group-bin {
background: alpha(@base_color, 0.4);
box-shadow:
inset 0 -1px 0 0 alpha(@highlight_color, 0.2),
Expand All @@ -94,7 +94,7 @@ icongroup .icon-group-box {
border-spacing: 3px;
}

.reduce-transparency icongroup box {
.reduce-transparency icongroup bin {
background: @base_color;
}

Expand Down
116 changes: 47 additions & 69 deletions src/BaseIconGroup.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,94 +4,72 @@
*/

public abstract class Dock.BaseIconGroup : BaseItem {
private class EmptyWidget : Gtk.Widget {}

private const int MAX_IN_ROW = 2;
private const int MAX_N_CHILDREN = MAX_IN_ROW * MAX_IN_ROW;

public ListModel icons { get; construct; }

private Gtk.Grid grid;

class construct {
set_css_name ("icongroup");
}

construct {
grid = new Gtk.Grid () {
hexpand = true,
vexpand = true,
var slice = new Gtk.SliceListModel (icons, 0, MAX_N_CHILDREN);

var flow_box = new Gtk.FlowBox () {
max_children_per_line = MAX_IN_ROW,
min_children_per_line = MAX_IN_ROW,
selection_mode = NONE,
halign = CENTER,
valign = CENTER
valign = CENTER,
};
flow_box.bind_model (slice, create_flow_box_child);

var box = new Gtk.Box (VERTICAL, 0);
box.add_css_class ("icon-group-box");
box.append (grid);

overlay.child = box;

update_icons ();
icons.items_changed.connect (update_icons);
notify["icon-size"].connect (update_icons);
var bin = new Granite.Bin () {
child = flow_box
};
bin.add_css_class ("icon-group-bin");
bind_property ("icon-size", bin, "width-request", SYNC_CREATE);
bind_property ("icon-size", bin, "height-request", SYNC_CREATE);

bind_property ("icon-size", box, "width-request", SYNC_CREATE);
bind_property ("icon-size", box, "height-request", SYNC_CREATE);
overlay.child = bin;
}

private void update_icons () {
unowned Gtk.Widget? child;
while ((child = grid.get_first_child ()) != null) {
grid.remove (child);
}

var grid_spacing = get_grid_spacing ();
grid.row_spacing = grid_spacing;
grid.column_spacing = grid_spacing;

var new_pixel_size = get_pixel_size ();
int i;
for (i = 0; i < uint.min (icons.get_n_items (), 4); i++) {
var image = new Gtk.Image.from_gicon ((Icon) icons.get_item (i)) {
pixel_size = new_pixel_size
};

grid.attach (image, i % MAX_IN_ROW, i / MAX_IN_ROW, 1, 1);
}

// We always need to attach at least 3 elements for grid to be square and properly aligned
for (; i < 3; i++) {
var empty_widget = new EmptyWidget ();
empty_widget.set_size_request (new_pixel_size, new_pixel_size);

grid.attach (empty_widget, i % MAX_IN_ROW, i / MAX_IN_ROW, 1, 1);
}
private Gtk.Widget create_flow_box_child (Object? item) {
var image = new Gtk.Image.from_gicon ((Icon) item);
bind_property ("icon-size", image, "pixel-size", SYNC_CREATE, (binding, from_value, ref to_value) => {
var icon_size = from_value.get_int ();
to_value.set_int (get_pixel_size (icon_size));
return true;
});
// We use margin instead of grid spacing because grid spacing in combination with
// min children per line causes the flow box to request the grid spacing as additional width
// even when there is only one child making it off center.
bind_property ("icon-size", image, "margin-start", SYNC_CREATE, icon_size_to_margin);
bind_property ("icon-size", image, "margin-top", SYNC_CREATE, icon_size_to_margin);
bind_property ("icon-size", image, "margin-end", SYNC_CREATE, icon_size_to_margin);
bind_property ("icon-size", image, "margin-bottom", SYNC_CREATE, icon_size_to_margin);

return new Gtk.FlowBoxChild () {
child = image,
can_target = false
};
}

private int get_pixel_size () {
var pixel_size = 8;

switch (icon_size) {
case 64:
pixel_size = 24;
break;
case 48:
pixel_size = 16;
break;
case 32:
pixel_size = 8;
break;
default:
pixel_size = (int) Math.round (icon_size / 3);
break;
}

return pixel_size;
private static bool icon_size_to_margin (Binding binding, Value from_value, ref Value to_value) {
var icon_size = from_value.get_int ();
var pixel_size = get_pixel_size (icon_size);
var spacing = (int) Math.round ((icon_size - pixel_size * MAX_IN_ROW) / 6);
to_value.set_int (spacing);
return true;
}

private int get_grid_spacing () {
var pixel_size = get_pixel_size ();

return (int) Math.round ((icon_size - pixel_size * MAX_IN_ROW) / 3);
private static int get_pixel_size (int for_icon_size) {
switch (for_icon_size) {
case 64: return 24;
case 48: return 16;
case 32: return 8;
default: return (int) Math.round (for_icon_size / 3);
}
}
}
15 changes: 8 additions & 7 deletions src/WorkspaceSystem/DynamicWorkspaceItem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@ public class Dock.DynamicWorkspaceIcon : BaseItem {
};
add_image.add_css_class ("add-image");

// Gtk.Box is used here to keep css nodes consistent with IconGroup
var box = new Gtk.Box (VERTICAL, 0);
box.add_css_class ("icon-group-box");
box.append (add_image);
// Granite.Bin is used here to keep css nodes consistent with IconGroup
var bin = new Granite.Bin () {
child = add_image
};
bin.add_css_class ("icon-group-bin");

overlay.child = box;
overlay.child = bin;

WorkspaceSystem.get_default ().workspace_added.connect (update_active_state);
WorkspaceSystem.get_default ().workspace_removed.connect (update_active_state);
WindowSystem.get_default ().notify["active-workspace"].connect (update_active_state);

dock_settings.bind ("icon-size", box, "width-request", DEFAULT);
dock_settings.bind ("icon-size", box, "height-request", DEFAULT);
dock_settings.bind ("icon-size", bin, "width-request", DEFAULT);
dock_settings.bind ("icon-size", bin, "height-request", DEFAULT);

dock_settings.bind_with_mapping (
"icon-size", add_image, "pixel_size", DEFAULT | GET,
Expand Down