[libpanel/wip/chergert/fix-14] save-dialog: use AdwMessageDialog



commit b41cea3c3d63580b6cc3e4342680358162a5b9d6
Author: Christian Hergert <chergert redhat com>
Date:   Tue Sep 13 06:50:16 2022 -0700

    save-dialog: use AdwMessageDialog
    
    Also start on row implementation. We still have a bunch to do with regards
    to being able to implement single vs group selections and all that.

 src/libpanel.gresource.xml          |   1 +
 src/meson.build                     |   1 +
 src/panel-save-dialog-row-private.h |  39 ++++++++
 src/panel-save-dialog-row.c         | 175 ++++++++++++++++++++++++++++++++++++
 src/panel-save-dialog-row.ui        |  22 +++++
 src/panel-save-dialog.c             |  92 +++++++++----------
 src/panel-save-dialog.h             |   4 +-
 src/panel-save-dialog.ui            |  92 ++++---------------
 8 files changed, 302 insertions(+), 124 deletions(-)
---
diff --git a/src/libpanel.gresource.xml b/src/libpanel.gresource.xml
index 80a6596..f8436bc 100644
--- a/src/libpanel.gresource.xml
+++ b/src/libpanel.gresource.xml
@@ -7,6 +7,7 @@
     <file compressed="true" preprocess="xml-stripblanks">panel-frame-header-bar-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">panel-frame.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">panel-save-dialog.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">panel-save-dialog-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">panel-theme-selector.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">panel-toggle-button.ui</file>
   </gresource>
diff --git a/src/meson.build b/src/meson.build
index fd567ca..2f38b5b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -27,6 +27,7 @@ libpanel_private_sources = [
   'panel-joined-menu.c',
   'panel-maximized-controls.c',
   'panel-resizer.c',
+  'panel-save-dialog-row.c',
   'panel-scaler.c',
 ]
 
