From: dvlierop2 Date: Wed, 30 Jan 2008 20:05:58 +0000 (+0000) Subject: 2nd part of the fix for bug #167500: correctly update the rulers when they change... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=8f155491f3b774a63b72ad889c0db7636f460f19;p=inkscape.git 2nd part of the fix for bug #167500: correctly update the rulers when they change size --- diff --git a/src/desktop.cpp b/src/desktop.cpp index 9498d5399..8cd63a68c 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -645,7 +645,7 @@ SPDesktop::push_current_zoom (GList **history) } /** - * Set viewbox. + * Set viewbox (x0, x1, y0 and y1 are in document pixels. Border is in screen pixels). */ void SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double border, bool log) @@ -673,7 +673,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double newscale = viewbox.dimensions()[NR::Y] / (y1 - y0); } - newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); + newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); // unit: 'screen pixels' per 'document pixels' int clear = FALSE; if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) { @@ -684,7 +684,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double clear = TRUE; } - /* Calculate top left corner */ + /* Calculate top left corner (in document pixels) */ x0 = cx - 0.5 * viewbox.dimensions()[NR::X] / newscale; y1 = cy + 0.5 * viewbox.dimensions()[NR::Y] / newscale; diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 2033f8a69..cce43825a 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1199,7 +1199,7 @@ sp_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation) } widget->allocation = *allocation; - + if (GTK_WIDGET_REALIZED (widget)) { gdk_window_move_resize (widget->window, widget->allocation.x, widget->allocation.y, @@ -2084,7 +2084,7 @@ sp_canvas_root (SPCanvas *canvas) } /** - * Scrolls canvas to specific position. + * Scrolls canvas to specific position (cx and cy are measured in screen pixels) */ void sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear, bool is_scrolling) @@ -2092,12 +2092,12 @@ sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear, g_return_if_fail (canvas != NULL); g_return_if_fail (SP_IS_CANVAS (canvas)); - int ix = (int) round(cx); //cx might be negative, so (int)(cx + 0.5) will not do! - int iy = (int) round(cy); - int dx = ix - canvas->x0; - int dy = iy - canvas->y0; + int ix = (int) round(cx); // ix and iy are the new canvas coordinates (integer screen pixels) + int iy = (int) round(cy); // cx might be negative, so (int)(cx + 0.5) will not do! + int dx = ix - canvas->x0; // dx and dy specify the displacement (scroll) of the + int dy = iy - canvas->y0; // canvas w.r.t its previous position - canvas->dx0 = cx; + canvas->dx0 = cx; // here the 'd' stands for double, not delta! canvas->dy0 = cy; canvas->x0 = ix; canvas->y0 = iy; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 4d44b1b26..76452d851 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1342,13 +1342,29 @@ SPDesktopWidget::viewSetPosition (NR::Point p) void sp_desktop_widget_update_rulers (SPDesktopWidget *dtw) { - NR::Rect const viewbox = dtw->canvas->getViewbox(); + sp_desktop_widget_update_hruler(dtw); + sp_desktop_widget_update_vruler(dtw); +} + +void +sp_desktop_widget_update_hruler (SPDesktopWidget *dtw) +{ + NR::Rect viewbox = dtw->canvas->getViewbox(); + double const scale = dtw->desktop->current_zoom(); double s = viewbox.min()[NR::X] / scale - dtw->ruler_origin[NR::X]; double e = viewbox.max()[NR::X] / scale - dtw->ruler_origin[NR::X]; gtk_ruler_set_range(GTK_RULER(dtw->hruler), s, e, GTK_RULER(dtw->hruler)->position, (e - s)); - s = viewbox.min()[NR::Y] / -scale - dtw->ruler_origin[NR::Y]; - e = viewbox.max()[NR::Y] / -scale - dtw->ruler_origin[NR::Y]; +} + +void +sp_desktop_widget_update_vruler (SPDesktopWidget *dtw) +{ + NR::Rect viewbox = dtw->canvas->getViewbox(); + + double const scale = dtw->desktop->current_zoom(); + double s = viewbox.min()[NR::Y] / -scale - dtw->ruler_origin[NR::Y]; + double e = viewbox.max()[NR::Y] / -scale - dtw->ruler_origin[NR::Y]; gtk_ruler_set_range(GTK_RULER(dtw->vruler), s, e, GTK_RULER(dtw->vruler)->position, (e - s)); } diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 8f38277ab..c20a8524e 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -43,6 +43,8 @@ void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw); void sp_desktop_widget_layout(SPDesktopWidget *dtw); void sp_desktop_widget_update_zoom(SPDesktopWidget *dtw); void sp_desktop_widget_update_rulers (SPDesktopWidget *dtw); +void sp_desktop_widget_update_hruler (SPDesktopWidget *dtw); +void sp_desktop_widget_update_vruler (SPDesktopWidget *dtw); /* Show/hide rulers & scrollbars */ void sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw); diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 07ee66c0c..e0f0ba680 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -17,9 +17,10 @@ #include #include #include "widget-sizes.h" +#include "desktop-widget.h" #include "ruler.h" #include "unit-constants.h" -#include +#include "round.h" #define MINIMUM_INCR 5 #define MAXIMUM_SUBDIVIDE 5 @@ -28,11 +29,12 @@ static void sp_hruler_class_init (SPHRulerClass *klass); static void sp_hruler_init (SPHRuler *hruler); -static gint sp_hruler_motion_notify (GtkWidget *widget, - GdkEventMotion *event); +static gint sp_hruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); static void sp_hruler_draw_ticks (GtkRuler *ruler); static void sp_hruler_draw_pos (GtkRuler *ruler); +static void sp_hruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static GtkWidgetClass *hruler_parent_class; GtkType sp_hruler_get_type (void) @@ -65,10 +67,13 @@ sp_hruler_class_init (SPHRulerClass *klass) GtkWidgetClass *widget_class; GtkRulerClass *ruler_class; + hruler_parent_class = (GtkWidgetClass *) gtk_type_class (GTK_TYPE_RULER); + widget_class = (GtkWidgetClass*) klass; ruler_class = (GtkRulerClass*) klass; widget_class->motion_notify_event = sp_hruler_motion_notify; + widget_class->size_allocate = sp_hruler_size_allocate; ruler_class->draw_ticks = sp_hruler_draw_ticks; ruler_class->draw_pos = sp_hruler_draw_pos; @@ -165,7 +170,7 @@ sp_hruler_draw_ticks (GtkRuler *ruler) width = widget->allocation.width; // in pixels; is apparently 2 pixels shorter than the canvas at each end height = widget->allocation.height;// - ythickness * 2; - + gtk_paint_box (widget->style, ruler->backing_store, GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, "hruler", @@ -227,7 +232,7 @@ sp_hruler_draw_ticks (GtkRuler *ruler) while (cur <= end) { - pos = int(round ((cur - lower) * increment) - UNUSED_PIXELS); + pos = int(Inkscape::round ((cur - lower) * increment) - UNUSED_PIXELS); gdk_draw_line (ruler->backing_store, gc, pos, height + ythickness, @@ -303,7 +308,7 @@ sp_hruler_draw_pos (GtkRuler *ruler) increment = (gfloat) (width + 2*UNUSED_PIXELS) / (ruler->upper - ruler->lower); - x = int(round ((ruler->position - ruler->lower) * increment) + (xthickness - bs_width) / 2 - 1); + x = int(Inkscape::round((ruler->position - ruler->lower) * increment + double(xthickness - bs_width) / 2.0) - 1); y = (height + bs_height) / 2 + ythickness; for (i = 0; i < bs_height; i++) @@ -318,6 +323,34 @@ sp_hruler_draw_pos (GtkRuler *ruler) } } +/** + * The hruler widget's size_allocate callback. + */ +static void +sp_hruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + g_assert (widget != NULL); + g_assert (SP_IS_HRULER (widget)); + + // First call the default gtk_widget_size_allocate() method (which is being overridden here) + if (GTK_WIDGET_CLASS (hruler_parent_class)->size_allocate) + (* GTK_WIDGET_CLASS (hruler_parent_class)->size_allocate) (widget, allocation); + + // Now the size of the ruler has changed, the ruler bounds (upper & lower) need to be updated + // For this we first need to obtain a pointer to the desktop, by walking up the tree of ancestors + GtkWidget *parent = gtk_widget_get_parent(widget); + do { + if (SP_IS_DESKTOP_WIDGET(parent)) { + // Now we've found the desktop widget we can have the ruler boundaries updated + sp_desktop_widget_update_hruler(SP_DESKTOP_WIDGET(parent)); + // If the size of the ruler has increased, then a blank part is uncovered; therefore + // it must be redrawn + sp_hruler_draw_ticks(GTK_RULER(widget)); + break; + } + parent = gtk_widget_get_parent(parent); + } while (parent != NULL); +} @@ -330,7 +363,9 @@ static gint sp_vruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); static void sp_vruler_draw_ticks (GtkRuler *ruler); static void sp_vruler_draw_pos (GtkRuler *ruler); +static void sp_vruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static GtkWidgetClass *vruler_parent_class; GtkType sp_vruler_get_type (void) @@ -363,10 +398,13 @@ sp_vruler_class_init (SPVRulerClass *klass) GtkWidgetClass *widget_class; GtkRulerClass *ruler_class; + vruler_parent_class = (GtkWidgetClass *) gtk_type_class (GTK_TYPE_RULER); + widget_class = (GtkWidgetClass*) klass; ruler_class = (GtkRulerClass*) klass; widget_class->motion_notify_event = sp_vruler_motion_notify; + widget_class->size_allocate = sp_vruler_size_allocate; ruler_class->draw_ticks = sp_vruler_draw_ticks; ruler_class->draw_pos = sp_vruler_draw_pos; @@ -473,7 +511,7 @@ sp_vruler_draw_ticks (GtkRuler *ruler) upper = ruler->upper / ruler->metric->pixels_per_unit; lower = ruler->lower / ruler->metric->pixels_per_unit; - + if ((upper - lower) == 0) return; increment = (double) (width + 2*UNUSED_PIXELS) / (upper - lower); @@ -525,7 +563,7 @@ sp_vruler_draw_ticks (GtkRuler *ruler) cur = start; while (cur < end) { - pos = int(round ((cur - lower) * increment) - UNUSED_PIXELS); + pos = int(Inkscape::round ((cur - lower) * increment) - UNUSED_PIXELS); gdk_draw_line (ruler->backing_store, gc, height + xthickness - length, pos, @@ -608,7 +646,7 @@ sp_vruler_draw_pos (GtkRuler *ruler) increment = (gfloat) (height + 2*UNUSED_PIXELS) / (ruler->upper - ruler->lower); x = (width + bs_width) / 2 + xthickness; - y = int(round ((ruler->position - ruler->lower) * increment) + (ythickness - bs_height) / 2 - 1); + y = int(Inkscape::round((ruler->position - ruler->lower) * increment + double(ythickness - bs_height) / 2.0) - 1); for (i = 0; i < bs_width; i++) gdk_draw_line (widget->window, gc, @@ -621,6 +659,36 @@ sp_vruler_draw_pos (GtkRuler *ruler) } } +/** + * The vruler widget's size_allocate callback. + */ +static void +sp_vruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + g_assert (widget != NULL); + g_assert (SP_IS_VRULER (widget)); + + // First call the default gtk_widget_size_allocate() method (which is being overridden here) + if (GTK_WIDGET_CLASS (vruler_parent_class)->size_allocate) + (* GTK_WIDGET_CLASS (vruler_parent_class)->size_allocate) (widget, allocation); + + // Now the size of the ruler has changed, the ruler bounds (upper & lower) need to be updated + // For this we first need to obtain a pointer to the desktop, by walking up the tree of ancestors + GtkWidget *parent = gtk_widget_get_parent(widget); + do { + if (SP_IS_DESKTOP_WIDGET(parent)) { + // Now we've found the desktop widget we can have the ruler boundaries updated + sp_desktop_widget_update_vruler(SP_DESKTOP_WIDGET(parent)); + // If the size of the ruler has increased, then a blank part is uncovered; therefore + // it must be redrawn + sp_vruler_draw_ticks(GTK_RULER(widget)); + break; + } + parent = gtk_widget_get_parent(parent); + } while (parent != NULL); +} + + /// Ruler metrics. static GtkRulerMetric const sp_ruler_metrics[] = { // NOTE: the order of records in this struct must correspond to the SPMetric enum. diff --git a/src/widgets/ruler.h b/src/widgets/ruler.h index 1370c19c8..8aa162940 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -15,7 +15,7 @@ #include #include "sp-metric.h" - +#include #include