Mercurial > projects > doodle
annotate doodle/tk/pixel_model.d @ 77:15ca7d5cd1ed
The rulers are broken
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Sun, 15 Aug 2010 01:36:22 +0930 |
parents | 5cc2de64f6d0 |
children | 024a5608087f |
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 |
77 | 11 // This class manages the relationship between screen space and model space. |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
12 // 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
|
13 // |
77 | 14 // 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
|
15 |
77 | 16 class ScreenModel { |
17 this(in double zoom, in Rectangle canvasBoundsModel, in Rectangle viewBoundsScreen) { | |
70 | 18 _zoom = zoom; |
77 | 19 _viewBoundsScreen = viewBoundsScreen; |
20 _canvasBoundsModel = canvasBoundsModel; | |
70 | 21 |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
22 // 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
|
23 _viewCentreModel = _canvasBoundsModel.centre; |
70 | 24 } |
25 | |
26 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { | |
77 | 27 _canvasBoundsModel = screenToModel(_viewBoundsScreen) | requiredCanvasBounds; |
70 | 28 } |
29 | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
30 void canvasAccommodate(in Rectangle bounds) { |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
31 _canvasBoundsModel = _canvasBoundsModel | bounds; |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
32 } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
33 |
77 | 34 void zoomRelative(in double factor, in Point screenDatum) { |
35 // 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
|
36 // Do the zoom, then work out the new centre that keeps the |
77 | 37 // 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
|
38 |
77 | 39 Point oldModelDatum = screenToModel(screenDatum); |
40 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
|
41 _zoom = clampZoom(zoom * factor); |
77 | 42 _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
|
43 } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
44 |
77 | 45 void panRelativeScreen(in Vector screenDisplacement) { _viewCentreModel = _viewCentreModel + screenToModel(screenDisplacement); } |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
46 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
|
47 |
77 | 48 // For userZoom 1.0 -> 100% means the presentation on the screen is |
70 | 49 // one-to-one with real-life |
77 | 50 double userZoom(in double screensPerMillimetre) const { return _zoom / screensPerMillimetre; } |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
51 double zoom() const { return _zoom; } |
77 | 52 Rectangle viewBoundsScreen() const { return _viewBoundsScreen; } |
53 Rectangle canvasBoundsModel() const { return _canvasBoundsModel; } | |
70 | 54 |
77 | 55 Point modelToScreen(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); } |
56 Point screenToModel(in Point screen) const { return _viewCentreModel + (screen - _viewBoundsScreen.centre) / _zoom; } | |
57 Vector modelToScreen(in Vector model) const { return _zoom * model; } | |
58 Vector screenToModel(in Vector screen) const { return screen / _zoom; } | |
59 Rectangle modelToScreen(in Rectangle model) const { return Rectangle(modelToScreen(model.position), modelToScreen(model.size)); } | |
60 Rectangle screenToModel(in Rectangle model) const { return Rectangle(screenToModel(model.position), screenToModel(model.size)); } | |
70 | 61 |
62 private { | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
63 static double clampZoom(in double zoom) { return clamp(zoom, 0.1, 10.0); } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
64 |
77 | 65 // Screen units are screens |
70 | 66 // Model units are millimetres |
77 | 67 double _zoom; // screens-per-millimetre |
68 Rectangle _viewBoundsScreen; // bounds of the viewport in screens | |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
69 Point _viewCentreModel; // where in the model is the centre of our view |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
70 Rectangle _canvasBoundsModel; // the bounds of the canvas in millimetres |
70 | 71 } |
72 } |