[gnome-notes] Implement adaptive sidebar design



commit 8af6f39a99f0ad58b67319c67db0d09f413f42aa
Author: Jonathan Kang <jonathankang gnome org>
Date:   Tue Aug 18 16:33:07 2020 +0800

    Implement adaptive sidebar design
    
    Removed BjbSelectionToolbar, BjbMainToolbar and BjbMainView classes which
    are not needed in the new design.
    
    https://gitlab.gnome.org/GNOME/gnome-notes/-/issues/154

 data/bjb.gresource.xml                             |   3 +-
 .../{main-toolbar.ui => bjb-window-base.ui}        | 312 +++++----
 src/bjb-application.c                              |   1 +
 src/bjb-controller.c                               |   1 -
 src/bjb-main-toolbar.c                             | 745 ---------------------
 src/bjb-main-toolbar.h                             |  39 --
 src/bjb-main-view.c                                | 482 -------------
 src/bjb-main-view.h                                |  63 --
 src/bjb-note-view.c                                |   1 -
 src/bjb-search-toolbar.c                           | 122 +---
 src/bjb-search-toolbar.h                           |  12 +-
 src/bjb-selection-toolbar.c                        | 426 ------------
 src/bjb-selection-toolbar.h                        |  33 -
 src/bjb-window-base.c                              | 378 +++++++----
 src/meson.build                                    |   3 -
 15 files changed, 457 insertions(+), 2164 deletions(-)
---
diff --git a/data/bjb.gresource.xml b/data/bjb.gresource.xml
index d5ac291..6568b8b 100644
--- a/data/bjb.gresource.xml
+++ b/data/bjb.gresource.xml
@@ -14,13 +14,12 @@
   </gresource>
     
   <gresource prefix="/org/gnome/Notes/ui">
+    <file alias="bjb-window-base.ui"   preprocess="xml-stripblanks">resources/bjb-window-base.ui</file>
     <file alias="empty-results-box.ui" preprocess="xml-stripblanks">resources/empty-results-box.ui</file>
     <file alias="import-dialog.ui"     preprocess="xml-stripblanks">resources/import-dialog.ui</file>
     <file alias="list-view.ui"         preprocess="xml-stripblanks">resources/list-view.ui</file>
     <file alias="list-view-row.ui"     preprocess="xml-stripblanks">resources/list-view-row.ui</file>
-    <file alias="main-toolbar.ui"      preprocess="xml-stripblanks">resources/main-toolbar.ui</file>
     <file alias="organize-dialog.ui"   preprocess="xml-stripblanks">resources/organize-dialog.ui</file>
-    <file alias="selection-toolbar.ui" preprocess="xml-stripblanks">resources/selection-toolbar.ui</file>
     <file alias="settings-dialog.ui"   preprocess="xml-stripblanks">resources/settings-dialog.ui</file>
   </gresource>
 </gresources>
diff --git a/data/resources/main-toolbar.ui b/data/resources/bjb-window-base.ui
similarity index 53%
rename from data/resources/main-toolbar.ui
rename to data/resources/bjb-window-base.ui
index 6728e51..0979ae2 100644
--- a/data/resources/main-toolbar.ui
+++ b/data/resources/bjb-window-base.ui
@@ -1,167 +1,168 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <template class="BjbMainToolbar" parent="GtkHeaderBar">
-    <property name="visible">1</property>
-    <property name="show-close-button">1</property>
-
+  <template class="BjbWindowBase" parent="GtkApplicationWindow">
+    <property name="can_focus">False</property>
     <child>
-      <object class="GtkStack" id="button_stack">
-        <property name="visible">true</property>
-
-        <child>
-          <object class="GtkButton" id="new_button">
-            <property name="visible">1</property>
-            <property name="label" translatable="yes">_New</property>
-            <property name="use-underline">1</property>
-            <signal name="clicked" handler="on_new_note_clicked" swapped="yes"/>
-          </object>
-        </child>
-
+      <object class="HdyLeaflet" id="main_leaflet">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="mode-transition-type">slide</property>
+        <property name="child-transition-type">slide</property>
         <child>
-          <object class="GtkButton" id="back_button">
-            <property name="visible">1</property>
-            <signal name="clicked" handler="on_back_button_clicked" swapped="yes"/>
-            <style>
-             <class name="image-button"/>
-            </style>
+          <object class="GtkBox" id="sidebar_box">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="hexpand">False</property>
+            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkImage">
-                <property name="visible">1</property>
-                <property name="icon-name">go-previous-symbolic</property>
-                <property name="icon-size">1</property>
+              <object class="BjbSearchToolbar" id="search_bar">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="search-mode-enabled">True</property>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="vexpand">True</property>
+                <property name="width-request">300</property>
+                <property name="hscrollbar_policy">never</property>
+                <style>
+                  <class name="view" />
+                </style>
+                <child>
+                  <object class="BjbListView" id="note_list">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
             </child>
           </object>
         </child>
