fix this routine.

1999-12-09  Miguel de Icaza  <miguel@gnu.org>

	* e-table-header.c (e_table_header_col_diff): fix this routine.

1999-12-04  Miguel de Icaza  <miguel@gnu.org>

	* e-table-header-item.c (ethi_event): Started drag and drop
	support.

	* e-table-item.c (eti_table_model_changed): The columns are
	controled by the Header, not by the TableModel.

	* e-table-header-item.c (ethi_draw): Fixed redraw logic to support
	arbitrary header positioning.

	* e-cell.h: Revamped e-cell interface.  We now provide the model
	column and the view column to all methods (so that the methods can
	talk to the view and to the model at the same time).

	* e-table-item.c: Update to new API
	* e-cell-test.c: Update to new API

1999-12-03  Miguel de Icaza  <miguel@gnu.org>

	* e-cell.c (e_cell_class_init): Provide emtpy methods for
	enter_edit, and leave_edit.

	* e-table-item.c: Killed draw cell.
	(eti_draw): Perform column mapping here.
	(e_table_item_leave_edit): ditto.
	(e_table_item_enter_edit): ditto.
	(eti_event): ditto.

svn path=/trunk/; revision=1478
This commit is contained in:
Miguel de Icaza
1999-12-10 07:36:51 +00:00
committed by Arturo Espinosa
parent 54e2b5022a
commit 48618eb6eb
52 changed files with 1599 additions and 473 deletions

View File

@ -1,3 +1,36 @@
1999-12-09 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_col_diff): fix this routine.
1999-12-04 Miguel de Icaza <miguel@gnu.org>
* e-table-header-item.c (ethi_event): Started drag and drop
support.
* e-table-item.c (eti_table_model_changed): The columns are
controled by the Header, not by the TableModel.
* e-table-header-item.c (ethi_draw): Fixed redraw logic to support
arbitrary header positioning.
* e-cell.h: Revamped e-cell interface. We now provide the model
column and the view column to all methods (so that the methods can
talk to the view and to the model at the same time).
* e-table-item.c: Update to new API
* e-cell-test.c: Update to new API
1999-12-03 Miguel de Icaza <miguel@gnu.org>
* e-cell.c (e_cell_class_init): Provide emtpy methods for
enter_edit, and leave_edit.
* e-table-item.c: Killed draw cell.
(eti_draw): Perform column mapping here.
(e_table_item_leave_edit): ditto.
(e_table_item_enter_edit): ditto.
(eti_event): ditto.
1999-12-02 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_index): fixed api.

View File

@ -51,5 +51,7 @@ table_test_LDFLAGS = `gnome-config --libs gdk_pixbuf`
EXTRA_DIST = \
sample.table \
add-col.xpm \
check-empty.xpm \
check-filled.xpm
check-filled.xpm \
remove-col.xpm

View File

@ -29,7 +29,7 @@ typedef struct {
/*
* Where the editing is taking place
*/
int col, row;
int model_col, view_col, row;
} CellEdit;
typedef struct {
@ -48,9 +48,9 @@ typedef struct {
static ECellClass *parent_class;
static void
ect_queue_redraw (ECellTextView *text_view, int col, int row)
ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -62,7 +62,7 @@ ect_accept_edits (ECellTextView *text_view)
const char *text = gtk_entry_get_text (text_view->edit->entry);
CellEdit *edit = text_view->edit;
e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
e_table_model_set_value_at (text_view->eti->table_model, edit->model_col, edit->row, text);
}
/*
@ -92,7 +92,7 @@ ect_stop_editing (ECellTextView *text_view)
static void
ect_cancel_edit (ECellTextView *text_view)
{
ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
ect_queue_redraw (text_view, text_view->edit->view_col, text_view->edit->row);
ect_stop_editing (text_view);
}
@ -149,14 +149,14 @@ ect_unrealize (ECellView *ecv)
*/
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
GdkFont *font = text_view->font;
const int height = font->ascent + font->descent;
int xoff;
@ -168,7 +168,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
if (text_view->edit){
CellEdit *edit = text_view->edit;
if ((edit->col == col) && (edit->row == row))
if ((edit->view_col == view_col) && (edit->row == row))
edit_display = TRUE;
}
@ -312,7 +312,7 @@ ect_edit_select_all (ECellTextView *text_view)
* ECell::event method
*/
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -327,7 +327,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
if (text_view->edit){
printf ("FIXME: Should handle click here\n");
} else
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
break;
case GDK_BUTTON_RELEASE:
@ -345,12 +345,12 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
if (!text_view->edit){
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
ect_edit_select_all (text_view);
}
gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
break;
case GDK_KEY_RELEASE:
@ -366,7 +366,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
ect_height (ECellView *ecell_view, int col, int row)
ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -386,16 +386,17 @@ ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
* ECellView::enter_edit method
*/
static void *
ect_enter_edit (ECellView *ecell_view, int col, int row)
ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
CellEdit *edit;
edit = g_new (CellEdit, 1);
text_view->edit = edit;
edit->col = col;
edit->model_col = model_col;
edit->view_col = view_col;
edit->row = row;
edit->entry = (GtkEntry *) gtk_entry_new ();
@ -412,7 +413,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
gtk_widget_show_all (edit->entry_top);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
return NULL;
}
@ -421,7 +422,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
* ECellView::leave_edit method
*/
static void
ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;

View File

@ -29,9 +29,9 @@ typedef struct {
static ECellClass *parent_class;
static void
etog_queue_redraw (ECellToggleView *text_view, int col, int row)
etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -40,7 +40,6 @@ etog_queue_redraw (ECellToggleView *text_view, int col, int row)
static ECellView *
etog_realize (ECell *ecell, void *view)
{
ECellToggle *eccb = E_CELL_TOGGLE (ecell);
ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
ETableItem *eti = E_TABLE_ITEM (view);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
@ -72,7 +71,7 @@ etog_unrealize (ECellView *ecv)
*/
static void
etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
@ -80,9 +79,8 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
GdkPixbuf *image;
ArtPixBuf *art;
int x, y, width, height;
gboolean free_image;
const int value = GPOINTER_TO_INT (
e_table_model_value_at (ecell_view->ecell->table_model, col, row));
e_table_model_value_at (ecell_view->ecell->table_model, model_col, row));
if (value >= toggle->n_states){
g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
@ -166,7 +164,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
}
static void
etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int row, int value)
{
ECell *ecell = toggle_view->cell_view.ecell;
ECellToggle *toggle = E_CELL_TOGGLE (ecell);
@ -174,29 +172,28 @@ etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
if (value >= toggle->n_states)
value = 0;
e_table_model_set_value_at (ecell->table_model, col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, col, row);
e_table_model_set_value_at (ecell->table_model, model_col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, view_col, row);
}
/*
* ECell::event method
*/
static gint
etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
const int value = GPOINTER_TO_INT (_value);
switch (event->type){
case GDK_BUTTON_RELEASE:
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
case GDK_KEY_PRESS:
if (event->key.keyval == GDK_space){
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
}
return FALSE;
@ -211,7 +208,7 @@ etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
etog_height (ECellView *ecell_view, int col, int row)
etog_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);

View File

@ -25,30 +25,30 @@ ec_unrealize (ECellView *e_cell)
static void
ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ec_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
ec_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static void
ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
ec_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2)
{
ecell_view->focus_col = col;
ecell_view->focus_col = view_col;
ecell_view->focus_row = row;
ecell_view->focus_x1 = x1;
ecell_view->focus_y1 = y1;
@ -67,6 +67,17 @@ ec_unfocus (ECellView *ecell_view)
ecell_view->focus_y2 = -1;
}
static void *
ec_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return NULL;
}
static void
ec_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *context)
{
}
static void
e_cell_class_init (GtkObjectClass *object_class)
{
@ -79,22 +90,23 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->focus = ec_focus;
ecc->unfocus = ec_unfocus;
ecc->height = ec_height;
ecc->enter_edit = ec_enter_edit;
ecc->leave_edit = ec_leave_edit;
}
static void
e_cell_init (GtkObject *object)
{
ECell *e_cell = E_CELL (object);
}
E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
void
e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
ecell_view, event, col, row);
ecell_view, event, model_col, view_col, row);
}
ECellView *
@ -112,29 +124,29 @@ e_cell_unrealize (ECellView *ecell_view)
void
e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2)
int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
ecell_view, drawable, model_col, view_col, row, selected, x1, y1, x2, y2);
}
int
e_cell_height (ECellView *ecell_view, int col, int row)
e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->height (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void *
e_cell_enter_edit (ECellView *ecell_view, int col, int row)
e_cell_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void
e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
ecell_view, col, row, edit_context);
ecell_view, model_col, view_col, row, edit_context);
}

View File

@ -32,28 +32,31 @@ typedef struct {
ECellView *(*realize) (ECell *ecell, void *view);
void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
int model_col, int view_col, int row,
gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
void (*focus) (ECellView *ecell_view, int model_col, int view_col,
int row, int x1, int y1, int x2, int y2);
void (*unfocus) (ECellView *ecell_view);
int (*height) (ECellView *ecell_view, int col, int row);
int (*height) (ECellView *ecell_view, int model_col, int view_col, int row);
void *(*enter_edit)(ECellView *ecell_view, int col, int row);
void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
void *(*enter_edit)(ECellView *ecell_view, int model_col, int view_col, int row);
void (*leave_edit)(ECellView *ecell_view, int model_col, int view_col, int row, void *context);
} ECellClass;
GtkType e_cell_get_type (void);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
int e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row);
void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
void *e_cell_enter_edit(ECellView *ecell_view, int model_col, int view_col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context);
#endif /* _E_CELL_H_ */

