[shotwell: 2/2] Use larger messages on empty layout



commit 43cb33fdcb84ad43df88e35a2af9dafc41b5d80c
Author: Jens Georg <mail jensge org>
Date:   Mon Jan 28 16:00:58 2019 +0100

    Use larger messages on empty layout

 data/org.gnome.Shotwell.gresource.xml |  1 +
 data/ui/message_pane.ui               | 47 ++++++++++++++++++
 src/CheckerboardLayout.vala           | 93 +++++++----------------------------
 src/Page.vala                         | 37 +++++++++++---
 src/library/TrashPage.vala            |  4 ++
 5 files changed, 101 insertions(+), 81 deletions(-)
---
diff --git a/data/org.gnome.Shotwell.gresource.xml b/data/org.gnome.Shotwell.gresource.xml
index f17928c4..07074b1c 100644
--- a/data/org.gnome.Shotwell.gresource.xml
+++ b/data/org.gnome.Shotwell.gresource.xml
@@ -12,6 +12,7 @@
       <file preprocess="xml-stripblanks">ui/import_queue.ui</file>
       <file preprocess="xml-stripblanks">ui/import.ui</file>
       <file preprocess="xml-stripblanks">ui/media.ui</file>
+      <file preprocess="xml-stripblanks">ui/message_pane.ui</file>
       <file preprocess="xml-stripblanks">ui/multitextentrydialog.ui</file>
       <file preprocess="xml-stripblanks">ui/manifest_widget.ui</file>
       <file preprocess="xml-stripblanks">ui/offline.ui</file>
