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