View File

@ -8,10 +8,19 @@
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdnd.h>
#include <libgnomeui/gnome-canvas.h>
#include <libgnomeui/gnome-canvas-util.h>
#include <libgnomeui/gnome-canvas-polygon.h>
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-col-dnd.h"
#include "e-cursors.h"
#include "add-col.xpm"
#include "remove-col.xpm"
/* Padding above and below of the string in the header display */
#define PADDING 4
@ -22,8 +31,17 @@
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
static GnomeCanvasItemClass *ethi_parent_class;
/*
* DnD icons
*/
static GdkColormap *dnd_colormap;
static GdkPixmap *remove_col_pixmap, *remove_col_mask;
static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
@ -32,6 +50,14 @@ enum {
ARG_TABLE_FONTSET
};
static GtkTargetEntry ethi_drag_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static GtkTargetEntry ethi_drop_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static void
ethi_destroy (GtkObject *object)
{
@ -151,6 +177,177 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
ethi_update (item, NULL, NULL, 0);
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
int x1 = ethi->x1;
int col;
if (x < x1)
return -1;
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
if ((x >= x1) && (x <= x1 + ecol->width))
return col;
x1 += ecol->width;
}
return -1;
}
static void
ethi_remove_drop_marker (ETableHeaderItem *ethi)
{
if (ethi->drag_mark == -1)
return;
ethi->drag_mark = -1;
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark_item = NULL;
}
static void
ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
{
GnomeCanvasPoints *points;
int x;
if (ethi->drag_mark == col)
return;
if (ethi->drag_mark_item)
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark = col;
ethi->drag_mark_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_group_get_type (),
"x", 0,
"y", 0,
NULL);
points = gnome_canvas_points_new (3);
x = e_table_header_col_diff (ethi->eth, 0, col);
points->coords [0] = ethi->x1 + x - 5;
points->coords [1] = ethi->y1;
points->coords [2] = points->coords [0] + 10;
points->coords [3] = points->coords [1];
points->coords [4] = ethi->x1 + x;
points->coords [5] = ethi->y1 + 5;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
points->coords [0] --;
points->coords [1] += ethi->height - 1;
points->coords [3] = points->coords [1];
points->coords [5] = points->coords [1] - 6;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
gnome_canvas_points_unref (points);
}
#define gray50_width 2
#define gray50_height 2
static char gray50_bits [] = {
0x02, 0x01, };
static void
ethi_add_destroy_marker (ETableHeaderItem *ethi)
{
double x1;
if (ethi->remove_item)
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
if (!ethi->stipple)
ethi->stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
ethi->remove_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
"y1", (double) ethi->y1 + 1,
"x2", (double) x1 + e_table_header_col_diff (ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
"y2", (double) ethi->y1 + ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
}
static void
ethi_remove_destroy_marker (ETableHeaderItem *ethi)
{
if (!ethi->remove_item)
return;
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
ethi->remove_item = NULL;
}
static gboolean
ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
gint x, gint y, guint time,
ETableHeaderItem *ethi)
{
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
(y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
if (col != -1){
ethi_remove_destroy_marker (ethi);
ethi_add_drop_marker (ethi, col);
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
gdk_drag_status (context, context->suggested_action, time);
return TRUE;
}
static void
ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *ethi)
{
printf ("Ending\n");
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
}
static void
ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableHeaderItem *ethi)
{
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
static void
ethi_realize (GnomeCanvasItem *item)
{
@ -171,19 +368,47 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
/*
* Now, configure DnD
*/
gtk_drag_dest_set (GTK_WIDGET (item->canvas), GTK_DEST_DEFAULT_ALL,
ethi_drop_types, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
ethi->drag_motion_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_motion",
GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
ethi->drag_leave_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_leave",
GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
ethi->drag_end_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_end",
GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
ethi->stipple = NULL;
}
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@ -228,25 +453,21 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
}
static void
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int width, int height)
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GnomeCanvas *canvas = item->canvas;
GdkGC *gc;
const int cols = e_table_header_count (ethi->eth);
int x2 = x1 + width;
int col, total;
int x;
total = 0;
x = -x1;
int x1, x2;
int col;
#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
#endif
for (col = 0; col < cols; col++){
x1 = x2 = ethi->x1;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
int col_width;
@ -255,23 +476,19 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
else
col_width = ecol->width;
if (x1 > total + col_width){
total += col_width;
x += col_width;
x2 += col_width;
if (x1 > (x + width))
break;
if (x2 < x)
continue;
}
if (x2 < total)
return;
gc = GTK_WIDGET (canvas)->style->bg_gc [GTK_STATE_ACTIVE];
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
x, ethi->y1 - y1, col_width, ethi->height);
x += col_width;
total += col_width;
x1 - x, ethi->y1 - y, col_width, ethi->height);
}
}
@ -356,6 +573,35 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
ethi_request_redraw (ethi);
}
static gboolean
ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event)
{
if (!ethi->maybe_drag)
return FALSE;
if (MAX (abs (ethi->click_x - event->x),
abs (ethi->click_y - event->y)) <= 3)
return FALSE;
return TRUE;
}
static void
ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
{
GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
GtkTargetList *list;
GdkDragContext *context;
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
return;
list = gtk_target_list_new (ethi_drag_types, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
ethi->maybe_drag = FALSE;
}
/*
* Handles the events on the ETableHeaderItem, particularly it handles resizing
*/
@ -405,6 +651,8 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
ethi_request_redraw (ethi);
} else if (ethi_maybe_start_drag (ethi, &e->motion)){
ethi_start_drag (ethi, e);
} else
set_cursor (ethi, x);
break;
@ -430,6 +678,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
ethi->resize_width = ecol->width;
ethi->resize_start_pos = start - ecol->width;
ethi->resize_min_width = ecol->min_width;
} else {
if (e->button.button == 1){
ethi->click_x = e->button.x;
ethi->click_y = e->button.y;
ethi->maybe_drag = TRUE;
}
}
break;
@ -439,8 +693,6 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (e->button.button != 1)
break;
printf ("Resize this guy\n");
break;
case GDK_BUTTON_RELEASE: {
@ -453,6 +705,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (needs_ungrab)
gnome_canvas_item_ungrab (item, e->button.time);
ethi->maybe_drag = FALSE;
break;
}
@ -487,6 +740,18 @@ ethi_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
/*
* Create our pixmaps for DnD
*/
dnd_colormap = gtk_widget_get_default_colormap ();
remove_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&remove_col_mask, NULL, remove_col_xpm);
add_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&add_col_mask, NULL, add_col_xpm);
}
static void
@ -500,6 +765,9 @@ ethi_init (GnomeCanvasItem *item)
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
ethi->drag_col = -1;
ethi->drag_mark = -1;
}
GtkType

View File

@ -34,6 +34,17 @@ typedef struct {
* Ids
*/
int structure_change_id, dimension_change_id;
/*
* For dragging columns
*/
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
int drag_col, drag_mark;
guint drag_motion_id, drag_end_id, drag_leave_id;
GnomeCanvasItem *drag_mark_item, *remove_item;
GdkBitmap *stipple;
} ETableHeaderItem;
typedef struct {

View File

@ -172,8 +172,6 @@ e_table_header_count (ETableHeader *eth)
int
e_table_header_index (ETableHeader *eth, int col)
{
int i;
g_return_val_if_fail (eth != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), -1);
g_return_val_if_fail (col < eth->col_count, -1);
@ -316,3 +314,26 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size)
eth->columns [idx]->width = size;
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx);
}
int
e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
{
int total, col;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
{
const int max_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
if (col == max_col)
break;
total += eth->columns [col]->width;
}
}
return total;
}

View File

@ -55,6 +55,9 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size);
void e_table_header_set_selection (ETableHeader *eth,
gboolean allow_selection);
int e_table_header_col_diff (ETableHeader *eth,
int start_col, int end_col);
GList *e_table_header_get_selected_indexes(ETableHeader *eth);

View File

