annotate doodle/tk/screen_model.d @ 91:42766e14534e

Update screenViewBounds when the window is resized
author daveb
date Thu, 19 Aug 2010 18:28:18 +0930
parents 100dd23c7bdf
children bc5baa585b32
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
1 module doodle.tk.screen_model;
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
2
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
3 public {
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
4 import doodle.tk.geometry;
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
5 }
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
6
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
7 private {
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
8 import doodle.core.misc;
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
9 }
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
10
88
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
11 /*
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
12 interface IScreenModelObserver {
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
13 void screenDamaged(in Rectangle screenDamage);
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
14 void cursorChanged(in Cursor cursor);
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
15 }
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
16 */
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
17
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
18 // This class manages the relationship between screen space and model space.
78
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
19 // Screen is defined as the current window/viewport into the model
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
20 // It provides convenient high-level operations.
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
21 //
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
22 // x and y run right and up respectively for screen and model space
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
23
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
24 class ScreenModel {
88
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
25 /*
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
26 void damageModel
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
27 */
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
28
100dd23c7bdf Ch ch ch changes:
David Bryant <bagnose@gmail.com>
parents: 81
diff changeset
29
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
30 this(in double zoom, in Rectangle canvasBoundsModel, in Rectangle viewBoundsScreen) {
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
31 _zoom = zoom;
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
32 _viewBoundsScreen = viewBoundsScreen;
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
33 _canvasBoundsModel = canvasBoundsModel;
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
34
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
35 // Choose the centre of the canvas as the centre of the view
72
5cc2de64f6d0 Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents: 71
diff changeset
36 _viewCentreModel = _canvasBoundsModel.centre;
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
37 }
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
38
91
42766e14534e Update screenViewBounds when the window is resized
daveb
parents: 88
diff changeset
39 void setViewBoundsScreen(in Rectangle viewBoundsScreen) { _viewBoundsScreen = viewBoundsScreen; }
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
40 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { _canvasBoundsModel = screenToModel(_viewBoundsScreen) | requiredCanvasBounds; }
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
41 void canvasAccommodate(in Rectangle bounds) { _canvasBoundsModel = _canvasBoundsModel | bounds; }
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
42
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
43 void zoomRelative(in double factor, in Point screenDatum) {
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
44 // Work out screen distance from current centre to datum,
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
45 // Do the zoom, then work out the new centre that keeps the
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
46 // screen distance the same
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
47
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
48 Point oldModelDatum = screenToModel(screenDatum);
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
49 Vector screenDistance = modelToScreen(oldModelDatum - _viewCentreModel);
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
50 _zoom = clampZoom(zoom * factor);
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
51 _viewCentreModel = oldModelDatum - screenToModel(screenDistance);
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
52 }
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
53
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
54 void panRelativeScreen(in Vector screenDisplacement) { _viewCentreModel = _viewCentreModel + screenToModel(screenDisplacement); }
72
5cc2de64f6d0 Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents: 71
diff changeset
55 void panRelativeModel(in Vector modelDisplacement) { _viewCentreModel = _viewCentreModel + modelDisplacement; }
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
56
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
57 // For userZoom 1.0 -> 100% means the presentation on the screen is one-to-one with real-life
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
58 double userZoom(in double pixelsPerMillimetre) const { return _zoom / pixelsPerMillimetre; }
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
59 double zoom() const { return _zoom; }
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
60 Rectangle viewBoundsScreen() const { return _viewBoundsScreen; }
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
61 Rectangle viewBoundsModel() const { return screenToModel(_viewBoundsScreen); }
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
62 Rectangle canvasBoundsModel() const { return _canvasBoundsModel; }
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
63 Rectangle canvasBoundsScreen() const { return modelToScreen(_canvasBoundsModel); }
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
64
77
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
65 Point modelToScreen(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); }
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
66 Point screenToModel(in Point screen) const { return _viewCentreModel + (screen - _viewBoundsScreen.centre) / _zoom; }
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
67 Vector modelToScreen(in Vector model) const { return _zoom * model; }
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
68 Vector screenToModel(in Vector screen) const { return screen / _zoom; }
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
69 Rectangle modelToScreen(in Rectangle model) const { return Rectangle(modelToScreen(model.position), modelToScreen(model.size)); }
15ca7d5cd1ed The rulers are broken
"David Bryant <bagnose@gmail.com>"
parents: 72
diff changeset
70 Rectangle screenToModel(in Rectangle model) const { return Rectangle(screenToModel(model.position), screenToModel(model.size)); }
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
71
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
72 private {
79
535bae7a7305 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents: 78
diff changeset
73 static double clampZoom(in double zoom) { return clamp(zoom, 1e-1, 1e2); }
71
0f7cf6c6f206 Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents: 70
diff changeset
74
78
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
75 // Screen units are pixels
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
76 // Model units are millimetres
78
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
77 double _zoom; // pixels-per-millimetre
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
78 Rectangle _viewBoundsScreen; // bounds of the viewport in screen space
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
79 Point _viewCentreModel; // where in the model is the centre of our screen
"David Bryant <bagnose@gmail.com>"
parents: 77
diff changeset
80 Rectangle _canvasBoundsModel; // the bounds of the canvas in model space
70
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
81 }
0e61702c6ea6 Checkpoint
"David Bryant <bagnose@gmail.com>"
parents:
diff changeset
82 }