aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Kestner <mkestner@ximian.com>2003-08-16 04:23:12 +0800
committerMike Kestner <mkestner@src.gnome.org>2003-08-16 04:23:12 +0800
commit405b846e5b5ab98ecb0d1a3545df3972df044730 (patch)
tree556cd9dd50d9d272fc0801d625e7333f0bf28aec
parent0595eace5611dd1c9741f7ea94af96f8c55ddc45 (diff)
downloadgsoc2013-evolution-405b846e5b5ab98ecb0d1a3545df3972df044730.tar.gz
gsoc2013-evolution-405b846e5b5ab98ecb0d1a3545df3972df044730.tar.zst
gsoc2013-evolution-405b846e5b5ab98ecb0d1a3545df3972df044730.zip
extracted from ect_draw (draw_expander): new gtktreeview-like expander
2003-08-15 Mike Kestner <mkestner@ximian.com> * e-cell-tree.c (draw_retro_expander): extracted from ect_draw (draw_expander): new gtktreeview-like expander drawing (ect_draw): draw lines and expanders based on retro_look style prop (adjust_event_position): extracted method from ect_event (event_in_expander): new checks for motion/clicks in expander (ect_event): handle prelight for new expanders * e-table-item.c (eti_init): init new motion col/row (eti_event): synthesize leave_notify events for cells and propogate existing motion events to the cells. * e-tree.c (e_tree_class_init): add retro_look and expander_size style props. svn path=/trunk/; revision=22251
-rw-r--r--widgets/table/e-cell-tree.c228
-rw-r--r--widgets/table/e-table-item.c46
-rw-r--r--widgets/table/e-table-item.h2
-rw-r--r--widgets/table/e-tree.c17
4 files changed, 207 insertions, 86 deletions
diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c
index 03a454e2c5..18c8146369 100644
--- a/widgets/table/e-cell-tree.c
+++ b/widgets/table/e-cell-tree.c
@@ -43,6 +43,7 @@
#include <libgnomecanvas/gnome-canvas.h>
#include "e-tree-table-adapter.h"
+#include "e-tree.h"
#include "e-tree-model.h"
#include "gal/util/e-util.h"
#include "e-table-item.h"
@@ -59,6 +60,8 @@ typedef struct {
GdkGC *gc;
GnomeCanvas *canvas;
+ gboolean retro_look;
+ gboolean prelit;
} ECellTreeView;
@@ -186,6 +189,40 @@ ect_unrealize (ECellView *ecv)
(* parent_class->unrealize) (ecv);
}
+static void
+draw_retro_expander (ECellTreeView *ectv, GdkDrawable *drawable, gboolean expanded, GdkRectangle *rect)
+{
+ GdkPixbuf *image;
+ int image_width, image_height;
+ ECellTree *ect = E_CELL_TREE(ectv->cell_view.ecell);
+
+ image = expanded ? ect->open_pixbuf : ect->closed_pixbuf;
+
+ image_width = gdk_pixbuf_get_width(image);
+ image_height = gdk_pixbuf_get_height(image);
+
+ gdk_pixbuf_render_to_drawable_alpha (image,
+ drawable,
+ rect->x, rect->y,
+ rect->width - image_width / 2,
+ rect->height - image_height / 2,
+ image_width, image_height,
+ GDK_PIXBUF_ALPHA_BILEVEL,
+ 128,
+ GDK_RGB_DITHER_NORMAL,
+ image_width, 0);
+}
+
+static void
+draw_expander (ECellTreeView *ectv, GdkDrawable *drawable, gboolean expanded, GtkStateType state, GdkRectangle *rect)
+{
+ GtkWidget *tree = GTK_WIDGET (ectv->canvas)->parent;
+ gint exp_size;
+ gtk_widget_style_get (tree, "expander_size", &exp_size, NULL);
+
+ gtk_paint_expander (tree->style, drawable, state, rect, tree, "treeview", rect->x + rect->width - exp_size / 2, rect->y + rect->height / 2, expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED);
+}
+
/*
* ECell::draw method
*/
@@ -213,6 +250,12 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
GdkPixbuf *node_image;
int node_image_width = 0, node_image_height = 0;
ETreePath parent_node;
+ ETree *tree = E_TREE (canvas->parent);
+
+ gtk_widget_style_get (GTK_WIDGET (tree),
+ "retro_look", &tree_view->retro_look,
+ NULL);
+ tree_view->prelit = FALSE;
node = e_cell_tree_get_node (ecell_view->e_table_model, row);
@@ -247,7 +290,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
gdk_gc_set_foreground (tree_view->gc, foreground);
/* draw our lines */
- if (E_CELL_TREE(tree_view->cell_view.ecell)->draw_lines) {
+ if (tree_view->retro_look && E_CELL_TREE(tree_view->cell_view.ecell)->draw_lines) {
int depth;
@@ -291,26 +334,19 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
/* now draw our icon if we're expandable */
if (e_tree_model_node_is_expandable (tree_model, node)) {
- GdkPixbuf *image;
- int image_width, image_height;
-
- image = (e_tree_table_adapter_node_is_expanded (tree_table_adapter, node)
- ? E_CELL_TREE(tree_view->cell_view.ecell)->open_pixbuf
- : E_CELL_TREE(tree_view->cell_view.ecell)->closed_pixbuf);
-
- image_width = gdk_pixbuf_get_width(image);
- image_height = gdk_pixbuf_get_height(image);
-
- gdk_pixbuf_render_to_drawable_alpha (image,
- drawable,
- 0, 0,
- x1 + subcell_offset - INDENT_AMOUNT / 2 - image_width / 2,
- y1 + (y2 - y1) / 2 - image_height / 2,
- image_width, image_height,
- GDK_PIXBUF_ALPHA_BILEVEL,
- 128,
- GDK_RGB_DITHER_NORMAL,
- image_width, 0);
+ gboolean expanded = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node);
+ GdkRectangle r;
+ if (tree_view->retro_look) {
+ r.x = 0;
+ r.y = 0;
+ r.width = x1 + subcell_offset - INDENT_AMOUNT / 2,
+ r.height = y1 + (y2 - y1) / 2,
+ draw_retro_expander (tree_view, drawable, expanded, &r);
+ } else {
+ r = rect;
+ r.width -= node_image_width + 2;
+ draw_expander (tree_view, drawable, expanded, GTK_STATE_NORMAL, &r);
+ }
}
if (node_image) {
@@ -340,6 +376,51 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
}
}
+static void
+adjust_event_position (GdkEvent *event, gint offset)
+{
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ event->button.x += offset;
+ break;
+ case GDK_MOTION_NOTIFY:
+ event->motion.x += offset;
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+event_in_expander (GdkEvent *event, gint offset, gint height)
+{
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ return (event->button.x > (offset - INDENT_AMOUNT) && event->button.x < offset);
+ case GDK_MOTION_NOTIFY:
+ return (event->motion.x > (offset - INDENT_AMOUNT) && event->motion.x < offset &&
+ event->motion.y > 2 && event->motion.y < (height - 2));
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * ECell::height method
+ */
+static int
+ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
+{
+ ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
+
+ return (((e_cell_height (tree_view->subcell_view, model_col, view_col, row)) + 1) / 2) * 2;
+}
+
/*
* ECell::event method
*/
@@ -348,78 +429,72 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col,
{
ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
ETreeModel *tree_model = e_cell_tree_get_tree_model (ecell_view->e_table_model, row);
- ETreeTableAdapter *tree_table_adapter = e_cell_tree_get_tree_table_adapter(ecell_view->e_table_model, row);
+ ETreeTableAdapter *etta = e_cell_tree_get_tree_table_adapter(ecell_view->e_table_model, row);
ETreePath node = e_cell_tree_get_node (ecell_view->e_table_model, row);
int offset = offset_of_node (ecell_view->e_table_model, row);
+ gint result;
switch (event->type) {
- case GDK_BUTTON_PRESS: {
- /* if the event happened in our area of control (and
- we care about it), handle it. */
+ case GDK_BUTTON_PRESS:
- /* only activate the tree control if the click/release happens in the icon's area. */
- if (event->button.x > (offset - INDENT_AMOUNT) && event->button.x < offset) {
+ if (event_in_expander (event, offset, 0)) {
if (e_tree_model_node_is_expandable (tree_model, node)) {
- e_tree_table_adapter_node_set_expanded (tree_table_adapter,
- node,
- !e_tree_table_adapter_node_is_expanded(tree_table_adapter, node));
+ gboolean expanded = !e_tree_table_adapter_node_is_expanded(etta, node);
+ e_tree_table_adapter_node_set_expanded (etta, node, expanded);
return TRUE;
}
}
else if (event->button.x < (offset - INDENT_AMOUNT))
return FALSE;
- }
- default: {
- gint return_value;
-
- /* modify the event and pass it off to our subcell_view */
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- event->button.x -= offset;
- break;
- case GDK_MOTION_NOTIFY:
- event->motion.x -= offset;
- break;
- default:
- /* nada */
- break;
- }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+
+ if (!tree_view->retro_look && e_tree_model_node_is_expandable (tree_model, node)) {
+ gint height = ect_height (ecell_view, model_col, view_col, row);
+ GdkRectangle area;
+ gboolean in_expander = event_in_expander (event, offset, height);
+
+ if (tree_view->prelit ^ in_expander) {
+ gint tmp_row = row;
+ e_table_item_get_cell_geometry (tree_view->cell_view.e_table_item_view,
+ &tmp_row, &view_col, &area.x, &area.y, NULL, &area.height);
+ area.width = offset - 2;
+ draw_expander (tree_view, GTK_LAYOUT (tree_view->canvas)->bin_window,
+ e_tree_table_adapter_node_is_expanded (etta, node),
+ in_expander ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
+ &area);
+ tree_view->prelit = in_expander;
+ return TRUE;
+ }
- return_value = e_cell_event(tree_view->subcell_view, event, model_col, view_col, row, flags, actions);
-
- /* modify the event and pass it off to our subcell_view */
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- event->button.x += offset;
- break;
- case GDK_MOTION_NOTIFY:
- event->motion.x += offset;
- break;
- default:
- /* nada */
- break;
}
+ break;
+
+ case GDK_LEAVE_NOTIFY:
+
+ if (tree_view->prelit) {
+ gint tmp_row = row;
+ GdkRectangle area;
+ e_table_item_get_cell_geometry (tree_view->cell_view.e_table_item_view,
+ &tmp_row, &view_col, &area.x, &area.y, NULL, &area.height);
+ area.width = offset - 2;
+ draw_expander (tree_view, GTK_LAYOUT (tree_view->canvas)->bin_window,
+ e_tree_table_adapter_node_is_expanded (etta, node),
+ GTK_STATE_NORMAL, &area);
+ tree_view->prelit = FALSE;
+ }
+ return TRUE;
- return return_value;
- }
+ default:
+ break;
}
-}
-/*
- * ECell::height method
- */
-static int
-ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
-{
- ECellTreeView *tree_view = (ECellTreeView *) ecell_view;
+ adjust_event_position (event, -offset);
+ result = e_cell_event(tree_view->subcell_view, event, model_col, view_col, row, flags, actions);
+ adjust_event_position (event, offset);
- return (((e_cell_height (tree_view->subcell_view, model_col, view_col, row)) + 1) / 2) * 2;
+ return result;
}
/*
@@ -775,3 +850,4 @@ e_cell_tree_new (GdkPixbuf *open_pixbuf,
return (ECell *) ect;
}
+
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index b125c8495d..ea2dc4297f 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -1558,6 +1558,8 @@ eti_init (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
+ eti->motion_row = -1;
+ eti->motion_col = -1;
eti->editing_col = -1;
eti->editing_row = -1;
eti->height = 0;
@@ -2512,7 +2514,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
break;
}
case GDK_MOTION_NOTIFY: {
- int col, row;
+ int col, row, flags;
double x1, y1;
gint cursor_col, cursor_row;
@@ -2536,6 +2538,19 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (!find_cell (eti, e->motion.x, e->motion.y, &col, &row, &x1, &y1))
return TRUE;
+ if (eti->motion_row != -1 && eti->motion_col != -1 &&
+ (row != eti->motion_row || col != eti->motion_col)) {
+ GdkEvent *cross = gdk_event_new (GDK_LEAVE_NOTIFY);
+ cross->crossing.time = e->motion.time;
+ return_val = eti_e_cell_event (eti, eti->cell_views [eti->motion_col],
+ cross, cross->crossing.time,
+ view_to_model_col(eti, eti->motion_col),
+ eti->motion_col, eti->motion_row, 0);
+ }
+
+ eti->motion_row = row;
+ eti->motion_col = col;
+
g_object_get(eti->selection,
"cursor_row", &cursor_row,
"cursor_col", &cursor_col,
@@ -2555,18 +2570,21 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
#endif
+ flags = 0;
if (cursor_row == view_to_model_row(eti, row) && cursor_col == view_to_model_col(eti, col)){
- ecell_view = eti->cell_views [col];
+ flags = E_CELL_EDITING | E_CELL_CURSOR;
+ }
- /*
- * Adjust the event positions
- */
- e->motion.x = x1;
- e->motion.y = y1;
+ ecell_view = eti->cell_views [col];
- return_val = eti_e_cell_event (eti, ecell_view, e, e->motion.time,
- view_to_model_col(eti, col), col, row, E_CELL_EDITING | E_CELL_CURSOR);
- }
+ /*
+ * Adjust the event positions
+ */
+ e->motion.x = x1;
+ e->motion.y = y1;
+
+ return_val = eti_e_cell_event (eti, ecell_view, e, e->motion.time,
+ view_to_model_col(eti, col), col, row, flags);
break;
}
@@ -2782,6 +2800,14 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti->tooltip->timer)
gtk_timeout_remove (eti->tooltip->timer);
eti->tooltip->timer = 0;
+ if (eti->motion_row != -1 && eti->motion_col != -1)
+ return_val = eti_e_cell_event (eti, eti->cell_views [eti->motion_col],
+ e, e->crossing.time,
+ view_to_model_col(eti, eti->motion_col),
+ eti->motion_col, eti->motion_row, 0);
+ eti->motion_row = -1;
+ eti->motion_col = -1;
+
break;
case GDK_FOCUS_CHANGE:
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index ef22cd9ab7..4776bc8ca7 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -150,6 +150,8 @@ typedef struct {
gint row_guess;
ECursorMode cursor_mode;
+ int motion_col, motion_row;
+
/*
* During editing
*/
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 938fd45136..84b5fb2a95 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -3292,6 +3292,23 @@ e_tree_class_init (ETreeClass *class)
_( "Always search" ),
FALSE,
G_PARAM_READWRITE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_boolean ("retro_look",
+ _("Retro Look"),
+ _("Draw lines and +/- expanders."),
+ FALSE,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("expander_size",
+ _("Expander Size"),
+ _("Size of the expander arrow"),
+ 0,
+ G_MAXINT,
+ 10,
+ G_PARAM_READABLE));
+
}
E_MAKE_TYPE(e_tree, "ETree", ETree, e_tree_class_init, e_tree_init, PARENT_TYPE)