@ -127,9 +127,12 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_row_change_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
eti->table_model_row_change_id = 0;
eti->table_model = NULL;
}
@ -171,7 +174,9 @@ eti_row_height (ETableItem *eti, int row)
max_h = 0;
for (col = 0; col < cols; col++){
h = e_cell_height (eti->cell_views [col], col, row);
ETableCol *ecol = e_table_header_get_column (eti->header, col);
h = e_cell_height (eti->cell_views [col], ecol->col_idx, col, row);
if (h > max_h)
max_h = h;
@ -225,8 +230,7 @@ eti_get_height (ETableItem *eti)
static void
eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
{
eti->cols = e_table_model_column_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
if (eti->cell_views)
eti->height = eti_get_height (eti);
@ -234,6 +238,7 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
}
/*
* eti_request_redraw:
*
@ -249,24 +254,6 @@ eti_request_redraw (ETableItem *eti)
eti->y1 + eti->height + 1);
}
/*
* Computes the distance from @start_col to @end_col in pixels.
*/
static int
eti_col_diff (ETableItem *eti, int start_col, int end_col)
{
int col, total;
total = 0;
for (col = start_col; col < end_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
total += ecol->width;
}
return total;
}
/*
* Computes the distance between @start_row and @end_row in pixels
*/
@ -301,9 +288,9 @@ eti_request_region_redraw (ETableItem *eti,
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
x1 = eti_col_diff (eti, 0, start_col);
x1 = e_table_header_col_diff (eti->header, 0, start_col);
y1 = eti_row_diff (eti, 0, start_row);
width = eti_col_diff (eti, start_col, end_col + 1);
width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
height = eti_row_diff (eti, start_row, end_row + 1);
gnome_canvas_request_redraw (canvas,
@ -313,6 +300,17 @@ eti_request_region_redraw (ETableItem *eti,
eti->y1 + y1 + height + 1 + border);
}
static void
eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
{
if (eti->renderers_can_change_size){
eti_table_model_changed (table_model, eti);
return;
}
eti_request_region_redraw (eti, 0, row, eti->cols, row, 0);
}
void
e_table_item_redraw_range (ETableItem *eti,
int start_col, int start_row,
@ -345,6 +343,10 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
eti->table_model_row_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_row_changed",
GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti);
eti_table_model_changed (table_model, eti);
}
@ -364,6 +366,7 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
eti_request_redraw (eti);
eti->cols = e_table_header_count (eti->header);
eti->width = e_table_header_total_width (eti->header);
eti_unrealize_cell_views (eti);
eti_realize_cell_views (eti);
@ -380,7 +383,7 @@ eti_add_header_model (ETableItem *eti, ETableHeader *header)
eti->header = header;
gtk_object_ref (GTK_OBJECT (header));
eti->width = e_table_header_total_width (header);
eti_header_structure_changed (header, eti);
eti->header_dim_change_id = gtk_signal_connect (
GTK_OBJECT (header), "dimension_change",
@ -467,7 +470,8 @@ eti_init (GnomeCanvasItem *item)
eti->height = 0;
eti->length_threshold = -1;
eti->renderers_can_change_size = 0;
eti->selection_mode = GTK_SELECTION_SINGLE;
}
@ -540,32 +544,6 @@ eti_unrealize (GnomeCanvasItem *item)
(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
}
static void
draw_cell (ETableItem *eti, GdkDrawable *drawable, int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellView *ecell_view;
ecell_view = eti->cell_views [col];
e_cell_draw (ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
#if 0
{
GdkFont *font;
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
font = GTK_WIDGET (canvas)->style->font;
sprintf (text, "%d:%d\n", col, row); gdk_draw_line (drawable, eti->grid_gc, x1, y1, x2, y2);
gdk_draw_line (drawable, eti->grid_gc, x1, y2, x2, y1);
sprintf (text, "%d:%d\n", col, row);
gdk_draw_text (drawable, font, eti->grid_gc, x1, y2, text, strlen (text));
}
#endif
}
static void
eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
@ -670,8 +648,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
for (col = first_col; col < last_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
ECellView *ecell_view = eti->cell_views [col];
draw_cell (eti, drawable, col, row, selected, xd, yd, xd + ecol->width, yd + height);
e_cell_draw (ecell_view, drawable, ecol->col_idx, col, row, selected,
xd, yd, xd + ecol->width, yd + height);
if (col == eti->focused_col && row == eti->focused_row){
f_x1 = xd;
@ -786,7 +766,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
ETableItem *eti = E_TABLE_ITEM (item);
ECellView *ecell_view;
ETableCol *ecol;
switch (e->type){
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
@ -798,6 +779,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -806,7 +789,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x = x1;
e->button.y = y1;
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
} else {
/*
* Focus the cell, and select the row
@ -826,6 +809,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -834,7 +818,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x -= (x1 + eti->x1);
e->button.y -= (y1 + eti->y1);
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
}
break;
}
@ -887,8 +871,9 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
}
ecol = e_table_header_get_column (eti->header, eti->focused_col);
ecell_view = eti->cell_views [eti->focused_col];
e_cell_event (ecell_view, e, eti->focused_col, eti->focused_row);
e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
break;
case GDK_KEY_RELEASE:
@ -897,7 +882,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti_editing (eti)){
ecell_view = eti->cell_views [eti->editing_col];
e_cell_event (ecell_view, e, eti->editing_col, eti->editing_row);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_event (ecell_view, e, ecol->col_idx, eti->editing_col, eti->editing_row);
}
break;
@ -1125,25 +1111,34 @@ e_table_item_select_row (ETableItem *eti, int row)
void
e_table_item_enter_edit (ETableItem *eti, int col, int row)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
eti->editing_col = col;
eti->editing_row = row;
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
ecol = e_table_header_get_column (eti->header, col);
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], ecol->col_idx, col, row);
}
void
e_table_item_leave_edit (ETableItem *eti)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
if (!eti_editing (eti))
return;
e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_leave_edit (
eti->cell_views [eti->editing_col],
ecol->col_idx, eti->editing_col,
eti->editing_row, eti->edit_ctx);
eti->editing_col = -1;
eti->editing_row = -1;
eti->edit_ctx = NULL;

View File

@ -27,6 +27,7 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
int table_model_row_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@ -36,6 +37,7 @@ typedef struct {
unsigned int draw_grid:1;
unsigned int draw_focus:1;
unsigned int mode_spreadsheet:1;
unsigned int renderers_can_change_size:1;
int focused_col, focused_row;

View File

@ -58,7 +58,16 @@ e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
return ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_ROW_CHANGED], row);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
/*
* Notice that "model_changed" is not emitted
*/
}
gboolean

View File

@ -28,6 +28,12 @@ typedef struct {
/*
* Signals
*/
/*
* Major structural changes: model_changed
* Changes only in a row: row_changed
* Only changes in a cell: cell_changed
*/
void (*model_changed) (ETableModel *etm);
void (*model_row_changed) (ETableModel *etm, int row);
void (*model_cell_changed) (ETableModel *etm, int col, int row);

View File

@ -18,8 +18,6 @@ static ETableModelClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
}

View File

@ -1,3 +1,36 @@
1999-12-09 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_col_diff): fix this routine.
1999-12-04 Miguel de Icaza <miguel@gnu.org>
* e-table-header-item.c (ethi_event): Started drag and drop
support.
* e-table-item.c (eti_table_model_changed): The columns are
controled by the Header, not by the TableModel.
* e-table-header-item.c (ethi_draw): Fixed redraw logic to support
arbitrary header positioning.
* e-cell.h: Revamped e-cell interface. We now provide the model
column and the view column to all methods (so that the methods can
talk to the view and to the model at the same time).
* e-table-item.c: Update to new API
* e-cell-test.c: Update to new API
1999-12-03 Miguel de Icaza <miguel@gnu.org>
* e-cell.c (e_cell_class_init): Provide emtpy methods for
enter_edit, and leave_edit.
* e-table-item.c: Killed draw cell.
(eti_draw): Perform column mapping here.
(e_table_item_leave_edit): ditto.
(e_table_item_enter_edit): ditto.
(eti_event): ditto.
1999-12-02 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_index): fixed api.

View File

@ -51,5 +51,7 @@ table_test_LDFLAGS = `gnome-config --libs gdk_pixbuf`
EXTRA_DIST = \
sample.table \
add-col.xpm \
check-empty.xpm \
check-filled.xpm
check-filled.xpm \
remove-col.xpm

View File

@ -29,7 +29,7 @@ typedef struct {
/*
* Where the editing is taking place
*/
int col, row;
int model_col, view_col, row;
} CellEdit;
typedef struct {
@ -48,9 +48,9 @@ typedef struct {
static ECellClass *parent_class;
static void
ect_queue_redraw (ECellTextView *text_view, int col, int row)
ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -62,7 +62,7 @@ ect_accept_edits (ECellTextView *text_view)
const char *text = gtk_entry_get_text (text_view->edit->entry);
CellEdit *edit = text_view->edit;
e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
e_table_model_set_value_at (text_view->eti->table_model, edit->model_col, edit->row, text);
}
/*
@ -92,7 +92,7 @@ ect_stop_editing (ECellTextView *text_view)
static void
ect_cancel_edit (ECellTextView *text_view)
{
ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
ect_queue_redraw (text_view, text_view->edit->view_col, text_view->edit->row);
ect_stop_editing (text_view);
}
@ -149,14 +149,14 @@ ect_unrealize (ECellView *ecv)
*/
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
GdkFont *font = text_view->font;
const int height = font->ascent + font->descent;
int xoff;
@ -168,7 +168,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
if (text_view->edit){
CellEdit *edit = text_view->edit;
if ((edit->col == col) && (edit->row == row))
if ((edit->view_col == view_col) && (edit->row == row))
edit_display = TRUE;
}
@ -312,7 +312,7 @@ ect_edit_select_all (ECellTextView *text_view)
* ECell::event method
*/
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -327,7 +327,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
if (text_view->edit){
printf ("FIXME: Should handle click here\n");
} else
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
break;
case GDK_BUTTON_RELEASE:
@ -345,12 +345,12 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
if (!text_view->edit){
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
ect_edit_select_all (text_view);
}
gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
break;
case GDK_KEY_RELEASE:
@ -366,7 +366,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
ect_height (ECellView *ecell_view, int col, int row)
ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -386,16 +386,17 @@ ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
* ECellView::enter_edit method
*/
static void *
ect_enter_edit (ECellView *ecell_view, int col, int row)
ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
CellEdit *edit;
edit = g_new (CellEdit, 1);
text_view->edit = edit;
edit->col = col;
edit->model_col = model_col;
edit->view_col = view_col;
edit->row = row;
edit->entry = (GtkEntry *) gtk_entry_new ();
@ -412,7 +413,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
gtk_widget_show_all (edit->entry_top);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
return NULL;
}
@ -421,7 +422,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
* ECellView::leave_edit method
*/
static void
ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;

View File

@ -29,9 +29,9 @@ typedef struct {
static ECellClass *parent_class;
static void
etog_queue_redraw (ECellToggleView *text_view, int col, int row)
etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -40,7 +40,6 @@ etog_queue_redraw (ECellToggleView *text_view, int col, int row)
static ECellView *
etog_realize (ECell *ecell, void *view)
{
ECellToggle *eccb = E_CELL_TOGGLE (ecell);
ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
ETableItem *eti = E_TABLE_ITEM (view);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
@ -72,7 +71,7 @@ etog_unrealize (ECellView *ecv)
*/
static void
etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
@ -80,9 +79,8 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
GdkPixbuf *image;
ArtPixBuf *art;
int x, y, width, height;
gboolean free_image;
const int value = GPOINTER_TO_INT (
e_table_model_value_at (ecell_view->ecell->table_model, col, row));
e_table_model_value_at (ecell_view->ecell->table_model, model_col, row));
if (value >= toggle->n_states){
g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
@ -166,7 +164,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
}
static void
etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int row, int value)
{
ECell *ecell = toggle_view->cell_view.ecell;
ECellToggle *toggle = E_CELL_TOGGLE (ecell);
@ -174,29 +172,28 @@ etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
if (value >= toggle->n_states)
value = 0;
e_table_model_set_value_at (ecell->table_model, col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, col, row);
e_table_model_set_value_at (ecell->table_model, model_col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, view_col, row);
}
/*
* ECell::event method
*/
static gint
etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
const int value = GPOINTER_TO_INT (_value);
switch (event->type){
case GDK_BUTTON_RELEASE:
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
case GDK_KEY_PRESS:
if (event->key.keyval == GDK_space){
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
}
return FALSE;
@ -211,7 +208,7 @@ etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
etog_height (ECellView *ecell_view, int col, int row)
etog_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);

View File

@ -25,30 +25,30 @@ ec_unrealize (ECellView *e_cell)
static void
ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ec_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
ec_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static void
ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
ec_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2)
{
ecell_view->focus_col = col;
ecell_view->focus_col = view_col;
ecell_view->focus_row = row;
ecell_view->focus_x1 = x1;
ecell_view->focus_y1 = y1;
@ -67,6 +67,17 @@ ec_unfocus (ECellView *ecell_view)
ecell_view->focus_y2 = -1;
}
static void *
ec_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return NULL;
}
static void
ec_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *context)
{
}
static void
e_cell_class_init (GtkObjectClass *object_class)
{
@ -79,22 +90,23 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->focus = ec_focus;
ecc->unfocus = ec_unfocus;
ecc->height = ec_height;
ecc->enter_edit = ec_enter_edit;
ecc->leave_edit = ec_leave_edit;
}
static void
e_cell_init (GtkObject *object)
{
ECell *e_cell = E_CELL (object);
}
E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
void
e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
ecell_view, event, col, row);
ecell_view, event, model_col, view_col, row);
}
ECellView *
@ -112,29 +124,29 @@ e_cell_unrealize (ECellView *ecell_view)
void
e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2)
int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
ecell_view, drawable, model_col, view_col, row, selected, x1, y1, x2, y2);
}
int
e_cell_height (ECellView *ecell_view, int col, int row)
e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->height (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void *
e_cell_enter_edit (ECellView *ecell_view, int col, int row)
e_cell_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void
e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
ecell_view, col, row, edit_context);
ecell_view, model_col, view_col, row, edit_context);
}

