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 }