/** * goc_canvas_get_item_at: * @canvas: #GocCanvas * @x: horizontal position * @y: vertical position * * Returns: (transfer none): the #GocItem displayed at (@x,@y) if any. **/ GocItem* goc_canvas_get_item_at (GocCanvas *canvas, double x, double y) { GocItem *result = NULL; double d = goc_item_distance (GOC_ITEM (canvas->root), x, y, &result); return (d == 0.)? result: NULL; }
static void ig_reload_style (GnmItemGrid *ig) { GocItem *item = GOC_ITEM (ig); GtkStyleContext *context = goc_item_get_style_context (item); GtkBorder border; GtkStateFlags state = GTK_STATE_FLAG_NORMAL; GnmPane *pane = GNM_PANE (item->canvas); gtk_style_context_save (context); gtk_style_context_add_region (context, "function-marker", 0); gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &ig->function_marker_color); gtk_style_context_get_border_color (context, state, &ig->function_marker_border_color); gtk_style_context_restore (context); gtk_style_context_save (context); gtk_style_context_add_region (context, "pane-divider", 0); gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &ig->pane_divider_color); gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &border); ig->pane_divider_width = border.top; /* Hack? */ gtk_style_context_restore (context); /* ---------------------------------------- */ context = gtk_widget_get_style_context (GTK_WIDGET (pane)); gtk_widget_style_get (GTK_WIDGET (pane), "function-indicator-size", &ig->function_marker_size, NULL); }
static void goc_canvas_unrealize (GtkWidget *widget) { GocCanvas *canvas = GOC_CANVAS (widget); GOC_ITEM_GET_CLASS (canvas->root)->unrealize (GOC_ITEM (canvas->root)); GTK_WIDGET_CLASS (parent_klass)->unrealize (widget); }
static void comment_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible) { CommentView *cv = (CommentView *)sov; GocPoints *points = goc_points_new (3); GocItem *item = GOC_ITEM (GOC_GROUP (sov)->children->data); if (visible) { SheetObject *so = sheet_object_view_get_so (sov); SheetControlGUI const *scg = GNM_SIMPLE_CANVAS (item->canvas)->scg; double scale; gint64 x, y, dx; int far_col; GnmRange const *r = gnm_sheet_merge_is_corner (so->sheet, &so->anchor.cell_bound.start); scale = 1. / item->canvas->pixels_per_unit; if (r != NULL) far_col = 1 + r->end.col; else far_col = 1 + so->anchor.cell_bound.start.col; /* TODO : This could be optimized using the offsets associated with the visible region */ /* Add 1 to y because we measure from start, x is measured from end, so * it does not need it */ y = scg_colrow_distance_get (scg, FALSE, 0, so->anchor.cell_bound.start.row)+ 1; points->points[0].y = scale * y; points->points[1].y = scale * y; points->points[2].y = scale * y + cv->comment_indicator_size; dx = cv->comment_indicator_size; x = scg_colrow_distance_get (scg, TRUE, 0, far_col); points->points[0].x = scale * x - dx; points->points[1].x = scale * x; points->points[2].x = scale * x; goc_item_set (item, "points", points, NULL); goc_points_unref (points); goc_item_show (GOC_ITEM (sov)); } else goc_item_hide (GOC_ITEM (sov)); }
static void goc_image_set_property (GObject *gobject, guint param_id, GValue const *value, GParamSpec *pspec) { GocImage *image = GOC_IMAGE (gobject); switch (param_id) { case IMAGE_PROP_X: image->x = g_value_get_double (value); break; case IMAGE_PROP_Y: image->y = g_value_get_double (value); break; case IMAGE_PROP_W: image->width = g_value_get_double (value); break; case IMAGE_PROP_H: image->height = g_value_get_double (value); break; case IMAGE_PROP_ROTATION: image->rotation = g_value_get_double (value); break; case IMAGE_PROP_IMAGE: if (image->image) g_object_unref (image); image->image = GO_IMAGE (g_object_ref (g_value_get_object (value))); break; case IMAGE_PROP_CROP_BOTTOM: image->crop_bottom = g_value_get_double (value); break; case IMAGE_PROP_CROP_LEFT: image->crop_left = g_value_get_double (value); break; case IMAGE_PROP_CROP_RIGHT: image->crop_right = g_value_get_double (value); break; case IMAGE_PROP_CROP_TOP: image->crop_top = g_value_get_double (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); return; /* NOTE : RETURN */ } goc_item_bounds_changed (GOC_ITEM (gobject)); }
/* Somewhat magic. * We do not honour all of the anchor flags. All that is used is the far corner. */ static void vcombo_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible) { GocGroup *view = GOC_GROUP (sov); if (visible) { double scale = goc_canvas_get_pixels_per_unit (GOC_ITEM (view)->canvas); double h = (coords[3] - coords[1]) + 1.; if (h > 20.) /* clip vertically */ h = 20.; h /= scale; goc_item_set (GOC_ITEM (view->children->data), /* put it outside the cell */ "x", ((coords[2] >= 0.)? coords[2] / scale: (coords[0] / scale - h + 1.)), "y", coords [3] / scale - h + 1., "width", h, /* force a square, use h for width too */ "height", h, NULL); goc_item_show (GOC_ITEM (view)); } else goc_item_hide (GOC_ITEM (view)); }
/** * goc_canvas_set_pixels_per_unit: * @canvas: #GocCanvas * @pixels_per_unit: the new scale * * Sets the scale as the number of pixels used for each unit when * displaying the canvas. **/ void goc_canvas_set_pixels_per_unit (GocCanvas *canvas, double pixels_per_unit) { GocItemClass *klass; g_return_if_fail (GOC_IS_CANVAS (canvas)); if (pixels_per_unit == canvas->pixels_per_unit) return; klass = GOC_ITEM_GET_CLASS (canvas->root); canvas->pixels_per_unit = pixels_per_unit; klass->notify_scrolled (GOC_ITEM (canvas->root)); #ifdef GOFFICE_WITH_GTK gtk_widget_queue_draw_area (GTK_WIDGET (canvas), 0, 0, G_MAXINT, G_MAXINT); #endif }
static gboolean ccombo_activate (GtkTreeView *list, gboolean button) { SheetObjectView *sov = g_object_get_data (G_OBJECT (list), SOV_ID); GocItem *view = GOC_ITEM (sov); GnmPane *pane = GNM_PANE (view->canvas); GnmCComboViewClass *klass = GNM_CCOMBO_VIEW_GET_CLASS (sov); if ((klass->activate) (sheet_object_view_get_so (sov), list, scg_wbcg (pane->simple.scg), button)) { ccombo_popup_destroy (GTK_WIDGET (list)); return TRUE; } return FALSE; }
/** * goc_canvas_scroll_to: * @canvas: #GocCanvas * @x: the horizontal position * @y: the vertical position * * Scrolls the canvas so that the origin of the visible region is at (@x,@y). * The origin position depends on the canvas direction (see #GocDirection). **/ void goc_canvas_scroll_to (GocCanvas *canvas, double x, double y) { GocItemClass *klass; g_return_if_fail (GOC_IS_CANVAS (canvas)); if (x == canvas->scroll_x1 && canvas->scroll_y1 == y) return; klass = GOC_ITEM_GET_CLASS (canvas->root); canvas->scroll_x1 = x; canvas->scroll_y1 = y; klass->notify_scrolled (GOC_ITEM (canvas->root)); #ifdef GOFFICE_WITH_GTK gtk_widget_queue_draw_area (GTK_WIDGET (canvas), 0, 0, G_MAXINT, G_MAXINT); #endif }
static void comment_view_reload_style (CommentView *cv) { GocItem *item = GOC_ITEM (cv); GnmPane *pane = GNM_PANE (item->canvas); GtkStyleContext *context; context = goc_item_get_style_context (item); gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &cv->comment_indicator_color); context = gtk_widget_get_style_context (GTK_WIDGET (pane)); gtk_widget_style_get (GTK_WIDGET (pane), "comment-indicator-size", &cv->comment_indicator_size, NULL); }
static void gnm_item_grid_init (GnmItemGrid *ig) { GocItem *item = GOC_ITEM (ig); item->x0 = 0; item->y0 = 0; item->x1 = 0; item->y1 = 0; ig->selecting = GNM_ITEM_GRID_NO_SELECTION; /* We need something at least as big as any sheet. */ ig->bound.start.col = ig->bound.start.row = 0; ig->bound.end.col = GNM_MAX_COLS - 1; ig->bound.end.row = GNM_MAX_ROWS - 1; ig->cursor_timer = 0; ig->cur_link = NULL; ig->tip_timer = 0; ig->tip = NULL; }
static void goc_polyline_set_property (GObject *gobject, guint param_id, GValue const *value, GParamSpec *pspec) { GocPolyline *polyline = GOC_POLYLINE (gobject); switch (param_id) { case POLYLINE_PROP_POINTS: { unsigned i; GocPoints *points = (GocPoints *) g_value_get_boxed (value); polyline->nb_points = points->n; g_free (polyline->points); if (points->n > 0) { polyline->points = g_new (GocPoint, points->n); for (i = 0; i < points->n; i++) polyline->points[i] = points->points[i]; } else polyline->points = NULL; break; } case POLYLINE_PROP_SPLINE: polyline->use_spline = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); return; /* NOTE : RETURN */ } if (polyline->use_spline && polyline->nb_points) { double *x, *y; unsigned i; x = g_alloca (polyline->nb_points * sizeof (double)); y = g_alloca (polyline->nb_points * sizeof (double)); for (i = 0; i < polyline->nb_points; i++) { x[i] = polyline->points[i].x - polyline->points[0].x; y[i] = polyline->points[i].y - polyline->points[0].y; } g_object_set_data_full (G_OBJECT (polyline), "spline", go_bezier_spline_init (x, y, polyline->nb_points, FALSE), (GDestroyNotify) go_bezier_spline_destroy); } goc_item_bounds_changed (GOC_ITEM (gobject)); }
static gboolean ig_obj_create_begin (GnmItemGrid *ig, int button, gint64 x, gint64 y) { GnmPane *pane = GNM_PANE (GOC_ITEM (ig)->canvas); SheetObject *so = ig->scg->wbcg->new_object; SheetObjectAnchor anchor; double coords[4]; g_return_val_if_fail (ig->scg->selected_objects == NULL, TRUE); g_return_val_if_fail (so != NULL, TRUE); coords[0] = coords[2] = x; coords[1] = coords[3] = y; sheet_object_anchor_init (&anchor, NULL, NULL, GOD_ANCHOR_DIR_DOWN_RIGHT); scg_object_coords_to_anchor (ig->scg, coords, &anchor); sheet_object_set_anchor (so, &anchor); sheet_object_set_sheet (so, scg_sheet (ig->scg)); scg_object_select (ig->scg, so); gnm_pane_object_start_resize (pane, button, x, y, so, 7, TRUE); return TRUE; }
static void preview_grid_set_property (GObject *obj, guint param_id, GValue const *value, GParamSpec *pspec) { GnmPreviewGrid *pg = GNM_PREVIEW_GRID (obj); switch (param_id){ case PREVIEW_GRID_PROP_RENDER_GRIDLINES : pg->gridlines = g_value_get_boolean (value); break; case PREVIEW_GRID_PROP_DEFAULT_COL_WIDTH : pg->defaults.col_width = g_value_get_uint (value); break; case PREVIEW_GRID_PROP_DEFAULT_ROW_HEIGHT : pg->defaults.row_height = g_value_get_uint (value); break; case PREVIEW_GRID_PROP_DEFAULT_STYLE : { /* add a ref */ GnmStyle *style = g_value_get_pointer (value); g_return_if_fail (style != NULL); gnm_style_ref (style); gnm_style_unref (pg->defaults.style); pg->defaults.style = style; break; } case PREVIEW_GRID_PROP_DEFAULT_VALUE : { /* steal ownership */ GnmValue *val = g_value_get_pointer (value); g_return_if_fail (val != NULL); if (pg->defaults.value != val) { value_release (pg->defaults.value); pg->defaults.value = val; } break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); return; /* NOTE : RETURN */ } goc_item_invalidate (GOC_ITEM (obj)); }
static SheetObjectView * gnm_so_path_new_view (SheetObject *so, SheetObjectViewContainer *container) { GnmSOPath *sop = GNM_SO_PATH (so); GnmSOPathView *item; /* FIXME: this is unsafe if the paths change after the view is created, * but this can't occur for now */ unsigned i; if (sop->path == NULL && sop->paths == NULL) return NULL; item = (GnmSOPathView *) goc_item_new ( gnm_pane_object_group (GNM_PANE (container)), so_path_goc_view_get_type (), NULL); if (sop->path) item->path = goc_item_new (GOC_GROUP (item), GOC_TYPE_PATH, "closed", TRUE, "fill-rule", TRUE, NULL); else { item->paths = g_ptr_array_sized_new (sop->paths->len); g_ptr_array_set_free_func (item->paths, g_object_unref); for (i = 0; i < sop->paths->len; i++) g_ptr_array_add (item->paths, goc_item_new (GOC_GROUP (item), GOC_TYPE_PATH, "closed", TRUE, "fill-rule", TRUE, NULL)); } cb_gnm_so_path_changed (sop, NULL, item); g_signal_connect_object (sop, "notify::style", G_CALLBACK (cb_gnm_so_path_changed), item, 0); return gnm_pane_object_register (so, GOC_ITEM (item), TRUE); }
static void so_image_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible) { GocItem *view = GOC_ITEM (GOC_GROUP (sov)->children->data); double scale = goc_canvas_get_pixels_per_unit (view->canvas); if (visible) { double x, y, width, height; double old_x1, old_y1, old_x2, old_y2, old_width, old_height; GdkPixbuf *placeholder = g_object_get_data (G_OBJECT (view), "tile"); x = MIN (coords [0], coords [2]) / scale; y = MIN (coords [1], coords [3]) / scale; width = fabs (coords [2] - coords [0]) / scale; height = fabs (coords [3] - coords [1]) / scale; goc_item_get_bounds (view, &old_x1, &old_y1, &old_x2, &old_y2); goc_item_set (view, "x", x, "y", y, "width", width, "height", height, NULL); /* regenerate the image if necessary */ old_width = fabs (old_x1 - old_x2); old_height = fabs (old_y1 - old_y2); if (placeholder != NULL && (fabs (width - old_width) > 0.5 || fabs (height - old_height) > 0.5)) { GdkPixbuf *newimage = go_pixbuf_tile (placeholder, (guint)width, (guint)height); goc_item_set (view, "pixbuf", newimage, NULL); g_object_unref (newimage); } goc_item_show (view); } else goc_item_hide (view); }
static void goc_line_set_property (GObject *gobject, guint param_id, GValue const *value, GParamSpec *pspec) { GocLine *line = GOC_LINE (gobject); switch (param_id) { case LINE_PROP_X0: line->startx = g_value_get_double (value); break; case LINE_PROP_Y0: line->starty = g_value_get_double (value); break; case LINE_PROP_X1: line->endx = g_value_get_double (value); break; case LINE_PROP_Y1: line->endy = g_value_get_double (value); break; case LINE_PROP_START_ARROW: line->start_arrow = *((GOArrow *)g_value_peek_pointer (value)); break; case LINE_PROP_END_ARROW: line->end_arrow = *((GOArrow *)g_value_peek_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); return; /* NOTE : RETURN */ } goc_item_bounds_changed (GOC_ITEM (gobject)); }
static void cb_gnm_so_path_changed (GnmSOPath const *sop, G_GNUC_UNUSED GParamSpec *pspec, GnmSOPathView *group) { GList *ptr = GOC_GROUP (group)->children; for (; ptr && ptr->data; ptr = ptr->next) if (GOC_IS_PATH (ptr->data)) cb_gnm_so_path_style_changed (GOC_ITEM (ptr->data), sop); if (sop->text != NULL && *sop->text != 0) { /* set a font, a very bad solution, but will do until we move to GOString */ PangoFontDescription *desc = pango_font_description_from_string ("Sans 10"); GOStyle *style; if (group->text == NULL) { double x0, y0, x1, y1; if (group->path) goc_item_get_bounds (group->path, &x0, &y0, &x1, &y1); else { unsigned i; double mx, my, Mx, My; x0 = y0 = G_MAXDOUBLE; x1 = y1 = -G_MAXDOUBLE; for (i = 0; i < group->paths->len; i++) { goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (group->paths, i)), &mx, &my, &Mx, &My); if (mx < x0) x0 = mx; if (my < y0) y0 = my; if (Mx > x1) x1 = Mx; if (My > y1) y1 = My; } } x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right; y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom; x0 += x1 / 2. + sop->margin_pts.left; y0 += y1 / 2. + sop->margin_pts.top; x1 = MAX (x1, DBL_MIN); y1 = MAX (y1, DBL_MIN); group->text = goc_item_new (GOC_GROUP (group), GOC_TYPE_TEXT, "anchor", GO_ANCHOR_CENTER, "clip", TRUE, "x", x0, "y", y0, "clip-height", y1, "clip-width", x1, "wrap-width", x1, "attributes", sop->markup, NULL); } style = go_styled_object_get_style (GO_STYLED_OBJECT (group->text)); go_style_set_font_desc (style, desc); goc_item_set (group->text, "text", sop->text, "attributes", sop->markup, NULL); } else if (group->text != NULL) { g_object_unref (group->text); group->text = NULL; } }
static void so_path_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible) { GnmSOPathView *spv = (GnmSOPathView *) sov; if (visible) { SheetObject *so = sheet_object_view_get_so (sov); GnmSOPath const *sop = GNM_SO_PATH (so); GOPath *path; double scale, x_scale, y_scale, x, y; if ((sop->path == NULL && sop->paths == NULL) || sop->width <=0. || sop->height <=0.) return; scale = goc_canvas_get_pixels_per_unit (GOC_ITEM (sov)->canvas); x_scale = fabs (coords[2] - coords[0]) / sop->width / scale; y_scale = fabs (coords[3] - coords[1]) / sop->height / scale; x = MIN (coords[0], coords[2]) / scale - sop->x_offset * x_scale; y = MIN (coords[1], coords[3]) / scale - sop->y_offset * y_scale; if (sop->path != NULL) { path = go_path_scale (sop->path, x_scale, y_scale); goc_item_set (spv->path, "x", x, "y", y, "path", path, NULL); go_path_free (path); } else { unsigned i; for (i = 0; i < sop->paths->len; i++) { path = go_path_scale ((GOPath *) g_ptr_array_index (sop->paths, i), x_scale, y_scale); goc_item_set (GOC_ITEM (g_ptr_array_index (spv->paths, i)), "x", x, "y", y, "path", path, NULL); go_path_free (path); } } if (spv->text != NULL && GOC_ITEM (spv->text)) { double x0, y0, x1, y1; if (spv->path) goc_item_get_bounds (spv->path, &x0, &y0, &x1, &y1); else { unsigned i; double mx, my, Mx, My; x0 = y0 = G_MAXDOUBLE; x1 = y1 = -G_MAXDOUBLE; for (i = 0; i < spv->paths->len; i++) { goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (spv->paths, i)), &mx, &my, &Mx, &My); if (mx < x0) x0 = mx; if (my < y0) y0 = my; if (Mx > x1) x1 = Mx; if (My > y1) y1 = My; } } x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right; y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom; x0 += x1 / 2. + sop->margin_pts.left; y0 += y1 / 2. + sop->margin_pts.top; x1 = MAX (x1, DBL_MIN); y1 = MAX (y1, DBL_MIN); goc_item_set (GOC_ITEM (spv->text), "x", x0, "y", y0, "clip-height", y1, "clip-width", x1, "wrap-width", x1, NULL); } } else goc_item_hide (GOC_ITEM (sov)); }
/** * gnm_cell_combo_view_popdown: * @sov: #SheetObjectView * @activate_time: event time * * Open the popup window associated with @sov **/ void gnm_cell_combo_view_popdown (SheetObjectView *sov, guint32 activate_time) { GocItem *view = GOC_ITEM (sov); GnmPane *pane = GNM_PANE (view->canvas); SheetControlGUI *scg = pane->simple.scg; SheetObject *so = sheet_object_view_get_so (sov); Sheet const *sheet = sheet_object_get_sheet (so); GtkWidget *frame, *popup, *list, *container; int root_x, root_y; gboolean make_buttons = FALSE; GtkTreePath *clip = NULL, *select = NULL; GtkWindow *toplevel = wbcg_toplevel (scg_wbcg (scg)); GdkWindow *popup_window; GdkDevice *device; GnmRange const *merge; popup = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO); gtk_window_group_add_window (gtk_window_get_group (toplevel), GTK_WINDOW (popup)); go_gtk_window_set_transient (toplevel, GTK_WINDOW (popup)); gtk_window_set_resizable (GTK_WINDOW (popup), FALSE); gtk_window_set_decorated (GTK_WINDOW (popup), FALSE); gtk_window_set_screen (GTK_WINDOW (popup), gtk_widget_get_screen (GTK_WIDGET (toplevel))); list = ccombo_create_list (GNM_CCOMBO_VIEW (sov), so, &clip, &select, &make_buttons); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE); g_object_set_data (G_OBJECT (list), SOV_ID, sov); frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); #if 0 range_dump (&so->anchor.cell_bound, ""); g_printerr (" : so = %p, view = %p\n", so, view); #endif if (clip != NULL) { GtkWidget *sw = gtk_scrolled_window_new ( gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (list)), gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (list))); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); g_object_set_data_full (G_OBJECT (list), "clip", clip, (GDestroyNotify)gtk_tree_path_free); gtk_container_add (GTK_CONTAINER (sw), list); /* * Do the sizing in a realize handler as newer versions of * gtk+ give us zero sizes until then. */ g_signal_connect_after (list, "realize", G_CALLBACK (cb_realize_treeview), sw); container = sw; } else container = list; if (make_buttons) { GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); GtkWidget *hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); GtkWidget *button; button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); g_signal_connect_swapped (button, "clicked", G_CALLBACK (cb_ccombo_cancel_button), list); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6); button = gtk_button_new_from_stock (GTK_STOCK_OK); g_signal_connect_swapped (button, "clicked", G_CALLBACK (cb_ccombo_ok_button), list); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6); gtk_box_pack_start (GTK_BOX (vbox), container, FALSE, TRUE, 6); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6); container = vbox; } gtk_container_add (GTK_CONTAINER (frame), container); /* do the popup */ gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (pane)), &root_x, &root_y); if (sheet->text_is_rtl) { GtkAllocation pa; gtk_widget_get_allocation (GTK_WIDGET (pane), &pa); root_x += pa.width; root_x -= scg_colrow_distance_get (scg, TRUE, pane->first.col, so->anchor.cell_bound.start.col + 1); } else root_x += scg_colrow_distance_get (scg, TRUE, pane->first.col, so->anchor.cell_bound.start.col); merge = gnm_sheet_merge_is_corner (sheet, &(so->anchor.cell_bound.start)); gtk_window_move (GTK_WINDOW (popup), root_x, root_y + scg_colrow_distance_get (scg, FALSE, pane->first.row, so->anchor.cell_bound.start.row + ((merge == NULL) ? 1 : range_height (merge)))); gtk_container_add (GTK_CONTAINER (popup), frame); g_signal_connect (popup, "key_press_event", G_CALLBACK (cb_ccombo_key_press), list); g_signal_connect (popup, "button_press_event", G_CALLBACK (cb_ccombo_button_press), list); g_signal_connect_after (popup, "button_release_event", G_CALLBACK (cb_ccombo_button_release), list); g_signal_connect (list, "motion_notify_event", G_CALLBACK (cb_ccombo_list_motion), list); g_signal_connect (list, "button_press_event", G_CALLBACK (cb_ccombo_list_button_press), popup); gtk_widget_show_all (popup); /* after we show the window setup the selection (showing the list * clears the selection) */ if (select != NULL) { gtk_tree_selection_select_path ( gtk_tree_view_get_selection (GTK_TREE_VIEW (list)), select); gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), select, NULL, FALSE); gtk_tree_path_free (select); } gtk_widget_grab_focus (popup); gtk_widget_grab_focus (GTK_WIDGET (list)); ccombo_focus_change (GTK_WIDGET (list), TRUE); popup_window = gtk_widget_get_window (popup); device = gtk_get_current_event_device (); if (0 == gdk_device_grab (device, popup_window, GDK_OWNERSHIP_APPLICATION, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, NULL, activate_time)) { if (0 == gdk_device_grab (gdk_device_get_associated_device (device), popup_window, GDK_OWNERSHIP_APPLICATION, TRUE, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL, activate_time)) gtk_grab_add (popup); else gdk_device_ungrab (device, activate_time); } }
void goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, double *x1, double *y1) { goc_item_get_bounds (GOC_ITEM (canvas->root), x0, y0, x1, y1); }
void goc_canvas_render (GocCanvas *canvas, cairo_t *cr, double x0, double y0, double x1, double y1) { goc_item_draw_region (GOC_ITEM (canvas->root), cr, x0, y0, x1, y1); }
static void goc_component_set_property (GObject *obj, guint param_id, GValue const *value, GParamSpec *pspec) { GocComponent *component = GOC_COMPONENT (obj); switch (param_id) { case COMPONENT_PROP_X: { double x = g_value_get_double (value); if (x == component->x) return; component->x = x; return; } case COMPONENT_PROP_Y: { double y = g_value_get_double (value); if (y == component->y) return; component->y = y; break; } /* NOTE: it is allowed to set width and height even if the component is not resizable * but this should be only used to convert the size in inches to pixels. * The default is 1 pixel == 1 point. */ case COMPONENT_PROP_H: { double h = g_value_get_double (value); if (!component->component || h == component->h) return; component->h = h; break; } case COMPONENT_PROP_W: { double w = g_value_get_double (value); if (!component->component || w == component->w) return; component->w = w; break; } case COMPONENT_PROP_ROTATION: { double r = g_value_get_double (value) / 180. * M_PI; if (!component->component || r == component->rotation) return; component->rotation = r; break; } case COMPONENT_PROP_OBJECT: if (component->component != NULL) g_object_unref (component->component); component->component = GO_COMPONENT (g_value_get_object (value)); if (component->component != NULL) { g_object_ref (component->component); /* set default or fixed size */ if (component->w == 0 || component->h == 0 || !go_component_is_resizable (component->component)) { go_component_get_size (component->component, &component->w, &component->h); component->w = GO_IN_TO_PT (component->w); component->h = GO_IN_TO_PT (component->h); } } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); return; /* NOTE : RETURN */ } goc_item_bounds_changed (GOC_ITEM (component)); }
static gboolean goc_canvas_draw (GtkWidget *widget, cairo_t *cr) { double x0, y0, x1, y1; double ax0, ay0, ax1, ay1; double clip_x1, clip_y1, clip_x2, clip_y2; GocCanvas *canvas = GOC_CANVAS (widget); GdkEventExpose *event = (GdkEventExpose *) gtk_get_current_event (); GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv; cairo_rectangle_list_t *l = cairo_copy_clip_rectangle_list (cr); int i, x, y; if (GOC_IS_ITEM (priv->invalidated_item) && priv->invalid_region) { /* evaluate the cairo clipped region and compare with the saved one */ cairo_region_t *region; cairo_rectangle_int_t rect[l->num_rectangles]; for (i= 0; i < l->num_rectangles; i++) { rect[i].x = l->rectangles[i].x; rect[i].y = l->rectangles[i].y; rect[i].width = l->rectangles[i].width; rect[i].height = l->rectangles[i].height; } region = cairo_region_create_rectangles (rect, l->num_rectangles); if (cairo_region_equal (priv->invalid_region, region)) { cairo_rectangle_list_destroy (l); cairo_region_destroy (region); /* looks like each time we call gtk_widget_queue_draw*, the draw event is fired twice */ if (priv->done) { priv->invalidated_item = NULL; cairo_region_destroy (priv->invalid_region); priv->invalid_region = NULL; } else { goc_item_draw (priv->invalidated_item, cr); priv->done = TRUE; } return TRUE; } cairo_region_destroy (region); } x = gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas))); y = gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas))); cairo_translate (cr, -x, -y); goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1); for (i= 0; i < l->num_rectangles; i++) { cairo_save (cr); cairo_rectangle (cr, l->rectangles[i].x, l->rectangles[i].y, l->rectangles[i].width, l->rectangles[i].height); cairo_clip (cr); clip_x1 = l->rectangles[i].x; clip_y1 = l->rectangles[i].y; clip_x2 = clip_x1 + l->rectangles[i].width; clip_y2 = clip_y1 + l->rectangles[i].height; if (canvas->direction == GOC_DIRECTION_RTL) { ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + canvas->scroll_x1; ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + canvas->scroll_x1; } else { ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1; ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1; } ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1; ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1; if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) { canvas->cur_event = (GdkEvent *) event; goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1); } cairo_restore (cr); } cairo_rectangle_list_destroy (l); return TRUE; }