View File

@ -32,28 +32,31 @@ typedef struct {
ECellView *(*realize) (ECell *ecell, void *view);
void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
int model_col, int view_col, int row,
gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
void (*focus) (ECellView *ecell_view, int model_col, int view_col,
int row, int x1, int y1, int x2, int y2);
void (*unfocus) (ECellView *ecell_view);
int (*height) (ECellView *ecell_view, int col, int row);
int (*height) (ECellView *ecell_view, int model_col, int view_col, int row);
void *(*enter_edit)(ECellView *ecell_view, int col, int row);
void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
void *(*enter_edit)(ECellView *ecell_view, int model_col, int view_col, int row);
void (*leave_edit)(ECellView *ecell_view, int model_col, int view_col, int row, void *context);
} ECellClass;
GtkType e_cell_get_type (void);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
int e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row);
void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
void *e_cell_enter_edit(ECellView *ecell_view, int model_col, int view_col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context);
#endif /* _E_CELL_H_ */

View File

@ -8,10 +8,19 @@
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdnd.h>
#include <libgnomeui/gnome-canvas.h>
#include <libgnomeui/gnome-canvas-util.h>
#include <libgnomeui/gnome-canvas-polygon.h>
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-col-dnd.h"
#include "e-cursors.h"
#include "add-col.xpm"
#include "remove-col.xpm"
/* Padding above and below of the string in the header display */
#define PADDING 4
@ -22,8 +31,17 @@
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
static GnomeCanvasItemClass *ethi_parent_class;
/*
* DnD icons
*/
static GdkColormap *dnd_colormap;
static GdkPixmap *remove_col_pixmap, *remove_col_mask;
static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
@ -32,6 +50,14 @@ enum {
ARG_TABLE_FONTSET
};
static GtkTargetEntry ethi_drag_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static GtkTargetEntry ethi_drop_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static void
ethi_destroy (GtkObject *object)
{
@ -151,6 +177,177 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
ethi_update (item, NULL, NULL, 0);
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
int x1 = ethi->x1;
int col;
if (x < x1)
return -1;
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
if ((x >= x1) && (x <= x1 + ecol->width))
return col;
x1 += ecol->width;
}
return -1;
}
static void
ethi_remove_drop_marker (ETableHeaderItem *ethi)
{
if (ethi->drag_mark == -1)
return;
ethi->drag_mark = -1;
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark_item = NULL;
}
static void
ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
{
GnomeCanvasPoints *points;
int x;
if (ethi->drag_mark == col)
return;
if (ethi->drag_mark_item)
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark = col;
ethi->drag_mark_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_group_get_type (),
"x", 0,
"y", 0,
NULL);
points = gnome_canvas_points_new (3);
x = e_table_header_col_diff (ethi->eth, 0, col);
points->coords [0] = ethi->x1 + x - 5;
points->coords [1] = ethi->y1;
points->coords [2] = points->coords [0] + 10;
points->coords [3] = points->coords [1];
points->coords [4] = ethi->x1 + x;
points->coords [5] = ethi->y1 + 5;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
points->coords [0] --;
points->coords [1] += ethi->height - 1;
points->coords [3] = points->coords [1];
points->coords [5] = points->coords [1] - 6;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
gnome_canvas_points_unref (points);
}
#define gray50_width 2
#define gray50_height 2
static char gray50_bits [] = {
0x02, 0x01, };
static void
ethi_add_destroy_marker (ETableHeaderItem *ethi)
{
double x1;
if (ethi->remove_item)
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
if (!ethi->stipple)
ethi->stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
ethi->remove_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
"y1", (double) ethi->y1 + 1,
"x2", (double) x1 + e_table_header_col_diff (ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
"y2", (double) ethi->y1 + ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
}
static void
ethi_remove_destroy_marker (ETableHeaderItem *ethi)
{
if (!ethi->remove_item)
return;
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
ethi->remove_item = NULL;
}
static gboolean
ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
gint x, gint y, guint time,
ETableHeaderItem *ethi)
{
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
(y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
if (col != -1){
ethi_remove_destroy_marker (ethi);
ethi_add_drop_marker (ethi, col);
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
gdk_drag_status (context, context->suggested_action, time);
return TRUE;
}
static void
ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *ethi)
{
printf ("Ending\n");
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
}
static void
ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableHeaderItem *ethi)
{
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
static void
ethi_realize (GnomeCanvasItem *item)
{
@ -171,19 +368,47 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
/*
* Now, configure DnD
*/
gtk_drag_dest_set (GTK_WIDGET (item->canvas), GTK_DEST_DEFAULT_ALL,
ethi_drop_types, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
ethi->drag_motion_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_motion",
GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
ethi->drag_leave_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_leave",
GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
ethi->drag_end_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_end",
GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
ethi->stipple = NULL;
}
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@ -228,25 +453,21 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
}
static void
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int width, int height)
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GnomeCanvas *canvas = item->canvas;
GdkGC *gc;
const int cols = e_table_header_count (ethi->eth);
int x2 = x1 + width;
int col, total;
int x;
total = 0;
x = -x1;
int x1, x2;
int col;
#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
#endif
for (col = 0; col < cols; col++){
x1 = x2 = ethi->x1;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
int col_width;
@ -255,23 +476,19 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
else
col_width = ecol->width;
if (x1 > total + col_width){
total += col_width;
x += col_width;
x2 += col_width;
if (x1 > (x + width))
break;
if (x2 < x)
continue;
}
if (x2 < total)
return;
gc = GTK_WIDGET (canvas)->style->bg_gc [GTK_STATE_ACTIVE];
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
x, ethi->y1 - y1, col_width, ethi->height);
x += col_width;
total += col_width;
x1 - x, ethi->y1 - y, col_width, ethi->height);
}
}
@ -356,6 +573,35 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
ethi_request_redraw (ethi);
}
static gboolean
ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event)
{
if (!ethi->maybe_drag)
return FALSE;
if (MAX (abs (ethi->click_x - event->x),
abs (ethi->click_y - event->y)) <= 3)
return FALSE;
return TRUE;
}
static void
ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
{
GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
GtkTargetList *list;
GdkDragContext *context;
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
return;
list = gtk_target_list_new (ethi_drag_types, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
ethi->maybe_drag = FALSE;
}
/*
* Handles the events on the ETableHeaderItem, particularly it handles resizing
*/
@ -405,6 +651,8 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
ethi_request_redraw (ethi);
} else if (ethi_maybe_start_drag (ethi, &e->motion)){
ethi_start_drag (ethi, e);
} else
set_cursor (ethi, x);
break;
@ -430,6 +678,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
ethi->resize_width = ecol->width;
ethi->resize_start_pos = start - ecol->width;
ethi->resize_min_width = ecol->min_width;
} else {
if (e->button.button == 1){
ethi->click_x = e->button.x;
ethi->click_y = e->button.y;
ethi->maybe_drag = TRUE;
}
}
break;
@ -439,8 +693,6 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (e->button.button != 1)
break;
printf ("Resize this guy\n");
break;
case GDK_BUTTON_RELEASE: {
@ -453,6 +705,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (needs_ungrab)
gnome_canvas_item_ungrab (item, e->button.time);
ethi->maybe_drag = FALSE;
break;
}
@ -487,6 +740,18 @@ ethi_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
/*
* Create our pixmaps for DnD
*/
dnd_colormap = gtk_widget_get_default_colormap ();
remove_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&remove_col_mask, NULL, remove_col_xpm);
add_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&add_col_mask, NULL, add_col_xpm);
}
static void
@ -500,6 +765,9 @@ ethi_init (GnomeCanvasItem *item)
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
ethi->drag_col = -1;
ethi->drag_mark = -1;
}
GtkType

