pspp-sheet-view: Add "special-cells" property to speed drawing many columns.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 12 Nov 2011 05:50:31 +0000 (21:50 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 25 Apr 2012 05:41:41 +0000 (22:41 -0700)
A "special cell" is a cell that is editable or activatable.  When a row
that contains a special cell is selected, the cursor is drawn around a
single cell; when other rows are selected, the cursor is drawn around the
entire row.

With the default of "detect" (the only mode previously supported), whether
a given row contains a special cell is detected automatically.  This is the
best choice most of the time.  For sheet views that contain more than 100
columns, an explicit "yes" or "no" improves performance.

src/ui/gui/pspp-sheet-private.h
src/ui/gui/pspp-sheet-view.c
src/ui/gui/pspp-sheet-view.h

index 8a258b2df2d269bfaba8d698ca81d872ec60a6bb..c964c5280613c9c31ca80c3ac9c5314aa5700953 100644 (file)
@@ -244,6 +244,9 @@ struct _PsppSheetViewPrivate
   PsppSheetViewGridLines grid_lines;
   GdkGC *grid_line_gc;
 
+  /* Special cells. */
+  PsppSheetViewSpecialCells special_cells;
+
   /* Tooltip support */
   gint tooltip_column;
 
index 312b55e57b12177b8fc3fec0350340462ab2e9b9..4eab74e3609992b486e409006f2c2c63400724e6 100644 (file)
@@ -143,7 +143,8 @@ enum {
   PROP_HOVER_SELECTION,
   PROP_RUBBER_BANDING,
   PROP_ENABLE_GRID_LINES,
-  PROP_TOOLTIP_COLUMN
+  PROP_TOOLTIP_COLUMN,
+  PROP_SPECIAL_CELLS
 };
 
 /* object signals */
@@ -629,6 +630,15 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class)
                                                       -1,
                                                       GTK_PARAM_READWRITE));
 
+    g_object_class_install_property (o_class,
+                                     PROP_SPECIAL_CELLS,
+                                     g_param_spec_enum ("special-cells",
+                                                       P_("Special Cells"),
+                                                       P_("Whether rows have special cells."),
+                                                       PSPP_TYPE_SHEET_VIEW_SPECIAL_CELLS,
+                                                       PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT,
+                                                       GTK_PARAM_READWRITE));
+
   /* Style properties */
 #define _TREE_VIEW_EXPANDER_SIZE 12
 #define _TREE_VIEW_VERTICAL_SEPARATOR 2
@@ -1005,6 +1015,8 @@ pspp_sheet_view_init (PsppSheetView *tree_view)
 
   tree_view->priv->tooltip_column = -1;
 
+  tree_view->priv->special_cells = PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT;
+
   tree_view->priv->post_validation_flag = FALSE;
 
   tree_view->priv->last_button_x = -1;
