#define CELL_SPACING 1
#define DRAG_WIDTH 6
-#define TIMEOUT_SCROLL 20
#define TIMEOUT_FLASH 200
+#define TIMEOUT_HOVER 300
#define TIME_INTERVAL 8
#define COLUMN_MIN_WIDTH 10
#define MINROWS 1
return cx;
}
-#define MIN_VISIBLE_ROW(sheet) sheet->view.row0
-#define MAX_VISIBLE_ROW(sheet) sheet->view.rowi
-#define MIN_VISIBLE_COLUMN(sheet) sheet->view.col0
-#define MAX_VISIBLE_COLUMN(sheet) sheet->view.coli
+#define MIN_VISIBLE_ROW(sheet) \
+ ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1)
+
+#define MAX_VISIBLE_ROW(sheet) \
+ ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1)
+
+#define MIN_VISIBLE_COLUMN(sheet) \
+ COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1)
+
+#define MAX_VISIBLE_COLUMN(sheet) \
+ COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width)
+
static inline gboolean
yyy_row_height (sheet, sheet->range.rowi);
if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
- ydrag = ROW_TOP_YPIXEL (sheet, sheet->view.row0);
+ ydrag = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet));
if (sheet->state == GTK_SHEET_ROW_SELECTED)
- xdrag = COLUMN_LEFT_XPIXEL (sheet, sheet->view.col0);
+ xdrag = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet));
*drag_column = COLUMN_FROM_XPIXEL (sheet,x);
*drag_row = ROW_FROM_YPIXEL (sheet,y);
gint row, gint column);
/* Clipped Range */
-static gint gtk_sheet_scroll (gpointer data);
static gint gtk_sheet_flash (gpointer data);
/* Drawing Routines */
static void gtk_sheet_cell_draw_default (GtkSheet *sheet,
gint row, gint column);
-/* draw cell border */
-static void gtk_sheet_cell_draw_border (GtkSheet *sheet,
- gint row, gint column,
- gint mask);
-
/* draw cell contents */
static void gtk_sheet_cell_draw_label (GtkSheet *sheet,
gint row, gint column);
/* Selection */
-static gint gtk_sheet_move_query (GtkSheet *sheet,
+static gboolean gtk_sheet_move_query (GtkSheet *sheet,
gint row, gint column);
static void gtk_sheet_real_select_range (GtkSheet * sheet,
const GtkSheetRange * range);
/* Scrollbars */
static void adjust_scrollbars (GtkSheet * sheet);
-static void vadjustment_changed (GtkAdjustment * adjustment,
- gpointer data);
-static void hadjustment_changed (GtkAdjustment * adjustment,
- gpointer data);
static void vadjustment_value_changed (GtkAdjustment * adjustment,
gpointer data);
static void hadjustment_value_changed (GtkAdjustment * adjustment,
sheet->children = NULL;
sheet->flags = 0;
- sheet->selection_mode = GTK_SELECTION_BROWSE;
+ sheet->selection_mode = GTK_SELECTION_NONE;
sheet->freeze_count = 0;
sheet->state = GTK_SHEET_NORMAL;
GTK_WIDGET_UNSET_FLAGS (sheet, GTK_NO_WINDOW);
GTK_WIDGET_SET_FLAGS (sheet, GTK_CAN_FOCUS);
- sheet->view.row0 = 0;
- sheet->view.col0 = 0;
- sheet->view.rowi = 0;
- sheet->view.coli = 0;
-
sheet->column_title_window = NULL;
sheet->column_title_area.x = 0;
sheet->column_title_area.y = 0;
gdk_color_parse ("gray", &sheet->grid_color);
gdk_color_alloc (gdk_colormap_get_system (), &sheet->grid_color);
sheet->show_grid = TRUE;
+
+ sheet->motion_events = 0;
}
range.coli = xxx_column_count (sheet) - 1;
range.rowi = yyy_row_count (sheet) - 1;
- sheet->view.col0 =
- COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1);
-
- sheet->view.coli =
- COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
-
- if ( sheet->view.coli > range.coli)
- sheet->view.coli = range.coli;
-
adjust_scrollbars (sheet);
if (sheet->active_cell.col >= model_columns)
range.rowi = yyy_row_count (sheet) - 1;
range.coli = xxx_column_count (sheet) - 1;
- sheet->view.row0 =
- ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
- sheet->view.rowi =
- ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
-
- if ( sheet->view.rowi > range.rowi)
- sheet->view.rowi = range.rowi;
-
adjust_scrollbars (sheet);
if (sheet->active_cell.row >= model_rows)
if ( ( row0 < 0 && col0 < 0 ) || ( rowi < 0 && coli < 0 ) )
{
+ gint i;
gtk_sheet_range_draw (sheet, NULL);
+ adjust_scrollbars (sheet);
+
+ for (i = MIN_VISIBLE_ROW (sheet); i <= MAX_VISIBLE_ROW (sheet); i++)
+ gtk_sheet_row_title_button_draw (sheet, i);
+
+ for (i = MIN_VISIBLE_COLUMN (sheet);
+ i <= MAX_VISIBLE_COLUMN (sheet); i++)
+ gtk_sheet_column_title_button_draw (sheet, i);
+
return;
}
else if ( row0 < 0 || rowi < 0 )
if (sheet->state == GTK_STATE_NORMAL)
if (sheet->sheet_entry && GTK_WIDGET_MAPPED (sheet->sheet_entry))
{
- gtk_sheet_activate_cell (sheet, sheet->active_cell.row, sheet->active_cell.col);
+ gtk_sheet_activate_cell (sheet, sheet->active_cell.row,
+ sheet->active_cell.col);
}
}
if (width < COLUMN_MIN_WIDTH) return;
sheet->row_title_area.width = width;
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1);
- sheet->view.coli = COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
-
adjust_scrollbars (sheet);
if (height < DEFAULT_ROW_HEIGHT (GTK_WIDGET (sheet))) return;
sheet->column_title_area.height = height;
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
- sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
adjust_scrollbars (sheet);
return sheet->row_titles_visible;
}
-
-
void
-gtk_sheet_moveto (GtkSheet * sheet,
+gtk_sheet_moveto (GtkSheet *sheet,
gint row,
gint column,
gfloat row_align,
width = sheet->sheet_window_width;
/* adjust vertical scrollbar */
-
if (row >= 0 && row_align >= 0.)
{
y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset
- - (gint) ( row_align*height + (1. - row_align) * yyy_row_height (sheet, row));
+ - (gint) ( row_align*height + (1. - row_align)
+ * yyy_row_height (sheet, row));
/* This forces the sheet to scroll when you don't see the entire cell */
min_row = row;
gtk_sheet_real_select_range (sheet, NULL);
}
+
+
void
gtk_sheet_clip_range (GtkSheet *sheet, const GtkSheetRange *range)
{
if (!GTK_SHEET_IN_CLIP (sheet)) return;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_CLIP);
+
gtk_timeout_remove (sheet->clip_timer);
gtk_sheet_range_draw (sheet, &sheet->clip_range);
GDK_THREADS_LEAVE ();
return TRUE;
-
}
static void
void
gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range)
{
-
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet)) ;
g_return_if_fail (range != NULL);
range->col0 = MIN_VISIBLE_COLUMN (sheet);
range->rowi = MAX_VISIBLE_ROW (sheet);
range->coli = MAX_VISIBLE_COLUMN (sheet);
-
}
GtkAdjustment *
gtk_object_ref (GTK_OBJECT (sheet->vadjustment));
gtk_object_sink (GTK_OBJECT (sheet->vadjustment));
- gtk_signal_connect (GTK_OBJECT (sheet->vadjustment), "changed",
- (GtkSignalFunc) vadjustment_changed,
- (gpointer) sheet);
gtk_signal_connect (GTK_OBJECT (sheet->vadjustment), "value_changed",
(GtkSignalFunc) vadjustment_value_changed,
(gpointer) sheet);
gtk_object_ref (GTK_OBJECT (sheet->hadjustment));
gtk_object_sink (GTK_OBJECT (sheet->hadjustment));
- gtk_signal_connect (GTK_OBJECT (sheet->hadjustment), "changed",
- (GtkSignalFunc) hadjustment_changed,
- (gpointer) sheet);
gtk_signal_connect (GTK_OBJECT (sheet->hadjustment), "value_changed",
(GtkSignalFunc) hadjustment_value_changed,
(gpointer) sheet);
sheet->button = NULL;
}
- if (sheet->timer)
- {
- gtk_timeout_remove (sheet->timer);
- sheet->timer = 0;
- }
-
if (sheet->clip_timer)
{
gtk_timeout_remove (sheet->clip_timer);
}
}
-static void
-gtk_sheet_cell_draw_border (GtkSheet *sheet, gint row, gint col, gint mask)
-{
- GtkWidget *widget;
- GdkGC *fg_gc, *bg_gc;
- GtkSheetCellAttr attributes;
- GdkRectangle area;
- guint width;
-
- g_return_if_fail (sheet != NULL);
-
- /* bail now if we arn't drawable yet */
- if (!GTK_WIDGET_DRAWABLE (sheet)) return;
-
- if (row < 0 || row >= yyy_row_count (sheet)) return;
- if (col < 0 || col >= xxx_column_count (sheet)) return;
- if (!xxx_column_is_visible (sheet, col)) return;
- if (!yyy_row_is_visible (sheet, row)) return;
-
- widget = GTK_WIDGET (sheet);
-
- gtk_sheet_get_attributes (sheet, row, col, &attributes);
-
- /* select GC for background rectangle */
- gdk_gc_set_foreground (sheet->fg_gc, &attributes.border.color);
- gdk_gc_set_foreground (sheet->bg_gc, &attributes.background);
-
- fg_gc = sheet->fg_gc;
- bg_gc = sheet->bg_gc;
-
- area.x = COLUMN_LEFT_XPIXEL (sheet,col);
- area.y = ROW_TOP_YPIXEL (sheet,row);
- area.width = xxx_column_width (sheet, col);
- area.height = yyy_row_height (sheet, row);
-
- width = attributes.border.width;
- gdk_gc_set_line_attributes (sheet->fg_gc, attributes.border.width,
- attributes.border.line_style,
- attributes.border.cap_style,
- attributes.border.join_style);
- if (width > 0)
- {
-
- if (attributes.border.mask & GTK_SHEET_LEFT_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x, area.y - width / 2,
- area.x, area.y + area.height + width / 2+1);
-
- if (attributes.border.mask & GTK_SHEET_RIGHT_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x + area.width, area.y - width / 2,
- area.x + area.width,
- area.y + area.height + width / 2+1);
-
- if (attributes.border.mask & GTK_SHEET_TOP_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x - width / 2,area.y,
- area.x + area.width + width / 2+1,
- area.y);
-
- if (attributes.border.mask & GTK_SHEET_BOTTOM_BORDER & mask)
- gdk_draw_line (sheet->pixmap, sheet->fg_gc,
- area.x - width / 2, area.y + area.height,
- area.x + area.width + width / 2+1,
- area.y + area.height);
- }
-
-}
-
-
static void
gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col)
{
}
-
-
static void
gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range)
{
{
drawing_range.row0 = MIN_VISIBLE_ROW (sheet);
drawing_range.col0 = MIN_VISIBLE_COLUMN (sheet);
- drawing_range.rowi = MIN (MAX_VISIBLE_ROW (sheet), yyy_row_count (sheet) - 1);
+ drawing_range.rowi = MIN (MAX_VISIBLE_ROW (sheet),
+ yyy_row_count (sheet) - 1);
drawing_range.coli = MAX_VISIBLE_COLUMN (sheet);
GTK_WIDGET (sheet)->style->white_gc,
TRUE,
0,0,
- sheet->sheet_window_width,sheet->sheet_window_height);
-
+ sheet->sheet_window_width,
+ sheet->sheet_window_height);
}
else
{
drawing_range.coli = MIN (range->coli, MAX_VISIBLE_COLUMN (sheet));
}
-
if (drawing_range.coli == xxx_column_count (sheet) - 1)
{
area.x = COLUMN_LEFT_XPIXEL (sheet,
for (j = drawing_range.col0; j <= drawing_range.coli; j++)
{
gtk_sheet_cell_draw_default (sheet, i, j);
+ gtk_sheet_cell_draw_label (sheet, i, j);
}
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.col0; j <= drawing_range.coli; j++)
- {
- gtk_sheet_cell_draw_border (sheet, i - 1, j, GTK_SHEET_BOTTOM_BORDER);
- gtk_sheet_cell_draw_border (sheet, i + 1, j, GTK_SHEET_TOP_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j - 1, GTK_SHEET_RIGHT_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j + 1, GTK_SHEET_LEFT_BORDER);
- gtk_sheet_cell_draw_border (sheet, i, j, 15);
- }
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.col0; j <= drawing_range.coli; j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j= xxx_column_left_column (sheet, drawing_range.col0);
- j < drawing_range.col0; j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
- for (i = drawing_range.row0; i <= drawing_range.rowi; i++)
- for (j = drawing_range.coli + 1;
- j <= xxx_column_right_column (sheet, drawing_range.coli);
- j++)
- gtk_sheet_cell_draw_label (sheet, i, j);
-
gtk_sheet_draw_backing_pixmap (sheet, drawing_range);
if (sheet->state != GTK_SHEET_NORMAL &&
sheet->active_cell.col >= drawing_range.col0 &&
sheet->active_cell.col <= drawing_range.coli)
gtk_sheet_show_active_cell (sheet);
-
}
static void
}
if (j == sheet->range.coli) area.width = area.width - 3;
- if (i!=sheet->active_cell.row || j!=sheet->active_cell.col)
+ if (i != sheet->active_cell.row || j != sheet->active_cell.col)
{
gdk_draw_rectangle (sheet->sheet_window,
sheet->xor_gc,
range.row0 = row;
range.rowi = row;
- range.col0 = sheet->view.col0;
- range.coli = sheet->view.coli;
+ range.col0 = MIN_VISIBLE_COLUMN (sheet);
+ range.coli = MAX_VISIBLE_COLUMN (sheet);
if (gtk_sheet_autoresize (sheet) &&
text_width > xxx_column_width (sheet, col) -
range.row0 = row;
range.rowi = row;
- range.col0 = sheet->view.col0;
- range.coli = sheet->view.coli;
+ range.col0 = MIN_VISIBLE_COLUMN (sheet);
+ range.coli = MAX_VISIBLE_COLUMN (sheet);
gtk_sheet_real_cell_clear (sheet, row, column, FALSE);
range.row0 = row;
range.rowi = row;
- range.col0 = sheet->view.col0;
- range.coli = sheet->view.coli;
+ range.col0 = MIN_VISIBLE_COLUMN (sheet);
+ range.coli = MAX_VISIBLE_COLUMN (sheet);
gtk_sheet_real_cell_clear (sheet, row, column, TRUE);
return GTK_STATE_NORMAL;
}
+/* Convert X, Y (in pixels) to *ROW, *COLUMN (in cell coords)
+ -1 indicates the title buttons.
+ If the function returns FALSE, then the results will be unreliable.
+*/
gboolean
-gtk_sheet_get_pixel_info (GtkSheet * sheet,
+gtk_sheet_get_pixel_info (GtkSheet *sheet,
gint x,
gint y,
- gint * row,
- gint * column)
+ gint *row,
+ gint *column)
{
gint trow, tcol;
+ *row = -G_MAXINT;
+ *column = -G_MAXINT;
g_return_val_if_fail (sheet != NULL, 0);
g_return_val_if_fail (GTK_IS_SHEET (sheet), 0);
/* bounds checking, return false if the user clicked
on a blank area */
- trow = ROW_FROM_YPIXEL (sheet, y);
- if (trow >= yyy_row_count (sheet))
+ if (y < 0)
return FALSE;
- *row = trow;
-
- tcol = COLUMN_FROM_XPIXEL (sheet, x);
- if (tcol >= xxx_column_count (sheet))
+ if (x < 0)
return FALSE;
- *column = tcol;
+ if ( y < sheet->column_title_area.height + sheet->column_title_area.y)
+ *row = -1;
+
+ else
+ {
+ trow = ROW_FROM_YPIXEL (sheet, y);
+ if (trow > yyy_row_count (sheet))
+ return FALSE;
+
+ *row = trow;
+ }
+
+ if ( x < sheet->row_title_area.width + sheet->row_title_area.x)
+ *column = -1;
+ else
+ {
+ tcol = COLUMN_FROM_XPIXEL (sheet, x);
+ if (tcol > xxx_column_count (sheet))
+ return FALSE;
+
+ *column = tcol;
+ }
return TRUE;
}
g_return_if_fail (sheet != NULL);
g_return_if_fail (GTK_IS_SHEET (sheet));
- *row = sheet->active_cell.row;
- *column = sheet->active_cell.col;
+ if ( row ) *row = sheet->active_cell.row;
+ if (column) *column = sheet->active_cell.col;
}
static void
sheet->selection_cell.col = col;
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
+
gtk_sheet_show_active_cell (sheet);
+
g_signal_connect (G_OBJECT (gtk_sheet_get_entry (sheet)),
"changed",
G_CALLBACK (gtk_sheet_entry_changed),
gtk_sheet_size_allocate_entry (sheet);
gtk_widget_map (sheet->sheet_entry);
- gtk_sheet_draw_active_cell (sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet_entry));
selected= (i <= new_range.rowi && i >= new_range.row0 &&
j <= new_range.coli && j >= new_range.col0) ? TRUE : FALSE;
- if (state!=GTK_STATE_SELECTED && selected &&
+ if (state != GTK_STATE_SELECTED && selected &&
xxx_column_is_visible (sheet, j) && yyy_row_is_visible (sheet, i) &&
(i != sheet->active_cell.row || j != sheet->active_cell.col))
{
mask2 = i == new_range.rowi ? mask2 + 2 : mask2;
mask2 = j == new_range.col0 ? mask2 + 4 : mask2;
mask2 = j == new_range.coli ? mask2 + 8 : mask2;
- if (mask2!=mask1 || (mask2 == mask1 && state!=GTK_STATE_SELECTED))
+ if (mask2 != mask1 || (mask2 == mask1 && state != GTK_STATE_SELECTED))
{
x = COLUMN_LEFT_XPIXEL (sheet,j);
y = ROW_TOP_YPIXEL (sheet, i);
GtkWidget *widget;
GdkRectangle area;
gint i;
- gint x,y,width,height;
+ gint x, y, width, height;
widget = GTK_WIDGET (sheet);
x = COLUMN_LEFT_XPIXEL (sheet,new_range.col0);
y = ROW_TOP_YPIXEL (sheet,new_range.row0);
- width = COLUMN_LEFT_XPIXEL (sheet,new_range.coli)- x+
+ width = COLUMN_LEFT_XPIXEL (sheet, new_range.coli) - x +
xxx_column_width (sheet, new_range.coli);
- height = ROW_TOP_YPIXEL (sheet,new_range.rowi)- y+
+ height = ROW_TOP_YPIXEL (sheet, new_range.rowi) - y +
yyy_row_height (sheet, new_range.rowi);
area.x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet));
gdk_draw_rectangle (sheet->sheet_window,
sheet->xor_gc,
FALSE,
- x + i,y + i,
- width - 2 * i,height - 2 * i);
+ x + i,
+ y + i,
+ width - 2 * i,
+ height - 2 * i);
gdk_gc_set_clip_rectangle (sheet->xor_gc, NULL);
- gtk_sheet_draw_corners (sheet, new_range);
+ gtk_sheet_draw_corners (sheet, new_range);
}
static void
width = 1;
if (sheet->state == GTK_SHEET_COLUMN_SELECTED)
{
- y = ROW_TOP_YPIXEL (sheet, sheet->view.row0)+3;
+ y = ROW_TOP_YPIXEL (sheet, MIN_VISIBLE_ROW (sheet))+3;
width = 3;
}
gdk_draw_pixmap (sheet->sheet_window,
width = 1;
if (sheet->state == GTK_SHEET_ROW_SELECTED)
{
- x = COLUMN_LEFT_XPIXEL (sheet, sheet->view.col0)+3;
+ x = COLUMN_LEFT_XPIXEL (sheet, MIN_VISIBLE_COLUMN (sheet))+3;
width = 3;
}
gdk_draw_pixmap (sheet->sheet_window,
gtk_signal_emit (GTK_OBJECT (sheet), sheet_signals[SELECT_RANGE], &sheet->range);
}
+
+void
+gtk_sheet_get_selected_range (GtkSheet *sheet,
+ GtkSheetRange *range)
+{
+ g_return_if_fail (sheet != NULL);
+ *range = sheet->range;
+}
+
+
void
gtk_sheet_select_range (GtkSheet * sheet, const GtkSheetRange *range)
{
g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
+
sheet = GTK_SHEET (widget);
if (GTK_WIDGET_DRAWABLE (widget))
}
-static gint
+static gboolean
gtk_sheet_button_press (GtkWidget * widget,
GdkEventButton * event)
{
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, event->time);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
+
+ /* This seems to be a kludge to work around a problem where the sheet
+ scrolls to another position. The timeout scrolls it back to its
+ original posn. JMD 3 July 2007
+ */
gtk_widget_grab_focus (GTK_WIDGET (sheet));
if (sheet->selection_mode != GTK_SELECTION_SINGLE &&
+ sheet->selection_mode != GTK_SELECTION_NONE &&
sheet->cursor_drag->type == GDK_SIZING &&
!GTK_SHEET_IN_SELECTION (sheet) && !GTK_SHEET_IN_RESIZE (sheet))
{
{
gtk_widget_get_pointer (widget, &x, &y);
column = COLUMN_FROM_XPIXEL (sheet, x);
+
if (xxx_column_is_sensitive (sheet, column))
{
gtk_sheet_click_cell (sheet, - 1, column, &veto);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
{
gtk_sheet_click_cell (sheet, row, - 1, &veto);
gtk_grab_add (GTK_WIDGET (sheet));
- sheet->timer = gtk_timeout_add (TIMEOUT_SCROLL, gtk_sheet_scroll, sheet);
gtk_widget_grab_focus (GTK_WIDGET (sheet));
GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
}
return TRUE;
}
+#if 0
static gint
gtk_sheet_scroll (gpointer data)
{
GDK_THREADS_LEAVE ();
return TRUE;
-
}
+#endif
static void
gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto)
if (GTK_SHEET_IN_SELECTION)
gdk_pointer_ungrab (event->time);
- if (sheet->timer)
- gtk_timeout_remove (sheet->timer);
gtk_grab_remove (GTK_WIDGET (sheet));
GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION);
return TRUE;
}
+/* Shamelessly lifted from gtktooltips */
+static gboolean
+gtk_sheet_subtitle_paint_window (GtkWidget *tip_window)
+{
+ GtkRequisition req;
+
+ gtk_widget_size_request (tip_window, &req);
+ gtk_paint_flat_box (tip_window->style, tip_window->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ NULL, GTK_WIDGET(tip_window), "tooltip",
+ 0, 0, req.width, req.height);
+
+ return FALSE;
+}
+
+static GtkSheetHoverTitle *
+create_hover_window (void)
+{
+ GtkSheetHoverTitle *hw = malloc (sizeof (*hw));
+
+ hw->window = gtk_window_new (GTK_WINDOW_POPUP);
+
+#if GTK_CHECK_VERSION (2, 9, 0)
+ gtk_window_set_type_hint (GTK_WINDOW (hw->window),
+ GDK_WINDOW_TYPE_HINT_TOOLTIP);
+#endif
+
+ gtk_widget_set_app_paintable (hw->window, TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (hw->window), FALSE);
+ gtk_widget_set_name (hw->window, "gtk-tooltips");
+ gtk_container_set_border_width (GTK_CONTAINER (hw->window), 4);
+
+ g_signal_connect (hw->window,
+ "expose_event",
+ G_CALLBACK (gtk_sheet_subtitle_paint_window),
+ NULL);
+
+ hw->label = gtk_label_new (NULL);
+
+
+ gtk_label_set_line_wrap (GTK_LABEL (hw->label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (hw->label), 0.5, 0.5);
+
+ gtk_container_add (GTK_CONTAINER (hw->window), hw->label);
+
+ gtk_widget_show (hw->label);
+
+ g_signal_connect (hw->window,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &hw->window);
+
+ return hw;
+}
+
+#define HOVER_WINDOW_Y_OFFSET 2
+
+static void
+show_subtitle (GtkSheet *sheet, gint row, gint column, const gchar *subtitle)
+{
+ gint x, y;
+ gint px, py;
+ gint width;
+
+ if ( ! subtitle )
+ return;
+
+ if ( ! sheet->hover_window)
+ {
+ sheet->hover_window = create_hover_window ();
+ gtk_widget_add_events (GTK_WIDGET (sheet), GDK_LEAVE_NOTIFY_MASK);
+
+ g_signal_connect_swapped (sheet, "leave-notify-event",
+ G_CALLBACK (gtk_widget_hide),
+ sheet->hover_window->window);
+ }
+
+ gtk_label_set_text (GTK_LABEL (sheet->hover_window->label),
+ subtitle);
+
+
+ sheet->hover_window->row = row;
+ sheet->hover_window->column = column;
+
+ gdk_window_get_origin (GTK_WIDGET (sheet)->window, &x, &y);
+
+ gtk_widget_get_pointer (GTK_WIDGET (sheet), &px, &py);
+
+ gtk_widget_show (sheet->hover_window->window);
+
+ width = GTK_WIDGET (sheet->hover_window->label)->allocation.width;
+
+ if (row == -1 )
+ {
+ x += px;
+ x -= width / 2;
+ y += sheet->column_title_area.y;
+ y += sheet->column_title_area.height;
+ y += HOVER_WINDOW_Y_OFFSET;
+ }
+
+ if ( column == -1 )
+ {
+ y += py;
+ x += sheet->row_title_area.x;
+ x += sheet->row_title_area.width * 2 / 3.0;
+ }
+
+ gtk_window_move (GTK_WINDOW (sheet->hover_window->window),
+ x, y);
+}
+
+static gboolean
+motion_timeout_callback (gpointer data)
+{
+ GtkSheet *sheet = GTK_SHEET (data);
+ if ( --sheet->motion_events == 0 )
+ {
+ gint x, y;
+ gint row, column;
+ gtk_widget_get_pointer (GTK_WIDGET (sheet), &x, &y);
+
+ if ( gtk_sheet_get_pixel_info (sheet, x, y, &row, &column) )
+ {
+ if ( column == -1 && row == -1 )
+ return FALSE;
+
+ if ( column == -1)
+ {
+ GSheetRow *row_geo = sheet->row_geometry;
+ gchar *text;
+
+ text = g_sheet_row_get_subtitle (row_geo, row);
+
+ show_subtitle (sheet, row, column, text);
+ g_free (text);
+ }
+
+ if ( row == -1)
+ {
+ GSheetColumn *col_geo = sheet->column_geometry;
+ gchar *text;
+
+ text = g_sheet_column_get_subtitle (col_geo, column);
+
+ show_subtitle (sheet, row, column, text );
+
+ g_free (text);
+ }
+ }
+ }
+
+ return FALSE;
+}
+
static gint
gtk_sheet_motion (GtkWidget * widget,
GdkEventMotion * event)
x = event->x;
y = event->y;
+ if (!sheet->hover_window || ! GTK_WIDGET_VISIBLE (sheet->hover_window->window))
+ {
+ sheet->motion_events++;
+ g_timeout_add (TIMEOUT_HOVER, motion_timeout_callback, sheet);
+ }
+ else
+ {
+ gint row, column;
+ gint wx, wy;
+ gtk_widget_get_pointer (widget, &wx, &wy);
+
+ if ( gtk_sheet_get_pixel_info (sheet, wx, wy, &row, &column) )
+ {
+ if ( row != sheet->hover_window->row || column != sheet->hover_window->column)
+ {
+ gtk_widget_hide (sheet->hover_window->window);
+ }
+ }
+ }
+
if (event->window == sheet->column_title_window &&
gtk_sheet_columns_resizable (sheet))
{
new_cursor = GDK_SIZING;
if ( event->window == sheet->sheet_window &&
+ sheet->selection_mode != GTK_SELECTION_NONE &&
!GTK_SHEET_IN_DRAG (sheet) &&
(POSSIBLE_RESIZE (sheet, x, y, &row, &column) ||
GTK_SHEET_IN_RESIZE (sheet)) &&
gdk_window_set_cursor (sheet->sheet_window,sheet->cursor_drag);
}
+
gdk_window_get_pointer (widget->window, &x, &y, &mods);
if (! (mods & GDK_BUTTON1_MASK)) return FALSE;
/*use half of column width resp. row height as threshold to
expand selection*/
- col_threshold = COLUMN_LEFT_XPIXEL (sheet,current_col)+xxx_column_width (sheet,current_col)/2;
+ col_threshold = COLUMN_LEFT_XPIXEL (sheet,current_col) +
+ xxx_column_width (sheet,current_col) / 2;
if (column > 0)
{
if (x < col_threshold)
if (aux.row0 + row >= 0 && aux.rowi + row < yyy_row_count (sheet) &&
aux.col0 + column >= 0 && aux.coli + column < xxx_column_count (sheet))
{
-
aux = sheet->drag_range;
sheet->drag_range = sheet->range;
return TRUE;
}
-
-
gtk_sheet_get_pixel_info (sheet, x, y, &row, &column);
if (sheet->state == GTK_SHEET_NORMAL && row == sheet->active_cell.row &&
return TRUE;
}
-static gint
+static gboolean
gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column)
{
gint row_move, column_move;
height = sheet->sheet_window_height;
width = sheet->sheet_window_width;
- if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
+ if (row >= MAX_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED)
{
row_align = 1.;
new_row = MIN (yyy_row_count (sheet), row + 1);
row_align = -1.;
}
}
- if (row < MIN_VISIBLE_ROW (sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED)
+ if (row < MIN_VISIBLE_ROW (sheet) && sheet->state != GTK_SHEET_COLUMN_SELECTED)
{
row_align= 0.;
row_move = TRUE;
}
- if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
+ if (column >= MAX_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED)
{
col_align = 1.;
new_col = MIN (xxx_column_count (sheet) - 1, column + 1);
col_align = -1.;
}
}
- if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED)
+ if (column < MIN_VISIBLE_COLUMN (sheet) && sheet->state != GTK_SHEET_ROW_SELECTED)
{
col_align = 0.;
column_move = TRUE;
if (sheet->row_titles_visible)
requisition->width += sheet->row_title_area.width;
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
- sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1);
- sheet->view.coli = COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
-
- if (!sheet->column_titles_visible)
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, 1);
-
- if (!sheet->row_titles_visible)
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, 1);
-
children = sheet->children;
while (children)
{
/* row button allocation */
size_allocate_row_title_buttons (sheet);
-
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
- sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1);
- sheet->view.coli = COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
-
- if (!sheet->column_titles_visible)
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, 1);
-
- if (!sheet->row_titles_visible)
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, 1);
-
size_allocate_column_title_buttons (sheet);
- size_allocate_row_title_buttons (sheet);
/* re - scale backing pixmap */
gtk_sheet_make_backing_pixmap (sheet, 0, 0);
*
* functions:
* adjust_scrollbars
- * vadjustment_changed
- * hadjustment_changed
* vadjustment_value_changed
* hadjustment_value_changed */
static void
adjust_scrollbars (GtkSheet * sheet)
{
-
if (sheet->vadjustment)
{
sheet->vadjustment->page_size = sheet->sheet_window_height;
}
}
-
-static void
-vadjustment_changed (GtkAdjustment * adjustment,
- gpointer data)
-{
- GtkSheet *sheet;
-
- g_return_if_fail (adjustment != NULL);
- g_return_if_fail (data != NULL);
-
- sheet = GTK_SHEET (data);
-
-}
-
-static void
-hadjustment_changed (GtkAdjustment * adjustment,
- gpointer data)
-{
- GtkSheet *sheet;
-
- g_return_if_fail (adjustment != NULL);
- g_return_if_fail (data != NULL);
-
- sheet = GTK_SHEET (data);
-}
-
-
static void
vadjustment_value_changed (GtkAdjustment * adjustment,
gpointer data)
sheet->voffset = - value;
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, sheet->column_title_area.height + 1);
- sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
- if (!sheet->column_titles_visible)
- sheet->view.row0 = ROW_FROM_YPIXEL (sheet, 1);
-
if (GTK_WIDGET_REALIZED (sheet->sheet_entry) &&
sheet->state == GTK_SHEET_NORMAL &&
sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 &&
}
sheet->hoffset = - value;
-
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, sheet->row_title_area.width + 1);
- sheet->view.coli = COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
- if (!sheet->row_titles_visible)
- sheet->view.col0 = COLUMN_FROM_XPIXEL (sheet, 1);
-
if (GTK_WIDGET_REALIZED (sheet->sheet_entry) &&
sheet->state == GTK_SHEET_NORMAL &&
sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 &&
width = min_width;
xxx_set_column_width (sheet, column, width);
- sheet->view.coli = COLUMN_FROM_XPIXEL (sheet, sheet->sheet_window_width);
size_allocate_column_title_buttons (sheet);
return width;
height = min_height;
yyy_set_row_height (sheet, row, height);
- sheet->view.rowi = ROW_FROM_YPIXEL (sheet, sheet->sheet_window_height - 1);
size_allocate_row_title_buttons (sheet);
return height;
return;
}
- gtk_sheet_attach (sheet, widget, row, col, GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
+ gtk_sheet_attach (sheet, widget, row, col,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
}
void