[gnome-flashback] desktop: calculate grid size
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: calculate grid size
- Date: Tue, 5 Nov 2019 16:35:08 +0000 (UTC)
commit 50fcd59ac29920d779e66b377cd863f5f454fd80
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Mon Nov 4 20:05:02 2019 +0200
desktop: calculate grid size
gnome-flashback/libdesktop/gf-monitor-view.c | 290 +++++++++++++++++++++++++--
1 file changed, 277 insertions(+), 13 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.c b/gnome-flashback/libdesktop/gf-monitor-view.c
index 4a89f6c..4b74a91 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.c
+++ b/gnome-flashback/libdesktop/gf-monitor-view.c
@@ -18,19 +18,37 @@
#include "config.h"
#include "gf-monitor-view.h"
+#include "gf-icon.h"
+#include "gf-utils.h"
+
struct _GfMonitorView
{
GtkFixed parent;
GdkMonitor *monitor;
+ gboolean grid_points;
+
guint icon_size;
guint extra_text_width;
guint column_spacing;
guint row_spacing;
- int width;
- int height;
+ guint grid_size_id;
+
+ GtkWidget *dummy_icon;
+
+ int view_width;
+ int view_height;
+
+ int columns;
+ int rows;
+
+ int spacing_x;
+ int spacing_y;
+
+ int offset_x;
+ int offset_y;
};
enum
@@ -39,6 +57,8 @@ enum
PROP_MONITOR,
+ PROP_GRID_POINTS,
+
PROP_ICON_SIZE,
PROP_EXTRA_TEXT_WIDTH,
PROP_COLUMN_SPACING,
@@ -51,6 +71,171 @@ static GParamSpec *view_properties[LAST_PROP] = { NULL };
G_DEFINE_TYPE (GfMonitorView, gf_monitor_view, GTK_TYPE_FIXED)
+static void
+icon_destroy_cb (GtkWidget *widget,
+ GFile *file)
+{
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+static GtkWidget *
+create_dummy_icon (GfMonitorView *self)
+{
+ GFileIOStream *iostream;
+ GError *error;
+ GFile *file;
+ char *attributes;
+ GFileInfo *info;
+ GIcon *icon;
+ const char *name;
+ GtkWidget *widget;
+
+ iostream = NULL;
+ error = NULL;
+
+ file = g_file_new_tmp ("dummy-desktop-file-XXXXXX", &iostream, &error);
+
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ attributes = gf_build_attributes_list (G_FILE_ATTRIBUTE_STANDARD_NAME,
+ G_FILE_ATTRIBUTE_STANDARD_ICON,
+ NULL);
+
+ info = g_file_io_stream_query_info (iostream, attributes, NULL, &error);
+ g_object_unref (iostream);
+ g_free (attributes);
+
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ icon = g_icon_new_for_string ("text-x-generic", NULL);
+ g_file_info_set_icon (info, icon);
+ g_object_unref (icon);
+
+ name = "Lorem Ipsum is simply dummy text of the printing and typesetting "
+ "industry. Lorem Ipsum has been the industry's standard dummy text "
+ "ever since the 1500s, when an unknown printer took a galley of "
+ "type and scrambled it to make a type specimen book.";
+
+ g_file_info_set_name (info, name);
+
+ widget = gf_icon_new (file, info);
+ g_object_unref (info);
+
+ g_object_bind_property (self, "icon-size",
+ widget, "icon-size",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (self, "extra-text-width",
+ widget, "extra-text-width",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (widget, "destroy",
+ G_CALLBACK (icon_destroy_cb),
+ g_object_ref (file));
+
+ g_object_unref (file);
+
+ return widget;
+}
+
+static void
+calculate_grid_size (GfMonitorView *self)
+{
+ GtkRequisition icon_size;
+ int columns;
+ int rows;
+
+ if (self->dummy_icon == NULL)
+ {
+ self->dummy_icon = create_dummy_icon (self);
+ gtk_widget_show (self->dummy_icon);
+ }
+
+ if (self->dummy_icon == NULL)
+ return;
+
+ gtk_widget_get_preferred_size (self->dummy_icon, &icon_size, NULL);
+
+ columns = self->view_width / icon_size.width;
+ rows = self->view_height / icon_size.height;
+
+ while (TRUE)
+ {
+ int spacing;
+
+ spacing = (columns - 1) * self->column_spacing;
+ if (spacing + columns * icon_size.width <= self->view_width ||
+ columns == 1)
+ break;
+
+ columns--;
+ }
+
+ while (TRUE)
+ {
+ int spacing;
+
+ spacing = (rows - 1) * self->row_spacing;
+ if (spacing + rows * icon_size.height <= self->view_height ||
+ rows == 1)
+ break;
+
+ rows--;
+ }
+
+ self->columns = columns;
+ self->rows = rows;
+
+ self->spacing_x = icon_size.width + self->column_spacing;
+ self->spacing_y = icon_size.height + self->row_spacing;
+
+ self->offset_x = (self->view_width - columns * icon_size.width -
+ (columns - 1) * self->column_spacing) / 2;
+ self->offset_y = (self->view_height - rows * icon_size.height -
+ (rows - 1) * self->row_spacing) / 2;
+
+ if (self->grid_points)
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static gboolean
+recalculate_grid_size_cb (gpointer user_data)
+{
+ GfMonitorView *self;
+
+ self = GF_MONITOR_VIEW (user_data);
+
+ calculate_grid_size (self);
+ self->grid_size_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+recalculate_grid_size (GfMonitorView *self)
+{
+ if (self->grid_size_id != 0)
+ return;
+
+ self->grid_size_id = g_idle_add (recalculate_grid_size_cb, self);
+
+ g_source_set_name_by_id (self->grid_size_id,
+ "[gnome-flashback] recalculate_grid_size_cb");
+}
+
static void
set_icon_size (GfMonitorView *self,
guint icon_size)
@@ -60,7 +245,7 @@ set_icon_size (GfMonitorView *self,
self->icon_size = icon_size;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ recalculate_grid_size (self);
}
static void
@@ -72,7 +257,7 @@ set_extra_text_width (GfMonitorView *self,
self->extra_text_width = extra_text_width;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ recalculate_grid_size (self);
}
static void
@@ -84,7 +269,7 @@ set_column_spacing (GfMonitorView *self,
self->column_spacing = column_spacing;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ recalculate_grid_size (self);
}
static void
@@ -96,7 +281,7 @@ set_row_spacing (GfMonitorView *self,
self->row_spacing = row_spacing;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ recalculate_grid_size (self);
}
static void
@@ -108,10 +293,10 @@ workarea_cb (GdkMonitor *monitor,
gdk_monitor_get_workarea (monitor, &workarea);
- self->width = workarea.width;
- self->height = workarea.height;
+ self->view_width = workarea.width;
+ self->view_height = workarea.height;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ recalculate_grid_size (self);
}
static void
@@ -142,6 +327,66 @@ gf_monitor_view_dispose (GObject *object)
G_OBJECT_CLASS (gf_monitor_view_parent_class)->dispose (object);
}
+static void
+gf_monitor_view_finalize (GObject *object)
+{
+ GfMonitorView *self;
+
+ self = GF_MONITOR_VIEW (object);
+
+ g_clear_pointer (&self->dummy_icon, gtk_widget_destroy);
+
+ if (self->grid_size_id != 0)
+ {
+ g_source_remove (self->grid_size_id);
+ self->grid_size_id = 0;
+ }
+
+ G_OBJECT_CLASS (gf_monitor_view_parent_class)->finalize (object);
+}
+
+static gboolean
+gf_monitor_view_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GfMonitorView *self;
+
+ self = GF_MONITOR_VIEW (widget);
+
+ if (self->grid_points)
+ {
+ int c;
+
+ cairo_save (cr);
+ cairo_set_line_width (cr, 1);
+
+ for (c = 0; c < self->columns; c++)
+ {
+ int r;
+
+ for (r = 0; r < self->rows; r++)
+ {
+ int x;
+ int y;
+
+ x = self->offset_x + c * self->spacing_x + self->spacing_x / 2;
+ y = self->offset_y + r * self->spacing_y + self->spacing_y / 2;
+
+ cairo_move_to (cr, x - 3, y);
+ cairo_line_to (cr, x + 3, y);
+
+ cairo_move_to (cr, x, y - 3);
+ cairo_line_to (cr, x, y + 3);
+ }
+ }
+
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ return GTK_WIDGET_CLASS (gf_monitor_view_parent_class)->draw (widget, cr);
+}
+
static void
gf_monitor_view_get_property (GObject *object,
guint property_id,
@@ -154,6 +399,10 @@ gf_monitor_view_get_property (GObject *object,
switch (property_id)
{
+ case PROP_GRID_POINTS:
+ g_value_set_boolean (value, self->grid_points);
+ break;
+
case PROP_ICON_SIZE:
g_value_set_uint (value, self->icon_size);
break;
@@ -185,6 +434,11 @@ gf_monitor_view_set_property (GObject *object,
self->monitor = g_value_dup_object (value);
break;
+ case PROP_GRID_POINTS:
+ self->grid_points = g_value_get_boolean (value);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ break;
+
case PROP_ICON_SIZE:
set_icon_size (self, g_value_get_uint (value));
break;
@@ -216,8 +470,8 @@ gf_monitor_view_get_preferred_height (GtkWidget *widget,
self = GF_MONITOR_VIEW (widget);
- *minimum_height = self->height;
- *natural_height = self->height;
+ *minimum_height = self->view_height;
+ *natural_height = self->view_height;
}
static void
@@ -229,8 +483,8 @@ gf_monitor_view_get_preferred_width (GtkWidget *widget,
self = GF_MONITOR_VIEW (widget);
- *minimum_width = self->width;
- *natural_width = self->width;
+ *minimum_width = self->view_width;
+ *natural_width = self->view_width;
}
static GtkSizeRequestMode
@@ -251,6 +505,14 @@ install_properties (GObjectClass *object_class)
G_PARAM_WRITABLE |
G_PARAM_STATIC_STRINGS);
+ view_properties[PROP_GRID_POINTS] =
+ g_param_spec_boolean ("grid-points",
+ "grid-points",
+ "grid-points",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
view_properties[PROP_ICON_SIZE] =
g_param_spec_uint ("icon-size",
"icon-size",
@@ -301,9 +563,11 @@ gf_monitor_view_class_init (GfMonitorViewClass *self_class)
object_class->constructed = gf_monitor_view_constructed;
object_class->dispose = gf_monitor_view_dispose;
+ object_class->finalize = gf_monitor_view_finalize;
object_class->get_property = gf_monitor_view_get_property;
object_class->set_property = gf_monitor_view_set_property;
+ widget_class->draw = gf_monitor_view_draw;
widget_class->get_preferred_height = gf_monitor_view_get_preferred_height;
widget_class->get_preferred_width = gf_monitor_view_get_preferred_width;
widget_class->get_request_mode = gf_monitor_view_get_request_mode;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]