Mercurial > projects > doodle
comparison canvas.d @ 2:d6f44347373d
* Switched over to geometry done with structs instead of classes.
* Removed direct access to gtk structs
* Refactoring
author | David Bryant <daveb@acres.com.au> |
---|---|
date | Fri, 10 Jul 2009 15:15:27 +0930 |
parents | e907d2c54ec3 |
children | 7d57cae10805 |
comparison
equal
deleted
inserted
replaced
1:c18e3f93d114 | 2:d6f44347373d |
---|---|
18 import gtk.VScrollbar; | 18 import gtk.VScrollbar; |
19 import gtk.DrawingArea; | 19 import gtk.DrawingArea; |
20 import gtk.Adjustment; | 20 import gtk.Adjustment; |
21 | 21 |
22 import tk.misc; | 22 import tk.misc; |
23 import tk.geometry; | 23 import tk.geometry2; |
24 import tk.types; | 24 import tk.types; |
25 import tk.events; | 25 import tk.events; |
26 import tk.gtk_support; | 26 import tk.gtk_support; |
27 | 27 |
28 private import gtkc.gtk; | 28 private import gtkc.gtk; |
29 | 29 |
30 import icanvas; | 30 import icanvas; |
31 import cairo_support; | |
31 | 32 |
32 // x and y run right and up respectively | 33 // x and y run right and up respectively |
33 | |
34 void rectangle(Context cr, Point corner1, Point corner2) { | |
35 double x = corner1.x; | |
36 double y = corner1.y; | |
37 double w = corner2.x - corner1.x; | |
38 double h = corner2.y - corner1.y; | |
39 | |
40 if (w < 0.0) { x += w; w = -w; } | |
41 if (h < 0.0) { y += h; h = -h; } | |
42 | |
43 //writefln("Rect: %f %f %f %f\n", x, y, w, h); | |
44 | |
45 cr.rectangle(x, y, w, h); | |
46 } | |
47 | 34 |
48 class Canvas : Table, ICanvas { | 35 class Canvas : Table, ICanvas { |
49 static this() { | 36 static this() { |
50 ORIGIN = new Point(0.0, 0.0); | 37 ORIGIN = Point2(0.0, 0.0); |
51 INITIAL_PAGE_SIZE = new Vector(210.0, 297.0); // A4 | 38 INITIAL_PAGE_SIZE = Vector2(210.0, 297.0); // A4 |
52 } | 39 } |
53 | 40 |
54 this(ICanvasEventHandler event_handler) { | 41 this(ICanvasEventHandler event_handler) { |
55 super(3, 3, 0); | 42 super(3, 3, 0); |
56 | 43 |
58 | 45 |
59 const double PPI = 120.0; | 46 const double PPI = 120.0; |
60 const double MM_PER_INCH = 25.4; | 47 const double MM_PER_INCH = 25.4; |
61 mZoom = 0.25 * PPI / MM_PER_INCH; | 48 mZoom = 0.25 * PPI / MM_PER_INCH; |
62 | 49 |
63 mPageLeftBottom = ORIGIN.clone(); | 50 mPageLeftBottom = ORIGIN; |
64 mPageRightTop = ORIGIN + INITIAL_PAGE_SIZE; | 51 mPageRightTop = ORIGIN + INITIAL_PAGE_SIZE; |
65 mViewCentre = ORIGIN + INITIAL_PAGE_SIZE / 2.0; | 52 mViewCentre = ORIGIN + INITIAL_PAGE_SIZE / 2.0; |
66 | 53 |
67 mCanvasLeftBottom = mPageLeftBottom - 3.0 * INITIAL_PAGE_SIZE; | 54 mCanvasLeftBottom = mPageLeftBottom - 3.0 * INITIAL_PAGE_SIZE; |
68 mCanvasRightTop = mPageRightTop + 3.0 * INITIAL_PAGE_SIZE; | 55 mCanvasRightTop = mPageRightTop + 3.0 * INITIAL_PAGE_SIZE; |
99 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL | AttachOptions.EXPAND, | 86 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL | AttachOptions.EXPAND, |
100 0, 0); | 87 0, 0); |
101 | 88 |
102 // value, lower, upper, step-inc, page-inc, page-size | 89 // value, lower, upper, step-inc, page-inc, page-size |
103 // Give the adjustments dummy values until we receive a configure | 90 // Give the adjustments dummy values until we receive a configure |
104 mHAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 1.0); | 91 mHAdjustment = new Adjustment(0.25, 0.0, 1.0, 0.2, 0.5, 0.5); |
105 mHAdjustment.addOnValueChanged(&onValueChanged); | 92 mHAdjustment.addOnValueChanged(&onValueChanged); |
106 mHScrollbar = new HScrollbar(mHAdjustment); | 93 mHScrollbar = new HScrollbar(mHAdjustment); |
107 attach(mHScrollbar, | 94 attach(mHScrollbar, |
108 1, 2, | 95 1, 2, |
109 2, 3, | 96 2, 3, |
110 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK, | 97 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK, |
111 0, 0); | 98 0, 0); |
112 | 99 |
113 mVAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.4); | 100 mVAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5); |
114 mVAdjustment.addOnValueChanged(&onValueChanged); | 101 mVAdjustment.addOnValueChanged(&onValueChanged); |
115 mVScrollbar = new VScrollbar(mVAdjustment); | 102 mVScrollbar = new VScrollbar(mVAdjustment); |
116 attach(mVScrollbar, | 103 attach(mVScrollbar, |
117 2, 3, | 104 2, 3, |
118 1, 2, | 105 1, 2, |
119 AttachOptions.SHRINK, | 106 AttachOptions.SHRINK, |
120 AttachOptions.FILL | AttachOptions.EXPAND, | 107 AttachOptions.FILL | AttachOptions.EXPAND, |
121 0, 0); | 108 0, 0); |
122 } | 109 } |
123 | 110 |
124 override void rel_zoom(Point screen_datum, double factor) { | 111 override void rel_zoom(Point2 screen_datum, double factor) { |
125 // Work out pixel distance from current centre to datum, | 112 // Work out pixel distance from current centre to datum, |
126 // Do the zoom, then work out the new centre that keeps the | 113 // Do the zoom, then work out the new centre that keeps the |
127 // pixel distance the same | 114 // pixel distance the same |
128 | 115 |
129 Point old_model_datum = screen_to_model(screen_datum); | 116 Point2 old_model_datum = screen_to_model(screen_datum); |
130 Vector pixel_distance = model_to_screen(old_model_datum - mViewCentre); | 117 Vector2 pixel_distance = model_to_screen(old_model_datum - mViewCentre); |
131 mZoom = clamp_zoom(factor * mZoom); | 118 mZoom = clamp_zoom(factor * mZoom); |
132 mViewCentre = old_model_datum - screen_to_model(pixel_distance); | 119 mViewCentre = old_model_datum - screen_to_model(pixel_distance); |
133 | 120 |
134 Point new_model_datum = screen_to_model(screen_datum); | 121 Point2 new_model_datum = screen_to_model(screen_datum); |
135 | 122 |
136 update_adjustments(); | 123 update_adjustments(); |
137 //update_rulers(new_model_datum); | 124 //update_rulers(new_model_datum); |
138 update_rulers(); | 125 update_rulers(); |
139 queueDraw(); | 126 queueDraw(); |
140 } | 127 } |
141 | 128 |
142 override void rel_pan(Vector screen_displacement) { | 129 override void rel_pan(Vector2 screen_displacement) { |
143 mViewCentre = mViewCentre + screen_to_model(screen_displacement); | 130 mViewCentre = mViewCentre + screen_to_model(screen_displacement); |
144 | 131 |
145 update_adjustments(); | 132 update_adjustments(); |
146 update_rulers(); | 133 update_rulers(); |
147 queueDraw(); | 134 queueDraw(); |
155 } | 142 } |
156 | 143 |
157 bool onConfigure(GdkEventConfigure * event, Widget widget) { | 144 bool onConfigure(GdkEventConfigure * event, Widget widget) { |
158 assert(widget is mDrawingArea); | 145 assert(widget is mDrawingArea); |
159 | 146 |
160 mViewSize = new Vector(cast(double)event.width, cast(double)event.height); | 147 mViewSize = Vector2(cast(double)event.width, cast(double)event.height); |
161 update_adjustments(); | 148 update_adjustments(); |
162 update_rulers(); | 149 update_rulers(); |
163 | 150 |
164 | 151 |
165 return 1; | 152 return true; |
166 } | 153 } |
167 | 154 |
168 bool onExpose(GdkEventExpose * event, Widget widget) { | 155 bool onExpose(GdkEventExpose * event, Widget widget) { |
169 assert(widget is mDrawingArea); | 156 assert(widget is mDrawingArea); |
170 | 157 |
192 cr.fill(); | 179 cr.fill(); |
193 | 180 |
194 { | 181 { |
195 // Make the paper white, with a border | 182 // Make the paper white, with a border |
196 | 183 |
197 Point screen_page_left_bottom = model_to_screen(mPageLeftBottom); | 184 Point2 screen_page_left_bottom = model_to_screen(mPageLeftBottom); |
198 Point screen_page_right_top = model_to_screen(mPageRightTop); | 185 Point2 screen_page_right_top = model_to_screen(mPageRightTop); |
199 | 186 |
200 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); | 187 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); |
201 rectangle(cr, screen_page_left_bottom, screen_page_right_top); | 188 rectangle(cr, screen_page_left_bottom, screen_page_right_top); |
202 cr.fill(); | 189 cr.fill(); |
203 | 190 |
204 cr.setSourceRgba(0.0, 0.0, 0.0, 1.0); | 191 cr.setSourceRgba(0.0, 0.0, 0.0, 1.0); |
205 rectangle(cr, screen_page_left_bottom, screen_page_right_top); | 192 rectangle(cr, screen_page_left_bottom, screen_page_right_top); |
206 cr.stroke(); | 193 cr.stroke(); |
207 } | 194 } |
208 | 195 |
209 return 1; | 196 return true; |
210 } | 197 } |
211 | 198 |
212 bool onButtonEvent(GdkEventButton * event, Widget widget) { | 199 bool onButtonEvent(GdkEventButton * event, Widget widget) { |
213 assert(widget is mDrawingArea); | 200 assert(widget is mDrawingArea); |
214 //writefln("Got button event\n"); | 201 //writefln("Got button event\n"); |
215 | 202 |
216 Point screen_point = new Point(event.x + 0.5, event.y + 0.5); | 203 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); |
217 Point model_point = screen_to_model(screen_point); | 204 Point2 model_point = screen_to_model(screen_point); |
218 | 205 |
219 auto button_event = new ButtonEvent(gtk2tk_click(event.type), | 206 auto button_event = new ButtonEvent(gtk2tk_click(event.type), |
220 gtk2tk_button(event.button), | 207 gtk2tk_button(event.button), |
221 screen_point, | 208 screen_point, |
222 model_point, | 209 model_point, |
223 gtk2tk_mask(event.state)); | 210 gtk2tk_mask(event.state)); |
224 | 211 |
225 //mEventHandle.handle_button_press | 212 //mEventHandle.handle_button_press |
226 | 213 |
227 return 1; | 214 return true; |
228 } | 215 } |
229 | 216 |
230 bool onKeyEvent(GdkEventKey * event, Widget widget) { | 217 bool onKeyEvent(GdkEventKey * event, Widget widget) { |
231 assert(widget is mDrawingArea); | 218 assert(widget is mDrawingArea); |
232 //writefln("Got key event\n"); | 219 //writefln("Got key event\n"); |
233 | 220 |
234 //auto key_event = new KeyEvent("", | 221 //auto key_event = new KeyEvent("", |
235 // mEventHandle.handle_key(key_event); | 222 // mEventHandle.handle_key(key_event); |
236 | 223 |
237 return 1; | 224 return true; |
238 } | 225 } |
239 | 226 |
240 bool onMotionNotify(GdkEventMotion * event, Widget widget) { | 227 bool onMotionNotify(GdkEventMotion * event, Widget widget) { |
241 assert(widget is mDrawingArea); | 228 assert(widget is mDrawingArea); |
242 //writefln("Got motion notify\n"); | 229 //writefln("Got motion notify\n"); |
243 gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event); | 230 gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event); |
244 gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event); | 231 gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event); |
245 | 232 |
246 Point screen_point = new Point(event.x + 0.5, event.y + 0.5); | 233 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); |
247 Point model_point = screen_to_model(screen_point); | 234 Point2 model_point = screen_to_model(screen_point); |
248 | 235 |
249 auto motion_event = new MotionEvent(screen_point, | 236 auto motion_event = new MotionEvent(screen_point, |
250 model_point, | 237 model_point, |
251 gtk2tk_mask(event.state)); | 238 gtk2tk_mask(event.state)); |
252 | 239 |
253 mEventHandler.handle_motion(this, motion_event); | 240 mEventHandler.handle_motion(this, motion_event); |
254 | 241 |
255 return 1; | 242 return true; |
256 } | 243 } |
257 | 244 |
258 bool onScroll(GdkEventScroll * event, Widget widget) { | 245 bool onScroll(GdkEventScroll * event, Widget widget) { |
259 assert(widget is mDrawingArea); | 246 assert(widget is mDrawingArea); |
260 //writefln("Got scroll\n"); | 247 //writefln("Got scroll\n"); |
261 | 248 |
262 Point screen_point = new Point(event.x + 0.5, event.y + 0.5); | 249 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); |
263 Point model_point = screen_to_model(screen_point); | 250 Point2 model_point = screen_to_model(screen_point); |
264 | 251 |
265 auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction), | 252 auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction), |
266 screen_point, | 253 screen_point, |
267 model_point, | 254 model_point, |
268 gtk2tk_mask(event.state)); | 255 gtk2tk_mask(event.state)); |
269 | 256 |
270 mEventHandler.handle_scroll(this, scroll_event); | 257 mEventHandler.handle_scroll(this, scroll_event); |
271 | 258 |
272 return 1; | 259 return true; |
273 } | 260 } |
274 | 261 |
275 void onValueChanged(Adjustment adjustment) { | 262 void onValueChanged(Adjustment adjustment) { |
276 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); | 263 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); |
277 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); | 264 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); |
278 | 265 |
279 Point view_left_bottom = new Point(h_gtkAdjustment.value, v_gtkAdjustment.value); | 266 Point2 view_left_bottom = Point2(gtk_adjustment_get_value(h_gtkAdjustment), |
267 gtk_adjustment_get_value(v_gtkAdjustment)); | |
280 writefln("%s", view_left_bottom); | 268 writefln("%s", view_left_bottom); |
281 Vector model_size = screen_to_model(mViewSize); | 269 Vector2 model_size = screen_to_model(mViewSize); |
282 mViewCentre = view_left_bottom + model_size / 2.0; | 270 mViewCentre = view_left_bottom + model_size / 2.0; |
283 | 271 |
284 update_rulers(); | 272 update_rulers(); |
285 | 273 |
286 queueDraw(); | 274 queueDraw(); |
287 } | 275 } |
288 | 276 |
289 void update_rulers() { | 277 void update_rulers() { |
290 Vector model_size = screen_to_model(mViewSize); | 278 Vector2 model_size = screen_to_model(mViewSize); |
291 | 279 |
292 Point view_left_bottom = mViewCentre - model_size / 2.0; | 280 Point2 view_left_bottom = mViewCentre - model_size / 2.0; |
293 Point view_right_top = mViewCentre + model_size / 2.0; | 281 Point2 view_right_top = mViewCentre + model_size / 2.0; |
294 | 282 |
295 mHRuler.setRange(view_left_bottom.x, | 283 mHRuler.setRange(view_left_bottom.x, |
296 view_right_top.x, | 284 view_right_top.x, |
297 0.0, // TODO preserve the value | 285 0.0, // TODO preserve the value |
298 mZoom * 2000.0); | 286 mZoom * 2000.0); |
301 0.0, | 289 0.0, |
302 mZoom * 2000.0); | 290 mZoom * 2000.0); |
303 } | 291 } |
304 | 292 |
305 void update_adjustments() { | 293 void update_adjustments() { |
306 Vector model_size = screen_to_model(mViewSize); | 294 Vector2 model_size = screen_to_model(mViewSize); |
307 | 295 |
308 Point view_left_bottom = mViewCentre - model_size / 2.0; | 296 Point2 view_left_bottom = mViewCentre - model_size / 2.0; |
309 Point view_right_top = mViewCentre + model_size / 2.0; | 297 Point2 view_right_top = mViewCentre + model_size / 2.0; |
310 | 298 |
311 // Adjust the canvas size if necessary | 299 // Adjust the canvas size if necessary |
312 mCanvasLeftBottom = min_extents(mCanvasLeftBottom, view_left_bottom); | 300 mCanvasLeftBottom = min_extents(mCanvasLeftBottom, view_left_bottom); |
313 mCanvasRightTop = max_extents(mCanvasRightTop, view_right_top); | 301 mCanvasRightTop = max_extents(mCanvasRightTop, view_right_top); |
314 | 302 |
315 Vector canvas_size = mCanvasRightTop - mCanvasLeftBottom; | 303 Vector2 canvas_size = mCanvasRightTop - mCanvasLeftBottom; |
316 Vector page_size = mPageRightTop - mPageLeftBottom; | 304 Vector2 page_size = mPageRightTop - mPageLeftBottom; |
317 | 305 |
318 // Update the adjustments | 306 // Update the adjustments |
319 | 307 |
320 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); | 308 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); |
321 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); | 309 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); |
322 | 310 |
323 h_gtkAdjustment.lower = mCanvasLeftBottom.x; | 311 gtk_adjustment_set_lower(h_gtkAdjustment, mCanvasLeftBottom.x); |
324 h_gtkAdjustment.upper = mCanvasRightTop.x; | 312 gtk_adjustment_set_upper(h_gtkAdjustment, mCanvasRightTop.x); |
325 h_gtkAdjustment.value = view_left_bottom.x; | 313 gtk_adjustment_set_value(h_gtkAdjustment, view_left_bottom.x); |
326 h_gtkAdjustment.step_increment = canvas_size.x / 10.0; | 314 gtk_adjustment_set_step_increment(h_gtkAdjustment, canvas_size.x / 10.0); |
327 h_gtkAdjustment.page_increment = canvas_size.x / 5.0; | 315 gtk_adjustment_set_page_increment(h_gtkAdjustment, canvas_size.x / 5.0); |
328 h_gtkAdjustment.page_size = model_size.x; | 316 gtk_adjustment_set_page_size(h_gtkAdjustment, model_size.x); |
329 | 317 |
330 v_gtkAdjustment.lower = mCanvasLeftBottom.y; | 318 gtk_adjustment_set_lower(v_gtkAdjustment, mCanvasLeftBottom.y); |
331 v_gtkAdjustment.upper = mCanvasRightTop.y; | 319 gtk_adjustment_set_upper(v_gtkAdjustment, mCanvasRightTop.y); |
332 v_gtkAdjustment.value = view_left_bottom.y; | 320 gtk_adjustment_set_value(v_gtkAdjustment, view_left_bottom.y); |
333 v_gtkAdjustment.step_increment = canvas_size.y / 10.0; | 321 gtk_adjustment_set_step_increment(v_gtkAdjustment, canvas_size.y / 10.0); |
334 v_gtkAdjustment.page_increment = canvas_size.y / 5.0; | 322 gtk_adjustment_set_page_increment(v_gtkAdjustment, canvas_size.y / 5.0); |
335 v_gtkAdjustment.page_size = model_size.y; | 323 gtk_adjustment_set_page_size(v_gtkAdjustment, model_size.y); |
336 | 324 |
337 mHAdjustment.changed(); | 325 mHAdjustment.changed(); |
338 mHAdjustment.valueChanged(); | 326 mHAdjustment.valueChanged(); |
339 mVAdjustment.changed(); | 327 mVAdjustment.changed(); |
340 mVAdjustment.valueChanged(); | 328 mVAdjustment.valueChanged(); |
341 } | 329 } |
342 | 330 |
343 Point model_to_screen(Point model) { return ORIGIN + mViewSize / 2.0 + mZoom * (model - mViewCentre); } | 331 Point2 model_to_screen(Point2 model) { return ORIGIN + mViewSize / 2.0 + mZoom * (model - mViewCentre); } |
344 Point screen_to_model(Point screen) { return mViewCentre + (screen - mViewSize / 2.0 - ORIGIN) / mZoom; } | 332 Point2 screen_to_model(Point2 screen) { return mViewCentre + (screen - mViewSize / 2.0 - ORIGIN) / mZoom; } |
345 Vector model_to_screen(Vector model) { return mZoom * model; } | 333 Vector2 model_to_screen(Vector2 model) { return mZoom * model; } |
346 Vector screen_to_model(Vector screen) { return screen / mZoom; } | 334 Vector2 screen_to_model(Vector2 screen) { return screen / mZoom; } |
347 double model_to_screen(double model) { return mZoom * model; } | 335 double model_to_screen(double model) { return mZoom * model; } |
348 double screen_to_model(double screen) { return screen / mZoom; } | 336 double screen_to_model(double screen) { return screen / mZoom; } |
349 | 337 |
350 double clamp_zoom(double zoom) { return clamp(zoom, 0.1, 10.0); } | 338 double clamp_zoom(double zoom) { return clamp(zoom, 0.1, 10.0); } |
351 | 339 |
352 static const Point ORIGIN; | 340 static const Point2 ORIGIN; |
353 static const Vector INITIAL_PAGE_SIZE; | 341 static const Vector2 INITIAL_PAGE_SIZE; |
354 | 342 |
355 ICanvasEventHandler mEventHandler; | 343 ICanvasEventHandler mEventHandler; |
356 | 344 |
357 // Model units are in millimetres | 345 // Model units are in millimetres |
358 // Screen units are in pixels | 346 // Screen units are in pixels |
359 | 347 |
360 double mZoom; // pixels-per-mm | 348 double mZoom; // pixels-per-mm |
361 Point mViewCentre; // model: where in the model is the centre of our view | 349 Point2 mViewCentre; // model: where in the model is the centre of our view |
362 | 350 |
363 Point mCanvasLeftBottom; // model: bottom left corner of canvas | 351 Point2 mCanvasLeftBottom; // model: bottom left corner of canvas |
364 Point mCanvasRightTop; // model: top right corner of canvas | 352 Point2 mCanvasRightTop; // model: top right corner of canvas |
365 Point mPageLeftBottom; // model: bottom left corner of page | 353 Point2 mPageLeftBottom; // model: bottom left corner of page |
366 Point mPageRightTop; // model: top right corner of page | 354 Point2 mPageRightTop; // model: top right corner of page |
367 | 355 |
368 Vector mViewSize; // screen: size of view window in pixels | 356 Vector2 mViewSize; // screen: size of view window in pixels |
369 | 357 |
370 HRuler mHRuler; | 358 HRuler mHRuler; |
371 VRuler mVRuler; | 359 VRuler mVRuler; |
372 DrawingArea mDrawingArea; | 360 DrawingArea mDrawingArea; |
373 Adjustment mHAdjustment; | 361 Adjustment mHAdjustment; |