[gnome-builder/wip/chergert/headerbar] build-tools: implement updated designs for build configuration



commit d3f09e4211aa2099ae2fe42a9a2ca7ce879d4a2f
Author: Christian Hergert <chergert redhat com>
Date:   Sat Jun 25 15:36:35 2016 -0700

    build-tools: implement updated designs for build configuration
    
    This moves some of the controls (delete/duplicate) to the build config
    sidebar.
    
    I decided to repurpose the GbpBuildConfigurationRow to be used here, since
    we will be removing it (and most of) the build panel from the editor (still
    to be done).

 data/theme/Adwaita-shared.css                      |   16 +++
 plugins/build-tools/gbp-build-configuration-row.c  |   47 +++++--
 plugins/build-tools/gbp-build-configuration-row.ui |   69 +++++++++--
 .../build-tools/gbp-build-configuration-view.ui    |   48 -------
 plugins/build-tools/gbp-build-perspective.c        |  135 +++++++++++++-------
 plugins/build-tools/gbp-build-perspective.ui       |    6 +-
 6 files changed, 200 insertions(+), 121 deletions(-)
---
diff --git a/data/theme/Adwaita-shared.css b/data/theme/Adwaita-shared.css
index 0a81c4c..78abae7 100644
--- a/data/theme/Adwaita-shared.css
+++ b/data/theme/Adwaita-shared.css
@@ -178,3 +178,19 @@ preferences stacksidebar list {
 preferences stacksidebar list separator {
   background-color: transparent;
 }
+
+
+buildperspective list.sidebar row:selected button:hover {
+  border-color: transparent;
+  box-shadow: none;
+  background: transparent;
+  color: @theme_selected_fg_color;
+  opacity: 1;
+}
+buildperspective list.sidebar row:selected button,
+buildperspective list.sidebar row:selected button:active {
+  opacity: 0.8;
+}
+buildperspective list.sidebar {
+  border-right: 1px solid alpha(@borders, 0.55);
+}
diff --git a/plugins/build-tools/gbp-build-configuration-row.c 
b/plugins/build-tools/gbp-build-configuration-row.c
index d77a860..1eddc5a 100644
--- a/plugins/build-tools/gbp-build-configuration-row.c
+++ b/plugins/build-tools/gbp-build-configuration-row.c
@@ -25,11 +25,15 @@ struct _GbpBuildConfigurationRow
   IdeConfiguration *configuration;
 
   GtkLabel         *label;
-  GtkImage         *check_image;
+  GtkImage         *radio;
+  GtkButton        *delete;
+  GtkButton        *duplicate;
+  GtkStack         *controls;
 };
 
 enum {
   PROP_0,
+  PROP_ACTIVE,
   PROP_CONFIGURATION,
   PROP_SELECTED,
   LAST_PROP
@@ -46,9 +50,10 @@ gbp_build_configuration_row_set_configuration (GbpBuildConfigurationRow *self,
   g_assert (GBP_IS_BUILD_CONFIGURATION_ROW (self));
   g_assert (IDE_IS_CONFIGURATION (configuration));
 
-  g_set_object (&self->configuration, configuration);
-
-  g_object_bind_property (configuration, "display-name", self->label, "label", G_BINDING_SYNC_CREATE);
+  if (g_set_object (&self->configuration, configuration))
+    g_object_bind_property (configuration, "display-name",
+                            self->label, "label",
+                            G_BINDING_SYNC_CREATE);
 }
 
 static void
@@ -75,10 +80,6 @@ gbp_build_configuration_row_get_property (GObject    *object,
       g_value_set_object (value, gbp_build_configuration_row_get_configuration (self));
       break;
 
-    case PROP_SELECTED:
-      g_value_set_boolean (value, gtk_widget_get_visible (GTK_WIDGET (self->check_image)));
-      break;
-
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -98,8 +99,22 @@ gbp_build_configuration_row_set_property (GObject      *object,
       gbp_build_configuration_row_set_configuration (self, g_value_get_object (value));
       break;
 
+    case PROP_ACTIVE:
+      if (g_value_get_boolean (value))
+        g_object_set (self->radio,
+                      "icon-name", "radio-checked-symbolic",
+                      NULL);
+      else
+        g_object_set (self->radio,
+                      "icon-name", "radio-symbolic",
+                      NULL);
+      break;
+
     case PROP_SELECTED:
-      gtk_widget_set_visible (GTK_WIDGET (self->check_image), g_value_get_boolean (value));
+      if (g_value_get_boolean (value))
+        gtk_stack_set_visible_child_name (self->controls, "controls");
+      else
+        gtk_stack_set_visible_child_name (self->controls, "empty");
       break;
 
     default:
@@ -124,18 +139,28 @@ gbp_build_configuration_row_class_init (GbpBuildConfigurationRowClass *klass)
                          IDE_TYPE_CONFIGURATION,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
 
+  properties [PROP_ACTIVE] =
+    g_param_spec_boolean ("active",
+                          "Active",
+                          "If the row is the active configuration",
+                          FALSE,
+                          (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
   properties [PROP_SELECTED] =
     g_param_spec_boolean ("selected",
                           "Selected",
                           "If the row is selected",
                           FALSE,
-                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+                          (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_properties (object_class, LAST_PROP, properties);
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/build-tools-plugin/gbp-build-configuration-row.ui");
-  gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, check_image);
   gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, label);
+  gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, duplicate);
+  gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, delete);
+  gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, radio);
+  gtk_widget_class_bind_template_child (widget_class, GbpBuildConfigurationRow, controls);
 }
 
 static void
diff --git a/plugins/build-tools/gbp-build-configuration-row.ui 
b/plugins/build-tools/gbp-build-configuration-row.ui
index 10157e1..fd0ba80 100644
--- a/plugins/build-tools/gbp-build-configuration-row.ui
+++ b/plugins/build-tools/gbp-build-configuration-row.ui
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <template class="GbpBuildConfigurationRow" parent="GtkListBoxRow">
     <child>
@@ -5,26 +6,74 @@
         <property name="orientation">horizontal</property>
         <property name="visible">true</property>
         <child>
-          <object class="GtkLabel" id="label">
+          <object class="GtkImage" id="radio">
+            <property name="icon-name">radio-symbolic</property>
+            <property name="margin-end">6</property>
+            <property name="margin-start">6</property>
             <property name="valign">baseline</property>
             <property name="visible">true</property>
-            <property name="xalign">0.0</property>
           </object>
         </child>
         <child>
-          <object class="GtkImage" id="check_image">
-            <property name="icon-name">object-select-symbolic</property>
-            <property name="margin-end">6</property>
-            <property name="margin-start">6</property>
-            <property name="valign">baseline</property>
+          <object class="GtkLabel" id="label">
+            <property name="hexpand">true</property>
+            <property name="ellipsize">middle</property>
             <property name="visible">true</property>
+            <property name="xalign">0.0</property>
           </object>
         </child>
         <child>
-          <object class="GtkLabel" id="spacer">
-            <property name="hexpand">true</property>
-            <property name="valign">baseline</property>
+          <object class="GtkStack" id="controls">
+            <property name="homogeneous">true</property>
             <property name="visible">true</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">true</property>
+              </object>
+              <packing>
+                <property name="name">empty</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">true</property>
+                <child>
+                  <object class="GtkButton" id="duplicate">
+                    <property name="action-name">perspective.duplicate-configuration</property>
+                    <property name="tooltip-text" translatable="yes">Duplicate the configuration</property>
+                    <property name="visible">true</property>
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="icon-name">edit-copy-symbolic</property>
+                        <property name="visible">true</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkButton" id="delete">
+                    <property name="action-name">perspective.delete-configuration</property>
+                    <property name="tooltip-text" translatable="yes">Delete the configuration</property>
+                    <property name="visible">true</property>
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="icon-name">user-trash-symbolic</property>
+                        <property name="visible">true</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="name">controls</property>
+              </packing>
+            </child>
           </object>
         </child>
       </object>
diff --git a/plugins/build-tools/gbp-build-configuration-view.ui 
b/plugins/build-tools/gbp-build-configuration-view.ui
index c7f520a..8bed09e 100644
--- a/plugins/build-tools/gbp-build-configuration-view.ui
+++ b/plugins/build-tools/gbp-build-configuration-view.ui
@@ -120,54 +120,6 @@
       </object>
     </child>
     <child>
-      <object class="GtkFrame">
-        <property name="visible">true</property>
-        <child>
-          <object class="GtkListBox">
-            <property name="selection-mode">none</property>
-            <property name="visible">true</property>
-            <child>
-              <object class="GtkListBoxRow">
-                <property name="visible">true</property>
-                <child>
-                  <object class="GtkBox">
-                    <property name="spacing">12</property>
-                    <property name="orientation">horizontal</property>
-                    <property name="visible">true</property>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="action-name">perspective.duplicate-configuration</property>
-                        <property name="label" translatable="yes">Duplicate Configuration</property>
-                        <property name="valign">center</property>
-                        <property name="visible">true</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="hexpand">true</property>
-                        <property name="visible">true</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="action-name">perspective.delete-configuration</property>
-                        <property name="label" translatable="yes">Delete Configuration</property>
-                        <property name="valign">center</property>
-                        <property name="visible">true</property>
-                        <style>
-                          <class name="destructive-action"/>
-                        </style>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-      </object>
-    </child>
-    <child>
       <object class="GtkBox">
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
diff --git a/plugins/build-tools/gbp-build-perspective.c b/plugins/build-tools/gbp-build-perspective.c
index de38473..9f45d7f 100644
--- a/plugins/build-tools/gbp-build-perspective.c
+++ b/plugins/build-tools/gbp-build-perspective.c
@@ -18,6 +18,7 @@
 
 #include <glib/gi18n.h>
 
+#include "gbp-build-configuration-row.h"
 #include "gbp-build-configuration-view.h"
 #include "gbp-build-perspective.h"
 
@@ -53,63 +54,69 @@ map_pointer_to (GBinding     *binding,
                 GValue       *to_value,
                 gpointer      user_data)
 {
-  if (user_data == g_value_get_object (from_value))
-    g_value_set_static_string (to_value, "radio-checked-symbolic");
-  else
-    g_value_set_static_string (to_value, "radio-symbolic");
-
+  g_value_set_boolean (to_value, user_data == g_value_get_object (from_value));
   return TRUE;
 }
 
+static void
+select_first_row (GtkWidget *widget,
+                  gpointer   user_data)
+{
+  gboolean *selected = user_data;
+
+  g_assert (GBP_IS_BUILD_CONFIGURATION_ROW (widget));
+  g_assert (selected != NULL);
+
+  if (*selected == FALSE)
+    {
+      *selected = TRUE;
+      gtk_list_box_select_row (GTK_LIST_BOX (gtk_widget_get_parent (widget)),
+                               GTK_LIST_BOX_ROW (widget));
+    }
+}
+
+static gboolean
+update_selection_in_main (gpointer data)
+{
+  g_autoptr(GtkListBox) list_box = data;
+  gboolean selected = FALSE;
+
+  g_assert (GTK_IS_LIST_BOX (list_box));
+
+  if (!gtk_widget_in_destruction (GTK_WIDGET (list_box)))
+    {
+      if (NULL == gtk_list_box_get_selected_row (list_box))
+        {
+          gtk_container_foreach (GTK_CONTAINER (list_box),
+                                 select_first_row,
+                                 &selected);
+        }
+    }
+
+  return G_SOURCE_REMOVE;
+}
+
 static GtkWidget *
 create_configuration_row (gpointer item,
                           gpointer user_data)
 {
   IdeConfigurationManager *manager = user_data;
   IdeConfiguration *configuration = item;
-  GtkWidget *row;
-  GtkWidget *box;
-  GtkWidget *label;
-  GtkWidget *image;
+  GtkWidget *ret;
 
   g_assert (IDE_IS_CONFIGURATION (configuration));
   g_assert (IDE_IS_CONFIGURATION_MANAGER (manager));
 
-  row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
+  ret = g_object_new (GBP_TYPE_BUILD_CONFIGURATION_ROW,
+                      "configuration", configuration,
                       "visible", TRUE,
                       NULL);
-  g_object_set_data_full (G_OBJECT (row), "IDE_CONFIGURATION",
-                          g_object_ref (configuration), g_object_unref);
 
-  box = g_object_new (GTK_TYPE_BOX,
-                      "orientation", GTK_ORIENTATION_HORIZONTAL,
-                      "visible", TRUE,
-                      NULL);
-  gtk_container_add (GTK_CONTAINER (row), box);
-
-  image = g_object_new (GTK_TYPE_IMAGE,
-                        "icon-name", "radio-symbolic",
-                        "visible", TRUE,
-                        "xpad", 6,
-                        NULL);
-  g_object_bind_property_full (manager, "current", image, "icon-name",
+  g_object_bind_property_full (manager, "current", ret, "active",
                                G_BINDING_SYNC_CREATE,
                                map_pointer_to, NULL, configuration, NULL);
-  gtk_container_add (GTK_CONTAINER (box), image);
-
-  label = g_object_new (GTK_TYPE_LABEL,
-                        "hexpand", TRUE,
-                        "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
-                        "visible", TRUE,
-                        "xalign", 0.0f,
-                        NULL);
-  g_object_bind_property (configuration, "display-name",
-                          label, "label",
-                          G_BINDING_SYNC_CREATE);
-  gtk_container_add (GTK_CONTAINER (box), label);
 
-
-  return row;
+  return ret;
 }
 
 static void
@@ -125,40 +132,70 @@ gbp_build_perspective_set_configuration_manager (GbpBuildPerspective     *self,
                            create_configuration_row,
                            g_object_ref (manager),
                            g_object_unref);
+
+  update_selection_in_main (g_object_ref (self->list_box));
+}
+
+static void
+update_selected_state (GtkWidget *widget,
+                       gpointer   user_data)
+{
+  GbpBuildConfigurationRow *row = (GbpBuildConfigurationRow *)widget;
+  IdeConfiguration *selected = user_data;
+  IdeConfiguration *config;
+
+  g_assert (GBP_IS_BUILD_CONFIGURATION_ROW (row));
+  g_assert (IDE_IS_CONFIGURATION (selected));
+
+  config = gbp_build_configuration_row_get_configuration (row);
+
+  g_object_set (row,
+                "selected", (config == selected),
+                NULL);
 }
 
 static void
-gbp_build_perspective_row_selected (GbpBuildPerspective *self,
-                                    GtkListBoxRow       *row,
-                                    GtkListBox          *list_box)
+gbp_build_perspective_row_selected (GbpBuildPerspective      *self,
+                                    GbpBuildConfigurationRow *row,
+                                    GtkListBox               *list_box)
 {
   g_assert (GBP_IS_BUILD_PERSPECTIVE (self));
-  g_assert (!row || GTK_IS_LIST_BOX_ROW (row));
+  g_assert (!row || GBP_IS_BUILD_CONFIGURATION_ROW (row));
   g_assert (GTK_IS_LIST_BOX (list_box));
 
   if (row != NULL)
     {
       IdeConfiguration *configuration;
 
-      configuration = g_object_get_data (G_OBJECT (row), "IDE_CONFIGURATION");
+      configuration = gbp_build_configuration_row_get_configuration (row);
       g_set_object (&self->configuration, configuration);
       gbp_build_configuration_view_set_configuration (self->view, configuration);
+
+      gtk_container_foreach (GTK_CONTAINER (list_box),
+                             update_selected_state,
+                             configuration);
+    }
+  else
+    {
+      /* Possibly wait for a new row to be added (the new default config)
+       * and select it in the main loop.
+       */
+      g_timeout_add (0, update_selection_in_main, g_object_ref (list_box));
     }
 }
 
 static void
-gbp_build_perspective_row_activated (GbpBuildPerspective *self,
-                                     GtkListBoxRow       *row,
-                                     GtkListBox          *list_box)
+gbp_build_perspective_row_activated (GbpBuildPerspective      *self,
+                                     GbpBuildConfigurationRow *row,
+                                     GtkListBox               *list_box)
 {
   IdeConfiguration *configuration;
 
   g_assert (GBP_IS_BUILD_PERSPECTIVE (self));
-  g_assert (GTK_IS_LIST_BOX_ROW (row));
+  g_assert (GBP_IS_BUILD_CONFIGURATION_ROW (row));
   g_assert (GTK_IS_LIST_BOX (list_box));
 
-
-  configuration = g_object_get_data (G_OBJECT (row), "IDE_CONFIGURATION");
+  configuration = gbp_build_configuration_row_get_configuration (row);
   ide_configuration_manager_set_current (self->configuration_manager, configuration);
 }
 
diff --git a/plugins/build-tools/gbp-build-perspective.ui b/plugins/build-tools/gbp-build-perspective.ui
index 420fe61..6cba460 100644
--- a/plugins/build-tools/gbp-build-perspective.ui
+++ b/plugins/build-tools/gbp-build-perspective.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <!-- interface-requires gtk+ 3.18 -->
+  <!-- interface-requires gtk+ 3.21 -->
   <template class="GbpBuildPerspective" parent="GtkBin">
     <child>
       <object class="GtkBox">
@@ -13,9 +13,9 @@
             <property name="visible">true</property>
             <child>
               <object class="GtkListBox" id="list_box">
-                <property name="selection-mode">browse</property>
+                <property name="selection-mode">single</property>
                 <property name="activate-on-single-click">false</property>
-                <property name="width-request">200</property>
+                <property name="width-request">300</property>
                 <property name="visible">true</property>
                 <style>
                   <class name="sidebar"/>


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