-
-      </object>
-    </child> <!-- /GtkStack button_stack -->
-
-    <child>
-      <object class="BjbColorButton" id="color_button">
-        <property name="visible">1</property>
-        <property name="tooltip-text" translatable="yes">Note color</property>
-        <signal name="color-set" handler="on_color_button_clicked" swapped="yes"/>
-      </object>
-      <packing>
-        <property name="position">4</property>
-        <property name="pack-type">end</property>
-      </packing>
-    </child>
-
-    <child>
-      <object class="GtkButton" id="empty_button">
-        <property name="visible">1</property>
-        <property name="label" translatable="yes" comments="Translators: “Empty” is a 
verb.">_Empty</property>
-        <property name="use-underline">1</property>
-        <!-- <property name="sensitive" bind-source="select_button" bind-property="sensitive" 
bind-flags="default"/> -->
-        <signal name="clicked" handler="on_empty_clicked_callback" swapped="yes"/>
-        <style>
-         <class name="destructive-action"/>
-        </style>
-      </object>
-      <packing>
-        <property name="position">3</property>
-        <property name="pack-type">end</property>
-      </packing>
-    </child>
-
-    <child>
-      <object class="GtkButton" id="cancel_button">
-        <property name="visible">1</property>
-        <property name="label" translatable="yes">_Cancel</property>
-        <property name="use-underline">1</property>
-        <property name="tooltip-text" translatable="yes">Exit selection mode</property>
-        <signal name="clicked" handler="on_selection_mode_clicked" swapped="yes"/>
-      </object>
-      <packing>
-        <property name="position">1</property>
-        <property name="pack-type">end</property>
-      </packing>
-    </child>
-
-    <child>
-      <object class="GtkToggleButton" id="search_button">
-        <property name="visible">1</property>
-        <style>
-         <class name="image-button"/>
-        </style>
-        <child>
-          <object class="GtkImage">
-            <property name="visible">1</property>
-            <property name="icon-name">edit-find-symbolic</property>
-            <property name="icon-size">1</property>
-            <property name="tooltip-text" translatable="yes">Search note titles, content and 
notebooks</property>
-          </object>
-        </child>
-      </object>
-      <packing>
-        <property name="position">2</property>
-        <property name="pack-type">end</property>
-      </packing>
-    </child>
-
-    <child>
-      <object class="GtkButton" id="select_button">
-        <property name="visible">1</property>
-        <signal name="clicked" handler="on_selection_mode_clicked" swapped="yes"/>
-        <style>
-         <class name="image-button"/>
-        </style>
         <child>
-          <object class="GtkImage">
-            <property name="visible">1</property>
-            <property name="icon-name">object-select-symbolic</property>
-            <property name="icon-size">1</property>
-            <property name="tooltip-text" translatable="yes">Selection mode</property>
+          <object class="GtkSeparator" id="main_leaflet_separator">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <style>
+              <class name="sidebar"/>
+            </style>
           </object>
         </child>
-      </object>
-      <packing>
-        <property name="position">1</property>
-        <property name="pack-type">end</property>
-      </packing>
-    </child>
-
-    <child>
-      <object class="GtkMenuButton" id="main_button">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="tooltip-text" translatable="yes">Open menu</property>
-        <property name="popover">main_menu</property>
-        <property name="receives_default">True</property>
         <child>
-          <object class="GtkImage" id="main_button_image">
+          <object class="GtkBox" id="note_box">
             <property name="visible">True</property>
-            <property name="icon_name">open-menu-symbolic</property>
+            <property name="can_focus">False</property>
+            <property name="expand">True</property>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="position">0</property>
-        <property name="pack-type">end</property>
-      </packing>
     </child>
-
-    <child>
-      <object class="GtkMenuButton" id="menu_button">
+    <child type="titlebar">
+      <object class="HdyTitleBar">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="tooltip-text" translatable="yes">More options</property>
-        <property name="popover">menu</property>
         <child>
-          <object class="GtkImage">
-            <property name="visible">1</property>
-            <property name="icon-name">view-more-symbolic</property>
+          <object class="HdyLeaflet" id="header_box">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">horizontal</property>
+            <property name="mode-transition-type" bind-source="main_leaflet" 
bind-property="mode-transition-type" bind-flags="bidirectional|sync-create"/>
+            <property name="mode-transition-duration" bind-source="main_leaflet" 
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+            <property name="child-transition-type" bind-source="main_leaflet" 
bind-property="child-transition-type" bind-flags="bidirectional|sync-create"/>
+            <property name="child-transition-duration" bind-source="main_leaflet" 
bind-property="child-transition-duration" bind-flags="bidirectional|sync-create"/>
+            <signal name="notify::visible-child" handler="notify_header_visible_child_cb" swapped="yes"/>
+            <signal name="notify::fold" handler="notify_fold_cb" object="BjbWindowBase" after="yes" 
swapped="yes"/>
+            <child>
+              <object class="GtkHeaderBar" id="headerbar">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="title" translatable="yes">All Notes</property>
+                <child>
+                  <object class="GtkButton" id="new_button">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_New</property>
+                    <property name="use-underline">True</property>
+                    <signal name="clicked" handler="on_new_note_clicked" swapped="yes"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuButton" id="main_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="tooltip-text" translatable="yes">Open menu</property>
+                    <property name="popover">main_menu</property>
+                    <property name="receives_default">True</property>
+                    <child>
+                      <object class="GtkImage" id="main_button_image">
+                        <property name="visible">True</property>
+                        <property name="icon_name">open-menu-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="pack-type">end</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkSeparator" id="headerbar_separator">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
+                <style>
+                  <class name="sidebar"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkHeaderBar" id="note_headerbar">
+                <property name="visible">True</property>
+                <property name="hexpand">True</property>
+                <property name="show-close-button">True</property>
+                <child>
+                  <object class="GtkRevealer" id="back_revealer">
+                    <property name="can_focus">False</property>
+                    <property name="transition-type">crossfade</property>
+                    <property name="transition-duration" bind-source="main_leaflet" 
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+                    <child>
+                      <object class="GtkMenuButton" id="menu_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="tooltip-text" translatable="yes">More options</property>
+                        <property name="popover">menu</property>
+                        <child>
+                          <object class="GtkImage">
+                            <property name="visible">1</property>
+                            <property name="icon-name">view-more-symbolic</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                        <property name="pack-type">end</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
           </object>
         </child>
       </object>
