[gnome-boxes/wip/exalm/light: 1/5] Clean up machine thumbnails
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/wip/exalm/light: 1/5] Clean up machine thumbnails
- Date: Sat, 25 Dec 2021 16:15:48 +0000 (UTC)
commit b52ed0a1140f4a5ec91d1805643dc2adbebac2f7
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sat Dec 25 19:44:12 2021 +0500
Clean up machine thumbnails
data/gtk-style.css | 23 +++++--
data/ui/icon-view-child.ui | 48 +++++++-------
data/ui/list-view-row.ui | 40 +++++-------
src/icon-view-child.vala | 47 +++++++++-----
src/list-view-row.vala | 40 +++++++-----
src/machine-thumbnailer.vala | 145 +++----------------------------------------
src/machine.vala | 8 ---
7 files changed, 119 insertions(+), 232 deletions(-)
---
diff --git a/data/gtk-style.css b/data/gtk-style.css
index d61c9be3..a6515b22 100644
--- a/data/gtk-style.css
+++ b/data/gtk-style.css
@@ -1,7 +1,3 @@
-@define-color boxes_bg_color shade (@theme_bg_color, 0.5);
-@define-color boxes_bg2_color mix (@theme_bg_color, @boxes_bg_color, 0.5);
-@define-color boxes_selected_color #3465a4;
-
.boxes-snapshot-list-row.indicator {
background-color: @insensitive_fg_color;
border: none;
@@ -21,8 +17,23 @@
}
.thumbnail {
- background: @boxes_bg2_color;
- border: 1px solid @theme_bg_color;
+ background: @theme_bg_color;
+ color: @theme_fg_color;
+ border: 1px solid @borders;
+}
+
+.thumbnail.running {
+ background: black;
+ color: white;
+ border: none;
+}
+
+.favorite {
+ color: @theme_text_color;
+}
+
+.favorite.running {
+ color: white;
}
.boxes-product-key-entry {
diff --git a/data/ui/icon-view-child.ui b/data/ui/icon-view-child.ui
index 63c40936..c237437e 100644
--- a/data/ui/icon-view-child.ui
+++ b/data/ui/icon-view-child.ui
@@ -19,9 +19,11 @@
<child>
<object class="GtkImage" id="favorite">
- <property name="visible">True</property>
- <property name="width-request">16</property>
- <property name="height-request">16</property>
+ <property name="visible">False</property>
+ <property name="icon-name">starred-symbolic</property>
+ <style>
+ <class name="favorite"/>
+ </style>
</object>
</child>
@@ -42,48 +44,44 @@
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<child>
- <object class="GtkImage" id="thumbnail">
+ <object class="GtkImage" id="running_thumbnail">
<property name="visible">True</property>
<style>
<class name="thumbnail"/>
+ <class name="running"/>
</style>
</object>
-
- <packing>
- <property name="name">thumbnail</property>
- </packing>
</child>
<child>
- <object class="GtkImage" id="live_thumbnail">
+ <object class="GtkImage" id="thumbnail">
<property name="visible">True</property>
- <property name="icon-name">media-optical-symbolic</property>
- <property name="icon-size">6</property>
+ <property name="pixel-size">32</property>
<style>
<class name="thumbnail"/>
</style>
</object>
-
- <packing>
- <property name="name">live</property>
- </packing>
</child>
<child>
- <object class="GtkSpinner" id="spinner">
+ <object class="GtkEventBox" id="spinner_box">
<property name="visible">True</property>
- <property name="height-request">8</property>
- <property name="width-request">8</property>
- <property name="halign">0.5</property>
- <property name="valign">0.5</property>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="width-request">32</property>
+ <property name="height-request">32</property>
+ <style>
+ <class name="slow-spinner"/>
+ </style>
+ </object>
+ </child>
<style>
- <class name="slow-spinner"/>
+ <class name="thumbnail"/>
</style>
</object>
-
- <packing>
- <property name="name">spinner</property>
- </packing>
</child>
</object>
</child>
diff --git a/data/ui/list-view-row.ui b/data/ui/list-view-row.ui
index 9e0a6a63..b0b7816d 100644
--- a/data/ui/list-view-row.ui
+++ b/data/ui/list-view-row.ui
@@ -25,48 +25,41 @@
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<child>
- <object class="GtkImage" id="thumbnail">
+ <object class="GtkImage" id="running_thumbnail">
<property name="visible">True</property>
<style>
<class name="thumbnail"/>
+ <class name="running"/>
</style>
</object>
-
- <packing>
- <property name="name">thumbnail</property>
- </packing>
</child>
<child>
- <object class="GtkImage" id="live_thumbnail">
+ <object class="GtkImage" id="thumbnail">
<property name="visible">True</property>
- <property name="icon-name">media-optical-symbolic</property>
- <property name="icon-size">3</property>
<style>
<class name="thumbnail"/>
</style>
</object>
-
- <packing>
- <property name="name">live_thumbnail</property>
- </packing>
</child>
<child>
- <object class="GtkSpinner" id="spinner">
+ <object class="GtkEventBox" id="spinner_box">
<property name="visible">True</property>
- <property name="height-request">8</property>
- <property name="width-request">8</property>
- <property name="halign">0.5</property>
- <property name="valign">0.5</property>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="slow-spinner"/>
+ </style>
+ </object>
+ </child>
<style>
- <class name="slow-spinner"/>
+ <class name="thumbnail"/>
</style>
</object>
-
- <packing>
- <property name="name">spinner</property>
- </packing>
</child>
</object>
@@ -79,8 +72,7 @@
<child>
<object class="GtkImage" id="favorite">
<property name="visible">True</property>
- <property name="width-request">16</property>
- <property name="height-request">16</property>
+ <property name="icon-name">starred-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/icon-view-child.vala b/src/icon-view-child.vala
index dd9b4f38..0baf6eed 100644
--- a/src/icon-view-child.vala
+++ b/src/icon-view-child.vala
@@ -4,6 +4,9 @@
[GtkTemplate (ui = "/org/gnome/Boxes/ui/icon-view-child.ui")]
private class Boxes.IconViewChild : Gtk.Box {
+ public const int SCREENSHOT_WIDTH = 180;
+ public const int SCREENSHOT_HEIGHT = 134;
+
public bool _selection_mode = false;
public bool selection_mode {
get { return _selection_mode; }
@@ -35,11 +38,13 @@
[GtkChild]
public unowned Gtk.Image thumbnail;
[GtkChild]
+ private unowned Gtk.EventBox spinner_box;
+ [GtkChild]
private unowned Gtk.Spinner spinner;
[GtkChild]
private unowned Gtk.Image favorite;
[GtkChild]
- private unowned Gtk.Image live_thumbnail;
+ private unowned Gtk.Image running_thumbnail;
[GtkChild]
private unowned Gtk.Label machine_name;
@@ -51,18 +56,22 @@
public IconViewChild (CollectionItem item) {
this.item = item;
- thumbnailer = machine.thumbnailer;
+ thumbnailer = new MachineThumbnailer (machine,
+ SCREENSHOT_WIDTH,
+ SCREENSHOT_HEIGHT);
- thumbnailer.favorite_emblem_enabled = false;
- thumbnailer.notify["thumbnail"].connect (() => {
- thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
- });
- thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
+ stack.width_request = SCREENSHOT_WIDTH;
+ stack.height_request = SCREENSHOT_HEIGHT;
selected_binding = bind_property ("selected", selection_button, "active",
BindingFlags.BIDIRECTIONAL);
machine.config.notify["categories"].connect (update_favorite);
machine.notify["under-construction"].connect (update_thumbnail);
+ machine.notify["is-stopped"].connect (update_thumbnail);
+ thumbnailer.notify["thumbnail"].connect (() => {
+ update_thumbnail ();
+ update_favorite ();
+ });
update_thumbnail ();
update_favorite ();
@@ -73,15 +82,23 @@ public IconViewChild (CollectionItem item) {
private void update_thumbnail () {
var libvirt_machine = machine as LibvirtMachine;
+ running_thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
+
if (machine.under_construction) {
- stack.visible_child = spinner;
+ stack.visible_child = spinner_box;
spinner.start ();
- spinner.visible = true;
return;
- } else if (VMConfigurator.is_live_config (libvirt_machine.domain_config)) {
- stack.visible_child = live_thumbnail;
+ } else if (thumbnailer.thumbnail != null) {
+ stack.visible_child = running_thumbnail;
} else {
+ if (VMConfigurator.is_live_config (libvirt_machine.domain_config))
+ thumbnail.icon_name = "media-optical-symbolic";
+ else if (machine.is_stopped)
+ thumbnail.icon_name = "system-shutdown-symbolic";
+ else
+ thumbnail.icon_name = "computer-symbolic";
+
stack.visible_child = thumbnail;
}
@@ -89,9 +106,11 @@ private void update_thumbnail () {
}
private void update_favorite () {
- if ("favorite" in machine.config.categories)
- favorite.set_from_icon_name ("starred-symbolic", Gtk.IconSize.MENU);
+ favorite.visible = "favorite" in machine.config.categories;
+
+ if (thumbnailer.thumbnail != null)
+ favorite.get_style_context ().add_class ("running");
else
- favorite.clear ();
+ favorite.get_style_context ().remove_class ("running");
}
}
diff --git a/src/list-view-row.vala b/src/list-view-row.vala
index a26a1427..b58eb9e7 100644
--- a/src/list-view-row.vala
+++ b/src/list-view-row.vala
@@ -5,10 +5,6 @@
private class Boxes.ListViewRow: Gtk.Box {
public const int SCREENSHOT_WIDTH = 60;
public const int SCREENSHOT_HEIGHT = 45;
- public const int CENTERED_EMBLEM_SIZE = 16;
- public const int EMBLEM_SIZE = 16;
- public const Gdk.RGBA FRAME_BORDER_COLOR = { 0x81 / 255.0, 0x85 / 255.0, 0x84 / 255.0, 1.0 };
- public const Gdk.RGBA FRAME_BACKGROUND_COLOR = { 0x4b / 255.0, 0x50 / 255.0, 0x50 / 255.0, 1.0 };
public bool _selection_mode = false;
public bool selection_mode {
@@ -41,7 +37,9 @@
[GtkChild]
private unowned Gtk.Image thumbnail;
[GtkChild]
- private unowned Gtk.Image live_thumbnail;
+ private unowned Gtk.Image running_thumbnail;
+ [GtkChild]
+ private unowned Gtk.EventBox spinner_box;
[GtkChild]
private unowned Gtk.Spinner spinner;
[GtkChild]
@@ -60,22 +58,22 @@
public ListViewRow (CollectionItem item) {
this.item = item;
- thumbnailer = new Boxes.MachineThumbnailer (machine,
- SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT,
- CENTERED_EMBLEM_SIZE, EMBLEM_SIZE);
- thumbnailer.favorite_emblem_enabled = false;
- thumbnailer.notify["thumbnail"].connect (() => {
- thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
- });
- thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
+ thumbnailer = new MachineThumbnailer (machine,
+ SCREENSHOT_WIDTH,
+ SCREENSHOT_HEIGHT);
+
+ stack.width_request = SCREENSHOT_WIDTH;
+ stack.height_request = SCREENSHOT_HEIGHT;
selected_binding = bind_property ("selected", selection_button, "active",
BindingFlags.BIDIRECTIONAL);
machine.config.notify["categories"].connect (update_favorite);
machine.notify["under-construction"].connect (update_thumbnail);
+ machine.notify["is-stopped"].connect (update_thumbnail);
machine.notify["info"].connect (update_info);
machine.notify["state"].connect (update_status);
machine.notify["status"].connect (update_status);
+ thumbnailer.notify["thumbnail"].connect (update_thumbnail);
update_thumbnail ();
update_favorite ();
@@ -88,15 +86,23 @@ public ListViewRow (CollectionItem item) {
private void update_thumbnail () {
var libvirt_machine = machine as LibvirtMachine;
+ running_thumbnail.set_from_pixbuf (thumbnailer.thumbnail);
+
if (machine.under_construction) {
- stack.visible_child = spinner;
+ stack.visible_child = spinner_box;
spinner.start ();
- spinner.visible = true;
return;
- } else if (VMConfigurator.is_live_config (libvirt_machine.domain_config)) {
- stack.visible_child = live_thumbnail;
+ } else if (thumbnailer.thumbnail != null) {
+ stack.visible_child = running_thumbnail;
} else {
+ if (VMConfigurator.is_live_config (libvirt_machine.domain_config))
+ thumbnail.icon_name = "media-optical-symbolic";
+ else if (machine.is_stopped)
+ thumbnail.icon_name = "system-shutdown-symbolic";
+ else
+ thumbnail.icon_name = "computer-symbolic";
+
stack.visible_child = thumbnail;
}
diff --git a/src/machine-thumbnailer.vala b/src/machine-thumbnailer.vala
index ceaa97f0..a0145b8f 100644
--- a/src/machine-thumbnailer.vala
+++ b/src/machine-thumbnailer.vala
@@ -1,165 +1,34 @@
// This file is part of GNOME Boxes. License: LGPLv2+
private class Boxes.MachineThumbnailer: Object {
- private const Gtk.CornerType[] right_corners = { Gtk.CornerType.TOP_RIGHT, Gtk.CornerType.BOTTOM_RIGHT };
- private const Gtk.CornerType[] bottom_corners = { Gtk.CornerType.BOTTOM_LEFT,
Gtk.CornerType.BOTTOM_RIGHT };
-
- public const double FRAME_RADIUS = 2.0;
- public const Gdk.RGBA CENTERED_EMBLEM_COLOR = { 0xbe / 255.0, 0xbe / 255.0, 0xbe / 255.0, 1.0 };
- public const Gdk.RGBA SMALL_EMBLEM_COLOR = { 1.0, 1.0, 1.0, 1.0 };
- public const int EMBLEM_PADDING = 8;
-
public weak Machine machine { get; private set; }
public int width { get; set; }
public int height { get; set; }
- public int centred_emblem_size { get; set; }
- public int emblem_size { get; set; }
- public Gdk.RGBA border_color { get; set; }
- public Gdk.RGBA background_color { get; set; }
-
- public Gdk.Pixbuf thumbnail { get; private set; }
- public bool favorite_emblem_enabled { get; set; default = true; }
+ public Gdk.Pixbuf? thumbnail { get; private set; }
- public MachineThumbnailer (Machine machine,
- int width, int height,
- int centred_emblem_size, int emblem_size) {
+ public MachineThumbnailer (Machine machine, int width, int height) {
this.machine = machine;
this.width = width;
this.height = height;
- this.centred_emblem_size = centred_emblem_size;
- this.emblem_size = emblem_size;
- this.border_color = border_color;
- this.background_color = background_color;
machine.notify["pixbuf"].connect (() => {
update_thumbnail ();
});
-
- machine.notify["under-construction"].connect (() => {
- update_thumbnail ();
- });
-
- machine.config.notify["categories"].connect (() => {
+ machine.notify["is-stopped"].connect (() => {
update_thumbnail ();
});
notify["width"].connect (update_thumbnail);
notify["height"].connect (update_thumbnail);
- notify["border-color"].connect (update_thumbnail);
- notify["favorite-emblem-enabled"].connect (update_thumbnail);
- notify["construction-spinner-enabled"].connect (update_thumbnail);
update_thumbnail ();
}
private void update_thumbnail () {
- Gdk.Pixbuf? new_thumbnail = null;
-
- if (machine.is_stopped)
- new_thumbnail = machine.under_construction ? get_under_construction_thumbnail () :
- get_stopped_thumbnail ();
- else if (machine.pixbuf != null)
- new_thumbnail = machine.pixbuf.scale_simple (width, height, Gdk.InterpType.BILINEAR);
-
- // Use the default thumbnail if no thumbnail have been chosen
- if (new_thumbnail == null)
- new_thumbnail = get_default_thumbnail ();
-
- if (favorite_emblem_enabled && "favorite" in machine.config.categories)
- new_thumbnail = add_emblem_icon (new_thumbnail, "starred-symbolic", Gtk.CornerType.BOTTOM_LEFT);
-
- thumbnail = new_thumbnail;
- }
-
- private Gdk.Pixbuf? empty_thumbnail;
- private Gdk.Pixbuf get_empty_thumbnail () {
- if (empty_thumbnail != null)
- return empty_thumbnail;
-
- empty_thumbnail = paint_empty_frame (width, height);
-
- return empty_thumbnail;
- }
-
- private Gdk.Pixbuf? default_thumbnail;
- private Gdk.Pixbuf get_default_thumbnail () {
- if (default_thumbnail != null)
- return default_thumbnail;
-
- var frame = get_empty_thumbnail ();
- default_thumbnail = add_centered_emblem_icon (frame, "computer-symbolic", centred_emblem_size);
-
- return default_thumbnail;
- }
-
- private Gdk.Pixbuf? stopped_thumbnail;
- private Gdk.Pixbuf get_stopped_thumbnail () {
- if (stopped_thumbnail != null)
- return stopped_thumbnail;
-
- var frame = get_empty_thumbnail ();
- stopped_thumbnail = add_centered_emblem_icon (frame, "system-shutdown-symbolic",
centred_emblem_size);
-
- return stopped_thumbnail;
- }
-
- private Gdk.Pixbuf get_under_construction_thumbnail () {
- // If the machine is being constructed, it will draw a spinner itself, so we only need to draw an
empty frame.
- return get_empty_thumbnail ();
- }
-
- private Gdk.Pixbuf add_centered_emblem_icon (Gdk.Pixbuf pixbuf, string icon_name, int size) {
- Gdk.Pixbuf? emblem = null;
-
- var theme = Gtk.IconTheme.get_default ();
- try {
- var icon_info = theme.lookup_icon (icon_name, size, Gtk.IconLookupFlags.FORCE_SIZE);
- emblem = icon_info.load_symbolic (CENTERED_EMBLEM_COLOR);
- } catch (GLib.Error error) {
- warning (@"Unable to get icon '$icon_name': $(error.message)");
- return pixbuf;
- }
-
- if (emblem == null)
- return pixbuf;
-
- double offset_x = pixbuf.width / 2.0 - emblem.width / 2.0;
- double offset_y = pixbuf.height / 2.0 - emblem.height / 2.0;
-
- var emblemed = pixbuf.copy ();
- emblem.composite (emblemed, (int) offset_x, (int) offset_y, size, size,
- offset_x, offset_y, 1.0, 1.0, Gdk.InterpType.BILINEAR, 255);
-
- return emblemed;
- }
-
-
- private Gdk.Pixbuf add_emblem_icon (Gdk.Pixbuf pixbuf, string icon_name, Gtk.CornerType corner_type) {
- Gdk.Pixbuf? emblem = null;
-
- var theme = Gtk.IconTheme.get_default ();
- try {
- var icon_info = theme.lookup_icon (icon_name, emblem_size, Gtk.IconLookupFlags.FORCE_SIZE);
- emblem = icon_info.load_symbolic (SMALL_EMBLEM_COLOR);
- } catch (GLib.Error error) {
- warning (@"Unable to get icon '$icon_name': $(error.message)");
- return pixbuf;
- }
-
- if (emblem == null)
- return pixbuf;
-
- var offset_x = corner_type in right_corners ? pixbuf.width - emblem.width - EMBLEM_PADDING :
- EMBLEM_PADDING;
-
- var offset_y = corner_type in bottom_corners ? pixbuf.height - emblem.height - EMBLEM_PADDING :
- EMBLEM_PADDING;
-
- var emblemed = pixbuf.copy ();
- emblem.composite (emblemed, offset_x, offset_y, emblem_size, emblem_size,
- offset_x, offset_y, 1.0, 1.0, Gdk.InterpType.BILINEAR, 255);
-
- return emblemed;
+ if (!machine.is_stopped && machine.pixbuf != null)
+ thumbnail = machine.pixbuf.scale_simple (width, height, Gdk.InterpType.BILINEAR);
+ else
+ thumbnail = null;
}
}
diff --git a/src/machine.vala b/src/machine.vala
index 556406aa..0d78148d 100644
--- a/src/machine.vala
+++ b/src/machine.vala
@@ -8,7 +8,6 @@
public Boxes.CollectionSource source;
public Boxes.BoxConfig config;
public Gdk.Pixbuf? pixbuf { get; set; }
- public MachineThumbnailer thumbnailer { get; private set; }
public bool stay_on_display;
public string? info { get; protected set; }
public string? status { get; set; }
@@ -75,8 +74,6 @@
private uint screenshot_id;
public const int SCREENSHOT_WIDTH = 180;
public const int SCREENSHOT_HEIGHT = 134;
- public const int CENTERED_EMBLEM_SIZE = 32;
- public const int EMBLEM_SIZE = 16;
private static Cairo.Surface grid_surface;
private bool updating_screenshot;
private uint autosave_timeout_id;
@@ -248,11 +245,6 @@ protected Machine (Boxes.CollectionSource source, string name, string? uuid = nu
create_display_config (uuid);
- // This needs to be set after the 'config' prop has been set.
- thumbnailer = new MachineThumbnailer (this,
- SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT,
- CENTERED_EMBLEM_SIZE, EMBLEM_SIZE);
-
notify["under-construction"].connect (() => {
if (under_construction) {
var inhibit_reason = _("Machine is under construction");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]