View File

@ -34,6 +34,17 @@ typedef struct {
* Ids
*/
int structure_change_id, dimension_change_id;
/*
* For dragging columns
*/
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
int drag_col, drag_mark;
guint drag_motion_id, drag_end_id, drag_leave_id;
GnomeCanvasItem *drag_mark_item, *remove_item;
GdkBitmap *stipple;
} ETableHeaderItem;
typedef struct {

View File

@ -172,8 +172,6 @@ e_table_header_count (ETableHeader *eth)
int
e_table_header_index (ETableHeader *eth, int col)
{
int i;
g_return_val_if_fail (eth != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), -1);
g_return_val_if_fail (col < eth->col_count, -1);
@ -316,3 +314,26 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size)
eth->columns [idx]->width = size;
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx);
}
int
e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
{
int total, col;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
{
const int max_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
if (col == max_col)
break;
total += eth->columns [col]->width;
}
}
return total;
}

View File

@ -55,6 +55,9 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size);
void e_table_header_set_selection (ETableHeader *eth,
gboolean allow_selection);
int e_table_header_col_diff (ETableHeader *eth,
int start_col, int end_col);
GList *e_table_header_get_selected_indexes(ETableHeader *eth);

View File

@ -127,9 +127,12 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_row_change_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
eti->table_model_row_change_id = 0;
eti->table_model = NULL;
}
@ -171,7 +174,9 @@ eti_row_height (ETableItem *eti, int row)
max_h = 0;
for (col = 0; col < cols; col++){
h = e_cell_height (eti->cell_views [col], col, row);
ETableCol *ecol = e_table_header_get_column (eti->header, col);
h = e_cell_height (eti->cell_views [col], ecol->col_idx, col, row);
if (h > max_h)
max_h = h;
@ -225,8 +230,7 @@ eti_get_height (ETableItem *eti)
static void
eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
{
eti->cols = e_table_model_column_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
if (eti->cell_views)
eti->height = eti_get_height (eti);
@ -234,6 +238,7 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
}
/*
* eti_request_redraw:
*
@ -249,24 +254,6 @@ eti_request_redraw (ETableItem *eti)
eti->y1 + eti->height + 1);
}
/*
* Computes the distance from @start_col to @end_col in pixels.
*/
static int
eti_col_diff (ETableItem *eti, int start_col, int end_col)
{
int col, total;
total = 0;
for (col = start_col; col < end_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
total += ecol->width;
}
return total;
}
/*
* Computes the distance between @start_row and @end_row in pixels
*/
@ -301,9 +288,9 @@ eti_request_region_redraw (ETableItem *eti,
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
x1 = eti_col_diff (eti, 0, start_col);
x1 = e_table_header_col_diff (eti->header, 0, start_col);
y1 = eti_row_diff (eti, 0, start_row);
width = eti_col_diff (eti, start_col, end_col + 1);
width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
height = eti_row_diff (eti, start_row, end_row + 1);
gnome_canvas_request_redraw (canvas,
@ -313,6 +300,17 @@ eti_request_region_redraw (ETableItem *eti,
eti->y1 + y1 + height + 1 + border);
}
static void
eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
{
if (eti->renderers_can_change_size){
eti_table_model_changed (table_model, eti);
return;
}
eti_request_region_redraw (eti, 0, row, eti->cols, row, 0);
}
void
e_table_item_redraw_range (ETableItem *eti,
int start_col, int start_row,
@ -345,6 +343,10 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
eti->table_model_row_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_row_changed",
GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti);
eti_table_model_changed (table_model, eti);
}
@ -364,6 +366,7 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
eti_request_redraw (eti);
eti->cols = e_table_header_count (eti->header);
eti->width = e_table_header_total_width (eti->header);
eti_unrealize_cell_views (eti);
eti_realize_cell_views (eti);
@ -380,7 +383,7 @@ eti_add_header_model (ETableItem *eti, ETableHeader *header)
eti->header = header;
gtk_object_ref (GTK_OBJECT (header));
eti->width = e_table_header_total_width (header);
eti_header_structure_changed (header, eti);
eti->header_dim_change_id = gtk_signal_connect (
GTK_OBJECT (header), "dimension_change",
@ -467,7 +470,8 @@ eti_init (GnomeCanvasItem *item)
eti->height = 0;
eti->length_threshold = -1;
eti->renderers_can_change_size = 0;
eti->selection_mode = GTK_SELECTION_SINGLE;
}
@ -540,32 +544,6 @@ eti_unrealize (GnomeCanvasItem *item)
(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
}
static void
draw_cell (ETableItem *eti, GdkDrawable *drawable, int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellView *ecell_view;
ecell_view = eti->cell_views [col];
e_cell_draw (ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
#if 0
{
GdkFont *font;
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
font = GTK_WIDGET (canvas)->style->font;
sprintf (text, "%d:%d\n", col, row); gdk_draw_line (drawable, eti->grid_gc, x1, y1, x2, y2);
gdk_draw_line (drawable, eti->grid_gc, x1, y2, x2, y1);
sprintf (text, "%d:%d\n", col, row);
gdk_draw_text (drawable, font, eti->grid_gc, x1, y2, text, strlen (text));
}
#endif
}
static void
eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
@ -670,8 +648,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
for (col = first_col; col < last_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
ECellView *ecell_view = eti->cell_views [col];
draw_cell (eti, drawable, col, row, selected, xd, yd, xd + ecol->width, yd + height);
e_cell_draw (ecell_view, drawable, ecol->col_idx, col, row, selected,
xd, yd, xd + ecol->width, yd + height);
if (col == eti->focused_col && row == eti->focused_row){
f_x1 = xd;
@ -786,7 +766,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
ETableItem *eti = E_TABLE_ITEM (item);
ECellView *ecell_view;
ETableCol *ecol;
switch (e->type){
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
@ -798,6 +779,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -806,7 +789,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x = x1;
e->button.y = y1;
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
} else {
/*
* Focus the cell, and select the row
@ -826,6 +809,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -834,7 +818,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x -= (x1 + eti->x1);
e->button.y -= (y1 + eti->y1);
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
}
break;
}
@ -887,8 +871,9 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
}
ecol = e_table_header_get_column (eti->header, eti->focused_col);
ecell_view = eti->cell_views [eti->focused_col];
e_cell_event (ecell_view, e, eti->focused_col, eti->focused_row);
e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
break;
case GDK_KEY_RELEASE:
@ -897,7 +882,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti_editing (eti)){
ecell_view = eti->cell_views [eti->editing_col];
e_cell_event (ecell_view, e, eti->editing_col, eti->editing_row);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_event (ecell_view, e, ecol->col_idx, eti->editing_col, eti->editing_row);
}
break;
@ -1125,25 +1111,34 @@ e_table_item_select_row (ETableItem *eti, int row)
void
e_table_item_enter_edit (ETableItem *eti, int col, int row)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
eti->editing_col = col;
eti->editing_row = row;
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
ecol = e_table_header_get_column (eti->header, col);
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], ecol->col_idx, col, row);
}
void
e_table_item_leave_edit (ETableItem *eti)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
if (!eti_editing (eti))
return;
e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_leave_edit (
eti->cell_views [eti->editing_col],
ecol->col_idx, eti->editing_col,
eti->editing_row, eti->edit_ctx);
eti->editing_col = -1;
eti->editing_row = -1;
eti->edit_ctx = NULL;

View File

@ -27,6 +27,7 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
int table_model_row_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@ -36,6 +37,7 @@ typedef struct {
unsigned int draw_grid:1;
unsigned int draw_focus:1;
unsigned int mode_spreadsheet:1;
unsigned int renderers_can_change_size:1;
int focused_col, focused_row;

View File

@ -58,7 +58,16 @@ e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
return ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_ROW_CHANGED], row);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
/*
* Notice that "model_changed" is not emitted
*/
}
gboolean

View File

@ -28,6 +28,12 @@ typedef struct {
/*
* Signals
*/
/*
* Major structural changes: model_changed
* Changes only in a row: row_changed
* Only changes in a cell: cell_changed
*/
void (*model_changed) (ETableModel *etm);
void (*model_row_changed) (ETableModel *etm, int row);
void (*model_cell_changed) (ETableModel *etm, int col, int row);

View File

@ -18,8 +18,6 @@ static ETableModelClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
}

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <fcntl.h>
#include <gnome.h>
#include "e-cursors.h"
int
main (int argc, char *argv [])
@ -32,7 +33,6 @@ main (int argc, char *argv [])
table_browser_test ();
multi_cols_test ();
check_test ();
gtk_main ();
e_cursors_shutdown ();

View File

@ -90,7 +90,6 @@ check_test (void)
ETableHeader *e_table_header;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
int i;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());

View File

@ -87,7 +87,7 @@ multi_cols_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
int i;
@ -122,13 +122,20 @@ multi_cols_test (void)
g_free (images);
}
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*
* Second test
*/
e_table_header_multiple = e_table_header_new ();
e_table_header_add_column (e_table_header_multiple, col_0, 0);
e_table_header_add_column (e_table_header_multiple, col_1, 1);
e_table_header_add_column (e_table_header_multiple, col_1, 2);
/*
* GUI
*/
@ -140,6 +147,7 @@ multi_cols_test (void)
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
@ -160,6 +168,25 @@ multi_cols_test (void)
"spreadsheet", TRUE,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header_multiple,
"x", 300,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
"x", 300,
"y", 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <fcntl.h>
#include <gnome.h>
#include "e-cursors.h"
int
main (int argc, char *argv [])
@ -32,7 +33,6 @@ main (int argc, char *argv [])
table_browser_test ();
multi_cols_test ();
check_test ();
gtk_main ();
e_cursors_shutdown ();

View File

@ -29,7 +29,7 @@ typedef struct {
/*
* Where the editing is taking place
*/
int col, row;
int model_col, view_col, row;
} CellEdit;
typedef struct {
@ -48,9 +48,9 @@ typedef struct {
static ECellClass *parent_class;
static void
ect_queue_redraw (ECellTextView *text_view, int col, int row)
ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -62,7 +62,7 @@ ect_accept_edits (ECellTextView *text_view)
const char *text = gtk_entry_get_text (text_view->edit->entry);
CellEdit *edit = text_view->edit;
e_table_model_set_value_at (text_view->eti->table_model, edit->col, edit->row, text);
e_table_model_set_value_at (text_view->eti->table_model, edit->model_col, edit->row, text);
}
/*
@ -92,7 +92,7 @@ ect_stop_editing (ECellTextView *text_view)
static void
ect_cancel_edit (ECellTextView *text_view)
{
ect_queue_redraw (text_view, text_view->edit->col, text_view->edit->row);
ect_queue_redraw (text_view, text_view->edit->view_col, text_view->edit->row);
ect_stop_editing (text_view);
}
@ -149,14 +149,14 @@ ect_unrealize (ECellView *ecv)
*/
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
GdkFont *font = text_view->font;
const int height = font->ascent + font->descent;
int xoff;
@ -168,7 +168,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
if (text_view->edit){
CellEdit *edit = text_view->edit;
if ((edit->col == col) && (edit->row == row))
if ((edit->view_col == view_col) && (edit->row == row))
edit_display = TRUE;
}
@ -312,7 +312,7 @@ ect_edit_select_all (ECellTextView *text_view)
* ECell::event method
*/
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -327,7 +327,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
if (text_view->edit){
printf ("FIXME: Should handle click here\n");
} else
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
break;
case GDK_BUTTON_RELEASE:
@ -345,12 +345,12 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
}
if (!text_view->edit){
e_table_item_enter_edit (text_view->eti, col, row);
e_table_item_enter_edit (text_view->eti, view_col, row);
ect_edit_select_all (text_view);
}
gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
break;
case GDK_KEY_RELEASE:
@ -366,7 +366,7 @@ ect_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
ect_height (ECellView *ecell_view, int col, int row)
ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
@ -386,16 +386,17 @@ ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
* ECellView::enter_edit method
*/
static void *
ect_enter_edit (ECellView *ecell_view, int col, int row)
ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
const char *str = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
CellEdit *edit;
edit = g_new (CellEdit, 1);
text_view->edit = edit;
edit->col = col;
edit->model_col = model_col;
edit->view_col = view_col;
edit->row = row;
edit->entry = (GtkEntry *) gtk_entry_new ();
@ -412,7 +413,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
gtk_widget_show_all (edit->entry_top);
ect_queue_redraw (text_view, col, row);
ect_queue_redraw (text_view, view_col, row);
return NULL;
}
@ -421,7 +422,7 @@ ect_enter_edit (ECellView *ecell_view, int col, int row)
* ECellView::leave_edit method
*/
static void
ect_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;

View File

@ -29,9 +29,9 @@ typedef struct {
static ECellClass *parent_class;
static void
etog_queue_redraw (ECellToggleView *text_view, int col, int row)
etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (text_view->eti, col, row, col, row);
e_table_item_redraw_range (text_view->eti, view_col, view_row, view_col, view_row);
}
/*
@ -40,7 +40,6 @@ etog_queue_redraw (ECellToggleView *text_view, int col, int row)
static ECellView *
etog_realize (ECell *ecell, void *view)
{
ECellToggle *eccb = E_CELL_TOGGLE (ecell);
ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
ETableItem *eti = E_TABLE_ITEM (view);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
@ -72,7 +71,7 @@ etog_unrealize (ECellView *ecv)
*/
static void
etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
@ -80,9 +79,8 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
GdkPixbuf *image;
ArtPixBuf *art;
int x, y, width, height;
gboolean free_image;
const int value = GPOINTER_TO_INT (
e_table_model_value_at (ecell_view->ecell->table_model, col, row));
e_table_model_value_at (ecell_view->ecell->table_model, model_col, row));
if (value >= toggle->n_states){
g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
@ -166,7 +164,7 @@ etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
}
static void
etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int row, int value)
{
ECell *ecell = toggle_view->cell_view.ecell;
ECellToggle *toggle = E_CELL_TOGGLE (ecell);
@ -174,29 +172,28 @@ etog_set_value (ECellToggleView *toggle_view, int col, int row, int value)
if (value >= toggle->n_states)
value = 0;
e_table_model_set_value_at (ecell->table_model, col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, col, row);
e_table_model_set_value_at (ecell->table_model, model_col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, view_col, row);
}
/*
* ECell::event method
*/
static gint
etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, col, row);
void *_value = e_table_model_value_at (ecell_view->ecell->table_model, model_col, row);
const int value = GPOINTER_TO_INT (_value);
switch (event->type){
case GDK_BUTTON_RELEASE:
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
case GDK_KEY_PRESS:
if (event->key.keyval == GDK_space){
etog_set_value (toggle_view, col, row, value + 1);
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
}
return FALSE;
@ -211,7 +208,7 @@ etog_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
* ECell::height method
*/
static int
etog_height (ECellView *ecell_view, int col, int row)
etog_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);