-      <packing>
-        <property name="position">0</property>
-        <property name="pack-type">end</property>
-      </packing>
     </child>
-
   </template>
 
   <object class="GtkPopoverMenu" id="main_menu">
@@ -387,6 +388,13 @@
     </child>
   </object>
 
+  <object class="HdyHeaderGroup" id="header_group">
+    <headerbars>
+      <headerbar name="headerbar"/>
+      <headerbar name="note_headerbar"/>
+    </headerbars>
+  </object>
+
   <object class="GtkEntry" id="title_entry">
     <property name="visible">True</property>
     <property name="can_focus">True</property>
@@ -394,5 +402,27 @@
     <signal name="changed" handler="on_title_changed" swapped="yes"/>
   </object>
 
-</interface>
+  <object class="GtkSizeGroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="headerbar" />
+      <widget name="sidebar_box" />
+    </widgets>
+  </object>
 
+  <object class="GtkSizeGroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="headerbar_separator" />
+      <widget name="main_leaflet_separator" />
+    </widgets>
+  </object>
+
+  <object class="GtkSizeGroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="note_headerbar" />
+      <widget name="note_box" />
+    </widgets>
+  </object>
+</interface>
diff --git a/src/bjb-application.c b/src/bjb-application.c
index 0c97b3b..a502f4f 100644
--- a/src/bjb-application.c
+++ b/src/bjb-application.c
@@ -28,6 +28,7 @@
 
 #include "bjb-application.h"
 #include "bjb-settings.h"
+#include "bjb-note-view.h"
 #include "bjb-window-base.h"
 #include "bjb-import-dialog.h"
 #include "bjb-log.h"
diff --git a/src/bjb-controller.c b/src/bjb-controller.c
index e02a485..b89d53b 100644
--- a/src/bjb-controller.c
+++ b/src/bjb-controller.c
@@ -25,7 +25,6 @@
 
 #include "bjb-application.h"
 #include "bjb-controller.h"
-#include "bjb-main-view.h"
 #include "bjb-window-base.h"
 
 /*
diff --git a/src/bjb-note-view.c b/src/bjb-note-view.c
index 732170c..f8b1230 100644
--- a/src/bjb-note-view.c
+++ b/src/bjb-note-view.c
@@ -22,7 +22,6 @@
 
 #include "bjb-application.h"
 #include "bjb-editor-toolbar.h"
-#include "bjb-main-view.h"
 #include "bjb-note-view.h"
 #include "bjb-window-base.h"
 
diff --git a/src/bjb-search-toolbar.c b/src/bjb-search-toolbar.c
index 9c92368..acfd016 100644
--- a/src/bjb-search-toolbar.c
+++ b/src/bjb-search-toolbar.c
@@ -30,29 +30,17 @@
 #include <gtk/gtk.h>
 
 #include "bjb-controller.h"
-#include "bjb-main-toolbar.h"
-#include "bjb-main-view.h"
 #include "bjb-search-toolbar.h"
 #include "bjb-window-base.h"
 
-enum
-{
-  PROP_0,
-  PROP_WINDOW,
-  PROP_CONTROLLER,
-  NUM_PROPERTIES
-};
-
-static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
-
 struct _BjbSearchToolbar
 {
   HdySearchBar    parent_instance;
 
-  GtkEntry      *entry;
-  gchar         *needle;
-  BjbController *controller;
-  BjbWindowBase *window;
+  GtkEntry        *entry;
+  gchar           *needle;
+  BjbController   *controller;
+  GtkWidget       *window;
 };
 
 G_DEFINE_TYPE (BjbSearchToolbar, bjb_search_toolbar, HDY_TYPE_SEARCH_BAR)
@@ -75,55 +63,46 @@ on_search_changed_cb (BjbSearchToolbar *self)
 }
 
 static void
-bjb_search_toolbar_get_property (GObject    *object,
-                                 guint       property_id,
-                                 GValue     *value,
-                                 GParamSpec *pspec)
+action_entry_text_change_callback (GtkEntry         *entry,
+                                   BjbSearchToolbar *self)
 {
-  BjbSearchToolbar *self = BJB_SEARCH_TOOLBAR (object);
-
-  switch (property_id)
-  {
-    case PROP_WINDOW:
-      g_value_set_object (value, self->window);
-      break;
-    case PROP_CONTROLLER:
-      g_value_set_object(value, self->controller);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
+  bjb_controller_set_needle (BJB_CONTROLLER (self->controller),
+                             gtk_entry_get_text (entry));
 }
 
-static void
-bjb_search_toolbar_set_property (GObject      *object,
-                                 guint         property_id,
-                                 const GValue *value,
-                                 GParamSpec   *pspec)
+void
+bjb_search_toolbar_disconnect (BjbSearchToolbar *self)
 {
-  BjbSearchToolbar *self = BJB_SEARCH_TOOLBAR (object);
+  if (self->key_pressed)
+    g_signal_handler_disconnect (self->window, self->key_pressed);
+  if (self->text_id)
+    g_signal_handler_disconnect (self->entry, self->text_id);
 
-  switch (property_id)
-  {
-    case PROP_WINDOW:
-      self->window = g_value_get_object (value);
-      break;
-    case PROP_CONTROLLER:
-      self->controller = g_value_get_object (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
+  self->key_pressed = 0;
+  self->text_id = 0;
 }
 
-static void
-bjb_search_toolbar_constructed (GObject *obj)
+void
+bjb_search_toolbar_connect (BjbSearchToolbar *self)
 {
-  BjbSearchToolbar *self = BJB_SEARCH_TOOLBAR (obj);
+  /* Connect to set the text */
+  if (self->key_pressed == 0)
+    self->key_pressed = g_signal_connect(self->window,"key-press-event",
+                                         G_CALLBACK(on_key_pressed), self);
 