diff --git a/data/ui/message_pane.ui b/data/ui/message_pane.ui
new file mode 100644
index 00000000..6ee95dc3
--- /dev/null
+++ b/data/ui/message_pane.ui
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.22"/>
+  <template class="PageMessagePane" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="valign">center</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkImage" id="icon_image">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
+        <property name="margin_bottom">12</property>
+        <property name="pixel_size">128</property>
+        <property name="icon_name">image-x-generic-symbolic</property>
+        <property name="icon_size">0</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">label</property>
+        <attributes>
+          <attribute name="scale" value="1.3999999999999999"/>
+        </attributes>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <style>
+      <class name="dim-label"/>
+    </style>
+  </template>
+</interface>
diff --git a/src/CheckerboardLayout.vala b/src/CheckerboardLayout.vala
index 20f0d14b..0bd80723 100644
--- a/src/CheckerboardLayout.vala
+++ b/src/CheckerboardLayout.vala
@@ -39,7 +39,6 @@ public class CheckerboardLayout : Gtk.DrawingArea {
     private Gee.HashSet<CheckerboardItem> exposed_items = new Gee.HashSet<CheckerboardItem>();
     private Gtk.Adjustment hadjustment = null;
     private Gtk.Adjustment vadjustment = null;
-    private string message = null;
     private Gdk.RGBA selected_color;
     private Gdk.RGBA unselected_color;
     private Gdk.RGBA focus_color;
@@ -145,23 +144,18 @@ public class CheckerboardLayout : Gtk.DrawingArea {
         Gtk.Allocation parent_allocation;
         parent.get_allocation(out parent_allocation);
         
-        if (message == null) {
-            // set the layout's new size to be the same as the parent's width but maintain 
-            // it's own height
+        // set the layout's new size to be the same as the parent's width but maintain
+        // it's own height
 #if TRACE_REFLOW
-            debug("on_viewport_resized: due_to_reflow=%s set_size_request %dx%d",
-                size_allocate_due_to_reflow.to_string(), parent_allocation.width, req.height);
+        debug("on_viewport_resized: due_to_reflow=%s set_size_request %dx%d",
+              size_allocate_due_to_reflow.to_string(), parent_allocation.width, req.height);
 #endif
-            // But if the current height is 0, don't request a size yet. Delay
-            // it to do_reflow (bgo#766864)
-            if (req.height != 0) {
-                set_size_request(parent_allocation.width - SCROLLBAR_PLACEHOLDER_WIDTH, req.height);
-            }
-        } else {
-            // set the layout's width and height to always match the parent's
-            set_size_request(parent_allocation.width, parent_allocation.height);
+        // But if the current height is 0, don't request a size yet. Delay
+        // it to do_reflow (bgo#766864)
+        if (req.height != 0) {
+            set_size_request(parent_allocation.width - SCROLLBAR_PLACEHOLDER_WIDTH, req.height);
         }
-        
+
         // possible for this widget's size_allocate not to be called, so need to update the page
         // rect here
         viewport_resized();
@@ -252,8 +246,6 @@ public class CheckerboardLayout : Gtk.DrawingArea {
     
     private void on_contents_altered(Gee.Iterable<DataObject>? added, 
         Gee.Iterable<DataObject>? removed) {
-        if (added != null)
-            message = null;
         
         if (removed != null) {
             foreach (DataObject object in removed)
@@ -324,31 +316,6 @@ public class CheckerboardLayout : Gtk.DrawingArea {
         queue_draw();
     }
     
-    public void set_message(string? text) {
-        if (text == message)
-            return;
-        
-        message = text;
-        
-        if (text != null) {
-            // message is being set, change size to match parent's; if no parent, then the size 
-            // will be set later when added to the parent
-            if (parent != null) {
-                Gtk.Allocation parent_allocation;
-                parent.get_allocation(out parent_allocation);
-                
-                set_size_request(parent_allocation.width, parent_allocation.height);
-            }
-        } else {
-            // message is being cleared, layout all the items again
-            need_reflow("set_message");
-        }
-    }
-    
-    public void unset_message() {
-        set_message(null);
-    }
-    
     private void update_visible_page() {
         if (hadjustment != null && vadjustment != null)
             visible_page = get_adjustment_page(hadjustment, vadjustment);
@@ -367,7 +334,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
     }
     
     public CheckerboardItem? get_item_at_pixel(double xd, double yd) {
-        if (message != null || item_rows == null)
+        if (item_rows == null)
             return null;
             
         int x = (int) xd;
@@ -742,10 +709,6 @@ public class CheckerboardLayout : Gtk.DrawingArea {
     private void reflow(string caller) {
         reflow_needed = false;
         
-        // if set in message mode, nothing to do here
-        if (message != null)
-            return;
-        
         Gtk.Allocation allocation;
         get_allocation(out allocation);
         
@@ -1139,35 +1102,17 @@ public class CheckerboardLayout : Gtk.DrawingArea {
         get_allocation(out allocation);
         get_style_context().render_background (ctx, 0, 0, allocation.width, allocation.height);
         
-        // watch for message mode
-        if (message == null) {
 #if TRACE_REFLOW
-            debug("draw %s: %s", page_name, rectangle_to_string(visible_page));
+        debug("draw %s: %s", page_name, rectangle_to_string(visible_page));
 #endif
-            
-            if (exposure_dirty)
-                expose_items("draw");
-            
-            // have all items in the exposed area paint themselves
-            foreach (CheckerboardItem item in intersection(visible_page)) {
-                item.paint(get_style_context(), ctx, bg_color, item.is_selected() ? selected_color : 
unselected_color,
-                    border_color, focus_color);
-            }
-        } else {
-            // draw the message in the center of the window
-            Pango.Layout pango_layout = create_pango_layout(message);
-            int text_width, text_height;
-            pango_layout.get_pixel_size(out text_width, out text_height);
-            
-            get_allocation(out allocation);
-            
-            int x = allocation.width - text_width;
-            x = (x > 0) ? x / 2 : 0;
-            
-            int y = allocation.height - text_height;
-            y = (y > 0) ? y / 2 : 0;
-            
-            get_style_context().render_layout(ctx, x, y, pango_layout);
+
+        if (exposure_dirty)
+            expose_items("draw");
+
+        // have all items in the exposed area paint themselves
+        foreach (CheckerboardItem item in intersection(visible_page)) {
+            item.paint(get_style_context(), ctx, bg_color, item.is_selected() ? selected_color : 
unselected_color,
+                border_color, focus_color);
         }
         
         bool result = (base.draw != null) ? base.draw(ctx) : true;
diff --git a/src/Page.vala b/src/Page.vala
index 7b787935..bf7df005 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -1213,11 +1213,26 @@ public abstract class Page : Gtk.ScrolledWindow {
 
 }
 
+[GtkTemplate (ui = "/org/gnome/Shotwell/ui/message_pane.ui")]
+private class PageMessagePane : Gtk.Box {
+    [GtkChild]
+    public Gtk.Label label;
+
+    [GtkChild]
+    public Gtk.Image icon_image;
+
+    public PageMessagePane() {
+        Object();
+    }
+}
+
 public abstract class CheckerboardPage : Page {
     private const int AUTOSCROLL_PIXELS = 50;
     private const int AUTOSCROLL_TICKS_MSEC = 50;
     
     private CheckerboardLayout layout;
+    private Gtk.Stack stack;
+    private PageMessagePane message_pane;
     private string item_context_menu_path = null;
     private string page_context_menu_path = null;
     private Gtk.Viewport viewport = new Gtk.Viewport(null, null);
@@ -1249,9 +1264,15 @@ public abstract class CheckerboardPage : Page {
 
     public CheckerboardPage(string page_name) {
         base (page_name);
+
+        stack = new Gtk.Stack();
+        message_pane = new PageMessagePane();
         
         layout = new CheckerboardLayout(get_view());
         layout.set_name(page_name);
+        stack.add_named (layout, "layout");
+        stack.add_named (message_pane, "message");
+        stack.set_visible_child(layout);
         
         set_event_source(layout);
 
@@ -1261,7 +1282,7 @@ public abstract class CheckerboardPage : Page {
         viewport.set_border_width(0);
         viewport.set_shadow_type(Gtk.ShadowType.NONE);
         
-        viewport.add(layout);
+        viewport.add(stack);
         
         // want to set_adjustments before adding to ScrolledWindow to let our signal handlers
         // run first ... otherwise, the thumbnails draw late
@@ -1323,6 +1344,10 @@ public abstract class CheckerboardPage : Page {
     protected override bool on_context_keypress() {
         return popup_context_menu(get_context_menu());
     }
+
+    protected virtual string get_view_empty_icon() {
+        return "image-x-generic-symbolic";
+    }
     
     protected virtual string get_view_empty_message() {
         return _("No photos/videos");
@@ -1416,15 +1441,13 @@ public abstract class CheckerboardPage : Page {
     }
     
     public void set_page_message(string message) {
-        layout.set_message(message);
-        if (is_in_view())
-            layout.queue_draw();
+        message_pane.label.label = message;
+        message_pane.icon_image.icon_name  = get_view_empty_icon();
+        stack.set_visible_child_name ("message");
     }
     
     public void unset_page_message() {
-        layout.unset_message();
-        if (is_in_view())
-            layout.queue_draw();
+        stack.set_visible_child (layout);
     }
     
     public override void set_page_name(string name) {
diff --git a/src/library/TrashPage.vala b/src/library/TrashPage.vala
index 35dee4e1..1e72f07a 100644
--- a/src/library/TrashPage.vala
+++ b/src/library/TrashPage.vala
@@ -105,6 +105,10 @@ public class TrashPage : CheckerboardPage {
     protected override string get_view_empty_message() {
         return _("Trash is empty");
     }
+
+    protected override string get_view_empty_icon() {
+        return "user-trash-symbolic";
+    }
     
     private void on_delete() {
         remove_from_app((Gee.Collection<MediaSource>) get_view().get_selected_sources(), _("Delete"), 


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