Mercurial > projects > doodle
comparison 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 |
comparison
equal
deleted
inserted
replaced
76:78bc2046256e | 77:15ca7d5cd1ed |
---|---|
1 module doodle.tk.pixel_model; | 1 module doodle.tk.screen_model; |
2 | 2 |
3 public { | 3 public { |
4 import doodle.tk.geometry; | 4 import doodle.tk.geometry; |
5 } | 5 } |
6 | 6 |
7 private { | 7 private { |
8 import doodle.core.misc; | 8 import doodle.core.misc; |
9 } | 9 } |
10 | 10 |
11 // FIXME consider using the term Screen instead of Pixel... | 11 // This class manages the relationship between screen space and model space. |
12 | |
13 // This class manages the relationship between pixel space and model space. | |
14 // It provides convenient high-level operations. | 12 // It provides convenient high-level operations. |
15 // | 13 // |
16 // x and y run right and up respectively for pixel and model space | 14 // x and y run right and up respectively for screen and model space |
17 | 15 |
18 class PixelModel { | 16 class ScreenModel { |
19 this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) { | 17 this(in double zoom, in Rectangle canvasBoundsModel, in Rectangle viewBoundsScreen) { |
20 _zoom = zoom; | 18 _zoom = zoom; |
21 _viewBoundsScreen = viewBounds; | 19 _viewBoundsScreen = viewBoundsScreen; |
22 _canvasBoundsModel = canvasBounds; | 20 _canvasBoundsModel = canvasBoundsModel; |
23 | 21 |
24 // Choose the centre of the canvas as the centre of the view | 22 // Choose the centre of the canvas as the centre of the view |
25 _viewCentreModel = _canvasBoundsModel.centre; | 23 _viewCentreModel = _canvasBoundsModel.centre; |
26 } | 24 } |
27 | 25 |
28 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { | 26 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { |
29 _canvasBoundsModel = pixelToModel(_viewBoundsScreen) | requiredCanvasBounds; | 27 _canvasBoundsModel = screenToModel(_viewBoundsScreen) | requiredCanvasBounds; |
30 } | 28 } |
31 | 29 |
32 void canvasAccommodate(in Rectangle bounds) { | 30 void canvasAccommodate(in Rectangle bounds) { |
33 _canvasBoundsModel = _canvasBoundsModel | bounds; | 31 _canvasBoundsModel = _canvasBoundsModel | bounds; |
34 } | 32 } |
35 | 33 |
36 void zoomRelative(in double factor, in Point pixelDatum) { | 34 void zoomRelative(in double factor, in Point screenDatum) { |
37 // Work out pixel distance from current centre to datum, | 35 // Work out screen distance from current centre to datum, |
38 // Do the zoom, then work out the new centre that keeps the | 36 // Do the zoom, then work out the new centre that keeps the |
39 // pixel distance the same | 37 // screen distance the same |
40 | 38 |
41 Point oldModelDatum = pixelToModel(pixelDatum); | 39 Point oldModelDatum = screenToModel(screenDatum); |
42 Vector pixelDistance = modelToPixel(oldModelDatum - _viewCentreModel); | 40 Vector screenDistance = modelToScreen(oldModelDatum - _viewCentreModel); |
43 _zoom = clampZoom(zoom * factor); | 41 _zoom = clampZoom(zoom * factor); |
44 _viewCentreModel = oldModelDatum - pixelToModel(pixelDistance); | 42 _viewCentreModel = oldModelDatum - screenToModel(screenDistance); |
45 } | 43 } |
46 | 44 |
47 void panRelativePixel(in Vector pixelDisplacement) { _viewCentreModel = _viewCentreModel + pixelToModel(pixelDisplacement); } | 45 void panRelativeScreen(in Vector screenDisplacement) { _viewCentreModel = _viewCentreModel + screenToModel(screenDisplacement); } |
48 void panRelativeModel(in Vector modelDisplacement) { _viewCentreModel = _viewCentreModel + modelDisplacement; } | 46 void panRelativeModel(in Vector modelDisplacement) { _viewCentreModel = _viewCentreModel + modelDisplacement; } |
49 | 47 |
50 // For normalZoom 1.0 -> 100% means the presentation on the screen is | 48 // For userZoom 1.0 -> 100% means the presentation on the screen is |
51 // one-to-one with real-life | 49 // one-to-one with real-life |
52 double normalZoom(in double pixelsPerMillimetre) const { return _zoom / pixelsPerMillimetre; } | 50 double userZoom(in double screensPerMillimetre) const { return _zoom / screensPerMillimetre; } |
53 double zoom() const { return _zoom; } | 51 double zoom() const { return _zoom; } |
54 Rectangle viewBounds() const { return _viewBoundsScreen; } | 52 Rectangle viewBoundsScreen() const { return _viewBoundsScreen; } |
55 Rectangle canvasBounds() const { return _canvasBoundsModel; } | 53 Rectangle canvasBoundsModel() const { return _canvasBoundsModel; } |
56 | 54 |
57 Point modelToPixel(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); } | 55 Point modelToScreen(in Point model) const { return _viewBoundsScreen.centre + _zoom * (model - _viewCentreModel); } |
58 Point pixelToModel(in Point pixel) const { return _viewCentreModel + (pixel - _viewBoundsScreen.centre) / _zoom; } | 56 Point screenToModel(in Point screen) const { return _viewCentreModel + (screen - _viewBoundsScreen.centre) / _zoom; } |
59 Vector modelToPixel(in Vector model) const { return _zoom * model; } | 57 Vector modelToScreen(in Vector model) const { return _zoom * model; } |
60 Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; } | 58 Vector screenToModel(in Vector screen) const { return screen / _zoom; } |
61 Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); } | 59 Rectangle modelToScreen(in Rectangle model) const { return Rectangle(modelToScreen(model.position), modelToScreen(model.size)); } |
62 Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); } | 60 Rectangle screenToModel(in Rectangle model) const { return Rectangle(screenToModel(model.position), screenToModel(model.size)); } |
63 | 61 |
64 private { | 62 private { |
65 static double clampZoom(in double zoom) { return clamp(zoom, 0.1, 10.0); } | 63 static double clampZoom(in double zoom) { return clamp(zoom, 0.1, 10.0); } |
66 | 64 |
67 // Screen units are pixels | 65 // Screen units are screens |
68 // Model units are millimetres | 66 // Model units are millimetres |
69 double _zoom; // pixels-per-millimetre | 67 double _zoom; // screens-per-millimetre |
70 Rectangle _viewBoundsScreen; // bounds of the viewport in pixels | 68 Rectangle _viewBoundsScreen; // bounds of the viewport in screens |
71 Point _viewCentreModel; // where in the model is the centre of our view | 69 Point _viewCentreModel; // where in the model is the centre of our view |
72 Rectangle _canvasBoundsModel; // the bounds of the canvas in millimetres | 70 Rectangle _canvasBoundsModel; // the bounds of the canvas in millimetres |
73 } | 71 } |
74 } | 72 } |