-  G_OBJECT_CLASS (bjb_search_toolbar_parent_class)->constructed (obj);
+
+  if (self->text_id == 0)
+    self->text_id = g_signal_connect (self->entry, "search-changed",
+                        G_CALLBACK (action_entry_text_change_callback), self);
+}
+
+void
+bjb_search_toolbar_setup (BjbSearchToolbar *self,
+                          GtkWidget        *window,
+                          BjbController    *controller)
+{
+  self->controller = controller;
+  self->window = window;
 
   self->needle = bjb_controller_get_needle (self->controller);
   if (self->needle && g_strcmp0 (self->needle, "") != 0)
@@ -156,38 +135,11 @@ bjb_search_toolbar_init (BjbSearchToolbar *self)
 static void
 bjb_search_toolbar_class_init (BjbSearchToolbarClass *class)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  object_class->get_property = bjb_search_toolbar_get_property;
-  object_class->set_property = bjb_search_toolbar_set_property;
-  object_class->constructed = bjb_search_toolbar_constructed;
-
-  properties[PROP_WINDOW] = g_param_spec_object ("window",
-                                                 "Window",
-                                                 "Window",
-                                                 GTK_TYPE_WIDGET,
-                                                 G_PARAM_READWRITE |
-                                                 G_PARAM_CONSTRUCT |
-                                                 G_PARAM_STATIC_STRINGS);
-
-  properties[PROP_CONTROLLER] = g_param_spec_object ("controller",
-                                                     "Controller",
-                                                     "Controller",
-                                                     BJB_TYPE_CONTROLLER,
-                                                     G_PARAM_READWRITE |
-                                                     G_PARAM_CONSTRUCT |
-                                                     G_PARAM_STATIC_STRINGS);
-
-  g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
 }
 
 BjbSearchToolbar *
-bjb_search_toolbar_new (BjbWindowBase *window,
-                        BjbController *controller)
+bjb_search_toolbar_new (void)
 {
-  return g_object_new (BJB_TYPE_SEARCH_TOOLBAR,
-                       "window",     window,
-                       "controller", controller,
-                       NULL);
+  return g_object_new (BJB_TYPE_SEARCH_TOOLBAR, NULL);
 }
 
diff --git a/src/bjb-search-toolbar.h b/src/bjb-search-toolbar.h
index ad682fa..bb887b7 100644
--- a/src/bjb-search-toolbar.h
+++ b/src/bjb-search-toolbar.h
@@ -22,7 +22,6 @@
 #include <handy.h>
 
 #include "bjb-controller.h"
-#include "bjb-window-base.h"
 
 G_BEGIN_DECLS
 
@@ -30,8 +29,15 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (BjbSearchToolbar, bjb_search_toolbar, BJB, SEARCH_TOOLBAR, HdySearchBar)
 
-BjbSearchToolbar *bjb_search_toolbar_new (BjbWindowBase *window,
-                                          BjbController *controller);
+BjbSearchToolbar  *bjb_search_toolbar_new                   (void);
+
+void               bjb_search_toolbar_disconnect            (BjbSearchToolbar *self);
+
+void               bjb_search_toolbar_connect               (BjbSearchToolbar *self);
+
+void               bjb_search_toolbar_setup                 (BjbSearchToolbar *self,
+                                                             GtkWidget        *window,
+                                                             BjbController    *controller);
 
 G_END_DECLS
 
diff --git a/src/bjb-window-base.c b/src/bjb-window-base.c
index d56a38f..20d4216 100644
--- a/src/bjb-window-base.c
+++ b/src/bjb-window-base.c
@@ -8,10 +8,11 @@
 #include "bjb-application.h"
 #include "bjb-empty-results-box.h"
 #include "bjb-window-base.h"
-#include "bjb-main-toolbar.h"
-#include "bjb-main-view.h"
+#include "bjb-list-view.h"
+#include "bjb-list-view-row.h"
 #include "bjb-note-view.h"
 #include "bjb-organize-dialog.h"
+#include "bjb-search-toolbar.h"
 #include "bjb-share.h"
 
 #define BIJIBEN_MAIN_WIN_TITLE N_("Notes")
@@ -44,14 +45,8 @@ struct _BjbWindowBase
   gchar                *entry; // FIXME, remove this
 
 
