Mercurial > projects > doodle
comparison doodle/tk/pixel_model.d @ 71:0f7cf6c6f206
Reimplemented gtk.canvas in terms of tk.pixel_model but
needs a lot of consolidation.
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Sat, 14 Aug 2010 20:48:41 +0930 |
parents | 0e61702c6ea6 |
children | 5cc2de64f6d0 |
comparison
equal
deleted
inserted
replaced
70:0e61702c6ea6 | 71:0f7cf6c6f206 |
---|---|
2 | 2 |
3 public { | 3 public { |
4 import doodle.tk.geometry; | 4 import doodle.tk.geometry; |
5 } | 5 } |
6 | 6 |
7 private { | |
8 import doodle.core.misc; | |
9 } | |
10 | |
7 // FIXME consider using the term Screen instead of Pixel... | 11 // FIXME consider using the term Screen instead of Pixel... |
12 | |
13 // This class manages the relationship between pixel space and model space. | |
14 // It provides convenient high-level operations. | |
15 // | |
16 // x and y run right and up respectively for pixel and model space | |
8 | 17 |
9 class PixelModel { | 18 class PixelModel { |
10 this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) { | 19 this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) { |
11 _zoom = zoom; | 20 _zoom = zoom; |
12 _viewBounds = viewBounds; | 21 _viewBounds = viewBounds; |
13 _canvasBounds = canvasBounds; | 22 _canvasBounds = canvasBounds; |
14 | 23 |
24 // Choose the centre of the canvas as the centre of the view | |
15 _viewCentre = _canvasBounds.centre; | 25 _viewCentre = _canvasBounds.centre; |
16 } | 26 } |
17 | 27 |
18 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { | 28 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) { |
19 Rectangle r = pixelToModel(_viewBounds); | 29 Rectangle r = pixelToModel(_viewBounds); |
20 _canvasBounds = r | requiredCanvasBounds; | 30 _canvasBounds = r | requiredCanvasBounds; |
21 } | 31 } |
22 | 32 |
33 void canvasAccommodate(in Rectangle bounds) { | |
34 _canvasBounds = _canvasBounds | bounds; | |
35 } | |
36 | |
37 void zoomRelative(in double factor, in Point pixelDatum) { | |
38 // Work out pixel distance from current centre to datum, | |
39 // Do the zoom, then work out the new centre that keeps the | |
40 // pixel distance the same | |
41 | |
42 Point oldModelDatum = pixelToModel(pixelDatum); | |
43 Vector pixelDistance = modelToPixel(oldModelDatum - _viewCentre); | |
44 _zoom = clampZoom(zoom * factor); | |
45 _viewCentre = oldModelDatum - pixelToModel(pixelDistance); | |
46 } | |
47 | |
48 void panRelativePixel(in Vector pixelDisplacement) { | |
49 _viewCentre = _viewCentre + pixelToModel(pixelDisplacement); | |
50 } | |
51 | |
52 void panRelativeModel(in Vector modelDisplacement) { | |
53 _viewCentre = _viewCentre + modelDisplacement; | |
54 } | |
55 | |
23 // For normalZoom 1.0 -> 100% means the presentation on the screen is | 56 // For normalZoom 1.0 -> 100% means the presentation on the screen is |
24 // one-to-one with real-life | 57 // one-to-one with real-life |
25 double normalZoom(in double pixelsPerMillimetre) { return _zoom / pixelsPerMillimetre; } | 58 double normalZoom(in double pixelsPerMillimetre) const { return _zoom / pixelsPerMillimetre; } |
59 double zoom() const { return _zoom; } | |
60 Rectangle viewBounds() const { return _viewBounds; } | |
61 Rectangle canvasBounds() const { return _canvasBounds; } | |
26 | 62 |
27 Point modelToPixel(in Point model) const { return _viewBounds.centre + _zoom * (model - _viewCentre); } | 63 Point modelToPixel(in Point model) const { return _viewBounds.centre + _zoom * (model - _viewCentre); } |
28 Point pixelToModel(in Point pixel) const { return _viewCentre + (pixel - _viewBounds.centre) / _zoom; } | 64 Point pixelToModel(in Point pixel) const { return _viewCentre + (pixel - _viewBounds.centre) / _zoom; } |
29 Vector modelToPixel(in Vector model) const { return _zoom * model; } | 65 Vector modelToPixel(in Vector model) const { return _zoom * model; } |
30 Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; } | 66 Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; } |
31 Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); } | 67 Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); } |
32 Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); } | 68 Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); } |
33 | 69 |
34 private { | 70 private { |
71 static double clampZoom(in double zoom) { return clamp(zoom, 0.1, 10.0); } | |
72 | |
35 // Screen units are pixels | 73 // Screen units are pixels |
36 // Model units are millimetres | 74 // Model units are millimetres |
37 double _zoom; // pixels-per-millimetre | 75 double _zoom; // pixels-per-millimetre |
38 Rectangle _viewBounds; // pixel: bounds of the viewport in pixels | 76 Rectangle _viewBounds; // pixel: bounds of the viewport in pixels |
39 Point _viewCentre; // model: where in the model is the centre of our view | 77 Point _viewCentre; // model: where in the model is the centre of our view |