diff --git a/src/panel-save-dialog-row-private.h b/src/panel-save-dialog-row-private.h
new file mode 100644
index 0000000..f6f31db
--- /dev/null
+++ b/src/panel-save-dialog-row-private.h
@@ -0,0 +1,39 @@
+/* panel-save-dialog-row-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 <adwaita.h>
+
+#include "panel-types.h"
+
+G_BEGIN_DECLS
+
+#define PANEL_TYPE_SAVE_DIALOG_ROW (panel_save_dialog_row_get_type())
+
+G_DECLARE_FINAL_TYPE (PanelSaveDialogRow, panel_save_dialog_row, PANEL, SAVE_DIALOG_ROW, AdwActionRow)
+
+GtkWidget         *panel_save_dialog_row_new          (PanelSaveDelegate  *delegate);
+PanelSaveDelegate *panel_save_dialog_row_get_delegate (PanelSaveDialogRow *self);
+gboolean           panel_save_dialog_row_get_selected (PanelSaveDialogRow *self);
+void               panel_save_dialog_row_set_selected (PanelSaveDialogRow *self,
+                                                       gboolean            selected);
+
+G_END_DECLS
diff --git a/src/panel-save-dialog-row.c b/src/panel-save-dialog-row.c
new file mode 100644
index 0000000..d8afcc2
--- /dev/null
+++ b/src/panel-save-dialog-row.c
@@ -0,0 +1,175 @@
+/* panel-save-dialog-row.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-save-delegate.h"
+#include "panel-save-dialog-row-private.h"
+
+struct _PanelSaveDialogRow
+{
+  AdwActionRow       parent_instance;
+
+  PanelSaveDelegate *delegate;
+
+  GtkCheckButton    *check;
+};
+
+enum {
+  PROP_0,
+  PROP_DELEGATE,
+  PROP_SELECTED,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (PanelSaveDialogRow, panel_save_dialog_row, ADW_TYPE_ACTION_ROW)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+on_notify_active_cb (PanelSaveDialogRow *self,
+                     GParamSpec         *pspec,
+                     GtkCheckButton     *check)
+{
+  g_assert (PANEL_IS_SAVE_DIALOG_ROW (self));
+  g_assert (GTK_IS_CHECK_BUTTON (check));
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SELECTED]);
+}
+
+static void
+panel_save_dialog_row_dispose (GObject *object)
+{
+  PanelSaveDialogRow *self = (PanelSaveDialogRow *)object;
+
+  g_clear_object (&self->delegate);
+
+  G_OBJECT_CLASS (panel_save_dialog_row_parent_class)->dispose (object);
+}
+
+static void
+panel_save_dialog_row_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  PanelSaveDialogRow *self = PANEL_SAVE_DIALOG_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_DELEGATE:
+      g_value_set_object (value, panel_save_dialog_row_get_delegate (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+panel_save_dialog_row_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  PanelSaveDialogRow *self = PANEL_SAVE_DIALOG_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_DELEGATE:
+      self->delegate = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+panel_save_dialog_row_class_init (PanelSaveDialogRowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->dispose = panel_save_dialog_row_dispose;
+  object_class->get_property = panel_save_dialog_row_get_property;
+  object_class->set_property = panel_save_dialog_row_set_property;
+
+  properties [PROP_DELEGATE] =
+    g_param_spec_object ("delegate", NULL, NULL,
+                         PANEL_TYPE_SAVE_DELEGATE,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_SELECTED] =
+    g_param_spec_boolean ("selected", NULL, NULL,
+                          TRUE,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_EXPLICIT_NOTIFY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libpanel/panel-save-dialog-row.ui");
+  gtk_widget_class_bind_template_child (widget_class, PanelSaveDialogRow, check);
+  gtk_widget_class_bind_template_callback (widget_class, on_notify_active_cb);
+}
+
+static void
+panel_save_dialog_row_init (PanelSaveDialogRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+PanelSaveDelegate *
+panel_save_dialog_row_get_delegate (PanelSaveDialogRow *self)
+{
+  g_return_val_if_fail (PANEL_IS_SAVE_DIALOG_ROW (self), NULL);
+
+  return self->delegate;
+}
+
+GtkWidget *
+panel_save_dialog_row_new (PanelSaveDelegate *delegate)
+{
+  g_return_val_if_fail (PANEL_IS_SAVE_DELEGATE (delegate), NULL);
+
+  return g_object_new (PANEL_TYPE_SAVE_DIALOG_ROW,
+                       "delegate", delegate,
+                       NULL);
+}
+
+gboolean
+panel_save_dialog_row_get_selected (PanelSaveDialogRow *self)
+{
+  g_return_val_if_fail (PANEL_IS_SAVE_DIALOG_ROW (self), FALSE);
+
+  return gtk_check_button_get_active (self->check);
+}
+
+void
+panel_save_dialog_row_set_selected (PanelSaveDialogRow *self,
+                                    gboolean            selected)
+{
+  g_return_if_fail (PANEL_IS_SAVE_DIALOG_ROW (self));
+
+  gtk_check_button_set_active (self->check, selected);
+}
diff --git a/src/panel-save-dialog-row.ui b/src/panel-save-dialog-row.ui
new file mode 100644
index 0000000..4a08073
--- /dev/null
+++ b/src/panel-save-dialog-row.ui
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="PanelSaveDialogRow" parent="AdwActionRow">
+    <binding name="title">
+      <lookup name="title" type="PanelSaveDelegate">
+        <lookup name="delegate">PanelSaveDialogRow</lookup>
+      </lookup>
+    </binding>
+    <binding name="subtitle">
+      <lookup name="subtitle" type="PanelSaveDelegate">
+        <lookup name="delegate">PanelSaveDialogRow</lookup>
+      </lookup>
+    </binding>
+    <child type="prefix">
+      <object class="GtkCheckButton" id="check">
+        <property name="active">true</property>
+        <property name="valign">center</property>
+        <signal name="notify::active" handler="on_notify_active_cb" swapped="true" 
object="PanelSaveDialogRow"/>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/panel-save-dialog.c b/src/panel-save-dialog.c
index 952516c..0137e93 100644
--- a/src/panel-save-dialog.c
+++ b/src/panel-save-dialog.c
@@ -26,17 +26,17 @@
 
 #include "panel-save-delegate.h"
 #include "panel-save-dialog.h"
+#include "panel-save-dialog-row-private.h"
 
 struct _PanelSaveDialog
 {
-  GtkDialog            parent_instance;
-  GtkHeaderBar        *headerbar;
-  AdwPreferencesGroup *list;
+  AdwMessageDialog     parent_instance;
+  AdwPreferencesGroup *group;
   GTask               *task;
   guint                count;
 };
 
-G_DEFINE_TYPE (PanelSaveDialog, panel_save_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_FINAL_TYPE (PanelSaveDialog, panel_save_dialog, ADW_TYPE_MESSAGE_DIALOG)
 
 /**
  * panel_save_dialog_new:
@@ -52,69 +52,71 @@ panel_save_dialog_new (void)
 }
 
 static void
-panel_save_dialog_response (GtkDialog *dialog,
-                            int        response)
+panel_save_dialog_response_cancel_cb (PanelSaveDialog *self,
+                                      const char      *response)
 {
-  PanelSaveDialog *self = (PanelSaveDialog *)dialog;
+  GTask *task;
 
   g_assert (PANEL_IS_SAVE_DIALOG (self));
 
-  if (response == GTK_RESPONSE_NO)
-    {
-    }
-  else if (response == GTK_RESPONSE_YES)
-    {
-    }
-  else
-    {
-      g_task_return_new_error (self->task,
-                               G_IO_ERROR,
-                               G_IO_ERROR_CANCELLED,
-                               "Operation was cancelled");
-      g_clear_object (&self->task);
-      gtk_window_destroy (GTK_WINDOW (dialog));
-      return;
-    }
+  task = g_steal_pointer (&self->task);
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_CANCELLED,
+                           "Operation was cancelled");
+  gtk_window_destroy (GTK_WINDOW (self));
+
+  g_clear_object (&task);
 }
 
 static void
-panel_save_dialog_constructed (GObject *object)
+panel_save_dialog_response_discard_cb (PanelSaveDialog *self,
+                                       const char      *response)
 {
-  PanelSaveDialog *self = (PanelSaveDialog *)object;
-  GtkWidget *box;
+  GTask *task;
+
+  g_assert (PANEL_IS_SAVE_DIALOG (self));
 
-  G_OBJECT_CLASS (panel_save_dialog_parent_class)->constructed (object);
+  task = g_steal_pointer (&self->task);
 
-  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-  gtk_window_set_titlebar (GTK_WINDOW (self), box);
-  gtk_widget_hide (box);
+  /* TODO: Discard widgets */
+  g_task_return_boolean (task, TRUE);
+
+  gtk_window_destroy (GTK_WINDOW (self));
+
+  g_clear_object (&task);
 }
 
 static void
