Mercurial > projects > doodle
annotate doodle/tk/pixel_model.d @ 72:5cc2de64f6d0
Cautious Saturday night commits
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Sun, 15 Aug 2010 00:30:03 +0930 |
parents | 0f7cf6c6f206 |
children | 15ca7d5cd1ed |
rev | line source |
---|---|
70 | 1 module doodle.tk.pixel_model; |
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 |
70 | 11 // FIXME consider using the term Screen instead of Pixel... |
12 | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
13 // This class manages the relationship between pixel space and model space. |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
14 // 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
|
15 // |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
16 // x and y run right and up respectively for pixel and model space |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
17 |
70 | 18 class PixelModel { |
19 this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) { | |
20 _zoom = zoom; | |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
21 _viewBoundsScreen = viewBounds; |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
22 _canvasBoundsModel = canvasBounds; |
70 | 23 |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
24 // 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
|
25 _viewCentreModel = _canvasBoundsModel.centre; |
70 | 26 } |
27 | |
28 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { | |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
29 _canvasBoundsModel = pixelToModel(_viewBoundsScreen) | requiredCanvasBounds; |
70 | 30 } |
31 | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
32 void canvasAccommodate(in Rectangle bounds) { |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
33 _canvasBoundsModel = _canvasBoundsModel | bounds; |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
34 } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
35 |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
36 void zoomRelative(in double factor, in Point pixelDatum) { |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
37 // Work out pixel distance from current centre to datum, |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
38 // Do the zoom, then work out the new centre that keeps the |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
39 // pixel distance the same |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
40 |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
41 Point oldModelDatum = pixelToModel(pixelDatum); |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
42 Vector pixelDistance = modelToPixel(oldModelDatum - _viewCentreModel); |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
43 _zoom = clampZoom(zoom * factor); |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
44 _viewCentreModel = oldModelDatum - pixelToModel(pixelDistance); |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
45 } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
46 |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
47 void panRelativePixel(in Vector pixelDisplacement) { _viewCentreModel = _viewCentreModel + pixelToModel(pixelDisplacement); } |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
48 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
|
49 |
70 | 50 // For normalZoom 1.0 -> 100% means the presentation on the screen is |
51 // one-to-one with real-life | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
52 double normalZoom(in double pixelsPerMillimetre) const { return _zoom / pixelsPerMillimetre; } |
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
53 double zoom() const { return _zoom; } |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
54 Rectangle viewBounds() const { return _viewBoundsScreen; } |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
55 Rectangle canvasBounds() const { return _canvasBoundsModel; } |
70 | 56 |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
57 Point modelToPixel(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); } |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
58 Point pixelToModel(in Point pixel) const { return _viewCentreModel + (pixel - _viewBoundsScreen.centre) / _zoom; } |
70 | 59 Vector modelToPixel(in Vector model) const { return _zoom * model; } |
60 Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; } | |
61 Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); } | |
62 Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); } | |
63 | |
64 private { | |
71
0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
"David Bryant <bagnose@gmail.com>"
parents:
70
diff
changeset
|
65 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
|
66 |
70 | 67 // Screen units are pixels |
68 // Model units are millimetres | |
72
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
69 double _zoom; // pixels-per-millimetre |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
70 Rectangle _viewBoundsScreen; // bounds of the viewport in pixels |
5cc2de64f6d0
Cautious Saturday night commits
"David Bryant <bagnose@gmail.com>"
parents:
71
diff
changeset
|
71 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
|
72 Rectangle _canvasBoundsModel; // the bounds of the canvas in millimetres |
70 | 73 } |
74 } |