X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpspp-sheet-view.c;h=ccdbd10e9919b5d61cbc059bd6d4c7284c66e277;hb=refs%2Fbuilds%2F20131111032724%2Fpspp;hp=6fce3a4930f8e7841c071d351db89ec0dc49a42e;hpb=5206c60ba8beaddccdf571db65709b38dbadb3fd;p=pspp diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c index 6fce3a4930..ccdbd10e99 100644 --- a/src/ui/gui/pspp-sheet-view.c +++ b/src/ui/gui/pspp-sheet-view.c @@ -135,6 +135,8 @@ enum { PROP_MODEL, PROP_HADJUSTMENT, PROP_VADJUSTMENT, + PROP_HSCROLL_POLICY, + PROP_VSCROLL_POLICY, PROP_HEADERS_VISIBLE, PROP_HEADERS_CLICKABLE, PROP_REORDERABLE, @@ -171,8 +173,8 @@ static void pspp_sheet_view_size_request (GtkWidget *widget, GtkRequisition *requisition); static void pspp_sheet_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static gboolean pspp_sheet_view_expose (GtkWidget *widget, - GdkEventExpose *event); +static gboolean pspp_sheet_view_draw (GtkWidget *widget, + cairo_t *cr); static gboolean pspp_sheet_view_key_press (GtkWidget *widget, GdkEventKey *event); static gboolean pspp_sheet_view_key_release (GtkWidget *widget, @@ -295,6 +297,12 @@ static void pspp_sheet_view_top_row_to_dy (PsppSheetView *tree_view); static void invalidate_empty_focus (PsppSheetView *tree_view); /* Internal functions */ +static GtkAdjustment *pspp_sheet_view_do_get_hadjustment (PsppSheetView *); +static GtkAdjustment *pspp_sheet_view_do_get_vadjustment (PsppSheetView *); +static void pspp_sheet_view_do_set_hadjustment (PsppSheetView *tree_view, + GtkAdjustment *adjustment); +static void pspp_sheet_view_do_set_vadjustment (PsppSheetView *tree_view, + GtkAdjustment *adjustment); static void pspp_sheet_view_add_move_binding (GtkBindingSet *binding_set, guint keyval, guint modmask, @@ -451,7 +459,32 @@ static GtkBindingSet *edit_bindings; G_DEFINE_TYPE_WITH_CODE (PsppSheetView, pspp_sheet_view, GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, - pspp_sheet_view_buildable_init)) + pspp_sheet_view_buildable_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) + +static void +pspp_sheet_view_get_preferred_width (GtkWidget *widget, + gint *minimal_width, + gint *natural_width) +{ + GtkRequisition requisition; + + pspp_sheet_view_size_request (widget, &requisition); + + *minimal_width = *natural_width = requisition.width; +} + +static void +pspp_sheet_view_get_preferred_height (GtkWidget *widget, + gint *minimal_height, + gint *natural_height) +{ + GtkRequisition requisition; + + pspp_sheet_view_size_request (widget, &requisition); + + *minimal_height = *natural_height = requisition.height; +} static void pspp_sheet_view_class_init (PsppSheetViewClass *class) @@ -481,14 +514,15 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) widget_class->map = pspp_sheet_view_map; widget_class->realize = pspp_sheet_view_realize; widget_class->unrealize = pspp_sheet_view_unrealize; - widget_class->size_request = pspp_sheet_view_size_request; + widget_class->get_preferred_width = pspp_sheet_view_get_preferred_width; + widget_class->get_preferred_height = pspp_sheet_view_get_preferred_height; widget_class->size_allocate = pspp_sheet_view_size_allocate; widget_class->button_press_event = pspp_sheet_view_button_press; widget_class->button_release_event = pspp_sheet_view_button_release; widget_class->grab_broken_event = pspp_sheet_view_grab_broken; /*widget_class->configure_event = pspp_sheet_view_configure;*/ widget_class->motion_notify_event = pspp_sheet_view_motion; - widget_class->expose_event = pspp_sheet_view_expose; + widget_class->draw = pspp_sheet_view_draw; widget_class->key_press_event = pspp_sheet_view_key_press; widget_class->key_release_event = pspp_sheet_view_key_release; widget_class->enter_notify_event = pspp_sheet_view_enter_notify; @@ -531,21 +565,10 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) GTK_TYPE_TREE_MODEL, GTK_PARAM_READWRITE)); - g_object_class_install_property (o_class, - PROP_HADJUSTMENT, - g_param_spec_object ("hadjustment", - P_("Horizontal Adjustment"), - P_("Horizontal Adjustment for the widget"), - GTK_TYPE_ADJUSTMENT, - GTK_PARAM_READWRITE)); - - g_object_class_install_property (o_class, - PROP_VADJUSTMENT, - g_param_spec_object ("vadjustment", - P_("Vertical Adjustment"), - P_("Vertical Adjustment for the widget"), - GTK_TYPE_ADJUSTMENT, - GTK_PARAM_READWRITE)); + g_object_class_override_property (o_class, PROP_HADJUSTMENT, "hadjustment"); + g_object_class_override_property (o_class, PROP_VADJUSTMENT, "vadjustment"); + g_object_class_override_property (o_class, PROP_HSCROLL_POLICY, "hscroll-policy"); + g_object_class_override_property (o_class, PROP_VSCROLL_POLICY, "vscroll-policy"); g_object_class_install_property (o_class, PROP_HEADERS_VISIBLE, @@ -754,6 +777,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) GTK_PARAM_READABLE)); /* Signals */ +#if GTK3_TRANSITION /** * PsppSheetView::set-scroll-adjustments * @horizontal: the horizontal #GtkAdjustment @@ -773,6 +797,7 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) G_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); +#endif /** * PsppSheetView::row-activated: @@ -1094,6 +1119,9 @@ pspp_sheet_view_init (PsppSheetView *tree_view) tree_view->priv->button_style = NULL; tree_view->dispose_has_run = FALSE; + + pspp_sheet_view_do_set_vadjustment (tree_view, NULL); + pspp_sheet_view_do_set_hadjustment (tree_view, NULL); } @@ -1117,12 +1145,20 @@ pspp_sheet_view_set_property (GObject *object, pspp_sheet_view_set_model (tree_view, g_value_get_object (value)); break; case PROP_HADJUSTMENT: - pspp_sheet_view_set_hadjustment (tree_view, g_value_get_object (value)); + pspp_sheet_view_do_set_hadjustment (tree_view, g_value_get_object (value)); break; case PROP_VADJUSTMENT: - pspp_sheet_view_set_vadjustment (tree_view, g_value_get_object (value)); + pspp_sheet_view_do_set_vadjustment (tree_view, g_value_get_object (value)); break; - case PROP_HEADERS_VISIBLE: + case PROP_HSCROLL_POLICY: + tree_view->priv->hscroll_policy = g_value_get_enum (value); + gtk_widget_queue_resize (GTK_WIDGET (tree_view)); + break; + case PROP_VSCROLL_POLICY: + tree_view->priv->vscroll_policy = g_value_get_enum (value); + gtk_widget_queue_resize (GTK_WIDGET (tree_view)); + break; + case PROP_HEADERS_VISIBLE: pspp_sheet_view_set_headers_visible (tree_view, g_value_get_boolean (value)); break; case PROP_HEADERS_CLICKABLE: @@ -1205,6 +1241,12 @@ pspp_sheet_view_get_property (GObject *object, case PROP_VADJUSTMENT: g_value_set_object (value, tree_view->priv->vadjustment); break; + case PROP_HSCROLL_POLICY: + g_value_set_enum (value, tree_view->priv->hscroll_policy); + break; + case PROP_VSCROLL_POLICY: + g_value_set_enum (value, tree_view->priv->vscroll_policy); + break; case PROP_HEADERS_VISIBLE: g_value_set_boolean (value, pspp_sheet_view_get_headers_visible (tree_view)); break; @@ -3792,21 +3834,24 @@ pspp_sheet_view_draw_vertical_grid_lines (PsppSheetView *tree_view, for (list = tree_view->priv->columns; list; list = list->next, i++) { PsppSheetViewColumn *column = list->data; - - /* We don't want a line for the last column */ - if (i == n_visible_columns - 1) - break; + gint x; if (! column->visible) continue; current_x += column->width; + /* Generally the grid lines should fit within the column, but for the + last visible column we put it just past the end of the column. + (Otherwise horizontal grid lines sometimes stick out by one pixel.) */ + x = current_x; + if (i != n_visible_columns - 1) + x--; + cairo_set_line_width (cr, 1.0); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); - cairo_move_to (cr, current_x - 0.5, min_y); - cairo_line_to (cr, current_x - 0.5 , max_y - min_y); - + cairo_move_to (cr, x + 0.5, min_y); + cairo_line_to (cr, x + 0.5, max_y - min_y); cairo_stroke (cr); } } @@ -3819,7 +3864,7 @@ pspp_sheet_view_draw_vertical_grid_lines (PsppSheetView *tree_view, */ static gboolean pspp_sheet_view_bin_expose (GtkWidget *widget, - GdkEventExpose *event) + cairo_t *cr) { PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget); GtkTreePath *path; @@ -3850,14 +3895,13 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, gboolean row_ending_details; gboolean draw_vgrid_lines, draw_hgrid_lines; gint min_y, max_y; - cairo_t *cr = gdk_cairo_create (event->window); + GdkRectangle Zarea; GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); Zarea.x = 0; Zarea.y = 0; - Zarea.width = gdk_window_get_width (event->window); Zarea.height = allocation.height; rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL); @@ -3899,10 +3943,9 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, if (tree_view->priv->height < bin_window_height) { gtk_paint_flat_box (gtk_widget_get_style (widget), - event->window, + cr, gtk_widget_get_state (widget), GTK_SHADOW_NONE, - &Zarea, widget, "cell_even", 0, tree_view->priv->height, @@ -4175,10 +4218,9 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, g_snprintf (new_detail, 128, "%s_middle", detail); gtk_paint_flat_box (gtk_widget_get_style (widget), - event->window, + cr, state, GTK_SHADOW_NONE, - &Zarea, widget, new_detail, background_area.x, @@ -4189,10 +4231,9 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, else { gtk_paint_flat_box (gtk_widget_get_style (widget), - event->window, + cr, state, GTK_SHADOW_NONE, - &Zarea, widget, detail, background_area.x, @@ -4221,7 +4262,7 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, #endif } - if (y_offset + max_height >= Zarea.height - 0.5) + if (y_offset + max_height <= Zarea.height - 0.5) { #if GTK3_TRANSITION gdk_draw_line (event->window, @@ -4243,7 +4284,6 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, cr, &background_area, &cell_area, - &Zarea, flags); if (node == cursor && has_special_cell && @@ -4256,7 +4296,6 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, cr, &background_area, &cell_area, - &Zarea, flags); } @@ -4266,10 +4305,9 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, if (cell_offset < Zarea.x) { gtk_paint_flat_box (gtk_widget_get_style (widget), - event->window, + cr, GTK_STATE_NORMAL, GTK_SHADOW_NONE, - &Zarea, widget, "base", cell_offset, @@ -4308,9 +4346,8 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, if (row_ending_details) gtk_paint_focus (gtk_widget_get_style (widget), - tree_view->priv->bin_window, + cr, gtk_widget_get_state (widget), - &Zarea, widget, (is_first ? (is_last ? "treeview-drop-indicator" : "treeview-drop-indicator-left" ) @@ -4321,9 +4358,8 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, - focus_line_width + 1); else gtk_paint_focus (gtk_widget_get_style (widget), - tree_view->priv->bin_window, + cr, gtk_widget_get_state (widget), - &Zarea, widget, "treeview-drop-indicator", 0, BACKGROUND_FIRST_PIXEL (tree_view, node) @@ -4376,9 +4412,8 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, if (row_ending_details) gtk_paint_focus (gtk_widget_get_style (widget), - tree_view->priv->bin_window, + cr, focus_rect_state, - &Zarea, widget, (is_first ? (is_last ? "treeview" : "treeview-left" ) @@ -4387,9 +4422,8 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, width, tmp_height); else gtk_paint_focus (gtk_widget_get_style (widget), - tree_view->priv->bin_window, + cr, focus_rect_state, - &Zarea, widget, "treeview", 0, tmp_y, @@ -4446,19 +4480,24 @@ done: return FALSE; } + static gboolean -pspp_sheet_view_expose (GtkWidget *widget, - GdkEventExpose *event) +pspp_sheet_view_draw (GtkWidget *widget, + cairo_t *cr) { PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget); - cairo_t *cr = gdk_cairo_create (event->window); - - if (event->window == tree_view->priv->bin_window) + GtkAllocation allocation; + gtk_widget_get_allocation (widget, &allocation); + + if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window)) { gboolean retval; GList *tmp_list; - retval = pspp_sheet_view_bin_expose (widget, event); + cairo_save (cr); + cairo_translate (cr, 0, gdk_window_get_height (tree_view->priv->header_window)); + retval = pspp_sheet_view_bin_expose (widget, cr); + cairo_restore (cr); /* We can't just chain up to Container::expose as it will try to send the * event to the headers, so we handle propagating it to our children @@ -4470,27 +4509,27 @@ pspp_sheet_view_expose (GtkWidget *widget, PsppSheetViewChild *child = tmp_list->data; tmp_list = tmp_list->next; - gtk_container_propagate_expose (GTK_CONTAINER (tree_view), child->widget, event); + gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr); } return retval; } - else if (event->window == tree_view->priv->header_window) + else if (gtk_cairo_should_draw_window (cr, tree_view->priv->header_window)) { gint n_visible_columns; GList *list; gtk_paint_flat_box (gtk_widget_get_style (widget), - event->window, + cr, GTK_STATE_NORMAL, GTK_SHADOW_NONE, - &event->area, widget, "cell_odd", - event->area.x, - event->area.y, - event->area.width, - event->area.height); + allocation.x, + allocation.y, + allocation.width, + allocation.height + ); for (list = tree_view->priv->columns; list != NULL; list = list->next) { @@ -4500,10 +4539,10 @@ pspp_sheet_view_expose (GtkWidget *widget, continue; if (span_intersects (column->allocation.x, column->allocation.width, - event->area.x, event->area.width) + allocation.x, allocation.width) && column->button != NULL) - gtk_container_propagate_expose (GTK_CONTAINER (tree_view), - column->button, event); + gtk_container_propagate_draw (GTK_CONTAINER (tree_view), + column->button, cr); } n_visible_columns = 0; @@ -4516,16 +4555,21 @@ pspp_sheet_view_expose (GtkWidget *widget, pspp_sheet_view_draw_vertical_grid_lines (tree_view, cr, n_visible_columns, - event->area.y, - event->area.height); + allocation.y, + allocation.height); + + return TRUE; } - else if (event->window == tree_view->priv->drag_window) + else if (gtk_cairo_should_draw_window (cr, tree_view->priv->drag_window)) { - gtk_container_propagate_expose (GTK_CONTAINER (tree_view), - tree_view->priv->drag_column->button, - event); + gtk_container_propagate_draw (GTK_CONTAINER (tree_view), + tree_view->priv->drag_column->button, + cr); + + return TRUE; } - return TRUE; + + return FALSE; } enum @@ -7736,7 +7780,9 @@ _pspp_sheet_view_column_start_drag (PsppSheetView *tree_view, send_event->button.axes = NULL; send_event->button.state = 0; send_event->button.button = 1; - send_event->button.device = gdk_display_get_core_pointer (display); + send_event->button.device = + gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (display)); + send_event->button.x_root = 0; send_event->button.y_root = 0; @@ -9186,9 +9232,12 @@ pspp_sheet_view_get_hadjustment (PsppSheetView *tree_view) { g_return_val_if_fail (PSPP_IS_SHEET_VIEW (tree_view), NULL); - if (tree_view->priv->hadjustment == NULL) - pspp_sheet_view_set_hadjustment (tree_view, NULL); + return pspp_sheet_view_do_get_hadjustment (tree_view); +} +static GtkAdjustment * +pspp_sheet_view_do_get_hadjustment (PsppSheetView *tree_view) +{ return tree_view->priv->hadjustment; } @@ -9212,23 +9261,60 @@ pspp_sheet_view_set_hadjustment (PsppSheetView *tree_view, g_object_notify (G_OBJECT (tree_view), "hadjustment"); } +static void +pspp_sheet_view_do_set_hadjustment (PsppSheetView *tree_view, + GtkAdjustment *adjustment) +{ + PsppSheetViewPrivate *priv = tree_view->priv; + + if (adjustment && priv->hadjustment == adjustment) + return; + + if (priv->hadjustment != NULL) + { + g_signal_handlers_disconnect_by_func (priv->hadjustment, + pspp_sheet_view_adjustment_changed, + tree_view); + g_object_unref (priv->hadjustment); + } + + if (adjustment == NULL) + adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, + 0.0, 0.0, 0.0); + + g_signal_connect (adjustment, "value-changed", + G_CALLBACK (pspp_sheet_view_adjustment_changed), tree_view); + priv->hadjustment = g_object_ref_sink (adjustment); + /* FIXME: Adjustment should probably be populated here with fresh values, but + * internal details are too complicated for me to decipher right now. + */ + pspp_sheet_view_adjustment_changed (NULL, tree_view); + + g_object_notify (G_OBJECT (tree_view), "hadjustment"); +} + /** * pspp_sheet_view_get_vadjustment: * @tree_view: A #PsppSheetView * * Gets the #GtkAdjustment currently being used for the vertical aspect. * - * Return value: A #GtkAdjustment object, or %NULL if none is currently being - * used. + * Return value: (transfer none): A #GtkAdjustment object, or %NULL + * if none is currently being used. + * + * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment() **/ GtkAdjustment * pspp_sheet_view_get_vadjustment (PsppSheetView *tree_view) { g_return_val_if_fail (PSPP_IS_SHEET_VIEW (tree_view), NULL); - if (tree_view->priv->vadjustment == NULL) - pspp_sheet_view_set_vadjustment (tree_view, NULL); + return pspp_sheet_view_do_get_vadjustment (tree_view); +} +static GtkAdjustment * +pspp_sheet_view_do_get_vadjustment (PsppSheetView *tree_view) +{ return tree_view->priv->vadjustment; } @@ -9238,17 +9324,47 @@ pspp_sheet_view_get_vadjustment (PsppSheetView *tree_view) * @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL * * Sets the #GtkAdjustment for the current vertical aspect. + * + * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment() **/ void pspp_sheet_view_set_vadjustment (PsppSheetView *tree_view, - GtkAdjustment *adjustment) + GtkAdjustment *adjustment) { g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view)); + g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment)); - pspp_sheet_view_set_adjustments (tree_view, - tree_view->priv->hadjustment, - adjustment); + pspp_sheet_view_do_set_vadjustment (tree_view, adjustment); +} +static void +pspp_sheet_view_do_set_vadjustment (PsppSheetView *tree_view, + GtkAdjustment *adjustment) +{ + PsppSheetViewPrivate *priv = tree_view->priv; + + if (adjustment && priv->vadjustment == adjustment) + return; + + if (priv->vadjustment != NULL) + { + g_signal_handlers_disconnect_by_func (priv->vadjustment, + pspp_sheet_view_adjustment_changed, + tree_view); + g_object_unref (priv->vadjustment); + } + + if (adjustment == NULL) + adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, + 0.0, 0.0, 0.0); + + g_signal_connect (adjustment, "value-changed", + G_CALLBACK (pspp_sheet_view_adjustment_changed), tree_view); + priv->vadjustment = g_object_ref_sink (adjustment); + /* FIXME: Adjustment should probably be populated here with fresh values, but + * internal details are too complicated for me to decipher right now. + */ + pspp_sheet_view_adjustment_changed (NULL, tree_view); g_object_notify (G_OBJECT (tree_view), "vadjustment"); }