Mercurial > projects > doodle
comparison doodle/gtk/canvas.d @ 41:f2e4e1d29b98
Bah
author | daveb |
---|---|
date | Tue, 01 Jun 2010 17:21:01 +0930 |
parents | 1f97022e5c6d |
children | 1b4c9ba58673 |
comparison
equal
deleted
inserted
replaced
40:1f97022e5c6d | 41:f2e4e1d29b98 |
---|---|
31 | 31 |
32 import gtkc.gtk; | 32 import gtkc.gtk; |
33 } | 33 } |
34 | 34 |
35 // x and y run right and up respectively | 35 // x and y run right and up respectively |
36 // | |
37 // Model units are millimetres. | |
38 // | |
39 // mZoom -> pixels-per-model-unit | |
40 // mViewSize -> size of view window in pixels | |
41 // mViewCentre -> location in model corresponding to centre of view | |
42 // mCanvasBounds -> size of the virtual canvas in model coordinates | |
43 // | |
44 // User operations: | |
45 // pan (middle click and drag) | |
46 // zoom about a point (hold control and move scroll wheel) | |
47 // resize the widget | |
36 | 48 |
37 class Canvas : Table, Viewport { | 49 class Canvas : Table, Viewport { |
38 this(in Layer[] layers, EventHandler event_handler, Grid grid, in double ppi) { | 50 this(in Layer[] layers, EventHandler event_handler, Grid grid, in double ppi) { |
39 super(3, 3, 0); | 51 super(3, 3, 0); |
40 | 52 |
182 mDamage = mDamage | area; | 194 mDamage = mDamage | area; |
183 } | 195 } |
184 | 196 |
185 private { | 197 private { |
186 | 198 |
199 void update_bounds() { | |
200 } | |
201 | |
202 | |
187 bool on_configure(GdkEventConfigure * event, Widget widget) { | 203 bool on_configure(GdkEventConfigure * event, Widget widget) { |
188 assert(widget is mDrawingArea); | 204 assert(widget is mDrawingArea); |
189 | 205 |
206 mViewSize = Vector(cast(double)event.width, cast(double)event.height); | |
207 | |
208 Rectangle layer_bounds = Rectangle.DEFAULT; | |
209 | |
210 foreach (ref layer; mLayers) { | |
211 layer_bounds = layer_bounds | layer.bounds; | |
212 } | |
213 | |
214 assert(layer_bounds.valid); | |
215 | |
216 Rectangle padded_layer_bounds = expand(move(layer_bounds, - layer_bounds.size), 2.0 * layer_bounds.size); | |
217 | |
190 if (!mHadConfigure) { | 218 if (!mHadConfigure) { |
219 info("1"); | |
191 const double MM_PER_INCH = 25.4; | 220 const double MM_PER_INCH = 25.4; |
192 mZoom = 0.25 * mPPI / MM_PER_INCH; | 221 mZoom = 0.25 * mPPI / MM_PER_INCH; |
193 | 222 |
194 // Take the union of the bounds of each layer to | 223 mCanvasBounds = padded_layer_bounds; |
195 // determine the canvas size | |
196 | |
197 Rectangle layer_bounds = Rectangle.DEFAULT; | |
198 | |
199 foreach (ref layer; mLayers) { | |
200 layer_bounds = layer_bounds | layer.bounds; | |
201 } | |
202 | |
203 assert(layer_bounds.valid); | |
204 | |
205 mCanvasBounds = expand(move(layer_bounds, -layer_bounds.size), 2.0 * layer_bounds.size); | |
206 mViewCentre = mCanvasBounds.centre; | 224 mViewCentre = mCanvasBounds.centre; |
207 | 225 |
208 mGrid.zoom_changed(mZoom); | 226 mGrid.zoom_changed(mZoom); |
209 | 227 |
210 mHadConfigure = true; | 228 mHadConfigure = true; |
211 } | 229 } |
212 | 230 else { |
213 mViewSize = Vector(cast(double)event.width, cast(double)event.height); | 231 // Use configure events as an opportunity |
232 // to consolidate the canvas-bounds | |
233 // XXX nasty code. | |
234 Vector z = mViewSize / mZoom; | |
235 Rectangle r = Rectangle(mViewCentre - z / 2.0, z); | |
236 mCanvasBounds = r | padded_layer_bounds; | |
237 } | |
238 | |
214 update_adjustments; | 239 update_adjustments; |
215 update_rulers; | 240 update_rulers; |
216 | 241 |
217 //writefln("Canvas bounds: %s", mCanvasBounds); | 242 //writefln("Canvas bounds: %s", mCanvasBounds); |
218 //writefln("View centre: %s", mViewCentre); | 243 //writefln("View centre: %s", mViewCentre); |
265 | 290 |
266 // Fill the background | 291 // Fill the background |
267 | 292 |
268 pixel_cr.save; { | 293 pixel_cr.save; { |
269 // Make the window light grey | 294 // Make the window light grey |
270 pixel_cr.setSourceRgba(0.6, 0.6, 0.6, 1.0); | 295 pixel_cr.setSourceRgba(0.9, 0.9, 0.9, 1.0); |
271 rectangle(pixel_cr, pixel_damage); | 296 rectangle(pixel_cr, pixel_damage); |
272 pixel_cr.fill; | 297 pixel_cr.fill; |
273 } pixel_cr.restore; | 298 } pixel_cr.restore; |
274 | 299 |
275 // Draw each layer | 300 // Draw each layer |
297 model_point, | 322 model_point, |
298 gtk2tk_mask(event.state)); | 323 gtk2tk_mask(event.state)); |
299 | 324 |
300 mEventHandler.handle_button_press(this, button_event); | 325 mEventHandler.handle_button_press(this, button_event); |
301 | 326 |
302 process_damage; | 327 fix_damage; |
303 | 328 |
304 return true; | 329 return true; |
305 } | 330 } |
306 | 331 |
307 bool on_button_release(GdkEventButton * event, Widget widget) { | 332 bool on_button_release(GdkEventButton * event, Widget widget) { |
317 model_point, | 342 model_point, |
318 gtk2tk_mask(event.state)); | 343 gtk2tk_mask(event.state)); |
319 | 344 |
320 mEventHandler.handle_button_release(this, button_event); | 345 mEventHandler.handle_button_release(this, button_event); |
321 | 346 |
322 process_damage; | 347 fix_damage; |
323 | 348 |
324 return true; | 349 return true; |
325 } | 350 } |
326 | 351 |
327 bool on_key_event(GdkEventKey * event, Widget widget) { | 352 bool on_key_event(GdkEventKey * event, Widget widget) { |
329 //writefln("Got key event\n"); | 354 //writefln("Got key event\n"); |
330 | 355 |
331 //auto key_event = new KeyEvent("", | 356 //auto key_event = new KeyEvent("", |
332 // mEventHandle.handle_key(key_event); | 357 // mEventHandle.handle_key(key_event); |
333 | 358 |
334 process_damage; | 359 fix_damage; |
335 | 360 |
336 return true; | 361 return true; |
337 } | 362 } |
338 | 363 |
339 bool on_motion_notify(GdkEventMotion * event, Widget widget) { | 364 bool on_motion_notify(GdkEventMotion * event, Widget widget) { |
349 model_point, | 374 model_point, |
350 gtk2tk_mask(event.state)); | 375 gtk2tk_mask(event.state)); |
351 | 376 |
352 mEventHandler.handle_motion(this, motion_event); | 377 mEventHandler.handle_motion(this, motion_event); |
353 | 378 |
354 process_damage; | 379 fix_damage; |
355 | 380 |
356 return true; | 381 return true; |
357 } | 382 } |
358 | 383 |
359 bool on_scroll(GdkEventScroll * event, Widget widget) { | 384 bool on_scroll(GdkEventScroll * event, Widget widget) { |
368 model_point, | 393 model_point, |
369 gtk2tk_mask(event.state)); | 394 gtk2tk_mask(event.state)); |
370 | 395 |
371 mEventHandler.handle_scroll(this, scroll_event); | 396 mEventHandler.handle_scroll(this, scroll_event); |
372 | 397 |
373 process_damage; | 398 fix_damage; |
374 | 399 |
375 return true; | 400 return true; |
376 } | 401 } |
377 | 402 |
378 /* | 403 /* |
490 mHAdjustment.valueChanged; | 515 mHAdjustment.valueChanged; |
491 mVAdjustment.changed; | 516 mVAdjustment.changed; |
492 mVAdjustment.valueChanged; | 517 mVAdjustment.valueChanged; |
493 } | 518 } |
494 | 519 |
495 void process_damage() { | 520 void fix_damage() { |
496 if (mDamage.valid) { | 521 if (mDamage.valid) { |
497 //writefln("Damage: %s", mDamage); | 522 //writefln("Damage: %s", mDamage); |
498 int x, y, w, h; | 523 int x, y, w, h; |
499 mDamage.get_quantised(x, y, w, h); | 524 mDamage.get_quantised(x, y, w, h); |
500 mDrawingArea.queueDrawArea(x, cast(int)mViewSize.y - (y + h), w, h); | 525 mDrawingArea.queueDrawArea(x, cast(int)mViewSize.y - (y + h), w, h); |
539 bool mHadConfigure; | 564 bool mHadConfigure; |
540 Rectangle mDamage; // pixels | 565 Rectangle mDamage; // pixels |
541 | 566 |
542 // Model units are in millimetres | 567 // Model units are in millimetres |
543 // Screen units are in pixels | 568 // Screen units are in pixels |
544 double mZoom; // pixels-per-model-unit (mm) | 569 double mZoom; // pixels-per-model-unit |
545 Vector mViewSize; // pixel: size of view window in pixels | 570 Vector mViewSize; // pixel: size of view window in pixels |
546 Point mViewCentre; // model: where in the model is the centre of our view | 571 Point mViewCentre; // model: where in the model is the centre of our view |
547 Rectangle mCanvasBounds; // model: | 572 Rectangle mCanvasBounds; // model: |
548 | 573 |
549 // Child widgets: | 574 // Child widgets: |