[gnome-utils] [baobab] Fixes #554126.



commit 80b9b17237939c426db8a64667b323446107189d
Author: Eduardo Lima Mitev <elima igalia com>
Date:   Wed Nov 4 20:50:26 2009 +0100

    [baobab] Fixes #554126.
    
    Limits treemap zooming to the actual depth of folders shown.

 baobab/src/baobab-chart.c   |   86 +++++++++++++++++++++++++++++++++++++++----
 baobab/src/baobab-chart.h   |    9 +++-
 baobab/src/baobab-treemap.c |   58 +++++++++++++++++++++++++++++
 baobab/src/baobab-treemap.h |    3 +
 baobab/src/callbacks.c      |    5 +-
 5 files changed, 147 insertions(+), 14 deletions(-)
---
diff --git a/baobab/src/baobab-chart.c b/baobab/src/baobab-chart.c
index 204801b..c24d6bb 100644
--- a/baobab/src/baobab-chart.c
+++ b/baobab/src/baobab-chart.c
@@ -45,6 +45,9 @@
 
 G_DEFINE_ABSTRACT_TYPE (BaobabChart, baobab_chart, GTK_TYPE_WIDGET);
 
+#define BAOBAB_CHART_MAX_DEPTH 8
+#define BAOBAB_CHART_MIN_DEPTH 1
+
 enum
 {
   LEFT_BUTTON   = 1,
@@ -52,7 +55,6 @@ enum
   RIGHT_BUTTON  = 3
 };
 