-panel_save_dialog_dispose (GObject *object)
+panel_save_dialog_response_save_cb (PanelSaveDialog *self,
+                                    const char      *response)
 {
-  PanelSaveDialog *self = (PanelSaveDialog *)object;
+  GTask *task;
 
-  g_clear_object (&self->task);
+  g_assert (PANEL_IS_SAVE_DIALOG (self));
+
+  task = g_steal_pointer (&self->task);
 
-  G_OBJECT_CLASS (panel_save_dialog_parent_class)->dispose (object);
+  /* TODO: Save using delegates */
+  g_task_return_boolean (task, TRUE);
+
+  gtk_window_destroy (GTK_WINDOW (self));
+
+  g_clear_object (&task);
 }
 
 static void
 panel_save_dialog_class_init (PanelSaveDialogClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-  GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
 
-  object_class->constructed = panel_save_dialog_constructed;
-  object_class->dispose = panel_save_dialog_dispose;
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libpanel/panel-save-dialog.ui");
 
-  dialog_class->response = panel_save_dialog_response;
+  gtk_widget_class_bind_template_child (widget_class, PanelSaveDialog, group);
 
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libpanel/panel-save-dialog.ui");
-  gtk_widget_class_bind_template_child (widget_class, PanelSaveDialog, list);
-  gtk_widget_class_bind_template_child (widget_class, PanelSaveDialog, headerbar);
+  gtk_widget_class_bind_template_callback (widget_class, panel_save_dialog_response_cancel_cb);
+  gtk_widget_class_bind_template_callback (widget_class, panel_save_dialog_response_discard_cb);
+  gtk_widget_class_bind_template_callback (widget_class, panel_save_dialog_response_save_cb);
 }
 
 static void
@@ -127,15 +129,13 @@ void
 panel_save_dialog_add_delegate (PanelSaveDialog   *self,
                                 PanelSaveDelegate *delegate)
 {
-  AdwActionRow *row;
-
   g_return_if_fail (PANEL_IS_SAVE_DIALOG (self));
   g_return_if_fail (PANEL_IS_SAVE_DELEGATE (delegate));
 
   self->count++;
 
-  row = ADW_ACTION_ROW (adw_action_row_new ());
-  adw_preferences_group_add (self->list, GTK_WIDGET (row));
+  adw_preferences_group_add (self->group,
+                             panel_save_dialog_row_new (delegate));
 }
 
 void