View File

@ -25,30 +25,30 @@ ec_unrealize (ECellView *e_cell)
static void
ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
ec_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int col, int row)
ec_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static void
ec_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2)
ec_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2)
{
ecell_view->focus_col = col;
ecell_view->focus_col = view_col;
ecell_view->focus_row = row;
ecell_view->focus_x1 = x1;
ecell_view->focus_y1 = y1;
@ -67,6 +67,17 @@ ec_unfocus (ECellView *ecell_view)
ecell_view->focus_y2 = -1;
}
static void *
ec_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return NULL;
}
static void
ec_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *context)
{
}
static void
e_cell_class_init (GtkObjectClass *object_class)
{
@ -79,22 +90,23 @@ e_cell_class_init (GtkObjectClass *object_class)
ecc->focus = ec_focus;
ecc->unfocus = ec_unfocus;
ecc->height = ec_height;
ecc->enter_edit = ec_enter_edit;
ecc->leave_edit = ec_leave_edit;
}
static void
e_cell_init (GtkObject *object)
{
ECell *e_cell = E_CELL (object);
}
E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
void
e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row)
e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
ecell_view, event, col, row);
ecell_view, event, model_col, view_col, row);
}
ECellView *
@ -112,29 +124,29 @@ e_cell_unrealize (ECellView *ecell_view)
void
e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2)
int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
ecell_view, drawable, model_col, view_col, row, selected, x1, y1, x2, y2);
}
int
e_cell_height (ECellView *ecell_view, int col, int row)
e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->height (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void *
e_cell_enter_edit (ECellView *ecell_view, int col, int row)
e_cell_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
ecell_view, col, row);
ecell_view, model_col, view_col, row);
}
void
e_cell_leave_edit (ECellView *ecell_view, int col, int row, void *edit_context)
e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
ecell_view, col, row, edit_context);
ecell_view, model_col, view_col, row, edit_context);
}

View File

@ -32,28 +32,31 @@ typedef struct {
ECellView *(*realize) (ECell *ecell, void *view);
void (*unrealize) (ECellView *e_cell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int col, int row, gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int col, int row);
void (*focus) (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
int model_col, int view_col, int row,
gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
void (*focus) (ECellView *ecell_view, int model_col, int view_col,
int row, int x1, int y1, int x2, int y2);
void (*unfocus) (ECellView *ecell_view);
int (*height) (ECellView *ecell_view, int col, int row);
int (*height) (ECellView *ecell_view, int model_col, int view_col, int row);
void *(*enter_edit)(ECellView *ecell_view, int col, int row);
void (*leave_edit)(ECellView *ecell_view, int col, int row, void *context);
void *(*enter_edit)(ECellView *ecell_view, int model_col, int view_col, int row);
void (*leave_edit)(ECellView *ecell_view, int model_col, int view_col, int row, void *context);
} ECellClass;
GtkType e_cell_get_type (void);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int col, int row);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
ECellView *e_cell_realize (ECell *ecell, void *view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int col, int row, gboolean selected,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int col, int row, int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int col, int row);
int e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row);
void *e_cell_enter_edit(ECellView *ecell_view, int col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int col, int row, void *edit_context);
void *e_cell_enter_edit(ECellView *ecell_view, int model_col, int view_col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context);
#endif /* _E_CELL_H_ */

