[baobab/wip/grid-layout: 8/9] Implement new layout for the location view



commit 38508dbcce00fe886f329bb5b62c8feda878f5a2
Author: Stefano Facchini <stefano facchini gmail com>
Date:   Sun Apr 15 15:19:25 2012 +0200

    Implement new layout for the location view
    
    Add a flow container for the location widgets and use it to implement a
    new location view.

 src/Makefile.am               |    1 +
 src/baobab-location-view.vala |  171 +++++++++++++++++++++++++++++++++++++++++
 src/baobab-main-window.ui     |   11 +--
 src/baobab-window.vala        |   30 +++++---
 src/baobab.css                |    8 ++
 5 files changed, 203 insertions(+), 18 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c45ad3..f900313 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@ baobab_SOURCES = \
 	baobab-location-monitor.vala	\
 	baobab-location.vala		\
 	baobab-location-widget.vala	\
+	baobab-location-view.vala	\
 	baobab-scanner.vala		\
 	baobab-window.vala		\
 	main.vala			\
diff --git a/src/baobab-location-view.vala b/src/baobab-location-view.vala
new file mode 100644
index 0000000..b5c73ce
--- /dev/null
+++ b/src/baobab-location-view.vala
@@ -0,0 +1,171 @@
+/* -*- indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* Baobab - disk usage analyzer
+ *
+ * Copyright (C) 2012  Stefano Facchini <stefano facchini gmail com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Baobab {
+
+    public class LocationView : Gtk.Grid {
+        private LocationFlowContainer volume_container;
+        private LocationFlowContainer folder_container;
+
+        public LocationView () {
+            orientation = Gtk.Orientation.VERTICAL;
+            hexpand = true;
+            vexpand = true;
+            margin = 10;
+
+            Gtk.Label label;
+
+            label = new Gtk.Label (_("Volumes"));
+            label.set_markup ("<b>" + _("Volumes") + "</b>");
+            label.halign = Gtk.Align.START;
+            add (label);
+            volume_container = new LocationFlowContainer ();
+            add (volume_container);
+
+            label = new Gtk.Label (_("Folders"));
+            label.set_markup ("<b>" + _("Folders") + "</b>");
+            label.halign = Gtk.Align.START;
+            label.margin_top = 24;
+            add (label);
+            folder_container = new LocationFlowContainer ();
+            add (folder_container);
+
+            show_all ();
+        }
+
+        public void add_to_volumes (LocationWidget location_widget) {
+            volume_container.add (location_widget);
+        }
+
+        public void add_to_folders (LocationWidget location_widget) {
+            folder_container.add (location_widget);
+        }
+
+        public void clear () {
+            volume_container.clear ();
+            folder_container.clear ();
+        }
+    }
+
+    public class LocationFlowContainer : Gtk.Container {
+        private int columns;
+        private int rows;
+
+        List<Gtk.Widget> children = null;
+
+        public LocationFlowContainer () {
+            hexpand = true;
+            set_has_window (false);
+        }
+
+        public void clear () {
+            this.foreach ((widget) => { widget.destroy (); });
+        }
+
+        protected override Gtk.SizeRequestMode get_request_mode () {
+            return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;
+        }
+
+        protected override void get_preferred_width (out int minimum, out int natural) {
+            int width = 0;
+
+            if (children.length () > 0) {
+                children.data.get_preferred_width (null, out width);
+            }
+
+            minimum = natural = width;
+        }
+
+        protected override void get_preferred_height_for_width (int width, out int minimum, out int natural) {
+            int height = 0;
+
+            var n_children = children.length ();
+            if (n_children > 0) {
+                int child_width, child_height;
+                children.data.get_preferred_width (null, out child_width);
+                children.data.get_preferred_height (null, out child_height);
+
+                int n_columns = width / child_width;
+                height = child_height * (int) Math.ceil((double) n_children / n_columns);
+            }
+
+            minimum = natural = height;
+        }
+
+        protected override void size_allocate (Gtk.Allocation alloc) {
+            set_allocation (alloc);
+
+            if (children.length () == 0) {
+                return;
+            }
+
+            int child_width, child_height;
+            children.data.get_preferred_width (null, out child_width);
+            children.data.get_preferred_height (null, out child_height);
+
+            columns = alloc.width / child_width;
+            rows = 0;
+
+            int col = 0;
+            foreach (var child in children) {
+                var child_alloc = Gtk.Allocation ();
+                child_alloc.x = alloc.x + col * child_width;
+                child_alloc.y = alloc.y + rows * child_height;
+                child_alloc.width = child_width;
+                child_alloc.height = child_height;
+
+                child.size_allocate (child_alloc);
+
+                if (++col >= columns) {
+                    col = 0;
+                    rows++;
+                }
+            }
+        }
+
+        protected override void forall_internal (bool include_internals, Gtk.Callback callback) {
+            unowned List<Gtk.Widget> list = children;
+            while (list != null) {
+                Gtk.Widget child = list.data;
+                list = list.next;
+
+                callback (child);
+            }
+        }
+
+        protected override void remove (Gtk.Widget widget) {
+            foreach (var child in children) {
+                if (child == widget) {
+                    widget.unparent ();
+                    children.remove (widget);
+
+                    queue_resize ();
+
+                    break;
+                }
+            }
+        }
+
+        protected override void add (Gtk.Widget widget) {
+            widget.set_parent (this);
+            children.append (widget);
+        }
+    }
+}
diff --git a/src/baobab-main-window.ui b/src/baobab-main-window.ui
index 828a14e..7974688 100644
--- a/src/baobab-main-window.ui
+++ b/src/baobab-main-window.ui
@@ -191,19 +191,14 @@
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
             <child>
-              <object class="GtkScrolledWindow" id="volume-scrolled-window">
+              <object class="GtkScrolledWindow" id="location-scrolled-window">
                 <property name="visible">True</property>
                 <property name="vexpand">True</property>
                 <property name="hexpand">True</property>
+                <property name="shadow_type">in</property>
                 <child>
-                  <object class="GtkViewport" id="volume-viewport">
+                  <object class="GtkViewport" id="location-viewport">
                     <property name="visible">True</property>
-                    <child>
-                      <object class="GtkGrid" id="location-view">
-                        <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
-                      </object>
-                    </child>
                   </object>
                 </child>
               </object>
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
index cffed1f..727b3c0 100644
--- a/src/baobab-window.vala
+++ b/src/baobab-window.vala
@@ -35,7 +35,7 @@ namespace Baobab {
         Gtk.Label infobar_secondary;
         Gtk.TreeView treeview;
         Gtk.Notebook chart_notebook;
-        Gtk.Grid location_view;
+        LocationView location_view;
         Gtk.Paned horizontal_paned;
         Chart rings_chart;
         Chart treemap_chart;
@@ -140,10 +140,9 @@ namespace Baobab {
             rings_chart = builder.get_object ("rings-chart") as Chart;
             treemap_chart = builder.get_object ("treemap-chart") as Chart;
             spinner = builder.get_object ("spinner") as Gtk.Spinner;
-            location_view = builder.get_object ("location-view") as Gtk.Grid;
             horizontal_paned = builder.get_object ("hpaned") as Gtk.Paned;
 
-            setup_home_page ();
+            setup_home_page (builder);
             setup_treeview (builder);
 
             setup_paned_autoresize ();
@@ -172,7 +171,6 @@ namespace Baobab {
             set_hide_titlebar_when_maximized (true);
 
             set_ui_page (UIPage.HOME);
-
             set_busy (false);
 
             show ();
@@ -350,7 +348,7 @@ namespace Baobab {
         }
 
         void update_locations () {
-            location_view.foreach ((widget) => { widget.destroy (); });
+            location_view.clear ();
 
             foreach (var location in location_monitor.get_locations ()) {
                 LocationWidget loc_widget;
@@ -358,6 +356,7 @@ namespace Baobab {
                     loc_widget = new LocationWidget (location, (location_) => {
                         on_scan_home_activate ();
                     });
+                    location_view.add_to_folders (loc_widget);
                 } else {
                     loc_widget = new LocationWidget (location, (location_) => {
                         location_.mount_volume.begin ((location__, res) => {
@@ -369,15 +368,26 @@ namespace Baobab {
                             }
                         });
                     });
+                    if (location.volume != null || location.mount_point == "/") {
+                        location_view.add_to_volumes (loc_widget);
+                    } else {
+                        location_view.add_to_folders (loc_widget);
+                    }
                 }
-
-                location_view.add (loc_widget);
             }
-
-            location_view.show_all ();
         }
 
-        void setup_home_page () {
+        void setup_home_page (Gtk.Builder builder) {
+            var scrolled_window = builder.get_object ("location-scrolled-window") as Gtk.ScrolledWindow;
+            scrolled_window.name = "baobab-location-scrolled-window";
+
+            location_view = new LocationView ();
+            location_view.show ();
+
+            var viewport = builder.get_object ("location-viewport") as Gtk.Viewport;
+            viewport.name = "baobab-location-viewport";
+            viewport.add (location_view);
+
             location_monitor = LocationMonitor.get ();
             location_monitor.changed.connect (() => { update_locations (); });
             update_locations ();
diff --git a/src/baobab.css b/src/baobab.css
index c4f91f0..d3fcc17 100644
--- a/src/baobab.css
+++ b/src/baobab.css
@@ -1,3 +1,11 @@
+#baobab-location-scrolled-window {
+    border-width: 1px 0 0 0;
+}
+
+#baobab-location-viewport {
+    background-color: #f1f2f1;
+}
+
 BaobabBaseLocationWidget {
     padding: 6px;
 



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