gnumeric-canvas.c 5.7 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * The Gnumeric Sheet widget.
 *
 * (C) 1998 The Free Software Foundation
 *
 * Author:
 *     Miguel de Icaza (miguel@kernel.org)
 */
9
#include <config.h>
10 11

#include <gnome.h>
12 13
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
14 15
#include "gnumeric.h"
#include "gnumeric-sheet.h"
16 17 18

/* Signals emited by the Gnumeric Sheet widget */
enum {
19
	LAST_SIGNAL
20 21
};

22
static guint sheet_signals [LAST_SIGNAL] = { 0 };
23 24 25 26 27 28 29 30 31

static GnomeCanvasClass *sheet_parent_class;

static void
gnumeric_sheet_destroy (GtkObject *object)
{
	GnumericSheet *gsheet;

	/* Add shutdown code here */
Arturo Espinosa's avatar
Arturo Espinosa committed
32 33
	gsheet = GNUMERIC_SHEET (object);
	
34 35 36 37
	if (GTK_OBJECT_CLASS (sheet_parent_class)->destroy)
		(*GTK_OBJECT_CLASS (sheet_parent_class)->destroy)(object);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
38
static GnumericSheet *
39
gnumeric_sheet_create (Sheet *sheet, GtkWidget *entry)
Arturo Espinosa's avatar
Arturo Espinosa committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
{
	GnumericSheet *gsheet;
	GnomeCanvas   *canvas;
	
	gsheet = gtk_type_new (gnumeric_sheet_get_type ());
	canvas = GNOME_CANVAS (gsheet);

	canvas->visual = gtk_widget_get_default_visual ();
	canvas->colormap = gtk_widget_get_default_colormap ();
	canvas->cc   = gdk_color_context_new (canvas->visual, canvas->colormap);
	canvas->root = gnome_canvas_group_new (canvas);
	
	gsheet->sheet   = sheet;
	gsheet->top_col = 0;
	gsheet->top_row = 0;
55
	gsheet->entry   = entry;
56
	
Arturo Espinosa's avatar
Arturo Espinosa committed
57 58 59
	return gsheet;
}

60 61 62 63 64 65 66
static void
gnumeric_sheet_move_cursor_horizontal (GnumericSheet *sheet, int count)
{
	ItemCursor *item_cursor = sheet->item_cursor;
	int new_left;
	
	new_left = item_cursor->start_col + count;
67 68 69

	if (new_left < 0)
		return;
70 71
	
	if (new_left < sheet->top_col){
72 73
		g_warning ("do scroll\n");
		return;
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
	}

	if (new_left < 0)
		new_left = 0;
	
	item_cursor_set_bounds (item_cursor,
				new_left, item_cursor->end_col + count,
				item_cursor->start_row, item_cursor->end_row);
}

static void
gnumeric_sheet_move_cursor_vertical (GnumericSheet *sheet, int count)
{
	ItemCursor *item_cursor = sheet->item_cursor;
	int new_top;
		
	new_top = item_cursor->start_row + count;

	if (new_top < 0)
93 94 95 96 97 98
		return;

	if (new_top < sheet->top_row){
		g_warning ("do scroll\n");
		return;
	}
99 100 101 102 103 104
	
	item_cursor_set_bounds (item_cursor,
				item_cursor->start_col, item_cursor->end_col,
				new_top, item_cursor->end_row + count);
}

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
static void
start_editing_at_cursor (GnumericSheet *sheet, GtkWidget *entry)
{
	GnomeCanvasItem *item;
	GnomeCanvas *canvas = GNOME_CANVAS (sheet);

	item = gnome_canvas_item_new (canvas, canvas->root,
				      item_edit_get_type (),
				      "ItemEdit::Sheet",    sheet->sheet,
				      "ItemEdit::Grid",     sheet->item_grid,
				      "ItemEdit::Col",      2,
				      "ItemEdit::Row",      2,
				      "ItemEdit::GtkEntry", entry,
				      NULL);

	sheet->item_editor = ITEM_EDIT (item);
}

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
static gint
gnumeric_sheet_key (GtkWidget *widget, GdkEventKey *event)
{
	GnumericSheet *sheet = GNUMERIC_SHEET (widget);

	switch (event->keyval){
	case GDK_Left:
		gnumeric_sheet_move_cursor_horizontal (sheet, -1);
		break;

	case GDK_Right:
		gnumeric_sheet_move_cursor_horizontal (sheet, 1);
		break;

	case GDK_Up:
		gnumeric_sheet_move_cursor_vertical (sheet, -1);
		break;

	case GDK_Down:
		gnumeric_sheet_move_cursor_vertical (sheet, 1);
		break;

	default:
146 147 148 149 150 151 152
		if (!sheet->item_editor){
			Workbook *wb = sheet->sheet->parent_workbook;
			
			gtk_window_set_focus (wb->toplevel, wb->ea_input);
			start_editing_at_cursor (sheet, wb->ea_input);
			gtk_widget_event (sheet->entry, event);
		}
153 154 155 156
	}
	return 1;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
157 158 159
GtkWidget *
gnumeric_sheet_new (Sheet *sheet)
{
160
	GnomeCanvasItem *item;
Arturo Espinosa's avatar
Arturo Espinosa committed
161
	GnumericSheet *gsheet;
162 163 164
	GnomeCanvas   *gsheet_canvas;
	GnomeCanvasGroup *gsheet_group;
	GtkWidget *widget;
165
	GtkWidget *entry = sheet->parent_workbook->ea_input;
Arturo Espinosa's avatar
Arturo Espinosa committed
166
	
167
	gsheet = gnumeric_sheet_create (sheet, entry);
Arturo Espinosa's avatar
Arturo Espinosa committed
168
	gnome_canvas_set_size (GNOME_CANVAS (gsheet), 300, 100);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

	/* handy shortcuts */
	gsheet_canvas = GNOME_CANVAS (gsheet);
	gsheet_group = GNOME_CANVAS_GROUP (gsheet_canvas->root);
	
	/* The grid */
	item = gnome_canvas_item_new (gsheet_canvas, gsheet_group,
				      item_grid_get_type (),
				      "ItemGrid::Sheet", sheet,
				      NULL);
	gsheet->item_grid = ITEM_GRID (item);

	/* The cursor */
	item = gnome_canvas_item_new (gsheet_canvas, gsheet_group,
				      item_cursor_get_type (),
				      "ItemCursor::Sheet", sheet,
				      "ItemCursor::Grid", gsheet->item_grid,
				      NULL);
	gsheet->item_cursor = ITEM_CURSOR (item);
188

189 190 191 192 193 194 195 196 197 198
	widget = GTK_WIDGET (gsheet);

	return widget;
}

static void
gnumeric_sheet_realize (GtkWidget *widget)
{
	if (GTK_WIDGET_CLASS (sheet_parent_class)->realize)
		(*GTK_WIDGET_CLASS (sheet_parent_class)->realize)(widget);
Arturo Espinosa's avatar
Arturo Espinosa committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
}

static void
gnumeric_sheet_class_init (GnumericSheetClass *class)
{
	GtkObjectClass *object_class;
	GtkWidgetClass *widget_class;
	GnomeCanvasClass *canvas_class;

	object_class = (GtkObjectClass *) class;
	widget_class = (GtkWidgetClass *) class;
	canvas_class = (GnomeCanvasClass *) class;
	
	sheet_parent_class = gtk_type_class (gnome_canvas_get_type());

	/* Method override */
	object_class->destroy = gnumeric_sheet_destroy;
216 217
	widget_class->key_press_event = gnumeric_sheet_key;
	widget_class->realize = gnumeric_sheet_realize;
Arturo Espinosa's avatar
Arturo Espinosa committed
218 219
}

Arturo Espinosa's avatar
Arturo Espinosa committed
220 221 222 223 224
static void
gnumeric_sheet_init (GnumericSheet *gsheet)
{
	GnomeCanvas *canvas = GNOME_CANVAS (gsheet);

225 226
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_DEFAULT);
Arturo Espinosa's avatar
Arturo Espinosa committed
227 228
}

229 230 231 232 233 234 235 236 237 238 239
GtkType
gnumeric_sheet_get_type (void)
{
	static GtkType gnumeric_sheet_type = 0;

	if (!gnumeric_sheet_type){
		GtkTypeInfo gnumeric_sheet_info = {
			"GnumericSheet",
			sizeof (GnumericSheet),
			sizeof (GnumericSheetClass),
			(GtkClassInitFunc) gnumeric_sheet_class_init,
Arturo Espinosa's avatar
Arturo Espinosa committed
240
			(GtkObjectInitFunc) gnumeric_sheet_init,
241 242 243 244 245
			NULL, /* reserved 1 */
			NULL, /* reserved 2 */
			(GtkClassInitFunc) NULL
		};

Arturo Espinosa's avatar
Arturo Espinosa committed
246
		gnumeric_sheet_type = gtk_type_unique (gnome_canvas_get_type (), &gnumeric_sheet_info);
247 248 249 250
	}

	return gnumeric_sheet_type;
}