132
133
static void sp_ruler_size_request (GtkWidget *widget,
133
134
GtkRequisition *requisition);
134
135
static void sp_ruler_style_set (GtkWidget *widget,
135
GtkStyle *prev_style);
136
GtkStyle *prev_style);
138
139
static gboolean sp_ruler_motion_notify (GtkWidget *widget,
139
140
GdkEventMotion *event);
140
141
static gboolean sp_ruler_draw (GtkWidget *widget,
142
143
#if !GTK_CHECK_VERSION(3,0,0)
143
144
static gboolean sp_ruler_expose (GtkWidget *widget,
144
145
GdkEventExpose *event);
146
147
static void sp_ruler_draw_ticks (SPRuler *ruler);
147
static void sp_ruler_draw_pos (SPRuler *ruler);
148
static GdkRectangle sp_ruler_get_pos_rect (SPRuler *ruler,
150
static gboolean sp_ruler_idle_queue_pos_redraw(gpointer data);
151
static void sp_ruler_queue_pos_redraw (SPRuler *ruler);
152
static void sp_ruler_draw_pos (SPRuler *ruler,
148
154
static void sp_ruler_make_pixmap (SPRuler *ruler);
150
156
static PangoLayout * sp_ruler_get_layout (GtkWidget *widget,
260
266
gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE);
262
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
263
priv->unit = unit_table.getUnit("px");
268
priv->backing_store = NULL;
269
priv->font_scale = DEFAULT_RULER_FONT_SCALE;
268
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
269
priv->unit = unit_table.getUnit("px");
275
priv->backing_store = NULL;
276
priv->backing_store_valid = FALSE;
278
priv->last_pos_rect.x = 0;
279
priv->last_pos_rect.y = 0;
280
priv->last_pos_rect.width = 0;
281
priv->last_pos_rect.height = 0;
282
priv->pos_redraw_idle_id = 0;
284
priv->font_scale = DEFAULT_RULER_FONT_SCALE;
271
286
#if GTK_CHECK_VERSION(3,0,0)
272
287
#if GTK_CHECK_VERSION(3,8,0)
732
755
CAIRO_CONTENT_COLOR,
733
756
allocation.width,
734
757
allocation.height);
759
priv->backing_store_valid = FALSE;
738
sp_ruler_draw_pos (SPRuler *ruler)
763
sp_ruler_draw_pos (SPRuler *ruler,
740
766
GtkWidget *widget = GTK_WIDGET (ruler);
742
768
#if GTK_CHECK_VERSION(3,0,0)
743
769
GtkStyleContext *context = gtk_widget_get_style_context (widget);
747
772
GtkStyle *style = gtk_widget_get_style (widget);
748
773
GtkStateType state = gtk_widget_get_state (widget);
753
776
SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler);
754
GtkAllocation allocation;
757
gint bs_width, bs_height;
777
GdkRectangle pos_rect;
759
779
if (! gtk_widget_is_drawable (widget))
762
gtk_widget_get_allocation(widget, &allocation);
764
#if GTK_CHECK_VERSION(3,0,0)
765
gtk_style_context_get_border (context, static_cast<GtkStateFlags>(0), &border);
767
xthickness = style->xthickness;
768
ythickness = style->ythickness;
771
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
773
width = allocation.width;
774
#if GTK_CHECK_VERSION(3,0,0)
775
height = allocation.height - (border.top + border.bottom);
777
height = allocation.height - ythickness * 2;
780
bs_width = height / 2 + 2;
781
bs_width |= 1; /* make sure it's odd */
782
bs_height = bs_width / 2 + 1;
786
#if GTK_CHECK_VERSION(3,0,0)
787
width = allocation.width - (border.left + border.right);
789
width = allocation.width - xthickness * 2;
791
height = allocation.height;
793
bs_height = width / 2 + 2;
794
bs_height |= 1; /* make sure it's odd */
795
bs_width = bs_height / 2 + 1;
798
if ((bs_width > 0) && (bs_height > 0))
800
cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
807
allocation.x, allocation.y,
808
allocation.width, allocation.height);
811
cairo_translate (cr, allocation.x, allocation.y);
813
/* If a backing store exists, restore the ruler */
814
if (priv->backing_store)
816
cairo_set_source_surface (cr, priv->backing_store, 0, 0);
817
cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height);
821
position = sp_ruler_get_position (ruler);
823
sp_ruler_get_range (ruler, &lower, &upper, NULL);
825
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
827
increment = (gdouble) width / (upper - lower);
829
#if GTK_CHECK_VERSION(3,0,0)
830
x = ROUND ((position - lower) * increment) + (border.left - bs_width) / 2 - 1;
831
y = (height + bs_height) / 2 + border.top;
833
x = ROUND ((position - lower) * increment) + (xthickness - bs_width) / 2 - 1;
834
y = (height + bs_height) / 2 + ythickness;
839
increment = (gdouble) height / (upper - lower);
841
#if GTK_CHECK_VERSION(3,0,0)
842
x = (width + bs_width) / 2 + border.left;
843
y = ROUND ((position - lower) * increment) + (border.top - bs_height) / 2 - 1;
845
x = (width + bs_width) / 2 + xthickness;
846
y = ROUND ((position - lower) * increment) + (ythickness - bs_height) / 2 - 1;
782
pos_rect = sp_ruler_get_pos_rect (ruler, sp_ruler_get_position (ruler));
784
if ((pos_rect.width > 0) && (pos_rect.height > 0))
850
786
#if GTK_CHECK_VERSION(3,0,0)
851
787
gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget),
855
791
gdk_cairo_set_source_color (cr, &style->fg[state]);
858
cairo_move_to (cr, x, y);
794
cairo_move_to (cr, pos_rect.x, pos_rect.y);
860
796
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
862
cairo_line_to (cr, x + bs_width / 2.0, y + bs_height);
863
cairo_line_to (cr, x + bs_width, y);
798
cairo_line_to (cr, pos_rect.x + pos_rect.width / 2.0,
799
pos_rect.y + pos_rect.height);
800
cairo_line_to (cr, pos_rect.x + pos_rect.width,
867
cairo_line_to (cr, x + bs_width, y + bs_height / 2.0);
868
cairo_line_to (cr, x, y + bs_height);
805
cairo_line_to (cr, pos_rect.x + pos_rect.width,
807
pos_rect.y + pos_rect.height / 2.0);
808
cairo_line_to (cr, pos_rect.x,
809
pos_rect.y + pos_rect.height);
815
priv->last_pos_rect = pos_rect;
1124
1063
if (priv->position != position)
1126
priv->position = position;
1127
g_object_notify (G_OBJECT (ruler), "position");
1129
sp_ruler_draw_pos (ruler);
1068
priv->position = position;
1069
g_object_notify (G_OBJECT (ruler), "position");
1071
rect = sp_ruler_get_pos_rect (ruler, priv->position);
1073
xdiff = rect.x - priv->last_pos_rect.x;
1074
ydiff = rect.y - priv->last_pos_rect.y;
1077
* If the position has changed far enough, queue a redraw immediately.
1078
* Otherwise, we only queue a redraw in a low priority idle handler, to
1079
* allow for other things (like updating the canvas) to run.
1081
* TODO: This might not be necessary any more in GTK3 with the frame
1082
* clock. Investigate this more after the port to GTK3.
1084
if (priv->last_pos_rect.width != 0 &&
1085
priv->last_pos_rect.height != 0 &&
1086
(ABS (xdiff) > IMMEDIATE_REDRAW_THRESHOLD ||
1087
ABS (ydiff) > IMMEDIATE_REDRAW_THRESHOLD))
1089
sp_ruler_queue_pos_redraw (ruler);
1091
else if (! priv->pos_redraw_idle_id)
1093
priv->pos_redraw_idle_id =
1094
g_idle_add_full (G_PRIORITY_LOW,
1095
sp_ruler_idle_queue_pos_redraw,
1447
1415
cairo_fill (cr);
1417
priv->backing_store_valid = TRUE;
1450
1420
cairo_destroy (cr);
1424
sp_ruler_get_pos_rect (SPRuler *ruler,
1427
GtkWidget *widget = GTK_WIDGET (ruler);
1428
GtkStyle *style = gtk_widget_get_style (widget);
1429
SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler);
1430
GtkAllocation allocation;
1434
gdouble upper, lower;
1436
GdkRectangle rect = { 0, };
1438
if (! gtk_widget_is_drawable (widget))
1441
gtk_widget_get_allocation (widget, &allocation);
1443
xthickness = style->xthickness;
1444
ythickness = style->ythickness;
1446
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1448
width = allocation.width;
1449
height = allocation.height - ythickness * 2;
1451
rect.width = height / 2 + 2;
1452
rect.width |= 1; /* make sure it's odd */
1453
rect.height = rect.width / 2 + 1;
1457
width = allocation.width - xthickness * 2;
1458
height = allocation.height;
1460
rect.height = width / 2 + 2;
1461
rect.height |= 1; /* make sure it's odd */
1462
rect.width = rect.height / 2 + 1;
1465
sp_ruler_get_range (ruler, &lower, &upper, NULL);
1467
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
1469
increment = (gdouble) width / (upper - lower);
1471
rect.x = ROUND ((position - lower) * increment) + (xthickness - rect.width) / 2 - 1;
1472
rect.y = (height + rect.height) / 2 + ythickness;
1476
increment = (gdouble) height / (upper - lower);
1478
rect.x = (width + rect.width) / 2 + xthickness;
1479
rect.y = ROUND ((position - lower) * increment) + (ythickness - rect.height) / 2 - 1;
1482
rect.x += allocation.x;
1483
rect.y += allocation.y;
1489
sp_ruler_idle_queue_pos_redraw (gpointer data)
1491
SPRuler *ruler = (SPRuler *)data;
1492
SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler);
1494
sp_ruler_queue_pos_redraw (ruler);
1496
gboolean ret = g_source_remove(priv->pos_redraw_idle_id);
1497
priv->pos_redraw_idle_id = 0;
1503
sp_ruler_queue_pos_redraw (SPRuler *ruler)
1505
SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler);
1506
const GdkRectangle rect = sp_ruler_get_pos_rect (ruler, priv->position);
1508
gtk_widget_queue_draw_area (GTK_WIDGET(ruler),
1514
if (priv->last_pos_rect.width != 0 || priv->last_pos_rect.height != 0)
1516
gtk_widget_queue_draw_area (GTK_WIDGET(ruler),
1517
priv->last_pos_rect.x,
1518
priv->last_pos_rect.y,
1519
priv->last_pos_rect.width,
1520
priv->last_pos_rect.height);
1522
priv->last_pos_rect.x = 0;
1523
priv->last_pos_rect.y = 0;
1524
priv->last_pos_rect.width = 0;
1525
priv->last_pos_rect.height = 0;
1453
1529
static PangoLayout*
1454
1530
sp_ruler_create_layout (GtkWidget *widget,
1455
1531
const gchar *text)