diff --git a/src/panel-save-dialog.h b/src/panel-save-dialog.h
index c55dca8..6b30841 100644
--- a/src/panel-save-dialog.h
+++ b/src/panel-save-dialog.h
@@ -20,7 +20,7 @@
 
 #pragma once
 
-#include <gtk/gtk.h>
+#include <adwaita.h>
 
 #include "panel-types.h"
 
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
 #define PANEL_TYPE_SAVE_DIALOG (panel_save_dialog_get_type())
 
 PANEL_AVAILABLE_IN_ALL
-G_DECLARE_FINAL_TYPE (PanelSaveDialog, panel_save_dialog, PANEL, SAVE_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (PanelSaveDialog, panel_save_dialog, PANEL, SAVE_DIALOG, AdwMessageDialog)
 
 PANEL_AVAILABLE_IN_ALL
 GtkWidget *panel_save_dialog_new          (void);
diff --git a/src/panel-save-dialog.ui b/src/panel-save-dialog.ui
index 84f9c3e..6c7c396 100644
--- a/src/panel-save-dialog.ui
+++ b/src/panel-save-dialog.ui
@@ -1,81 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <template class="PanelSaveDialog" parent="GtkDialog">
-    <style>
-      <class name="message"/>
-    </style>
-    <property name="title"></property>
-    <property name="resizable">false</property>
-    <child internal-child="headerbar">
-      <object class="GtkHeaderBar" id="headerbar">
-        <property name="show-title-buttons">0</property>
+  <template class="PanelSaveDialog" parent="AdwMessageDialog">
+    <property name="heading" translatable="yes">Save or Discard Changes?</property>
+    <property name="body" translatable="yes">Open documents contain unsaved changes. Changes which are not 
saved will be permanently lost.</property>
+    <property name="default-response">save</property>
+    <property name="close-response">cancel</property>
+    <signal name="response::cancel" handler="panel_save_dialog_response_cancel_cb"/>
+    <signal name="response::discard" handler="panel_save_dialog_response_discard_cb"/>
+    <signal name="response::save" handler="panel_save_dialog_response_save_cb"/>
+    <responses>
+      <response id="cancel" translatable="yes">_Cancel</response>
+      <response id="discard" translatable="yes" appearance="destructive">_Discard</response>
+      <response id="save" translatable="yes" appearance="suggested">_Save</response>
+    </responses>
+    <property name="extra-child">
+      <object class="AdwPreferencesGroup" id="group">
       </object>
-    </child>
-    <child internal-child="content_area">
-      <object class="GtkBox">
-        <property name="margin-top">30</property>
-        <property name="margin-bottom">30</property>
-        <property name="margin-start">30</property>
-        <property name="margin-end">30</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">12</property>
-        <child>
-          <object class="GtkLabel" id="title">
-            <style>
-              <class name="title-2"/>
-            </style>
-            <property name="label" translatable="yes">Save Changes?</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkLabel">
-            <property name="wrap">true</property>
-            <property name="xalign">0</property>
-            <property name="max-width-chars">60</property>
-            <property name="label" translatable="yes">Open pages contain unsaved changes. Changes which are 
not saved will be permanently lost.</property>
-          </object>
-        </child>
-        <child>
-          <object class="AdwPreferencesGroup" id="list">
-          </object>
-        </child>
-      </object>
-    </child>
-    <child internal-child="action_area">
-      <object class="GtkBox">
-        <property name="hexpand">true</property>
-        <property name="halign">fill</property>
-        <property name="homogeneous">true</property>
-        <style>
-          <class name="linked"/>
-        </style>
-        <child>
-          <object class="GtkButton" id="cancel_button">
-            <property name="hexpand">true</property>
-            <property name="use-underline">true</property>
-            <property name="label" translatable="yes">Cancel</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkButton" id="discard_button">
-            <property name="hexpand">true</property>
-            <property name="use-underline">true</property>
-            <property name="label" translatable="yes">_Discard All</property>
-          </object>
-        </child>
-        <child>
-          <object class="GtkButton" id="save_button">
-            <property name="hexpand">true</property>
-            <property name="use-underline">true</property>
-            <property name="label" translatable="yes">_Save</property>
-          </object>
-        </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="cancel">cancel_button</action-widget>
-      <action-widget response="no">discard_button</action-widget>
-      <action-widget response="yes">save_button</action-widget>
-    </action-widgets>
+    </property>
   </template>
 </interface>


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