-  GtkWidget            *vbox;
-  BjbMainToolbar       *main_toolbar;
-  BjbSearchToolbar     *search_bar;
-
-
   GtkStack             *stack;
   BjbWindowViewType     current_view;
-  BjbMainView          *view;
   BjbNoteView          *note_view;
   GtkWidget            *spinner;
   GtkWidget            *no_note;
@@ -66,11 +61,119 @@ struct _BjbWindowBase
   gint                  pos_x;
   gint                  pos_y;
   gboolean              is_maximized;
+
+  HdyLeaflet           *header_box;
+  HdyHeaderGroup       *header_group;
+  GtkRevealer          *back_revealer;
+  GtkWidget            *note_box;
+  GtkWidget            *note_headerbar;
+  GtkWidget            *note_list;
+  GtkWidget            *search_bar;
+  GtkWidget            *title_entry;
 };
 
 /* Gobject */
 G_DEFINE_TYPE (BjbWindowBase, bjb_window_base, GTK_TYPE_APPLICATION_WINDOW)
 
+static void
+update_fold_state (BjbWindowBase *self)
+{
+  GtkWidget *header_child;
+  HdyFold fold;
+
+  header_child = hdy_leaflet_get_visible_child (self->header_box);
+  fold = hdy_leaflet_get_fold (self->header_box);
+
+  hdy_header_group_set_focus (self->header_group, fold == HDY_FOLD_FOLDED ? GTK_HEADER_BAR(header_child) : 
NULL);
+
+  gtk_widget_set_visible (GTK_WIDGET(self->back_revealer), fold == HDY_FOLD_FOLDED);
+  gtk_revealer_set_reveal_child (self->back_revealer, fold == HDY_FOLD_FOLDED);
+}
+
+static void
+notify_header_visible_child_cb (BjbWindowBase *self)
+{
+  update_fold_state (self);
+}
+
+static void
+notify_fold_cb (BjbWindowBase *self)
+{
+  update_fold_state (self);
+}
+
+static void
+on_note_renamed (BijiItem      *note,
+                 BjbWindowBase *self)
+{
+  const char *str;
+
+  str = biji_item_get_title (note);
+  if (str == NULL || strlen(str) == 0)
+    str = _("Untitled");
+  gtk_entry_set_text (GTK_ENTRY (self->title_entry), str);
+  gtk_header_bar_set_custom_title (GTK_HEADER_BAR (self->note_headerbar),
+                                   self->title_entry);
+}
+
+static void
+on_note_list_row_activated (GtkListBox    *box,
+                            GtkListBoxRow *row,
+                            gpointer       user_data)
+{
+  const char *note_uuid;
+  BijiItem *to_open;
+  BijiManager *manager;
+  BjbWindowBase *self = BJB_WINDOW_BASE (user_data);
+
+  manager = bjb_window_base_get_manager (GTK_WIDGET (self));
+  note_uuid = bjb_list_view_row_get_uuid (BJB_LIST_VIEW_ROW (row));
+  to_open = biji_manager_get_item_at_path (manager, note_uuid);
+
+  if (to_open && BIJI_IS_NOTE_OBJ (to_open))
+    {
+      /* Only open the note if it's not already opened. */
+      if (!biji_note_obj_is_opened (BIJI_NOTE_OBJ (to_open)))
+        {
+          bjb_window_base_switch_to_item (self, to_open);
+          on_note_renamed (to_open, self);
+        }
+    }
+  else if (to_open && BIJI_IS_NOTEBOOK (to_open))
+    {
+      bjb_controller_set_notebook (self->controller, BIJI_NOTEBOOK (to_open));
+    }
+}
+
+static void
+on_new_note_clicked (BjbWindowBase *self)
+{
+  BijiNoteObj *result;
+  BijiManager *manager;
+
+  g_assert (BJB_IS_WINDOW_BASE (self));
+
+  /* append note to notebook */
+  manager = bjb_window_base_get_manager (GTK_WIDGET (self));
+  result = biji_manager_note_new (manager,
+                                  NULL,
+                                  bjb_settings_get_default_location (self->settings));
+
+  /* Go to that note */
+  bjb_window_base_switch_to_item (self, BIJI_ITEM (result));
+  on_note_renamed (BIJI_ITEM (result), self);
+}
+
+static void
+on_title_changed (BjbWindowBase *self,
+                  GtkEntry      *title)
+{
+  const char *str = gtk_entry_get_text (title);
+
+  if (strlen (str) > 0)
+    biji_note_obj_set_title (self->note, str);
+}
+
 static void
 bjb_window_base_finalize (GObject *object)
 {
@@ -130,28 +233,65 @@ on_key_pressed_cb (BjbWindowBase *self, GdkEvent *event)
   GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask ();
 
   if ((event->key.state & modifiers) == GDK_MOD1_MASK &&
-      event->key.keyval == GDK_KEY_Left)
-    {
-      bjb_window_base_go_back (self);
-      return TRUE;
-    }
-  else if ((event->key.state & modifiers) != GDK_CONTROL_MASK &&
-           event->key.keyval == GDK_KEY_F1)
-    {
-      bjb_app_help (BJB_APPLICATION (app));
-      return TRUE;
-    }
-  else if ((event->key.state & modifiers) != GDK_CONTROL_MASK &&
-           event->key.keyval == GDK_KEY_F10)
-    {
-      bjb_main_toolbar_open_menu (self->main_toolbar);
-      return TRUE;
-    }
-  else if ((event->key.state & modifiers) == GDK_CONTROL_MASK &&
-           event->key.keyval == GDK_KEY_q)
-    {
-      g_application_quit (app);
+      event->key.keyval == GDK_KEY_Left &&
+      (self->current_view == BJB_WINDOW_BASE_MAIN_VIEW ||
+       self->current_view == BJB_WINDOW_BASE_ARCHIVE_VIEW ||
+       self->current_view == BJB_WINDOW_BASE_NOTE_VIEW))
+  {
+    BijiItemsGroup items;
+
+    items = bjb_controller_get_group (self->controller);
+
+    /* Back to main view from trash bin */
+    if (items == BIJI_ARCHIVED_ITEMS)
+      bjb_controller_set_group (self->controller, BIJI_LIVING_ITEMS);
+    /* Back to main view */
+    else
+      bjb_controller_set_notebook (self->controller, NULL);
+
+    return TRUE;
+  }
+
+  switch (event->key.keyval)
+  {
+    case GDK_KEY_F1:
+      if ((event->key.state & modifiers) != GDK_CONTROL_MASK)
+        {
+          bjb_app_help (BJB_APPLICATION (app));
+          return TRUE;
+        }
+      break;
+
+    case GDK_KEY_F10:
+      if ((event->key.state & modifiers) != GDK_CONTROL_MASK)
+        {
+          /* FIXME: Port this to BjbWindowBase. */
+          /* bjb_main_toolbar_open_menu (self->main_toolbar); */
+          return TRUE;
+        }
+      break;
+
+    case GDK_KEY_F2:
+    case GDK_KEY_F3:
+    case GDK_KEY_F4:
+    case GDK_KEY_F5:
+    case GDK_KEY_F6:
+    case GDK_KEY_F7:
+    case GDK_KEY_F8:
+    case GDK_KEY_F9:
+    case GDK_KEY_F11:
       return TRUE;
+
+    case GDK_KEY_q:
+      if ((event->key.state & modifiers) == GDK_CONTROL_MASK)
+        {
+          g_application_quit (app);
+          return TRUE;
+        }
+      break;
+
+    default:
+      ;
     }
 
   return FALSE;
@@ -334,7 +474,10 @@ static GActionEntry win_entries[] = {
 static void
 bjb_window_base_constructed (GObject *obj)
 {
+  BjbListView *listview;
+  BjbSearchToolbar *search_bar;
   BjbWindowBase *self = BJB_WINDOW_BASE (obj);
+  GtkListBox *list_box;
 
   G_OBJECT_CLASS (bjb_window_base_parent_class)->constructed (obj);
 
@@ -364,30 +507,33 @@ bjb_window_base_constructed (GObject *obj)
      GTK_WINDOW (obj),
      self->entry );
 
-  /* Search entry toolbar */
-  self->search_bar = bjb_search_toolbar_new (self, self->controller);
-  gtk_box_pack_start (GTK_BOX (self->vbox), GTK_WIDGET (self->search_bar), FALSE, FALSE, 0);
+  listview = BJB_LIST_VIEW (self->note_list);
+  bjb_list_view_setup (listview, self->controller);
 
-  /* Shared toolbar */
-  self->view = bjb_main_view_new (GTK_WIDGET (obj), self->controller);
-  self->main_toolbar = bjb_main_toolbar_new (self->view, self->controller);
-  gtk_window_set_titlebar (GTK_WINDOW (self), GTK_WIDGET (self->main_toolbar));
+  list_box = bjb_list_view_get_list_box (listview);
+  g_signal_connect (list_box, "row-activated",
+                    G_CALLBACK (on_note_list_row_activated), self);
 
+  /* Search entry toolbar */
+  search_bar = BJB_SEARCH_TOOLBAR (self->search_bar);
+  bjb_search_toolbar_setup (search_bar, GTK_WIDGET(obj), self->controller);
+
+  /* TODO: A stack in sidebar. */
   /* UI : stack for different views */
-  self->stack = GTK_STACK (gtk_stack_new ());
-  gtk_box_pack_start (GTK_BOX (self->vbox), GTK_WIDGET (self->stack), TRUE, TRUE, 0);
+  /* self->stack = GTK_STACK (gtk_stack_new ()); */
+  /* gtk_box_pack_start (GTK_BOX (self->vbox), GTK_WIDGET (self->stack), TRUE, TRUE, 0); */
 
-  self->spinner = gtk_spinner_new ();
-  gtk_stack_add_named (self->stack, self->spinner, "spinner");
-  gtk_stack_set_visible_child_name (self->stack, "spinner");
-  gtk_widget_show (self->spinner);
-  gtk_spinner_start (GTK_SPINNER (self->spinner));
+  /* self->spinner = gtk_spinner_new (); */
+  /* gtk_stack_add_named (self->stack, self->spinner, "spinner"); */
+  /* gtk_stack_set_visible_child_name (self->stack, "spinner"); */
+  /* gtk_widget_show (self->spinner); */
+  /* gtk_spinner_start (GTK_SPINNER (self->spinner)); */
 
-  self->no_note = bjb_empty_results_box_new ();
-  gtk_stack_add_named (self->stack, self->no_note, "empty");
+  /* self->no_note = bjb_empty_results_box_new (); */
+  /* gtk_stack_add_named (self->stack, self->no_note, "empty"); */
 
-  gtk_stack_add_named (self->stack, GTK_WIDGET (self->view), "main-view");
-  gtk_widget_show (GTK_WIDGET (self->stack));
+  /* gtk_stack_add_named (self->stack, GTK_WIDGET (self->view), "main-view"); */
+  /* gtk_widget_show (GTK_WIDGET (self->stack)); */
 
 
   /* Connection to window signals */
@@ -399,42 +545,25 @@ bjb_window_base_constructed (GObject *obj)
 
   /* Keys */
 
-  g_signal_connect_swapped (GTK_WIDGET (self),
-                            "key-press-event",
-                            G_CALLBACK(on_key_pressed_cb),
-                            self);
+  g_signal_connect (GTK_WIDGET (self),
+                    "key-press-event",
+                    G_CALLBACK(on_key_pressed_cb),
+                    self);
 
   /* If a note is requested at creation, show it
    * This is a specific type of window not associated with any view */
-  if (self->note == NULL)
-  {
-    bjb_window_base_switch_to (self, BJB_WINDOW_BASE_MAIN_VIEW);
-  }
-
-  else
+  if (self->note != NULL)
   {
     self->detached = TRUE;
     bjb_window_base_switch_to_item (self, BIJI_ITEM (self->note));
   }
-
-
-  /* For some reason, do not gtk_widget_show _self_
-   * or gtk_application_get_menu_bar will run,
-   * fire a warning, while app menu will not show up
-   * you have been warned!
-   *
-   * This is probably due to the fact that,
-   * at startup, we still are
-   * inside... drums... gapplication startup () */
-  gtk_widget_show (self->vbox);
 }
 
 
 static void
 bjb_window_base_init (BjbWindowBase *self)
 {
-  self->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-  gtk_container_add (GTK_CONTAINER (self), self->vbox);
+  gtk_widget_init_template (GTK_WIDGET (self));
 }
 
 static void
@@ -481,6 +610,19 @@ bjb_window_base_class_init (BjbWindowBaseClass *klass)
 
   g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
 
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Notes/ui/bjb-window-base.ui");
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, header_box);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, header_group);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, back_revealer);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, note_box);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, note_headerbar);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, note_list);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, search_bar);
+  gtk_widget_class_bind_template_child (widget_class, BjbWindowBase, title_entry);
+  gtk_widget_class_bind_template_callback(widget_class, notify_header_visible_child_cb);
+  gtk_widget_class_bind_template_callback(widget_class, notify_fold_cb);
+  gtk_widget_class_bind_template_callback(widget_class, on_new_note_clicked);
+  gtk_widget_class_bind_template_callback(widget_class, on_title_changed);
 }
 
 