@@ -1076,6 +1088,9 @@ pspp_sheet_view_set_property (GObject         *object,
     case PROP_TOOLTIP_COLUMN:
       pspp_sheet_view_set_tooltip_column (tree_view, g_value_get_int (value));
       break;
+    case PROP_SPECIAL_CELLS:
+      pspp_sheet_view_set_special_cells (tree_view, g_value_get_enum (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1133,6 +1148,9 @@ pspp_sheet_view_get_property (GObject    *object,
     case PROP_TOOLTIP_COLUMN:
       g_value_set_int (value, tree_view->priv->tooltip_column);
       break;
+    case PROP_SPECIAL_CELLS:
+      g_value_set_enum (value, tree_view->priv->special_cells);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3853,21 +3871,26 @@ pspp_sheet_view_bin_expose (GtkWidget      *widget,
 
       parity = node % 2;
 
-      /* we *need* to set cell data on all cells before the call
-       * to _has_special_cell, else _has_special_cell() does not
-       * return a correct value.
-       */
-      for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
-          list;
-          list = (rtl ? list->prev : list->next))
+      if (tree_view->priv->special_cells == PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT)
         {
-         PsppSheetViewColumn *column = list->data;
-         pspp_sheet_view_column_cell_set_cell_data (column,
-                                                  tree_view->priv->model,
-                                                  &iter);
-        }
+          /* we *need* to set cell data on all cells before the call
+           * to _has_special_cell, else _has_special_cell() does not
+           * return a correct value.
+           */
+          for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+               list;
+               list = (rtl ? list->prev : list->next))
+            {
+              PsppSheetViewColumn *column = list->data;
+              pspp_sheet_view_column_cell_set_cell_data (column,
+                                                         tree_view->priv->model,
+                                                         &iter);
+            }
 
-      has_special_cell = pspp_sheet_view_has_special_cell (tree_view);
+          has_special_cell = pspp_sheet_view_has_special_cell (tree_view);
+        }
+      else
+        has_special_cell = tree_view->priv->special_cells == PSPP_SHEET_VIEW_SPECIAL_CELLS_YES;
 
       for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
           list;
@@ -6426,6 +6449,9 @@ pspp_sheet_view_has_special_cell (PsppSheetView *tree_view)
 {
   GList *list;
 
+  if (tree_view->priv->special_cells != PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT)
+    return tree_view->priv->special_cells = PSPP_SHEET_VIEW_SPECIAL_CELLS_YES;
+
   for (list = tree_view->priv->columns; list; list = list->next)
     {
       if (!((PsppSheetViewColumn *)list->data)->visible)
@@ -12237,6 +12263,52 @@ pspp_sheet_view_set_grid_lines (PsppSheetView           *tree_view,
     }
 }
 
+/**
+ * pspp_sheet_view_get_special_cells:
+ * @tree_view: a #PsppSheetView
+ *
+ * Returns which grid lines are enabled in @tree_view.
+ *
+ * Return value: a #PsppSheetViewSpecialCells value indicating whether rows in
+ * the sheet view contain special cells.
+ */
+PsppSheetViewSpecialCells
+pspp_sheet_view_get_special_cells (PsppSheetView *tree_view)
+{
+  g_return_val_if_fail (PSPP_IS_SHEET_VIEW (tree_view), 0);
+
+  return tree_view->priv->special_cells;
+}
+
+/**
+ * pspp_sheet_view_set_special_cells:
+ * @tree_view: a #PsppSheetView
+ * @special_cells: a #PsppSheetViewSpecialCells value indicating whether rows in
+ * the sheet view contain special cells.
+ *
+ * Sets whether rows in the sheet view contain special cells, controlling the
+ * rendering of row selections.
+ */
+void
+pspp_sheet_view_set_special_cells (PsppSheetView           *tree_view,
+                             PsppSheetViewSpecialCells   special_cells)
+{
+  PsppSheetViewPrivate *priv;
+  GtkWidget *widget;
+
+  g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view));
+
+  priv = tree_view->priv;
+  widget = GTK_WIDGET (tree_view);
+
+  if (priv->special_cells != special_cells)
+    {
+      priv->special_cells = special_cells;
+      gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+      g_object_notify (G_OBJECT (tree_view), "special-cells");
+    }
+}
+
 /**
  * pspp_sheet_view_set_tooltip_row:
  * @tree_view: a #PsppSheetView
@@ -12567,3 +12639,19 @@ pspp_sheet_view_grid_lines_get_type (void)
     }
     return etype;
 }
+
+GType
+pspp_sheet_view_special_cells_get_type (void)
+{
+    static GType etype = 0;
+    if (G_UNLIKELY(etype == 0)) {
+        static const GEnumValue values[] = {
+            { PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT, "PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT", "detect" },
+            { PSPP_SHEET_VIEW_SPECIAL_CELLS_YES, "PSPP_SHEET_VIEW_SPECIAL_CELLS_YES", "yes" },
+            { PSPP_SHEET_VIEW_SPECIAL_CELLS_NO, "PSPP_SHEET_VIEW_SPECIAL_CELLS_NO", "no" },
+            { 0, NULL, NULL }
+        };
+        etype = g_enum_register_static (g_intern_static_string ("PsppSheetViewSpecialCells"), values);
+    }
+    return etype;
+}
index 09a89e2d523802ff8ca2b85ea923783ae2abd965..3df7360e68f7a507b058ba8fd7b093b34cfea460 100644 (file)
@@ -53,6 +53,25 @@ typedef enum
 GType pspp_sheet_view_grid_lines_get_type (void) G_GNUC_CONST;
 #define PSPP_TYPE_SHEET_VIEW_GRID_LINES (pspp_sheet_view_grid_lines_get_type ())
 
+/* A "special cell" is a cell that is editable or activatable.  When a row that
+ * contains a special cell is selected, the cursor is drawn around a single
+ * cell; when other rows are selected, the cursor is drawn around the entire
+ * row.
+ *
+ * With the default of "detect", whether a given row contains a special cell is
+ * detected automatically.  This is the best choice most of the time.  For
+ * sheet views that contain more than 100 columns, an explicit "yes" or "no"
+ * improves performance. */
+typedef enum
+{
+  PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT,
+  PSPP_SHEET_VIEW_SPECIAL_CELLS_YES,
+  PSPP_SHEET_VIEW_SPECIAL_CELLS_NO,
+} PsppSheetViewSpecialCells;
+
+GType pspp_sheet_view_special_cells_get_type (void) G_GNUC_CONST;
+#define PSPP_TYPE_SHEET_VIEW_SPECIAL_CELLS (pspp_sheet_view_special_cells_get_type ())
+
 typedef enum
 {
   /* drop before/after this row */
@@ -367,12 +386,11 @@ gboolean pspp_sheet_view_is_rubber_banding_active (PsppSheetView       *tree_vie
 PsppSheetViewGridLines        pspp_sheet_view_get_grid_lines         (PsppSheetView                *tree_view);
 void                        pspp_sheet_view_set_grid_lines         (PsppSheetView                *tree_view,
                                                                  PsppSheetViewGridLines        grid_lines);
-gboolean                    pspp_sheet_view_get_enable_tree_lines  (PsppSheetView                *tree_view);
-void                        pspp_sheet_view_set_enable_tree_lines  (PsppSheetView                *tree_view,
-                                                                 gboolean                    enabled);
-void                        pspp_sheet_view_set_level_indentation  (PsppSheetView                *tree_view,
-                                                                 gint                        indentation);
-gint                        pspp_sheet_view_get_level_indentation  (PsppSheetView                *tree_view);
+
+PsppSheetViewSpecialCells pspp_sheet_view_get_special_cells (PsppSheetView                *tree_view);
+void                        pspp_sheet_view_set_special_cells (PsppSheetView                *tree_view,
+                                                               PsppSheetViewSpecialCells);
+
 
 /* Convenience functions for setting tooltips */
 void          pspp_sheet_view_set_tooltip_row    (PsppSheetView       *tree_view,