View File

@ -8,10 +8,19 @@
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdnd.h>
#include <libgnomeui/gnome-canvas.h>
#include <libgnomeui/gnome-canvas-util.h>
#include <libgnomeui/gnome-canvas-polygon.h>
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-col-dnd.h"
#include "e-cursors.h"
#include "add-col.xpm"
#include "remove-col.xpm"
/* Padding above and below of the string in the header display */
#define PADDING 4
@ -22,8 +31,17 @@
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
static GnomeCanvasItemClass *ethi_parent_class;
/*
* DnD icons
*/
static GdkColormap *dnd_colormap;
static GdkPixmap *remove_col_pixmap, *remove_col_mask;
static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
@ -32,6 +50,14 @@ enum {
ARG_TABLE_FONTSET
};
static GtkTargetEntry ethi_drag_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static GtkTargetEntry ethi_drop_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static void
ethi_destroy (GtkObject *object)
{
@ -151,6 +177,177 @@ ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
ethi_update (item, NULL, NULL, 0);
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
int x1 = ethi->x1;
int col;
if (x < x1)
return -1;
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
if ((x >= x1) && (x <= x1 + ecol->width))
return col;
x1 += ecol->width;
}
return -1;
}
static void
ethi_remove_drop_marker (ETableHeaderItem *ethi)
{
if (ethi->drag_mark == -1)
return;
ethi->drag_mark = -1;
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark_item = NULL;
}
static void
ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
{
GnomeCanvasPoints *points;
int x;
if (ethi->drag_mark == col)
return;
if (ethi->drag_mark_item)
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark = col;
ethi->drag_mark_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_group_get_type (),
"x", 0,
"y", 0,
NULL);
points = gnome_canvas_points_new (3);
x = e_table_header_col_diff (ethi->eth, 0, col);
points->coords [0] = ethi->x1 + x - 5;
points->coords [1] = ethi->y1;
points->coords [2] = points->coords [0] + 10;
points->coords [3] = points->coords [1];
points->coords [4] = ethi->x1 + x;
points->coords [5] = ethi->y1 + 5;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
points->coords [0] --;
points->coords [1] += ethi->height - 1;
points->coords [3] = points->coords [1];
points->coords [5] = points->coords [1] - 6;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
gnome_canvas_points_unref (points);
}
#define gray50_width 2
#define gray50_height 2
static char gray50_bits [] = {
0x02, 0x01, };
static void
ethi_add_destroy_marker (ETableHeaderItem *ethi)
{
double x1;
if (ethi->remove_item)
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
if (!ethi->stipple)
ethi->stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
ethi->remove_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
"y1", (double) ethi->y1 + 1,
"x2", (double) x1 + e_table_header_col_diff (ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
"y2", (double) ethi->y1 + ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
}
static void
ethi_remove_destroy_marker (ETableHeaderItem *ethi)
{
if (!ethi->remove_item)
return;
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
ethi->remove_item = NULL;
}
static gboolean
ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
gint x, gint y, guint time,
ETableHeaderItem *ethi)
{
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
(y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
if (col != -1){
ethi_remove_destroy_marker (ethi);
ethi_add_drop_marker (ethi, col);
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
gdk_drag_status (context, context->suggested_action, time);
return TRUE;
}
static void
ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *ethi)
{
printf ("Ending\n");
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
}
static void
ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableHeaderItem *ethi)
{
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
static void
ethi_realize (GnomeCanvasItem *item)
{
@ -171,19 +368,47 @@ ethi_realize (GnomeCanvasItem *item)
if (!ethi->font)
ethi_font_load (ethi, "fixed");
/*
* Now, configure DnD
*/
gtk_drag_dest_set (GTK_WIDGET (item->canvas), GTK_DEST_DEFAULT_ALL,
ethi_drop_types, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
ethi->drag_motion_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_motion",
GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
ethi->drag_leave_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_leave",
GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
ethi->drag_end_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_end",
GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
ethi->stipple = NULL;
}
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
@ -228,25 +453,21 @@ draw_button (ETableHeaderItem *ethi, ETableCol *col,
}
static void
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int width, int height)
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GnomeCanvas *canvas = item->canvas;
GdkGC *gc;
const int cols = e_table_header_count (ethi->eth);
int x2 = x1 + width;
int col, total;
int x;
total = 0;
x = -x1;
int x1, x2;
int col;
#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
#endif
for (col = 0; col < cols; col++){
x1 = x2 = ethi->x1;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
int col_width;
@ -255,23 +476,19 @@ ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int wid
else
col_width = ecol->width;
if (x1 > total + col_width){
total += col_width;
x += col_width;
x2 += col_width;
if (x1 > (x + width))
break;
if (x2 < x)
continue;
}
if (x2 < total)
return;
gc = GTK_WIDGET (canvas)->style->bg_gc [GTK_STATE_ACTIVE];
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
x, ethi->y1 - y1, col_width, ethi->height);
x += col_width;
total += col_width;
x1 - x, ethi->y1 - y, col_width, ethi->height);
}
}
@ -356,6 +573,35 @@ ethi_end_resize (ETableHeaderItem *ethi, int new_size)
ethi_request_redraw (ethi);
}
static gboolean
ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event)
{
if (!ethi->maybe_drag)
return FALSE;
if (MAX (abs (ethi->click_x - event->x),
abs (ethi->click_y - event->y)) <= 3)
return FALSE;
return TRUE;
}
static void
ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
{
GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
GtkTargetList *list;
GdkDragContext *context;
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
return;
list = gtk_target_list_new (ethi_drag_types, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
ethi->maybe_drag = FALSE;
}
/*
* Handles the events on the ETableHeaderItem, particularly it handles resizing
*/
@ -405,6 +651,8 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
ethi_request_redraw (ethi);
} else if (ethi_maybe_start_drag (ethi, &e->motion)){
ethi_start_drag (ethi, e);
} else
set_cursor (ethi, x);
break;
@ -430,6 +678,12 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
ethi->resize_width = ecol->width;
ethi->resize_start_pos = start - ecol->width;
ethi->resize_min_width = ecol->min_width;
} else {
if (e->button.button == 1){
ethi->click_x = e->button.x;
ethi->click_y = e->button.y;
ethi->maybe_drag = TRUE;
}
}
break;
@ -439,8 +693,6 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (e->button.button != 1)
break;
printf ("Resize this guy\n");
break;
case GDK_BUTTON_RELEASE: {
@ -453,6 +705,7 @@ ethi_event (GnomeCanvasItem *item, GdkEvent *e)
if (needs_ungrab)
gnome_canvas_item_ungrab (item, e->button.time);
ethi->maybe_drag = FALSE;
break;
}
@ -487,6 +740,18 @@ ethi_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
/*
* Create our pixmaps for DnD
*/
dnd_colormap = gtk_widget_get_default_colormap ();
remove_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&remove_col_mask, NULL, remove_col_xpm);
add_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&add_col_mask, NULL, add_col_xpm);
}
static void
@ -500,6 +765,9 @@ ethi_init (GnomeCanvasItem *item)
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
ethi->drag_col = -1;
ethi->drag_mark = -1;
}
GtkType

View File

@ -34,6 +34,17 @@ typedef struct {
* Ids
*/
int structure_change_id, dimension_change_id;
/*
* For dragging columns
*/
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
int drag_col, drag_mark;
guint drag_motion_id, drag_end_id, drag_leave_id;
GnomeCanvasItem *drag_mark_item, *remove_item;
GdkBitmap *stipple;
} ETableHeaderItem;
typedef struct {

View File

@ -172,8 +172,6 @@ e_table_header_count (ETableHeader *eth)
int
e_table_header_index (ETableHeader *eth, int col)
{
int i;
g_return_val_if_fail (eth != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), -1);
g_return_val_if_fail (col < eth->col_count, -1);
@ -316,3 +314,26 @@ e_table_header_set_size (ETableHeader *eth, int idx, int size)
eth->columns [idx]->width = size;
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx);
}
int
e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
{
int total, col;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
{
const int max_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
if (col == max_col)
break;
total += eth->columns [col]->width;
}
}
return total;
}

View File

@ -55,6 +55,9 @@ void e_table_header_set_size (ETableHeader *eth, int idx, int size);
void e_table_header_set_selection (ETableHeader *eth,
gboolean allow_selection);
int e_table_header_col_diff (ETableHeader *eth,
int start_col, int end_col);
GList *e_table_header_get_selected_indexes(ETableHeader *eth);

View File

