Mercurial > projects > doodle
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 |
rev | line source |
---|---|
77 | 1 module doodle.tk.screen_model; |
70 | 2 |
3 public { | |
4 import doodle.tk.geometry; | |
5 } | |
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 | 11 /* |
12 interface IScreenModelObserver { | |
13 void screenDamaged(in Rectangle screenDamage); | |
14 void cursorChanged(in Cursor cursor); | |
15 } | |
16 */ | |
17 | |
77 | 18 // This class manages the relationship between screen space and model space. |
78 | 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 | 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 | 24 class ScreenModel { |
88 | 25 /* |
26 void damageModel | |
27 */ | |
28 | |
29 | |
77 | 30 this(in double zoom, in Rectangle canvasBoundsModel, in Rectangle viewBoundsScreen) { |
70 | 31 _zoom = zoom; |
77 | 32 _viewBoundsScreen = viewBoundsScreen; |
33 _canvasBoundsModel = canvasBoundsModel; | |
70 | 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 | 37 } |
38 | |
91 | 39 void setViewBoundsScreen(in Rectangle viewBoundsScreen) { _viewBoundsScreen = viewBoundsScreen; } |
79 | 40 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { _canvasBoundsModel = screenToModel(_viewBoundsScreen) | requiredCanvasBounds; } |
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 | 43 void zoomRelative(in double factor, in Point screenDatum) { |
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 | 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 | 48 Point oldModelDatum = screenToModel(screenDatum); |
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 | 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 | 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 | 57 // For userZoom 1.0 -> 100% means the presentation on the screen is one-to-one with real-life |
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 | 60 Rectangle viewBoundsScreen() const { return _viewBoundsScreen; } |
79 | 61 Rectangle viewBoundsModel() const { return screenToModel(_viewBoundsScreen); } |
77 | 62 Rectangle canvasBoundsModel() const { return _canvasBoundsModel; } |
79 | 63 Rectangle canvasBoundsScreen() const { return modelToScreen(_canvasBoundsModel); } |
70 | 64 |
77 | 65 Point modelToScreen(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); } |
66 Point screenToModel(in Point screen) const { return _viewCentreModel + (screen - _viewBoundsScreen.centre) / _zoom; } | |
67 Vector modelToScreen(in Vector model) const { return _zoom * model; } | |
68 Vector screenToModel(in Vector screen) const { return screen / _zoom; } | |
69 Rectangle modelToScreen(in Rectangle model) const { return Rectangle(modelToScreen(model.position), modelToScreen(model.size)); } | |
70 Rectangle screenToModel(in Rectangle model) const { return Rectangle(screenToModel(model.position), screenToModel(model.size)); } | |
70 | 71 |
72 private { | |
79 | 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 | 75 // Screen units are pixels |
70 | 76 // Model units are millimetres |
78 | 77 double _zoom; // pixels-per-millimetre |
78 Rectangle _viewBoundsScreen; // bounds of the viewport in screen space | |
79 Point _viewCentreModel; // where in the model is the centre of our screen | |
80 Rectangle _canvasBoundsModel; // the bounds of the canvas in model space | |
70 | 81 } |
82 } |