Mercurial > projects > doodle
annotate canvas.d @ 20:d6e7a5a6f008
Checkpoint
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Wed, 15 Jul 2009 23:23:02 +0930 |
parents | 22abbf4cde96 |
children |
rev | line source |
---|---|
0 | 1 module canvas; |
2 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
3 public { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
4 import icanvas; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
5 import tk.geometry; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
6 import tk.events; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
7 } |
0 | 8 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
9 private { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
10 import tk.gtk_support; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
11 import tk.misc; |
0 | 12 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
13 import cairo.Surface; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
14 import cairo_support; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
15 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
16 import std.math; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
17 import std.stdio; |
0 | 18 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
19 import gtk.Widget; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
20 import gtk.Toolbar; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
21 import gtk.Table; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
22 import gtk.HRuler; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
23 import gtk.VRuler; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
24 import gtk.Range; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
25 import gtk.HScrollbar; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
26 import gtk.VScrollbar; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
27 import gtk.DrawingArea; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
28 import gtk.Adjustment; |
0 | 29 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
30 import gdk.Drawable; |
0 | 31 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
32 import gtkc.gtk; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
33 } |
0 | 34 |
35 // x and y run right and up respectively | |
36 | |
10 | 37 class Canvas : Table, Viewport { |
11 | 38 this(in Layer[] layers, EventHandler event_handler, in double ppi) { |
0 | 39 super(3, 3, 0); |
40 | |
17 | 41 mDamage = Rectangle.DEFAULT; |
42 | |
11 | 43 mLayers = layers.dup; |
0 | 44 mEventHandler = event_handler; |
13 | 45 mPPI = ppi; |
0 | 46 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
47 /* |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
48 writefln("Layer bounds: %s", layer_bounds); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
49 writefln("Canvas bounds: %s", mCanvasBounds); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
50 writefln("View centre: %s", mViewCentre); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
51 */ |
0 | 52 |
13 | 53 // Create our child widgets and register callbacks |
54 | |
55 mHRuler = new HRuler; | |
0 | 56 attach(mHRuler, |
57 1, 2, | |
58 0, 1, | |
59 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK, | |
60 0, 0); | |
20 | 61 mHRuler.setMetric(MetricType.PIXELS); |
0 | 62 |
13 | 63 mVRuler = new VRuler; |
0 | 64 attach(mVRuler, |
65 0, 1, | |
66 1, 2, | |
67 AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND, | |
68 0, 0); | |
20 | 69 mVRuler.setMetric(MetricType.PIXELS); |
0 | 70 |
13 | 71 mDrawingArea = new DrawingArea; |
0 | 72 mDrawingArea.addOnRealize(&onRealize); |
73 mDrawingArea.addOnConfigure(&onConfigure); | |
74 mDrawingArea.addOnExpose(&onExpose); | |
5 | 75 mDrawingArea.addOnButtonPress(&onButtonPress); |
76 mDrawingArea.addOnButtonRelease(&onButtonRelease); | |
0 | 77 mDrawingArea.addOnKeyPress(&onKeyEvent); |
78 mDrawingArea.addOnKeyRelease(&onKeyEvent); | |
79 mDrawingArea.addOnMotionNotify(&onMotionNotify); | |
80 mDrawingArea.addOnScroll(&onScroll); | |
20 | 81 mDrawingArea.addOnEnterNotify(&onEnterNotify); |
82 mDrawingArea.addOnLeaveNotify(&onLeaveNotify); | |
83 mDrawingArea.setEvents(EventMask.EXPOSURE_MASK | | |
84 EventMask.POINTER_MOTION_MASK | | |
85 EventMask.POINTER_MOTION_HINT_MASK | | |
86 EventMask.BUTTON_MOTION_MASK | | |
87 EventMask.BUTTON_PRESS_MASK | | |
88 EventMask.BUTTON_RELEASE_MASK | | |
89 EventMask.KEY_PRESS_MASK | | |
90 EventMask.KEY_RELEASE_MASK | | |
91 EventMask.ENTER_NOTIFY_MASK | | |
92 EventMask.LEAVE_NOTIFY_MASK | | |
93 EventMask.FOCUS_CHANGE_MASK | | |
94 EventMask.SCROLL_MASK); | |
95 | |
0 | 96 attach(mDrawingArea, |
97 1, 2, | |
98 1, 2, | |
99 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL | AttachOptions.EXPAND, | |
100 0, 0); | |
101 | |
102 // value, lower, upper, step-inc, page-inc, page-size | |
103 // Give the adjustments dummy values until we receive a configure | |
12 | 104 mHAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5); |
0 | 105 mHAdjustment.addOnValueChanged(&onValueChanged); |
106 mHScrollbar = new HScrollbar(mHAdjustment); | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
107 mHScrollbar.setInverted(false); |
0 | 108 attach(mHScrollbar, |
109 1, 2, | |
110 2, 3, | |
111 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK, | |
112 0, 0); | |
113 | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
114 mVAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5); |
0 | 115 mVAdjustment.addOnValueChanged(&onValueChanged); |
116 mVScrollbar = new VScrollbar(mVAdjustment); | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
117 mVScrollbar.setInverted(true); |
0 | 118 attach(mVScrollbar, |
119 2, 3, | |
120 1, 2, | |
121 AttachOptions.SHRINK, | |
122 AttachOptions.FILL | AttachOptions.EXPAND, | |
123 0, 0); | |
124 } | |
125 | |
20 | 126 override void zoom_relative(Point pixel_datum, double factor) { |
0 | 127 // Work out pixel distance from current centre to datum, |
128 // Do the zoom, then work out the new centre that keeps the | |
129 // pixel distance the same | |
130 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
131 Point old_model_datum = pixel_to_model(pixel_datum); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
132 Vector pixel_distance = model_to_pixel(old_model_datum - mViewCentre); |
0 | 133 mZoom = clamp_zoom(factor * mZoom); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
134 mViewCentre = old_model_datum - pixel_to_model(pixel_distance); |
0 | 135 |
13 | 136 update_adjustments; |
137 update_rulers; | |
138 queueDraw; | |
0 | 139 } |
140 | |
20 | 141 override void pan_relative(Vector pixel_displacement) { |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
142 mViewCentre = mViewCentre + pixel_to_model(pixel_displacement); |
0 | 143 |
13 | 144 update_adjustments; |
145 update_rulers; | |
146 queueDraw; | |
147 } | |
148 | |
17 | 149 override void damage_model(Rectangle area) { |
150 mDamage = mDamage | model_to_pixel(area); | |
151 } | |
152 | |
18 | 153 override void damage_pixel(Rectangle area) { |
154 mDamage = mDamage | area; | |
155 } | |
156 | |
13 | 157 override double zoom() const { |
158 return mZoom; | |
159 } | |
160 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
161 override Point model_to_pixel(Point model) const { |
13 | 162 return Point.DEFAULT + mViewSize / 2.0 + mZoom * (model - mViewCentre); |
163 } | |
164 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
165 override Point pixel_to_model(Point pixel) const { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
166 return mViewCentre + (pixel - mViewSize / 2.0 - Point.DEFAULT) / mZoom; |
0 | 167 } |
168 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
169 override Vector model_to_pixel(Vector model) const { |
13 | 170 return mZoom * model; |
171 } | |
172 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
173 override Vector pixel_to_model(Vector pixel) const { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
174 return pixel / mZoom; |
13 | 175 } |
176 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
177 override double model_to_pixel(double model) const { |
13 | 178 return mZoom * model; |
179 } | |
180 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
181 override double pixel_to_model(double pixel) const { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
182 return pixel / mZoom; |
13 | 183 } |
184 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
185 override Rectangle model_to_pixel(Rectangle model) const { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
186 return Rectangle(model_to_pixel(model.position), model_to_pixel(model.size)); |
13 | 187 } |
188 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
189 override Rectangle pixel_to_model(Rectangle model) const { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
190 return Rectangle(pixel_to_model(model.position), pixel_to_model(model.size)); |
13 | 191 } |
10 | 192 |
0 | 193 private { |
194 | |
195 void onRealize(Widget widget) { | |
196 assert(widget is mDrawingArea); | |
197 //writefln("Got realize\n"); | |
198 } | |
199 | |
200 bool onConfigure(GdkEventConfigure * event, Widget widget) { | |
201 assert(widget is mDrawingArea); | |
202 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
203 if (!mHadConfigure) { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
204 const double MM_PER_INCH = 25.4; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
205 mZoom = 0.25 * mPPI / MM_PER_INCH; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
206 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
207 // Take the union of the bounds of each layer to |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
208 // determine the canvas size |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
209 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
210 Rectangle layer_bounds = Rectangle.DEFAULT; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
211 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
212 foreach (ref layer; mLayers) { |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
213 layer_bounds = layer_bounds | layer.bounds; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
214 } |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
215 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
216 assert(layer_bounds.valid); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
217 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
218 mCanvasBounds = layer_bounds.moved(-layer_bounds.size).expanded(2.0 * layer_bounds.size); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
219 mViewCentre = mCanvasBounds.centre; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
220 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
221 mHadConfigure = true; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
222 } |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
223 |
3
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
224 mViewSize = Vector(cast(double)event.width, cast(double)event.height); |
13 | 225 update_adjustments; |
226 update_rulers; | |
0 | 227 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
228 //writefln("Canvas bounds: %s", mCanvasBounds); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
229 //writefln("View centre: %s", mViewCentre); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
230 |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
231 return true; |
0 | 232 } |
233 | |
234 bool onExpose(GdkEventExpose * event, Widget widget) { | |
235 assert(widget is mDrawingArea); | |
236 | |
13 | 237 Drawable dr = mDrawingArea.getWindow; |
0 | 238 |
239 int width, height; | |
240 dr.getSize(width, height); | |
241 //writefln("Got expose %dx%d\n", width, height); | |
242 | |
12 | 243 scope model_cr = new Context(dr); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
244 scope pixel_cr = new Context(dr); |
12 | 245 |
19 | 246 Rectangle pixel_damage = |
11 | 247 event is null ? |
19 | 248 Rectangle(Point(0.0, 0.0), mViewSize) : |
249 Rectangle(Point(cast(double)event.area.x, mViewSize.y - cast(double)(event.area.y + event.area.height)), | |
11 | 250 Vector(cast(double)event.area.width, cast(double)event.area.height)); |
0 | 251 |
19 | 252 Rectangle model_damage = pixel_to_model(pixel_damage); |
253 | |
254 //writefln("Pixel damage: %s, model damage: %s", pixel_damage, model_damage); | |
255 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
256 model_cr.save; pixel_cr.save; { |
19 | 257 // Setup model context and clip |
12 | 258 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
259 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
260 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct; |
12 | 261 |
13 | 262 model_cr.scale(mZoom, -mZoom); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
263 model_cr.translate(-gtk_adjustment_get_value(h_gtkAdjustment), |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
264 -gtk_adjustment_get_value(v_gtkAdjustment) - gtk_adjustment_get_page_size(v_gtkAdjustment)); |
0 | 265 |
19 | 266 rectangle(model_cr, model_damage); |
267 model_cr.clip; | |
268 | |
269 // Setup pixel context and clip | |
12 | 270 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
271 pixel_cr.translate(0.0, mViewSize.y); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
272 pixel_cr.scale(1.0, -1.0); |
19 | 273 |
274 rectangle(pixel_cr, pixel_damage); | |
275 pixel_cr.clip; | |
12 | 276 |
277 // Fill the background | |
278 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
279 pixel_cr.save; { |
11 | 280 // Make the window light grey |
18 | 281 pixel_cr.setSourceRgba(0.6, 0.6, 0.6, 1.0); |
19 | 282 rectangle(pixel_cr, pixel_damage); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
283 pixel_cr.fill; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
284 } pixel_cr.restore; |
12 | 285 |
286 // Draw each layer | |
0 | 287 |
11 | 288 foreach(ref layer; mLayers) { |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
289 model_cr.save; pixel_cr.save; { |
19 | 290 layer.draw(this, pixel_damage, pixel_cr, model_damage, model_cr); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
291 } pixel_cr.restore; model_cr.restore; |
11 | 292 } |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
293 } pixel_cr.restore; model_cr.restore; |
0 | 294 |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
295 return true; |
0 | 296 } |
297 | |
5 | 298 bool onButtonPress(GdkEventButton * event, Widget widget) { |
0 | 299 assert(widget is mDrawingArea); |
300 //writefln("Got button event\n"); | |
301 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
302 Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5)); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
303 Point model_point = pixel_to_model(pixel_point); |
0 | 304 |
7 | 305 auto button_event = new ButtonEvent(gtk2tk_button_action(event.type), |
306 gtk2tk_button_name(event.button), | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
307 pixel_point, |
0 | 308 model_point, |
309 gtk2tk_mask(event.state)); | |
310 | |
5 | 311 mEventHandler.handle_button_press(this, button_event); |
312 | |
17 | 313 process_damage; |
314 | |
5 | 315 return true; |
316 } | |
317 | |
318 bool onButtonRelease(GdkEventButton * event, Widget widget) { | |
319 assert(widget is mDrawingArea); | |
320 //writefln("Got button event\n"); | |
321 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
322 Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5)); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
323 Point model_point = pixel_to_model(pixel_point); |
5 | 324 |
7 | 325 auto button_event = new ButtonEvent(gtk2tk_button_action(event.type), |
326 gtk2tk_button_name(event.button), | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
327 pixel_point, |
5 | 328 model_point, |
329 gtk2tk_mask(event.state)); | |
330 | |
331 mEventHandler.handle_button_release(this, button_event); | |
0 | 332 |
17 | 333 process_damage; |
334 | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
335 return true; |
0 | 336 } |
337 | |
338 bool onKeyEvent(GdkEventKey * event, Widget widget) { | |
339 assert(widget is mDrawingArea); | |
340 //writefln("Got key event\n"); | |
341 | |
342 //auto key_event = new KeyEvent("", | |
343 // mEventHandle.handle_key(key_event); | |
344 | |
17 | 345 process_damage; |
346 | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
347 return true; |
0 | 348 } |
349 | |
350 bool onMotionNotify(GdkEventMotion * event, Widget widget) { | |
351 assert(widget is mDrawingArea); | |
352 //writefln("Got motion notify\n"); | |
353 gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event); | |
354 gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event); | |
355 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
356 Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5)); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
357 Point model_point = pixel_to_model(pixel_point); |
0 | 358 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
359 auto motion_event = new MotionEvent(pixel_point, |
0 | 360 model_point, |
361 gtk2tk_mask(event.state)); | |
362 | |
363 mEventHandler.handle_motion(this, motion_event); | |
364 | |
17 | 365 process_damage; |
366 | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
367 return true; |
0 | 368 } |
369 | |
370 bool onScroll(GdkEventScroll * event, Widget widget) { | |
371 assert(widget is mDrawingArea); | |
372 //writefln("Got scroll\n"); | |
373 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
374 Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5)); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
375 Point model_point = pixel_to_model(pixel_point); |
0 | 376 |
377 auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction), | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
378 pixel_point, |
0 | 379 model_point, |
380 gtk2tk_mask(event.state)); | |
381 | |
382 mEventHandler.handle_scroll(this, scroll_event); | |
383 | |
17 | 384 process_damage; |
385 | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
386 return true; |
0 | 387 } |
388 | |
20 | 389 /* |
390 public enum GdkCrossingMode { | |
391 NORMAL, | |
392 GRAB, | |
393 UNGRAB, | |
394 GTK_GRAB, | |
395 GTK_UNGRAB, | |
396 STATE_CHANGED | |
397 } | |
398 | |
399 public struct GdkEventCrossing { | |
400 GdkEventType type; | |
401 GdkWindow *window; | |
402 byte sendEvent; | |
403 GdkWindow *subwindow; | |
404 uint time; | |
405 double x; | |
406 double y; | |
407 double xRoot; | |
408 double yRoot; | |
409 GdkCrossingMode mode; | |
410 GdkNotifyType detail; | |
411 int focus; | |
412 uint state; | |
413 } | |
414 */ | |
415 | |
416 bool onEnterNotify(GdkEventCrossing * event, Widget widget) { | |
417 assert(widget is mDrawingArea); | |
418 writefln("Enter %d %d %d", cast(int)event.mode, event.focus, event.state); | |
419 return true; | |
420 } | |
421 | |
422 bool onLeaveNotify(GdkEventCrossing * event, Widget widget) { | |
423 assert(widget is mDrawingArea); | |
424 writefln("Leave %d %d %d", cast(int)event.mode, event.focus, event.state); | |
425 return true; | |
426 } | |
427 | |
0 | 428 void onValueChanged(Adjustment adjustment) { |
13 | 429 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct; |
430 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct; | |
0 | 431 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
432 Point view_left_top = Point(gtk_adjustment_get_value(h_gtkAdjustment), |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
433 gtk_adjustment_get_value(v_gtkAdjustment)); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
434 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
435 Vector model_size = pixel_to_model(mViewSize); |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
436 |
9 | 437 //writefln("%s", view_left_bottom); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
438 mViewCentre = view_left_top + model_size / 2.0; |
19 | 439 //writefln("onValueChanged mViewCentre: %s", mViewCentre); |
0 | 440 |
13 | 441 update_rulers; |
0 | 442 |
13 | 443 queueDraw; |
0 | 444 } |
445 | |
446 void update_rulers() { | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
447 Vector model_size = pixel_to_model(mViewSize); |
0 | 448 |
3
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
449 Point view_left_bottom = mViewCentre - model_size / 2.0; |
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
450 Point view_right_top = mViewCentre + model_size / 2.0; |
0 | 451 |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
452 // Define these just to obtain the position |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
453 // below and we can preserve it |
12 | 454 double lower, upper, position, max_size; |
455 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
456 |
12 | 457 mHRuler.getRange(lower, upper, position, max_size); |
0 | 458 mHRuler.setRange(view_left_bottom.x, |
459 view_right_top.x, | |
12 | 460 position, |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
461 mZoom * 50.0); |
12 | 462 |
463 mVRuler.getRange(lower, upper, position, max_size); | |
0 | 464 mVRuler.setRange(view_right_top.y, |
465 view_left_bottom.y, | |
14 | 466 position, |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
467 mZoom * 50.0); |
0 | 468 } |
469 | |
470 void update_adjustments() { | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
471 Vector model_size = pixel_to_model(mViewSize); |
0 | 472 |
3
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
473 Point view_left_bottom = mViewCentre - model_size / 2.0; |
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
474 Point view_right_top = mViewCentre + model_size / 2.0; |
0 | 475 |
476 // Adjust the canvas size if necessary | |
15 | 477 mCanvasBounds = Rectangle(min_extents(mCanvasBounds.min_corner, view_left_bottom), |
478 max_extents(mCanvasBounds.max_corner, view_right_top)); | |
0 | 479 |
480 // Update the adjustments | |
481 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
482 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct; |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
483 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct; |
0 | 484 |
15 | 485 gtk_adjustment_set_lower(h_gtkAdjustment, mCanvasBounds.min_corner.x); |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
486 gtk_adjustment_set_upper(h_gtkAdjustment, mCanvasBounds.max_corner.x); |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
487 gtk_adjustment_set_value(h_gtkAdjustment, view_left_bottom.x); |
15 | 488 gtk_adjustment_set_step_increment(h_gtkAdjustment, mCanvasBounds.size.x / 16.0); |
489 gtk_adjustment_set_page_increment(h_gtkAdjustment, mCanvasBounds.size.x / 4.0); | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
490 gtk_adjustment_set_page_size(h_gtkAdjustment, model_size.x); |
0 | 491 |
15 | 492 gtk_adjustment_set_lower(v_gtkAdjustment, mCanvasBounds.min_corner.y); |
493 gtk_adjustment_set_upper(v_gtkAdjustment, mCanvasBounds.max_corner.y); | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
494 gtk_adjustment_set_value(v_gtkAdjustment, view_left_bottom.y); |
15 | 495 gtk_adjustment_set_step_increment(v_gtkAdjustment, mCanvasBounds.size.y / 16.0); |
496 gtk_adjustment_set_page_increment(v_gtkAdjustment, mCanvasBounds.size.y / 4.0); | |
2
d6f44347373d
* Switched over to geometry done with structs instead of classes.
David Bryant <daveb@acres.com.au>
parents:
0
diff
changeset
|
497 gtk_adjustment_set_page_size(v_gtkAdjustment, model_size.y); |
0 | 498 |
13 | 499 mHAdjustment.changed; |
500 mHAdjustment.valueChanged; | |
501 mVAdjustment.changed; | |
502 mVAdjustment.valueChanged; | |
0 | 503 } |
504 | |
17 | 505 void process_damage() { |
506 if (mDamage.valid) { | |
18 | 507 //writefln("Damage: %s", mDamage); |
17 | 508 int x, y, w, h; |
509 mDamage.get_quantised(x, y, w, h); | |
18 | 510 //writefln("Quantised damage: %d %d %d %d", x, y, w, h); |
511 y = cast(int)mViewSize.y - (y + h); | |
512 //writefln("Flipped Quantised damage: %d %d %d %d", x, y, w, h); | |
19 | 513 mDrawingArea.queueDrawArea(x, y, w, h); |
514 //mDrawingArea.queueDraw(); | |
17 | 515 mDamage = Rectangle.DEFAULT; |
516 } | |
517 else { | |
18 | 518 //writefln("No damage"); |
17 | 519 } |
520 } | |
521 | |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
522 double clamp_zoom(double zoom) { return clamp(zoom, 0.2, 10.0); } |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
523 |
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
524 bool mHadConfigure; |
17 | 525 Rectangle mDamage; // pixels |
0 | 526 |
527 // Model units are in millimetres | |
528 // Screen units are in pixels | |
11 | 529 double mZoom; // pixels-per-model-unit (mm) |
16
9e63308b749c
* Fix up public/private includes
David Bryant <daveb@acres.com.au>
parents:
15
diff
changeset
|
530 Vector mViewSize; // pixel: size of view window in pixels |
3
7d57cae10805
Renamed geometry2 to geometry
David Bryant <daveb@acres.com.au>
parents:
2
diff
changeset
|
531 Point mViewCentre; // model: where in the model is the centre of our view |
15 | 532 Rectangle mCanvasBounds; // model: |
0 | 533 |
10 | 534 // Child widgets: |
0 | 535 HRuler mHRuler; |
536 VRuler mVRuler; | |
537 DrawingArea mDrawingArea; | |
538 Adjustment mHAdjustment; | |
539 HScrollbar mHScrollbar; | |
540 Adjustment mVAdjustment; | |
541 VScrollbar mVScrollbar; | |
11 | 542 |
543 // Layers: | |
544 Layer[] mLayers; | |
13 | 545 EventHandler mEventHandler; |
546 double mPPI; | |
0 | 547 } |
548 } |