@ -127,9 +127,12 @@ eti_remove_table_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_change_id);
gtk_signal_disconnect (GTK_OBJECT (eti->table_model),
eti->table_model_row_change_id);
gtk_object_unref (GTK_OBJECT (eti->table_model));
eti->table_model_change_id = 0;
eti->table_model_row_change_id = 0;
eti->table_model = NULL;
}
@ -171,7 +174,9 @@ eti_row_height (ETableItem *eti, int row)
max_h = 0;
for (col = 0; col < cols; col++){
h = e_cell_height (eti->cell_views [col], col, row);
ETableCol *ecol = e_table_header_get_column (eti->header, col);
h = e_cell_height (eti->cell_views [col], ecol->col_idx, col, row);
if (h > max_h)
max_h = h;
@ -225,8 +230,7 @@ eti_get_height (ETableItem *eti)
static void
eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
{
eti->cols = e_table_model_column_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
eti->rows = e_table_model_row_count (eti->table_model);
if (eti->cell_views)
eti->height = eti_get_height (eti);
@ -234,6 +238,7 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0);
}
/*
* eti_request_redraw:
*
@ -249,24 +254,6 @@ eti_request_redraw (ETableItem *eti)
eti->y1 + eti->height + 1);
}
/*
* Computes the distance from @start_col to @end_col in pixels.
*/
static int
eti_col_diff (ETableItem *eti, int start_col, int end_col)
{
int col, total;
total = 0;
for (col = start_col; col < end_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
total += ecol->width;
}
return total;
}
/*
* Computes the distance between @start_row and @end_row in pixels
*/
@ -301,9 +288,9 @@ eti_request_region_redraw (ETableItem *eti,
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
int x1, y1, width, height;
x1 = eti_col_diff (eti, 0, start_col);
x1 = e_table_header_col_diff (eti->header, 0, start_col);
y1 = eti_row_diff (eti, 0, start_row);
width = eti_col_diff (eti, start_col, end_col + 1);
width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
height = eti_row_diff (eti, start_row, end_row + 1);
gnome_canvas_request_redraw (canvas,
@ -313,6 +300,17 @@ eti_request_region_redraw (ETableItem *eti,
eti->y1 + y1 + height + 1 + border);
}
static void
eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
{
if (eti->renderers_can_change_size){
eti_table_model_changed (table_model, eti);
return;
}
eti_request_region_redraw (eti, 0, row, eti->cols, row, 0);
}
void
e_table_item_redraw_range (ETableItem *eti,
int start_col, int start_row,
@ -345,6 +343,10 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
eti->table_model_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_changed",
GTK_SIGNAL_FUNC (eti_table_model_changed), eti);
eti->table_model_row_change_id = gtk_signal_connect (
GTK_OBJECT (table_model), "model_row_changed",
GTK_SIGNAL_FUNC (eti_table_model_row_changed), eti);
eti_table_model_changed (table_model, eti);
}
@ -364,6 +366,7 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
{
eti_request_redraw (eti);
eti->cols = e_table_header_count (eti->header);
eti->width = e_table_header_total_width (eti->header);
eti_unrealize_cell_views (eti);
eti_realize_cell_views (eti);
@ -380,7 +383,7 @@ eti_add_header_model (ETableItem *eti, ETableHeader *header)
eti->header = header;
gtk_object_ref (GTK_OBJECT (header));
eti->width = e_table_header_total_width (header);
eti_header_structure_changed (header, eti);
eti->header_dim_change_id = gtk_signal_connect (
GTK_OBJECT (header), "dimension_change",
@ -467,7 +470,8 @@ eti_init (GnomeCanvasItem *item)
eti->height = 0;
eti->length_threshold = -1;
eti->renderers_can_change_size = 0;
eti->selection_mode = GTK_SELECTION_SINGLE;
}
@ -540,32 +544,6 @@ eti_unrealize (GnomeCanvasItem *item)
(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
}
static void
draw_cell (ETableItem *eti, GdkDrawable *drawable, int col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellView *ecell_view;
ecell_view = eti->cell_views [col];
e_cell_draw (ecell_view, drawable, col, row, selected, x1, y1, x2, y2);
#if 0
{
GdkFont *font;
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
font = GTK_WIDGET (canvas)->style->font;
sprintf (text, "%d:%d\n", col, row); gdk_draw_line (drawable, eti->grid_gc, x1, y1, x2, y2);
gdk_draw_line (drawable, eti->grid_gc, x1, y2, x2, y1);
sprintf (text, "%d:%d\n", col, row);
gdk_draw_text (drawable, font, eti->grid_gc, x1, y2, text, strlen (text));
}
#endif
}
static void
eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
@ -670,8 +648,10 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
for (col = first_col; col < last_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
ECellView *ecell_view = eti->cell_views [col];
draw_cell (eti, drawable, col, row, selected, xd, yd, xd + ecol->width, yd + height);
e_cell_draw (ecell_view, drawable, ecol->col_idx, col, row, selected,
xd, yd, xd + ecol->width, yd + height);
if (col == eti->focused_col && row == eti->focused_row){
f_x1 = xd;
@ -786,7 +766,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
{
ETableItem *eti = E_TABLE_ITEM (item);
ECellView *ecell_view;
ETableCol *ecol;
switch (e->type){
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
@ -798,6 +779,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -806,7 +789,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x = x1;
e->button.y = y1;
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
} else {
/*
* Focus the cell, and select the row
@ -826,6 +809,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return TRUE;
if (eti->focused_row == row && eti->focused_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
/*
@ -834,7 +818,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e->button.x -= (x1 + eti->x1);
e->button.y -= (y1 + eti->y1);
e_cell_event (ecell_view, e, col, row);
e_cell_event (ecell_view, e, ecol->col_idx, col, row);
}
break;
}
@ -887,8 +871,9 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
}
}
ecol = e_table_header_get_column (eti->header, eti->focused_col);
ecell_view = eti->cell_views [eti->focused_col];
e_cell_event (ecell_view, e, eti->focused_col, eti->focused_row);
e_cell_event (ecell_view, e, ecol->col_idx, eti->focused_col, eti->focused_row);
break;
case GDK_KEY_RELEASE:
@ -897,7 +882,8 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (eti_editing (eti)){
ecell_view = eti->cell_views [eti->editing_col];
e_cell_event (ecell_view, e, eti->editing_col, eti->editing_row);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_event (ecell_view, e, ecol->col_idx, eti->editing_col, eti->editing_row);
}
break;
@ -1125,25 +1111,34 @@ e_table_item_select_row (ETableItem *eti, int row)
void
e_table_item_enter_edit (ETableItem *eti, int col, int row)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
eti->editing_col = col;
eti->editing_row = row;
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], col, row);
ecol = e_table_header_get_column (eti->header, col);
eti->edit_ctx = e_cell_enter_edit (eti->cell_views [col], ecol->col_idx, col, row);
}
void
e_table_item_leave_edit (ETableItem *eti)
{
ETableCol *ecol;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
if (!eti_editing (eti))
return;
e_cell_leave_edit (eti->cell_views [eti->editing_col], eti->editing_col, eti->editing_row, eti->edit_ctx);
ecol = e_table_header_get_column (eti->header, eti->editing_col);
e_cell_leave_edit (
eti->cell_views [eti->editing_col],
ecol->col_idx, eti->editing_col,
eti->editing_row, eti->edit_ctx);
eti->editing_col = -1;
eti->editing_row = -1;
eti->edit_ctx = NULL;

View File

@ -27,6 +27,7 @@ typedef struct {
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
int table_model_row_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@ -36,6 +37,7 @@ typedef struct {
unsigned int draw_grid:1;
unsigned int draw_focus:1;
unsigned int mode_spreadsheet:1;
unsigned int renderers_can_change_size:1;
int focused_col, focused_row;

View File

@ -58,7 +58,16 @@ e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
return ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_ROW_CHANGED], row);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
/*
* Notice that "model_changed" is not emitted
*/
}
gboolean

View File

@ -28,6 +28,12 @@ typedef struct {
/*
* Signals
*/
/*
* Major structural changes: model_changed
* Changes only in a row: row_changed
* Only changes in a cell: cell_changed
*/
void (*model_changed) (ETableModel *etm);
void (*model_row_changed) (ETableModel *etm, int row);
void (*model_cell_changed) (ETableModel *etm, int col, int row);

View File

@ -18,8 +18,6 @@ static ETableModelClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
ets_parent_class = gtk_type_class (PARENT_TYPE);
}

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <fcntl.h>
#include <gnome.h>
#include "e-cursors.h"
int
main (int argc, char *argv [])
@ -32,7 +33,6 @@ main (int argc, char *argv [])
table_browser_test ();
multi_cols_test ();
check_test ();
gtk_main ();
e_cursors_shutdown ();

View File

@ -90,7 +90,6 @@ check_test (void)
ETableHeader *e_table_header;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
int i;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());

View File

@ -87,7 +87,7 @@ multi_cols_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
int i;
@ -122,13 +122,20 @@ multi_cols_test (void)
g_free (images);
}
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*
* Second test
*/
e_table_header_multiple = e_table_header_new ();
e_table_header_add_column (e_table_header_multiple, col_0, 0);
e_table_header_add_column (e_table_header_multiple, col_1, 1);
e_table_header_add_column (e_table_header_multiple, col_1, 2);
/*
* GUI
*/
@ -140,6 +147,7 @@ multi_cols_test (void)
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
@ -160,6 +168,25 @@ multi_cols_test (void)
"spreadsheet", TRUE,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header_multiple,
"x", 300,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
"x", 300,
"y", 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}

View File

@ -90,7 +90,6 @@ check_test (void)
ETableHeader *e_table_header;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
int i;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());

View File

@ -87,7 +87,7 @@ multi_cols_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
int i;
@ -122,13 +122,20 @@ multi_cols_test (void)
g_free (images);
}
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*
* Second test
*/
e_table_header_multiple = e_table_header_new ();
e_table_header_add_column (e_table_header_multiple, col_0, 0);
e_table_header_add_column (e_table_header_multiple, col_1, 1);
e_table_header_add_column (e_table_header_multiple, col_1, 2);
/*
* GUI
*/
@ -140,6 +147,7 @@ multi_cols_test (void)
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
@ -160,6 +168,25 @@ multi_cols_test (void)
"spreadsheet", TRUE,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header_multiple,
"x", 300,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
"x", 300,
"y", 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}