@@ -521,39 +663,6 @@ destroy_note_if_needed (BjbWindowBase *self)
   self->note_view = NULL;
 }
 
-void
-bjb_window_base_go_back (BjbWindowBase *self)
-{
-  BijiNoteObj *note = bjb_window_base_get_note (self);
-  BijiItemsGroup group = bjb_controller_get_group (self->controller);
-
-  if (!(group == BIJI_ARCHIVED_ITEMS ||
-        bjb_controller_get_notebook (self->controller) != NULL ||
-        self->current_view == BJB_WINDOW_BASE_NOTE_VIEW))
-    return;
-
-  if (bjb_window_base_is_detached (self))
-    {
-      gtk_widget_destroy (GTK_WIDGET (self));
-      return;
-    }
-
-  if (self->note)
-    {
-      if (biji_note_obj_is_trashed (note))
-        bjb_window_base_switch_to (self, BJB_WINDOW_BASE_ARCHIVE_VIEW);
-      else
-        bjb_window_base_switch_to (self, BJB_WINDOW_BASE_MAIN_VIEW);
-      bjb_main_view_update_model (self->view);
-      return;
-    }
-
-  if (group == BIJI_ARCHIVED_ITEMS)
-    bjb_controller_set_group (self->controller, BIJI_LIVING_ITEMS);
-  else
-    bjb_controller_set_notebook (self->controller, NULL);
-}
-
 void
 bjb_window_base_switch_to (BjbWindowBase *self, BjbWindowViewType type)
 {
@@ -571,50 +680,52 @@ bjb_window_base_switch_to (BjbWindowBase *self, BjbWindowViewType type)
      */
 
     case BJB_WINDOW_BASE_MAIN_VIEW:
-      gtk_widget_show (GTK_WIDGET (self->search_bar));
-      gtk_stack_set_visible_child_name (self->stack, "main-view");
+      /* bjb_search_toolbar_connect (BJB_SEARCH_TOOLBAR (self->search_bar)); */
+      /* gtk_widget_show (GTK_WIDGET (self->search_bar)); */
+      /* gtk_stack_set_visible_child_name (self->stack, "main-view"); */
       break;
 
    case BJB_WINDOW_BASE_ARCHIVE_VIEW:
-      gtk_widget_show (GTK_WIDGET (self->search_bar));
-      gtk_stack_set_visible_child_name (self->stack, "main-view");
+      /* bjb_search_toolbar_connect (BJB_SEARCH_TOOLBAR (self->search_bar)); */
+      /* gtk_widget_show (GTK_WIDGET (self->search_bar)); */
+      /* gtk_stack_set_visible_child_name (self->stack, "main-view"); */
       break;
 
     case BJB_WINDOW_BASE_SPINNER_VIEW:
-      gtk_stack_set_visible_child_name (self->stack, "spinner");
+      /* gtk_stack_set_visible_child_name (self->stack, "spinner"); */
       break;
 
 
     case BJB_WINDOW_BASE_NO_NOTE:
-      bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note),
-                                      BJB_EMPTY_RESULTS_NO_NOTE);
-      gtk_widget_show (self->no_note);
-      gtk_widget_hide (GTK_WIDGET (self->search_bar));
-      gtk_stack_set_visible_child_name (self->stack, "empty");
+      /* bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note), */
+      /*                                 BJB_EMPTY_RESULTS_NO_NOTE); */
+      /* gtk_widget_show (self->no_note); */
+      /* gtk_widget_hide (GTK_WIDGET (self->search_bar)); */
+      /* gtk_stack_set_visible_child_name (self->stack, "empty"); */
       break;
 
 
     case BJB_WINDOW_BASE_NO_RESULT:
-      bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note),
-                                      BJB_EMPTY_RESULTS_NO_RESULTS);
-      gtk_widget_show (self->no_note);
-      gtk_stack_set_visible_child_name (self->stack, "empty");
+      /* bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note), */
+      /*                                 BJB_EMPTY_RESULTS_NO_RESULTS); */
+      /* gtk_widget_show (self->no_note); */
+      /* gtk_stack_set_visible_child_name (self->stack, "empty"); */
       break;
 
 
     case BJB_WINDOW_BASE_ERROR_TRACKER:
-      bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note),
-                                      BJB_EMPTY_RESULTS_TRACKER);
-      gtk_widget_show_all (self->no_note);
-      gtk_widget_hide (GTK_WIDGET (self->search_bar));
-      gtk_stack_set_visible_child_name (self->stack, "empty");
+      /* bjb_empty_results_box_set_type (BJB_EMPTY_RESULTS_BOX (self->no_note), */
+      /*                                 BJB_EMPTY_RESULTS_TRACKER); */
+      /* gtk_widget_show_all (self->no_note); */
+      /* gtk_widget_hide (GTK_WIDGET (self->search_bar)); */
+      /* gtk_stack_set_visible_child_name (self->stack, "empty"); */
       break;
 
 
     case BJB_WINDOW_BASE_NOTE_VIEW:
-      gtk_widget_show (GTK_WIDGET (self->note_view));
-      gtk_widget_hide (GTK_WIDGET (self->search_bar));
-      gtk_stack_set_visible_child_name (self->stack, "note-view");
+      /* gtk_widget_show (GTK_WIDGET (self->note_view)); */
+      /* gtk_widget_hide (GTK_WIDGET (self->search_bar)); */
+      /* gtk_stack_set_visible_child_name (self->stack, "note-view"); */
       break;
 
 
@@ -628,7 +739,6 @@ bjb_window_base_switch_to (BjbWindowBase *self, BjbWindowViewType type)
   g_signal_emit (G_OBJECT (self), bjb_win_base_signals[BJB_WIN_BASE_VIEW_CHANGED],0);
 }
 
-
 void
 bjb_window_base_switch_to_item (BjbWindowBase *self, BijiItem *item)
 {
@@ -638,21 +748,15 @@ bjb_window_base_switch_to_item (BjbWindowBase *self, BijiItem *item)
 
   if (BIJI_IS_NOTE_OBJ (item))
   {
-
     BijiNoteObj *note = BIJI_NOTE_OBJ (item);
 
     self->note = note;
-
     self->note_view = bjb_note_view_new (w, note);
-    gtk_stack_add_named (self->stack, GTK_WIDGET (self->note_view), "note-view");
-
-    g_object_add_weak_pointer (G_OBJECT (self->note_view),
-                               (gpointer *) &self->note_view);
+    gtk_container_add (GTK_CONTAINER (self->note_box), GTK_WIDGET (self->note_view));
+    gtk_widget_show (GTK_WIDGET (self->note_view));
 
     bjb_window_base_switch_to (self, BJB_WINDOW_BASE_NOTE_VIEW);
-    gtk_widget_show (w);
     bjb_note_view_grab_focus (self->note_view);
-    bjb_main_toolbar_title_focus (self->main_toolbar);
   }
 }
 
@@ -687,12 +791,6 @@ bjb_window_base_get_entry(GtkWidget *win)
   return self->entry;
 }
 
-gpointer
-bjb_window_base_get_main_view (BjbWindowBase *self)
-{
-  return (gpointer) self->view;
-}
-
 GtkWidget *
 bjb_window_base_get_search_bar (BjbWindowBase *self)
 {
diff --git a/src/meson.build b/src/meson.build
index 7e007e2..38b4a34 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -17,12 +17,9 @@ sources = files(
   'bjb-list-view.c',
   'bjb-list-view-row.c',
   'bjb-main.c',
-  'bjb-main-toolbar.c',
-  'bjb-main-view.c',
   'bjb-note-view.c',
   'bjb-organize-dialog.c',
   'bjb-search-toolbar.c',
-  'bjb-selection-toolbar.c',
   'bjb-settings.c',
   'bjb-settings-dialog.c',
   'bjb-share.c',


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