comparison doodle/gtk/canvas.d @ 77:15ca7d5cd1ed

The rulers are broken
author "David Bryant <bagnose@gmail.com>"
date Sun, 15 Aug 2010 01:36:22 +0930
parents 3cac0ee8ca35
children 024a5608087f
comparison
equal deleted inserted replaced
76:78bc2046256e 77:15ca7d5cd1ed
4 import doodle.dia.icanvas; 4 import doodle.dia.icanvas;
5 import doodle.gtk.events; 5 import doodle.gtk.events;
6 } 6 }
7 7
8 private { 8 private {
9 import doodle.core.misc;
10 import doodle.core.logging; 9 import doodle.core.logging;
11 import doodle.tk.pixel_model; 10 import doodle.tk.pixel_model;
12 import doodle.tk.cairo; 11 import doodle.tk.cairo;
13 import doodle.dia.layer_stack; 12 import doodle.dia.layer_stack;
14 import doodle.gtk.conversions; 13 import doodle.gtk.conversions;
142 protected { // XXX the compiler complains about unimplemented methods if this is private 141 protected { // XXX the compiler complains about unimplemented methods if this is private
143 142
144 // IViewport overrides: 143 // IViewport overrides:
145 144
146 void zoomRelative(in Point screenDatum, in double factor) { 145 void zoomRelative(in Point screenDatum, in double factor) {
147 _pixelModel.zoomRelative(factor, screenDatum); 146 _screenModel.zoomRelative(factor, screenDatum);
148 147
149 consolidateBounds; 148 consolidateBounds;
150 149
151 updateAdjustments; 150 updateAdjustments;
152 updateRulers; 151 updateRulers;
153 _grid.zoomChanged(_pixelModel.zoom); 152 _grid.zoomChanged(_screenModel.zoom);
154 queueDraw; 153 queueDraw;
155 } 154 }
156 155
157 void panRelative(in Vector screenDisplacement) { 156 void panRelative(in Vector screenDisplacement) {
158 _pixelModel.panRelativePixel(screenDisplacement); 157 _screenModel.panRelativeScreen(screenDisplacement);
159 158
160 consolidateBounds; 159 consolidateBounds;
161 160
162 updateAdjustments; 161 updateAdjustments;
163 updateRulers; 162 updateRulers;
164 queueDraw; 163 queueDraw;
165 } 164 }
166 165
167 void setCursor(in Cursor cursor) { 166 void setCursor(in Cursor cursor) {
167 // FIXME how about an associative array instead of a switch statement?
168 CursorType cursorType; 168 CursorType cursorType;
169 169
170 switch (cursor) { 170 switch (cursor) {
171 case Cursor.DEFAULT: 171 case Cursor.DEFAULT:
172 cursorType = CursorType.ARROW; 172 cursorType = CursorType.ARROW;
186 186
187 _drawingArea.setCursor(new gdk.Cursor.Cursor(cursorType)); 187 _drawingArea.setCursor(new gdk.Cursor.Cursor(cursorType));
188 } 188 }
189 189
190 void damageModel(in Rectangle area) { 190 void damageModel(in Rectangle area) {
191 _damageScreen = _damageScreen | _pixelModel.modelToPixel(area); 191 _damageScreen = _damageScreen | _screenModel.modelToScreen(area);
192 } 192 }
193 193
194 void damagePixel(in Rectangle area) { 194 void damageScreen(in Rectangle area) {
195 _damageScreen = _damageScreen | area; 195 _damageScreen = _damageScreen | area;
196 } 196 }
197 } 197 }
198 198
199 private { 199 private {
200 200
201 void initialiseBounds(in Rectangle viewBounds) { 201 void initialiseBounds(in Rectangle viewBoundsScreen) {
202 Rectangle lb = _layerStack.bounds; 202 Rectangle lb = _layerStack.bounds;
203 203
204 // FIXME use a function that grows a rectangle about its centre 204 // FIXME use a function that grows a rectangle about its centre
205 // and change 2.0 to a class-level constant 205 // and change 2.0 to a class-level constant
206 Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size); 206 Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size);
207 207
208 _pixelModel = new PixelModel(0.25 * _pixelsPerMillimetre, paddedLayerBounds, viewBounds); 208 _screenModel = new ScreenModel(0.25 * _pixelsPerMillimetre, paddedLayerBounds, viewBoundsScreen);
209 209
210 _grid.zoomChanged(_pixelModel.zoom); 210 _grid.zoomChanged(_screenModel.zoom);
211 211
212 updateAdjustments; 212 updateAdjustments;
213 updateRulers; 213 updateRulers;
214 } 214 }
215 215
217 Rectangle lb = _layerStack.bounds; 217 Rectangle lb = _layerStack.bounds;
218 218
219 // FIXME likewise as above 219 // FIXME likewise as above
220 Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size); 220 Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size);
221 221
222 _pixelModel.consolidateCanvasBounds(paddedLayerBounds); 222 _screenModel.consolidateCanvasBounds(paddedLayerBounds);
223 223
224 updateAdjustments; 224 updateAdjustments;
225 updateRulers; 225 updateRulers;
226 } 226 }
227 227
228 bool onConfigure(GdkEventConfigure * event, Widget widget) { 228 bool onConfigure(GdkEventConfigure * event, Widget widget) {
229 assert(widget is _drawingArea); 229 assert(widget is _drawingArea);
230 230
231 Rectangle viewBounds = Rectangle(Point(0.0, 0.0), Vector(cast(double)event.width, cast(double)event.height)); 231 Rectangle viewBoundsScreen = Rectangle(Point(0.0, 0.0), Vector(cast(double)event.width, cast(double)event.height));
232 232
233 if (_pixelModel is null) { 233 if (_screenModel is null) {
234 initialiseBounds(viewBounds); 234 initialiseBounds(viewBoundsScreen);
235 } 235 }
236 else { 236 else {
237 consolidateBounds; 237 consolidateBounds;
238 } 238 }
239 239
248 int width, height; 248 int width, height;
249 dr.getSize(width, height); 249 dr.getSize(width, height);
250 //trace("Got expose %dx%d\n", width, height); 250 //trace("Got expose %dx%d\n", width, height);
251 251
252 scope modelCr = new Context(dr); 252 scope modelCr = new Context(dr);
253 scope pixelCr = new Context(dr); 253 scope screenCr = new Context(dr);
254 254
255 Rectangle pixelDamage = 255 Rectangle screenDamage =
256 event is null ? _pixelModel.viewBounds : 256 event is null ? _screenModel.viewBoundsScreen :
257 // FIXME next line sucks 257 // FIXME next line sucks
258 Rectangle(_pixelModel.viewBounds.position + Vector(cast(double)event.area.x, _pixelModel.viewBounds.h - cast(double)(event.area.y + event.area.height)), 258 Rectangle(_screenModel.viewBoundsScreen.position + Vector(cast(double)event.area.x, _screenModel.viewBoundsScreen.h - cast(double)(event.area.y + event.area.height)),
259 Vector(cast(double)event.area.width, cast(double)event.area.height)); 259 Vector(cast(double)event.area.width, cast(double)event.area.height));
260 260
261 Rectangle modelDamage = _pixelModel.pixelToModel(pixelDamage); 261 Rectangle modelDamage = _screenModel.screenToModel(screenDamage);
262 262
263 //trace("Pixel damage: %s, model damage: %s", pixelDamage, modelDamage); 263 //trace("Screen damage: %s, model damage: %s", screenDamage, modelDamage);
264 264
265 modelCr.save; pixelCr.save; { 265 modelCr.save; screenCr.save; {
266 { 266 {
267 // Setup model context and clip 267 // Setup model context and clip
268 modelCr.translate(0.0, _pixelModel.viewBounds.h); 268 modelCr.translate(0.0, _screenModel.viewBoundsScreen.h);
269 modelCr.scale(_pixelModel.zoom, -_pixelModel.zoom); 269 modelCr.scale(_screenModel.zoom, -_screenModel.zoom);
270 270
271 immutable Point viewLeftBottom = _pixelModel.pixelToModel(Point(0.0, 0.0)); 271 immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
272 modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y); 272 modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y);
273 273
274 rectangle(modelCr, modelDamage); 274 rectangle(modelCr, modelDamage);
275 modelCr.clip; 275 modelCr.clip;
276 } 276 }
277 277
278 { 278 {
279 // Setup pixel context and clip 279 // Setup screen context and clip
280 pixelCr.translate(0.0, _pixelModel.viewBounds.h); 280 screenCr.translate(0.0, _screenModel.viewBoundsScreen.h);
281 pixelCr.scale(1.0, -1.0); 281 screenCr.scale(1.0, -1.0);
282 282
283 rectangle(pixelCr, pixelDamage); 283 rectangle(screenCr, screenDamage);
284 pixelCr.clip; 284 screenCr.clip;
285 } 285 }
286 286
287 pixelCr.save; { 287 screenCr.save; {
288 // Fill the background with light grey 288 // Fill the background with light grey
289 pixelCr.setSourceRgba(0.9, 0.9, 0.9, 1.0); 289 screenCr.setSourceRgba(0.9, 0.9, 0.9, 1.0);
290 rectangle(pixelCr, pixelDamage); 290 rectangle(screenCr, screenDamage);
291 pixelCr.fill; 291 screenCr.fill;
292 } pixelCr.restore; 292 } screenCr.restore;
293 293
294 _layerStack.draw(pixelDamage, pixelCr, modelDamage, modelCr); 294 _layerStack.draw(screenDamage, screenCr, modelDamage, modelCr);
295 } pixelCr.restore; modelCr.restore; 295 } screenCr.restore; modelCr.restore;
296 296
297 return true; 297 return true;
298 } 298 }
299 299
300 bool onButtonPress(GdkEventButton * event, Widget widget) { 300 bool onButtonPress(GdkEventButton * event, Widget widget) {
301 assert(widget is _drawingArea); 301 assert(widget is _drawingArea);
302 302
303 auto buttonEvent = makeButtonEvent(event, _pixelModel); 303 auto buttonEvent = makeButtonEvent(event, _screenModel);
304 _eventHandler.handleButtonPress(this, buttonEvent); 304 _eventHandler.handleButtonPress(this, buttonEvent);
305 fixDamage; 305 fixDamage;
306 return true; 306 return true;
307 } 307 }
308 308
309 bool onButtonRelease(GdkEventButton * event, Widget widget) { 309 bool onButtonRelease(GdkEventButton * event, Widget widget) {
310 assert(widget is _drawingArea); 310 assert(widget is _drawingArea);
311 311
312 auto buttonEvent = makeButtonEvent(event, _pixelModel); 312 auto buttonEvent = makeButtonEvent(event, _screenModel);
313 _eventHandler.handleButtonRelease(this, buttonEvent); 313 _eventHandler.handleButtonRelease(this, buttonEvent);
314 fixDamage; 314 fixDamage;
315 return true; 315 return true;
316 } 316 }
317 317
330 } 330 }
331 331
332 bool onKeyReleaseEvent(GdkEventKey * event, Widget widget) { 332 bool onKeyReleaseEvent(GdkEventKey * event, Widget widget) {
333 assert(widget is _drawingArea); 333 assert(widget is _drawingArea);
334 334
335 _eventHandler.handleKeyRelease(this, makeKeyEvent(event, _pixelModel)); 335 _eventHandler.handleKeyRelease(this, makeKeyEvent(event, _screenModel));
336 fixDamage; 336 fixDamage;
337 return true; 337 return true;
338 } 338 }
339 339
340 bool onMotionNotify(GdkEventMotion * event, Widget widget) { 340 bool onMotionNotify(GdkEventMotion * event, Widget widget) {
341 assert(widget is _drawingArea); 341 assert(widget is _drawingArea);
342 342
343 { 343 // Pass the events on to the rulers so that they update
344 // Pass the events on to the rulers so that they update 344 gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event);
345 gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event); 345 gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event);
346 gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event); 346
347 } 347 _eventHandler.handleMotion(this, makeMotionEvent(event, _screenModel));
348
349 _eventHandler.handleMotion(this, makeMotionEvent(event, _pixelModel));
350 fixDamage; 348 fixDamage;
351 return true; 349 return true;
352 } 350 }
353 351
354 bool onScroll(GdkEventScroll * event, Widget widget) { 352 bool onScroll(GdkEventScroll * event, Widget widget) {
355 assert(widget is _drawingArea); 353 assert(widget is _drawingArea);
356 354
357 _eventHandler.handleScroll(this, makeScrollEvent(event, _pixelModel)); 355 _eventHandler.handleScroll(this, makeScrollEvent(event, _screenModel));
358 fixDamage; 356 fixDamage;
359 return true; 357 return true;
360 } 358 }
361 359
362 bool onEnterNotify(GdkEventCrossing * event, Widget widget) { 360 bool onEnterNotify(GdkEventCrossing * event, Widget widget) {
363 assert(widget is _drawingArea); 361 assert(widget is _drawingArea);
364 362
365 _eventHandler.handleEnter(this, makeCrossingEvent(event, _pixelModel)); 363 _eventHandler.handleEnter(this, makeCrossingEvent(event, _screenModel));
366 fixDamage; 364 fixDamage;
367 return true; 365 return true;
368 } 366 }
369 367
370 bool onLeaveNotify(GdkEventCrossing * event, Widget widget) { 368 bool onLeaveNotify(GdkEventCrossing * event, Widget widget) {
371 assert(widget is _drawingArea); 369 assert(widget is _drawingArea);
372 370
373 _eventHandler.handleLeave(this, makeCrossingEvent(event, _pixelModel)); 371 _eventHandler.handleLeave(this, makeCrossingEvent(event, _screenModel));
374 fixDamage; 372 fixDamage;
375 return true; 373 return true;
376 } 374 }
377 375
378 bool onFocusIn(GdkEventFocus * event, Widget widget) { 376 bool onFocusIn(GdkEventFocus * event, Widget widget) {
404 402
405 void onAdjustmentValueChanged(Adjustment adjustment) { 403 void onAdjustmentValueChanged(Adjustment adjustment) {
406 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct; 404 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
407 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct; 405 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
408 406
409 Point oldViewLeftBottom = _pixelModel.pixelToModel(Point(0.0, 0.0)); 407 Point oldViewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
410 Point newViewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment), 408 Point newViewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment),
411 gtk_adjustment_get_value(vGtkAdjustment)); 409 gtk_adjustment_get_value(vGtkAdjustment));
412 410
413 _pixelModel.panRelativeModel(newViewLeftBottom - oldViewLeftBottom); 411 _screenModel.panRelativeModel(newViewLeftBottom - oldViewLeftBottom);
414 412
415 updateRulers; 413 updateRulers;
416 queueDraw; 414 queueDraw;
417 } 415 }
418 416
419 void updateRulers() { 417 void updateRulers() {
420 immutable Point viewLeftBottom = _pixelModel.pixelToModel(Point(0.0, 0.0)); 418 immutable Point viewLeftBottom = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
421 immutable Point viewRightTop = _pixelModel.pixelToModel(_pixelModel.viewBounds.corner1); 419 immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
422 420
423 // Define these just to obtain the position 421 // Define these just to obtain the position
424 // below and we can preserve it 422 // below and we can preserve it
425 double lower, upper, position, maxSize; 423 double lower, upper, position, maxSize;
426 424
427 _hRuler.getRange(lower, upper, position, maxSize); 425 _hRuler.getRange(lower, upper, position, maxSize);
428 _hRuler.setRange(viewLeftBottom.x, 426 _hRuler.setRange(viewLeftBottom.x,
429 viewRightTop.x, 427 viewRightTop.x,
430 position, 428 position,
431 _pixelModel.zoom * 50.0); 429 _screenModel.zoom * 50.0);
432 430
433 _vRuler.getRange(lower, upper, position, maxSize); 431 _vRuler.getRange(lower, upper, position, maxSize);
434 _vRuler.setRange(viewRightTop.y, 432 _vRuler.setRange(viewRightTop.y,
435 viewLeftBottom.y, 433 viewLeftBottom.y,
436 position, 434 position,
437 _pixelModel.zoom * 50.0); 435 _screenModel.zoom * 50.0);
438 } 436 }
439 437
440 void updateAdjustments() { 438 void updateAdjustments() {
441 immutable Point viewLeftBottom = _pixelModel.pixelToModel(Point(0.0, 0.0)); 439 immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
442 immutable Point viewRightTop = _pixelModel.pixelToModel(_pixelModel.viewBounds.corner1); 440 immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
443 441
444 // Adjust the canvas size if necessary FIXME is this required?? 442 // Adjust the canvas size if necessary FIXME is this required??
445 _pixelModel.canvasAccommodate(Rectangle(viewLeftBottom, viewRightTop)); 443 _screenModel.canvasAccommodate(Rectangle(viewLeftBottom, viewRightTop));
446 444
447 // FIXME 445 // FIXME
448 Rectangle modelSize = _pixelModel.pixelToModel(_pixelModel.viewBounds); 446 Rectangle modelSize = _screenModel.screenToModel(_screenModel.viewBoundsScreen);
449 447
450 // Update the adjustments 448 // Update the adjustments
451 449
452 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct; 450 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
453 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct; 451 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
454 452
455 gtk_adjustment_set_lower(hGtkAdjustment, _pixelModel.canvasBounds.x0); 453 gtk_adjustment_set_lower(hGtkAdjustment, _screenModel.canvasBoundsModel.x0);
456 gtk_adjustment_set_upper(hGtkAdjustment, _pixelModel.canvasBounds.x1); 454 gtk_adjustment_set_upper(hGtkAdjustment, _screenModel.canvasBoundsModel.x1);
457 gtk_adjustment_set_value(hGtkAdjustment, viewLeftBottom.x); 455 gtk_adjustment_set_value(hGtkAdjustment, viewLeftBottom.x);
458 gtk_adjustment_set_step_increment(hGtkAdjustment, _pixelModel.canvasBounds.w / 16.0); 456 gtk_adjustment_set_step_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 16.0);
459 gtk_adjustment_set_page_increment(hGtkAdjustment, _pixelModel.canvasBounds.w / 4.0); 457 gtk_adjustment_set_page_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 4.0);
460 gtk_adjustment_set_page_size(hGtkAdjustment, modelSize.w); 458 gtk_adjustment_set_page_size(hGtkAdjustment, modelSize.w);
461 459
462 gtk_adjustment_set_lower(vGtkAdjustment, _pixelModel.canvasBounds.y0); 460 gtk_adjustment_set_lower(vGtkAdjustment, _screenModel.canvasBoundsModel.y0);
463 gtk_adjustment_set_upper(vGtkAdjustment, _pixelModel.canvasBounds.y1); 461 gtk_adjustment_set_upper(vGtkAdjustment, _screenModel.canvasBoundsModel.y1);
464 gtk_adjustment_set_value(vGtkAdjustment, viewLeftBottom.y); 462 gtk_adjustment_set_value(vGtkAdjustment, viewLeftBottom.y);
465 gtk_adjustment_set_step_increment(vGtkAdjustment, _pixelModel.canvasBounds.h / 16.0); 463 gtk_adjustment_set_step_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 16.0);
466 gtk_adjustment_set_page_increment(vGtkAdjustment, _pixelModel.canvasBounds.h / 4.0); 464 gtk_adjustment_set_page_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 4.0);
467 gtk_adjustment_set_page_size(vGtkAdjustment, modelSize.h); 465 gtk_adjustment_set_page_size(vGtkAdjustment, modelSize.h);
468 466
469 _hAdjustment.changed; 467 _hAdjustment.changed;
470 _hAdjustment.valueChanged; 468 _hAdjustment.valueChanged;
471 _vAdjustment.changed; 469 _vAdjustment.changed;
474 472
475 void fixDamage() { 473 void fixDamage() {
476 if (_damageScreen.valid) { 474 if (_damageScreen.valid) {
477 int x, y, w, h; 475 int x, y, w, h;
478 _damageScreen.getQuantised(x, y, w, h); 476 _damageScreen.getQuantised(x, y, w, h);
479 _drawingArea.queueDrawArea(x, cast(int)_pixelModel.viewBounds.h - (y + h), w, h); 477 _drawingArea.queueDrawArea(x, cast(int)_screenModel.viewBoundsScreen.h - (y + h), w, h);
480 _damageScreen = Rectangle.DEFAULT; 478 _damageScreen = Rectangle.DEFAULT;
481 } 479 }
482 } 480 }
483 481
484 void onRealize(Widget widget) { 482 void onRealize(Widget widget) {
499 Adjustment _hAdjustment; 497 Adjustment _hAdjustment;
500 HScrollbar _hScrollbar; 498 HScrollbar _hScrollbar;
501 Adjustment _vAdjustment; 499 Adjustment _vAdjustment;
502 VScrollbar _vScrollbar; 500 VScrollbar _vScrollbar;
503 501
504 Rectangle _damageScreen; // in pixels 502 Rectangle _damageScreen; // in screens
505 PixelModel _pixelModel; 503 ScreenModel _screenModel;
506 } 504 }
507 } 505 }