[libpanel/wip/chergert/fix-14: 1/2] position: add PanelPosition object




commit e8275080f41bbd487518d6cf88e0eef265ffa19e
Author: Christian Hergert <chergert redhat com>
Date:   Sat Sep 10 17:44:57 2022 -0700

    position: add PanelPosition object
    
    Adds a new PanelPosition GObject that we can use to hoist features from
    libide-gui into libpanel. Additionally, we can use this from PanelLayout
    to track items in the dock.

 src/libpanel.h               |   1 +
 src/meson.build              |   2 +
 src/panel-position-private.h |  30 +++
 src/panel-position.c         | 469 +++++++++++++++++++++++++++++++++++++++++++
 src/panel-position.h         |  78 +++++++
 5 files changed, 580 insertions(+)
---
diff --git a/src/libpanel.h b/src/libpanel.h
index 1948406..5d01ccb 100644
--- a/src/libpanel.h
+++ b/src/libpanel.h
@@ -33,6 +33,7 @@
 # include "panel-init.h"
 # include "panel-omni-bar.h"
 # include "panel-paned.h"
+# include "panel-position.h"
 # include "panel-save-delegate.h"
 # include "panel-statusbar.h"
 # include "panel-theme-selector.h"
diff --git a/src/meson.build b/src/meson.build
index 619ada9..b018115 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -42,6 +42,7 @@ libpanel_sources = [
   'panel-init.c',
   'panel-omni-bar.c',
   'panel-paned.c',
+  'panel-position.c',
   'panel-save-dialog.c',
   'panel-save-delegate.c',
   'panel-statusbar.c',
@@ -63,6 +64,7 @@ libpanel_headers = [
   'panel-init.h',
   'panel-omni-bar.h',
   'panel-paned.h',
+  'panel-position.h',
   'panel-save-delegate.h',
   'panel-statusbar.h',
   'panel-theme-selector.h',
diff --git a/src/panel-position-private.h b/src/panel-position-private.h
new file mode 100644
index 0000000..28e1e71
--- /dev/null
+++ b/src/panel-position-private.h
@@ -0,0 +1,30 @@
+/* panel-position-private.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "panel-position.h"
+
+G_BEGIN_DECLS
+
+GVariant      *_panel_position_to_variant       (PanelPosition *self);
+PanelPosition *_panel_position_new_from_variant (GVariant      *variant);
+
+G_END_DECLS
diff --git a/src/panel-position.c b/src/panel-position.c
new file mode 100644
index 0000000..92838bc
--- /dev/null
+++ b/src/panel-position.c
@@ -0,0 +1,469 @@
+/* panel-position.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include "panel-dock.h"
+#include "panel-enums.h"
+#include "panel-position-private.h"
+
+struct _PanelPosition
+{
+  GObject parent_instance;
+
+  guint column;
+  guint depth;
+  guint row;
+
+  PanelArea area : 3;
+  guint area_set : 1;
+  guint column_set : 1;
+  guint depth_set : 1;
+  guint row_set : 1;
+};
+
+enum {
+  PROP_0,
+  PROP_AREA,
+  PROP_AREA_SET,
+  PROP_COLUMN,
+  PROP_COLUMN_SET,
+  PROP_DEPTH,
+  PROP_DEPTH_SET,
+  PROP_ROW,
+  PROP_ROW_SET,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (PanelPosition, panel_position, G_TYPE_OBJECT)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+panel_position_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  PanelPosition *self = PANEL_POSITION (object);
+
+  switch (prop_id)
+    {
+    case PROP_AREA:
+      g_value_set_enum (value, panel_position_get_area (self));
+      break;
+
+    case PROP_AREA_SET:
+      g_value_set_boolean (value, panel_position_get_area_set (self));
+      break;
+
+    case PROP_COLUMN:
+      g_value_set_uint (value, panel_position_get_column (self));
+      break;
+
+    case PROP_COLUMN_SET:
+      g_value_set_boolean (value, panel_position_get_column_set (self));
+      break;
+
+    case PROP_DEPTH:
+      g_value_set_uint (value, panel_position_get_depth (self));
+      break;
+
+    case PROP_DEPTH_SET:
+      g_value_set_boolean (value, panel_position_get_depth_set (self));
+      break;
+
+    case PROP_ROW:
+      g_value_set_uint (value, panel_position_get_row (self));
+      break;
+
+    case PROP_ROW_SET:
+      g_value_set_boolean (value, panel_position_get_row_set (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+panel_position_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  PanelPosition *self = PANEL_POSITION (object);
+
+  switch (prop_id)
+    {
+    case PROP_AREA:
+      panel_position_set_area (self, g_value_get_enum (value));
+      break;
+
+    case PROP_AREA_SET:
+      panel_position_set_area_set (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_COLUMN:
+      panel_position_set_column (self, g_value_get_uint (value));
+      break;
+
+    case PROP_COLUMN_SET:
+      panel_position_set_column_set (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_DEPTH:
+      panel_position_set_depth (self, g_value_get_uint (value));
+      break;
+
+    case PROP_DEPTH_SET:
+      panel_position_set_depth_set (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_ROW:
+      panel_position_set_row (self, g_value_get_uint (value));
+      break;
+
+    case PROP_ROW_SET:
+      panel_position_set_row_set (self, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+panel_position_class_init (PanelPositionClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = panel_position_get_property;
+  object_class->set_property = panel_position_set_property;
+
+  properties[PROP_AREA] =
+    g_param_spec_enum ("area", NULL, NULL,
+                       PANEL_TYPE_AREA,
+                       PANEL_AREA_CENTER,
+                       (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_AREA_SET] =
+    g_param_spec_boolean ("area-set", NULL, NULL,
+                          FALSE,
+                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_COLUMN] =
+    g_param_spec_uint ("column", NULL, NULL,
+                       0, G_MAXUINT, 0,
+                       (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_COLUMN_SET] =
+    g_param_spec_boolean ("column-set", NULL, NULL,
+                          FALSE,
+                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_DEPTH] =
+    g_param_spec_uint ("depth", NULL, NULL,
+                       0, G_MAXUINT, 0,
+                       (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_DEPTH_SET] =
+    g_param_spec_boolean ("depth-set", NULL, NULL,
+                          FALSE,
+                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_ROW] =
+    g_param_spec_uint ("row", NULL, NULL,
+                       0, G_MAXUINT, 0,
+                       (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_ROW_SET] =
+    g_param_spec_boolean ("row-set", NULL, NULL,
+                          FALSE,
+                          (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+panel_position_init (PanelPosition *self)
+{
+  self->area = PANEL_AREA_CENTER;
+}
+
+PanelPosition *
+panel_position_new (void)
+{
+  return g_object_new (PANEL_TYPE_POSITION, NULL);
+}
+
+#define SET_MEMBER(member, value, prop)                                    \
+  G_STMT_START {                                                           \
+    gboolean notify_set = self->member##_set == FALSE;                     \
+    gboolean notify = self->member != value;                               \
+    self->member = value;                                                  \
+    self->member##_set = TRUE;                                             \
+    if (notify)                                                            \
+      g_object_notify_by_pspec (G_OBJECT (self), properties [prop]);       \
+    if (notify_set)                                                        \
+      g_object_notify_by_pspec (G_OBJECT (self), properties [prop##_SET]); \
+  } G_STMT_END
+#define SET_MEMBER_SET(member, value, prop)                                \
+  G_STMT_START {                                                           \
+    value = !!value;                                                       \
+    if (value != self->member)                                             \
+      {                                                                    \
+        self->member = value;                                              \
+        g_object_notify_by_pspec (G_OBJECT (self), properties [prop]);     \
+      }                                                                    \
+  } G_STMT_END
+
+PanelArea
+panel_position_get_area (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), 0);
+
+  return self->area;
+}
+
+void
+panel_position_set_area (PanelPosition *self,
+                         PanelArea      area)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+  g_return_if_fail (area <= PANEL_AREA_CENTER);
+
+  SET_MEMBER (area, area, PROP_AREA);
+}
+
+gboolean
+panel_position_get_area_set (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), FALSE);
+
+  return self->area_set;
+}
+
+void
+panel_position_set_area_set (PanelPosition *self,
+                             gboolean       area_set)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER_SET (area_set, area_set, PROP_AREA_SET);
+}
+
+guint
+panel_position_get_column (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), 0);
+
+  return self->column;
+}
+
+void
+panel_position_set_column (PanelPosition *self,
+                           guint          column)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER (column, column, PROP_COLUMN);
+}
+
+gboolean
+panel_position_get_column_set (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), FALSE);
+
+  return self->column_set;
+}
+
+void
+panel_position_set_column_set (PanelPosition *self,
+                               gboolean       column_set)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER_SET (column_set, column_set, PROP_COLUMN_SET);
+}
+
+guint
+panel_position_get_depth (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), 0);
+
+  return self->depth;
+}
+
+void
+panel_position_set_depth (PanelPosition *self,
+                          guint          depth)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER (depth, depth, PROP_DEPTH);
+}
+
+gboolean
+panel_position_get_depth_set (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), FALSE);
+
+  return self->depth_set;
+}
+
+void
+panel_position_set_depth_set (PanelPosition *self,
+                              gboolean       depth_set)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER_SET (depth_set, depth_set, PROP_DEPTH_SET);
+}
+
+guint
+panel_position_get_row (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), 0);
+
+  return self->row;
+}
+
+void
+panel_position_set_row (PanelPosition *self,
+                        guint          row)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER (row, row, PROP_ROW);
+}
+
+gboolean
+panel_position_get_row_set (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), FALSE);
+
+  return self->row_set;
+}
+
+void
+panel_position_set_row_set (PanelPosition *self,
+                            gboolean       row_set)
+{
+  g_return_if_fail (PANEL_IS_POSITION (self));
+
+  SET_MEMBER_SET (row_set, row_set, PROP_ROW_SET);
+}
+
+gboolean
+panel_position_is_indeterminate (PanelPosition *self)
+{
+  g_return_val_if_fail (PANEL_IS_POSITION (self), FALSE);
+
+  return !self->area_set || !self->column_set || !self->row_set;
+}
+
+GVariant *
+_panel_position_to_variant (PanelPosition *self)
+{
+  GVariantDict dict;
+
+  g_return_val_if_fail (PANEL_IS_POSITION (self), NULL);
+
+  g_variant_dict_init (&dict, NULL);
+
+  if (self->area_set)
+    {
+      const char *area;
+
+      switch (self->area)
+        {
+        case PANEL_AREA_START:
+          area = "start";
+          break;
+
+        case PANEL_AREA_END:
+          area = "end";
+          break;
+
+        case PANEL_AREA_TOP:
+          area = "top";
+          break;
+
+        case PANEL_AREA_BOTTOM:
+          area = "bottom";
+          break;
+
+        case PANEL_AREA_CENTER:
+          area = "center";
+          break;
+
+        default:
+          g_assert_not_reached ();
+        }
+
+      g_variant_dict_insert (&dict, "area", "s", area);
+    }
+
+  if (self->column_set)
+    g_variant_dict_insert (&dict, "column", "u", self->column);
+
+  if (self->depth_set)
+    g_variant_dict_insert (&dict, "depth", "u", self->depth);
+
+  if (self->row_set)
+    g_variant_dict_insert (&dict, "row", "u", self->row);
+
+  return g_variant_dict_end (&dict);
+}
+
+PanelPosition *
+_panel_position_new_from_variant (GVariant *variant)
+{
+
+  PanelPosition *self;
+  const char *area;
+
+  g_return_val_if_fail (variant, NULL);
+
+  self = g_object_new (PANEL_TYPE_POSITION, NULL);
+
+  if (g_variant_lookup (variant, "area", "&s", &area))
+    {
+      if (area[0] == 't')
+        self->area = PANEL_AREA_TOP;
+      else if (area[0] == 'e')
+        self->area = PANEL_AREA_END;
+      else if (area[0] == 'b')
+        self->area = PANEL_AREA_BOTTOM;
+      else if (area[0] == 's')
+        self->area = PANEL_AREA_START;
+      else if (area[0] == 'c')
+        self->area = PANEL_AREA_CENTER;
+
+      self->area_set = TRUE;
+    }
+
+  self->column_set = g_variant_lookup (variant, "column", "u", &self->column);
+  self->depth_set = g_variant_lookup (variant, "depth", "u", &self->depth);
+  self->row_set = g_variant_lookup (variant, "row", "u", &self->row);
+
+  return self;
+}
diff --git a/src/panel-position.h b/src/panel-position.h
new file mode 100644
index 0000000..513df4c
--- /dev/null
+++ b/src/panel-position.h
@@ -0,0 +1,78 @@
+/* panel-position.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "panel-dock.h"
+#include "panel-version-macros.h"
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_POSITION (panel_position_get_type())
+
+PANEL_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (PanelPosition, panel_position, PANEL, POSITION, GObject)
+
+PANEL_AVAILABLE_IN_ALL
+PanelPosition *panel_position_new              (void);
+PANEL_AVAILABLE_IN_ALL
+PanelArea      panel_position_get_area         (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+gboolean       panel_position_get_area_set     (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+guint          panel_position_get_column       (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+gboolean       panel_position_get_column_set   (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+guint          panel_position_get_depth        (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+gboolean       panel_position_get_depth_set    (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+guint          panel_position_get_row          (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+gboolean       panel_position_get_row_set      (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+gboolean       panel_position_is_indeterminate (PanelPosition *self);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_area         (PanelPosition *self,
+                                                PanelArea      area);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_area_set     (PanelPosition *self,
+                                                gboolean       area_set);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_column       (PanelPosition *self,
+                                                guint          column);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_column_set   (PanelPosition *self,
+                                                gboolean       column_set);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_depth        (PanelPosition *self,
+                                                guint          depth);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_depth_set    (PanelPosition *self,
+                                                gboolean       depth_set);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_row          (PanelPosition *self,
+                                                guint          row);
+PANEL_AVAILABLE_IN_ALL
+void           panel_position_set_row_set      (PanelPosition *self,
+                                                gboolean       row_set);
+
+G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]