[gnome-flashback] desktop: add gf_monitor_view_find_next_icon
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: add gf_monitor_view_find_next_icon
- Date: Sun, 17 Nov 2019 19:23:52 +0000 (UTC)
commit 27d567ef869a7fa561e1af555595ee1b30d050f5
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Sun Nov 17 20:08:15 2019 +0200
desktop: add gf_monitor_view_find_next_icon
gnome-flashback/libdesktop/gf-monitor-view.c | 261 +++++++++++++++++++++++++--
gnome-flashback/libdesktop/gf-monitor-view.h | 38 ++--
2 files changed, 263 insertions(+), 36 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.c b/gnome-flashback/libdesktop/gf-monitor-view.c
index c476523..b245b36 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.c
+++ b/gnome-flashback/libdesktop/gf-monitor-view.c
@@ -53,7 +53,7 @@ struct _GfMonitorView
int offset_x;
int offset_y;
- int *grid;
+ GHashTable *grid;
};
enum
@@ -84,6 +84,204 @@ static guint view_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GfMonitorView, gf_monitor_view, GTK_TYPE_FIXED)
+static GfIcon *
+find_first_icon (GfMonitorView *self)
+{
+ int column;
+ int row;
+
+ for (column = 0; column < self->columns; column++)
+ {
+ for (row = 0; row < self->rows; row++)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ return array->pdata[0];
+ }
+ }
+
+ return NULL;
+}
+
+static gboolean
+find_icon_grid_position (GfMonitorView *self,
+ GfIcon *icon,
+ int *column_out,
+ int *row_out)
+{
+ int column;
+ int row;
+
+ for (column = 0; column < self->columns; column++)
+ {
+ for (row = 0; row < self->rows; row++)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ if (g_ptr_array_find (array, icon, NULL))
+ {
+ *column_out = column;
+ *row_out = row;
+
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static GfIcon *
+find_icon_up (GfMonitorView *self,
+ int start_column,
+ int start_row)
+{
+ int row;
+
+ for (row = start_row - 1; row >= 0; row--)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (start_column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ return array->pdata[0];
+ }
+
+ return NULL;
+}
+
+static GfIcon *
+find_icon_down (GfMonitorView *self,
+ int start_column,
+ int start_row)
+{
+ int row;
+
+ for (row = start_row + 1; row < self->rows; row++)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (start_column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ return array->pdata[0];
+ }
+
+ return NULL;
+}
+
+static GfIcon *
+find_icon_left (GfMonitorView *self,
+ int start_column,
+ int start_row)
+{
+ int column;
+
+ for (column = start_column - 1; column >= 0; column--)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (column * self->rows + start_row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ return array->pdata[0];
+ }
+
+ return NULL;
+}
+
+static GfIcon *
+find_icon_right (GfMonitorView *self,
+ int start_column,
+ int start_row)
+{
+ int column;
+
+ for (column = start_column + 1; column < self->columns; column++)
+ {
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (column * self->rows + start_row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
+ continue;
+
+ return array->pdata[0];
+ }
+
+ return NULL;
+}
+
+static GfIcon *
+find_next_icon (GfMonitorView *self,
+ GfIcon *next_to,
+ GtkDirectionType direction)
+{
+ int column;
+ int row;
+ GfIcon *next_icon;
+
+ if (!find_icon_grid_position (self, next_to, &column, &row))
+ return NULL;
+
+ next_icon = NULL;
+
+ switch (direction)
+ {
+ case GTK_DIR_UP:
+ next_icon = find_icon_up (self, column, row);
+ break;
+
+ case GTK_DIR_DOWN:
+ next_icon = find_icon_down (self, column, row);
+ break;
+
+ case GTK_DIR_LEFT:
+ next_icon = find_icon_left (self, column, row);
+ break;
+
+ case GTK_DIR_RIGHT:
+ next_icon = find_icon_right (self, column, row);
+ break;
+
+ case GTK_DIR_TAB_FORWARD:
+ case GTK_DIR_TAB_BACKWARD:
+ default:
+ break;
+ }
+
+ return next_icon;
+}
+
static gboolean
find_free_grid_position (GfMonitorView *self,
int *column_out,
@@ -96,7 +294,13 @@ find_free_grid_position (GfMonitorView *self,
{
for (row = 0; row < self->rows; row++)
{
- if (self->grid[column * self->rows + row] == 0)
+ gpointer key;
+ GPtrArray *array;
+
+ key = GINT_TO_POINTER (column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL || array->len == 0)
{
*column_out = column;
*row_out = row;
@@ -186,8 +390,7 @@ calculate_grid_size (GfMonitorView *self)
if (!changed)
return;
- g_clear_pointer (&self->grid, g_free);
- self->grid = g_new0 (int, columns * rows);
+ g_hash_table_remove_all (self->grid);
g_signal_emit (self, view_signals[SIZE_CHANGED], 0);
@@ -290,7 +493,7 @@ gf_monitor_view_finalize (GObject *object)
self->grid_size_id = 0;
}
- g_clear_pointer (&self->grid, g_free);
+ g_clear_pointer (&self->grid, g_hash_table_destroy);
G_OBJECT_CLASS (gf_monitor_view_parent_class)->finalize (object);
}
@@ -517,6 +720,8 @@ gf_monitor_view_class_init (GfMonitorViewClass *self_class)
static void
gf_monitor_view_init (GfMonitorView *self)
{
+ self->grid = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+ (GDestroyNotify) g_ptr_array_unref);
}
GtkWidget *
@@ -573,17 +778,28 @@ gf_monitor_view_add_icon (GfMonitorView *self,
{
int column;
int row;
+ gpointer key;
+ GPtrArray *array;
int x;
int y;
if (!find_free_grid_position (self, &column, &row))
return FALSE;
+ key = GINT_TO_POINTER (column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
+
+ if (array == NULL)
+ {
+ array = g_ptr_array_new ();
+ g_hash_table_insert (self->grid, key, array);
+ }
+
+ g_ptr_array_add (array, icon);
+
x = self->offset_x + column * self->spacing_x;
y = self->offset_y + row * self->spacing_y;
- self->grid[column * self->rows + row] = 1;
-
gtk_fixed_put (GTK_FIXED (self), icon, x, y);
gtk_widget_show (icon);
@@ -594,27 +810,23 @@ void
gf_monitor_view_remove_icon (GfMonitorView *self,
GtkWidget *icon)
{
- GtkAllocation allocation;
int column;
int row;
- gtk_widget_get_allocation (icon, &allocation);
- gtk_widget_translate_coordinates (icon, GTK_WIDGET (self),
- 0, 0, &allocation.x, &allocation.y);
-
for (column = 0; column < self->columns; column++)
{
for (row = 0; row < self->rows; row++)
{
- GdkRectangle rect;
+ gpointer key;
+ GPtrArray *array;
- rect.x = self->offset_x + column * self->spacing_x;
- rect.y = self->offset_y + row * self->spacing_y;
- rect.width = self->icon_width;
- rect.height = self->icon_height;
+ key = GINT_TO_POINTER (column * self->rows + row);
+ array = g_hash_table_lookup (self->grid, key);
- if (gdk_rectangle_intersect (&allocation, &rect, NULL))
- self->grid[column * self->rows + row]--;
+ if (array == NULL || array->len == 0)
+ continue;
+
+ g_ptr_array_remove (array, icon);
}
}
@@ -651,3 +863,14 @@ gf_monitor_view_get_icons (GfMonitorView *self,
return icons;
}
+
+GfIcon *
+gf_monitor_view_find_next_icon (GfMonitorView *self,
+ GfIcon *next_to,
+ GtkDirectionType direction)
+{
+ if (next_to == NULL)
+ return find_first_icon (self);
+
+ return find_next_icon (self, next_to, direction);
+}
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.h b/gnome-flashback/libdesktop/gf-monitor-view.h
index d80a5c1..51abd0c 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.h
+++ b/gnome-flashback/libdesktop/gf-monitor-view.h
@@ -26,30 +26,34 @@ G_BEGIN_DECLS
#define GF_TYPE_MONITOR_VIEW (gf_monitor_view_get_type ())
G_DECLARE_FINAL_TYPE (GfMonitorView, gf_monitor_view, GF, MONITOR_VIEW, GtkFixed)
-GtkWidget *gf_monitor_view_new (GdkMonitor *monitor,
- GfDummyIcon *dummy_icon,
- guint column_spacing,
- guint row_spacing);
+GtkWidget *gf_monitor_view_new (GdkMonitor *monitor,
+ GfDummyIcon *dummy_icon,
+ guint column_spacing,
+ guint row_spacing);
-void gf_monitor_view_set_placement (GfMonitorView *self,
- GfPlacement placement);
+void gf_monitor_view_set_placement (GfMonitorView *self,
+ GfPlacement placement);
-void gf_monitor_view_set_size (GfMonitorView *self,
- int width,
- int height);
+void gf_monitor_view_set_size (GfMonitorView *self,
+ int width,
+ int height);
-GdkMonitor *gf_monitor_view_get_monitor (GfMonitorView *self);
+GdkMonitor *gf_monitor_view_get_monitor (GfMonitorView *self);
-gboolean gf_monitor_view_is_primary (GfMonitorView *self);
+gboolean gf_monitor_view_is_primary (GfMonitorView *self);
-gboolean gf_monitor_view_add_icon (GfMonitorView *self,
- GtkWidget *icon);
+gboolean gf_monitor_view_add_icon (GfMonitorView *self,
+ GtkWidget *icon);
-void gf_monitor_view_remove_icon (GfMonitorView *self,
- GtkWidget *icon);
+void gf_monitor_view_remove_icon (GfMonitorView *self,
+ GtkWidget *icon);
-GList *gf_monitor_view_get_icons (GfMonitorView *self,
- GdkRectangle *rect);
+GList *gf_monitor_view_get_icons (GfMonitorView *self,
+ GdkRectangle *rect);
+
+GfIcon *gf_monitor_view_find_next_icon (GfMonitorView *self,
+ GfIcon *next_to,
+ GtkDirectionType direction);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]