X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fgtksheet%2Fgtksheet.c;h=ae71057215f37b12054247da15528c4cca5c920a;hb=0e9db36b34555b194714aa3f2af19e51907e8426;hp=57ae79dfe36d3abb03c3164f5d55df41bb012ec8;hpb=8fa97cbb0299bddaa217bb23dcbac3e6f2503cd1;p=pspp-builds.git diff --git a/lib/gtksheet/gtksheet.c b/lib/gtksheet/gtksheet.c index 57ae79df..ae710572 100644 --- a/lib/gtksheet/gtksheet.c +++ b/lib/gtksheet/gtksheet.c @@ -96,6 +96,7 @@ enum #define CELL_SPACING 1 #define DRAG_WIDTH 6 #define TIMEOUT_FLASH 200 +#define TIMEOUT_HOVER 300 #define TIME_INTERVAL 8 #define COLUMN_MIN_WIDTH 10 #define MINROWS 1 @@ -1167,6 +1168,8 @@ gtk_sheet_init (GtkSheet *sheet) 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; } @@ -3803,6 +3806,10 @@ gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) 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, gint x, @@ -3810,25 +3817,43 @@ gtk_sheet_get_pixel_info (GtkSheet *sheet, gint *row, gint *column) { - gint trow = -1; - gint tcol = -1; + 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; } @@ -5271,6 +5296,159 @@ gtk_sheet_button_release (GtkWidget * widget, 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); + + gtk_window_set_type_hint (GTK_WINDOW (hw->window), + GDK_WINDOW_TYPE_HINT_TOOLTIP); + + 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) @@ -5291,6 +5469,26 @@ gtk_sheet_motion (GtkWidget * widget, 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)) { @@ -5467,7 +5665,8 @@ gtk_sheet_motion (GtkWidget * widget, /*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) @@ -5505,7 +5704,6 @@ gtk_sheet_motion (GtkWidget * widget, 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; @@ -5526,8 +5724,6 @@ gtk_sheet_motion (GtkWidget * widget, return TRUE; } - - gtk_sheet_get_pixel_info (sheet, x, y, &row, &column); if (sheet->state == GTK_SHEET_NORMAL && row == sheet->active_cell.row &&