-
 struct _BaobabChartPrivate
 {
   guint name_column;
@@ -195,6 +197,8 @@ baobab_chart_class_init (BaobabChartClass *class)
   class->calculate_item_geometry = NULL;
   class->is_point_over_item      = NULL;
   class->get_item_rectangle      = NULL;
+  class->can_zoom_in             = NULL;
+  class->can_zoom_out            = NULL;
 
   g_object_class_install_property (obj_class,
                                    PROP_MAX_DEPTH,
@@ -549,7 +553,7 @@ baobab_chart_get_items (GtkWidget *chart, GtkTreePath *root)
         }
 
       /* Get item's children and add them to the list */
-      if ((item->has_any_child) && (item->depth < priv->max_depth))
+      if ((item->has_any_child) && (item->depth < priv->max_depth + 1))
         {
           rel_start = 0;
 
@@ -606,7 +610,8 @@ baobab_chart_draw (GtkWidget *chart,
     {
       item = (BaobabChartItem *) node->data;
 
-      if ((item->visible) && (gdk_rectangle_intersect (&area, &item->rect, NULL)))
+      if ((item->visible) && (gdk_rectangle_intersect (&area, &item->rect, NULL))
+          && (item->depth <= priv->max_depth))
         {
           highlighted = (node == priv->highlighted_item);
 
@@ -935,14 +940,16 @@ baobab_chart_scroll (GtkWidget *widget,
     {
     case GDK_SCROLL_LEFT :
     case GDK_SCROLL_UP :
-      baobab_chart_zoom_out (widget);
+      if (baobab_chart_can_zoom_out (widget))
+        baobab_chart_zoom_out (widget);
       /* change the selected item when zooming */
       baobab_chart_motion_notify (widget, (GdkEventMotion *)event);
       break;
 
     case GDK_SCROLL_RIGHT :
     case GDK_SCROLL_DOWN :
-      baobab_chart_zoom_in (widget);
+      if (baobab_chart_can_zoom_in (widget))
+        baobab_chart_zoom_in (widget);
       break;
     }
 
@@ -1548,14 +1555,25 @@ baobab_chart_thaw_updates (GtkWidget *chart)
 void
 baobab_chart_zoom_in (GtkWidget *chart)
 {
+  BaobabChartPrivate *priv;
+  BaobabChartClass *class;
+  guint new_max_depth;
+
   g_return_if_fail (BAOBAB_IS_CHART (chart));
 
-  baobab_chart_set_max_depth (chart,
-                              baobab_chart_get_max_depth (chart) - 1);
+  priv = BAOBAB_CHART (chart)->priv;
+  class = BAOBAB_CHART_GET_CLASS (chart);
+
+  if (class->can_zoom_in != NULL)
+    new_max_depth = class->can_zoom_in (chart);
+  else
+    new_max_depth = priv->max_depth - 1;
+
+  baobab_chart_set_max_depth (chart, new_max_depth);
 }
 
 /**
- * baobab_chart_zoom_in:
+ * baobab_chart_zoom_out:
  * @chart: the #BaobabChart requested to zoom out.
  *
  * Zooms out the chart by increasing its maximun depth.
@@ -1784,3 +1802,55 @@ baobab_chart_get_highlighted_item (GtkWidget *chart)
   return (priv->highlighted_item ? 
     (BaobabChartItem *) priv->highlighted_item->data : NULL);
 }
+
+/**
+ * baobab_chart_can_zoom_in:
+ * @chart: the #BaobabChart to ask if can be zoomed in.
+ *
+ * Returns a boolean telling whether the chart can be zoomed in, given its current
+ * visualization conditions.
+ *
+ * Fails if @chart is not a #BaobabChart.
+ **/
+gboolean
+baobab_chart_can_zoom_in (GtkWidget *chart)
+{
+  BaobabChartPrivate *priv;
+  BaobabChartClass *class;
+
+  g_return_if_fail (BAOBAB_IS_CHART (chart));
+
+  priv = BAOBAB_CHART (chart)->priv;
+  class = BAOBAB_CHART_GET_CLASS (chart);
+
+  if (class->can_zoom_in != NULL)
+    return class->can_zoom_in (chart) > 0;
+  else
+    return priv->max_depth > 1;
+}
+
+/**
+ * baobab_chart_can_zoom_out:
+ * @chart: the #BaobabChart to ask if can be zoomed out.
+ *
+ * Returns a boolean telling whether the chart can be zoomed out, given its current
+ * visualization conditions.
+ *
+ * Fails if @chart is not a #BaobabChart.
+ **/
+gboolean
+baobab_chart_can_zoom_out (GtkWidget *chart)
+{
+  BaobabChartPrivate *priv;
+  BaobabChartClass *class;
+
+  g_return_if_fail (BAOBAB_IS_CHART (chart));
+
+  priv = BAOBAB_CHART (chart)->priv;
+  class = BAOBAB_CHART_GET_CLASS (chart);
+
+  if (class->can_zoom_out != NULL)
+    return class->can_zoom_out (chart) > 0;
+  else
+    return (priv->max_depth < BAOBAB_CHART_MAX_DEPTH);
+}
diff --git a/baobab/src/baobab-chart.h b/baobab/src/baobab-chart.h
index dbfe89e..1977302 100644
--- a/baobab/src/baobab-chart.h
+++ b/baobab/src/baobab-chart.h
@@ -38,9 +38,6 @@
 
 G_BEGIN_DECLS
 
-#define BAOBAB_CHART_MAX_DEPTH 8
-#define BAOBAB_CHART_MIN_DEPTH 1
-
 #define BAOBAB_CHART_TYPE       (baobab_chart_get_type ())
 #define BAOBAB_CHART(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj), BAOBAB_CHART_TYPE, BaobabChart))
 #define BAOBAB_CHART_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), BAOBAB_CHART_TYPE, BaobabChartClass))
@@ -117,6 +114,9 @@ struct _BaobabChartClass
 
   void (* get_item_rectangle) (GtkWidget *chart,
                                BaobabChartItem *item);
+
+  guint (* can_zoom_in) (GtkWidget *chart);
+  guint (* can_zoom_out) (GtkWidget *chart);
 };
 
 GType baobab_chart_get_type (void) G_GNUC_CONST;
@@ -151,6 +151,9 @@ void baobab_chart_save_snapshot (GtkWidget *chart);
 gboolean baobab_chart_is_frozen (GtkWidget *chart);
 BaobabChartItem *baobab_chart_get_highlighted_item (GtkWidget *chart);
 
+gboolean baobab_chart_can_zoom_in (GtkWidget *chart);
+gboolean baobab_chart_can_zoom_out (GtkWidget *chart);
+
 G_END_DECLS
 
 #endif
diff --git a/baobab/src/baobab-treemap.c b/baobab/src/baobab-treemap.c
index 374800b..3cf904a 100644
--- a/baobab/src/baobab-treemap.c
+++ b/baobab/src/baobab-treemap.c
@@ -32,6 +32,10 @@
 #include "baobab-chart.h"
 #include "baobab-treemap.h"
 
+#define BAOBAB_TREEMAP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+                                         BAOBAB_TREEMAP_TYPE, \
+                                         BaobabTreemapPrivate))
+
 #define ITEM_TEXT_PADDING  3
 #define ITEM_BORDER_WIDTH  1
 #define ITEM_PADDING       6
@@ -43,6 +47,12 @@
 
 G_DEFINE_TYPE (BaobabTreemap, baobab_treemap, BAOBAB_CHART_TYPE);
 
+struct _BaobabTreemapPrivate
+{
+  guint max_visible_depth;
+  gboolean more_visible_childs;
+};
+
 static void baobab_treemap_class_init (BaobabTreemapClass *class);
 static void baobab_treemap_init (BaobabTreemap *object);
 static void baobab_treemap_draw_rectangle (GtkWidget *chart,
@@ -63,12 +73,16 @@ static gboolean baobab_treemap_is_point_over_item (GtkWidget *chart,
                                                    gdouble y);
 static void baobab_treemap_get_item_rectangle (GtkWidget *chart,
                                                BaobabChartItem *item);
+guint baobab_treemap_can_zoom_in (GtkWidget *chart);
+guint baobab_treemap_can_zoom_out (GtkWidget *chart);
 
 static void
 baobab_treemap_class_init (BaobabTreemapClass *class)
 {
+  GObjectClass *obj_class;
   BaobabChartClass *chart_class;
 
+  obj_class = G_OBJECT_CLASS (class);
   chart_class = BAOBAB_CHART_CLASS (class);
 
   /* BaobabChart abstract methods */
@@ -76,11 +90,20 @@ baobab_treemap_class_init (BaobabTreemapClass *class)
   chart_class->calculate_item_geometry = baobab_treemap_calculate_item_geometry;
   chart_class->is_point_over_item = baobab_treemap_is_point_over_item;
   chart_class->get_item_rectangle = baobab_treemap_get_item_rectangle;
+  chart_class->can_zoom_in        = baobab_treemap_can_zoom_in;
+  chart_class->can_zoom_out       = baobab_treemap_can_zoom_out;
+
+  g_type_class_add_private (obj_class, sizeof (BaobabTreemapPrivate));
 }
 
 static void
 baobab_treemap_init (BaobabTreemap *chart)
 {
+  BaobabTreemapPrivate *priv;
+
+  priv = BAOBAB_TREEMAP_GET_PRIVATE (chart);
+
+  chart->priv = priv;
 }
 
 static void
@@ -166,10 +189,20 @@ static void
 baobab_treemap_calculate_item_geometry (GtkWidget *chart,
                                         BaobabChartItem *item)
 {
+  BaobabTreemapPrivate *priv;
   cairo_rectangle_t p_area;
   static cairo_rectangle_t *rect;
   gdouble width, height;
   BaobabChartItem *parent = NULL;
+  guint max_depth;
+
+  priv = BAOBAB_TREEMAP (chart)->priv;
+
+  if (item->depth == 0)
+    {
+      priv->max_visible_depth = 0;
+      priv->more_visible_childs = FALSE;
+    }
 
   item->visible = FALSE;
 
@@ -225,6 +258,11 @@ baobab_treemap_calculate_item_geometry (GtkWidget *chart,
     parent->has_visible_children = TRUE;
 
   baobab_treemap_get_item_rectangle (chart, item);
+
+  if (item->depth == baobab_chart_get_max_depth (chart) + 1)
+    priv->more_visible_childs = TRUE;
+  else
+    priv->max_visible_depth = MAX (priv->max_visible_depth, item->depth);
 }
 
 static gboolean
@@ -264,6 +302,26 @@ baobab_treemap_get_item_rectangle (GtkWidget *chart,
 
 }
 
+guint
+baobab_treemap_can_zoom_in (GtkWidget *chart)
+{
+  BaobabTreemapPrivate *priv;
+
+  priv = BAOBAB_TREEMAP (chart)->priv;
+
+  return MAX (0, (gint) (priv->max_visible_depth - 1));
+}
+
+guint
+baobab_treemap_can_zoom_out (GtkWidget *chart)
+{
+  BaobabTreemapPrivate *priv;
+
+  priv = BAOBAB_TREEMAP (chart)->priv;
+
+  return priv->more_visible_childs ? 1 : 0;
+}
+
 /* Public functions start here */
 
 /**
diff --git a/baobab/src/baobab-treemap.h b/baobab/src/baobab-treemap.h
index c829394..734bc27 100644
--- a/baobab/src/baobab-treemap.h
+++ b/baobab/src/baobab-treemap.h
@@ -42,10 +42,13 @@ G_BEGIN_DECLS
 
 typedef struct _BaobabTreemap BaobabTreemap;
 typedef struct _BaobabTreemapClass BaobabTreemapClass;
+typedef struct _BaobabTreemapPrivate BaobabTreemapPrivate;
 
 struct _BaobabTreemap
 {
   BaobabChart parent;
+
+  BaobabTreemapPrivate *priv;
 };
 
 struct _BaobabTreemapClass
diff --git a/baobab/src/callbacks.c b/baobab/src/callbacks.c
index 680159f..653b62a 100644
--- a/baobab/src/callbacks.c
+++ b/baobab/src/callbacks.c
@@ -375,10 +375,9 @@ on_chart_button_release (BaobabChart *chart, GdkEventButton *event,
                                 ((root_path != NULL) &&
                                  (gtk_tree_path_get_depth (root_path) > 1)));
       gtk_widget_set_sensitive (menu->zoom_in_item,
-                                (baobab_chart_get_max_depth (baobab.current_chart) > 1));
+                                baobab_chart_can_zoom_in (baobab.current_chart));
       gtk_widget_set_sensitive (menu->zoom_out_item,
-                               (baobab_chart_get_max_depth (baobab.current_chart) 
-                                < BAOBAB_CHART_MAX_DEPTH));
+                                baobab_chart_can_zoom_out (baobab.current_chart));
 
       /* show the menu */
       gtk_menu_popup (GTK_MENU (menu->widget), NULL, NULL, NULL, NULL,



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