Mercurial > projects > doodle
comparison canvas.d @ 3:7d57cae10805
Renamed geometry2 to geometry
author | David Bryant <daveb@acres.com.au> |
---|---|
date | Fri, 10 Jul 2009 15:25:48 +0930 |
parents | d6f44347373d |
children | 8a39b13cd3e6 |
comparison
equal
deleted
inserted
replaced
2:d6f44347373d | 3:7d57cae10805 |
---|---|
18 import gtk.VScrollbar; | 18 import gtk.VScrollbar; |
19 import gtk.DrawingArea; | 19 import gtk.DrawingArea; |
20 import gtk.Adjustment; | 20 import gtk.Adjustment; |
21 | 21 |
22 import tk.misc; | 22 import tk.misc; |
23 import tk.geometry2; | 23 import tk.geometry; |
24 import tk.types; | 24 import tk.types; |
25 import tk.events; | 25 import tk.events; |
26 import tk.gtk_support; | 26 import tk.gtk_support; |
27 | 27 |
28 private import gtkc.gtk; | 28 private import gtkc.gtk; |
32 | 32 |
33 // x and y run right and up respectively | 33 // x and y run right and up respectively |
34 | 34 |
35 class Canvas : Table, ICanvas { | 35 class Canvas : Table, ICanvas { |
36 static this() { | 36 static this() { |
37 ORIGIN = Point2(0.0, 0.0); | 37 ORIGIN = Point(0.0, 0.0); |
38 INITIAL_PAGE_SIZE = Vector2(210.0, 297.0); // A4 | 38 INITIAL_PAGE_SIZE = Vector(210.0, 297.0); // A4 |
39 } | 39 } |
40 | 40 |
41 this(ICanvasEventHandler event_handler) { | 41 this(ICanvasEventHandler event_handler) { |
42 super(3, 3, 0); | 42 super(3, 3, 0); |
43 | 43 |
106 AttachOptions.SHRINK, | 106 AttachOptions.SHRINK, |
107 AttachOptions.FILL | AttachOptions.EXPAND, | 107 AttachOptions.FILL | AttachOptions.EXPAND, |
108 0, 0); | 108 0, 0); |
109 } | 109 } |
110 | 110 |
111 override void rel_zoom(Point2 screen_datum, double factor) { | 111 override void rel_zoom(Point screen_datum, double factor) { |
112 // Work out pixel distance from current centre to datum, | 112 // Work out pixel distance from current centre to datum, |
113 // Do the zoom, then work out the new centre that keeps the | 113 // Do the zoom, then work out the new centre that keeps the |
114 // pixel distance the same | 114 // pixel distance the same |
115 | 115 |
116 Point2 old_model_datum = screen_to_model(screen_datum); | 116 Point old_model_datum = screen_to_model(screen_datum); |
117 Vector2 pixel_distance = model_to_screen(old_model_datum - mViewCentre); | 117 Vector pixel_distance = model_to_screen(old_model_datum - mViewCentre); |
118 mZoom = clamp_zoom(factor * mZoom); | 118 mZoom = clamp_zoom(factor * mZoom); |
119 mViewCentre = old_model_datum - screen_to_model(pixel_distance); | 119 mViewCentre = old_model_datum - screen_to_model(pixel_distance); |
120 | 120 |
121 Point2 new_model_datum = screen_to_model(screen_datum); | 121 Point new_model_datum = screen_to_model(screen_datum); |
122 | 122 |
123 update_adjustments(); | 123 update_adjustments(); |
124 //update_rulers(new_model_datum); | 124 //update_rulers(new_model_datum); |
125 update_rulers(); | 125 update_rulers(); |
126 queueDraw(); | 126 queueDraw(); |
127 } | 127 } |
128 | 128 |
129 override void rel_pan(Vector2 screen_displacement) { | 129 override void rel_pan(Vector screen_displacement) { |
130 mViewCentre = mViewCentre + screen_to_model(screen_displacement); | 130 mViewCentre = mViewCentre + screen_to_model(screen_displacement); |
131 | 131 |
132 update_adjustments(); | 132 update_adjustments(); |
133 update_rulers(); | 133 update_rulers(); |
134 queueDraw(); | 134 queueDraw(); |
142 } | 142 } |
143 | 143 |
144 bool onConfigure(GdkEventConfigure * event, Widget widget) { | 144 bool onConfigure(GdkEventConfigure * event, Widget widget) { |
145 assert(widget is mDrawingArea); | 145 assert(widget is mDrawingArea); |
146 | 146 |
147 mViewSize = Vector2(cast(double)event.width, cast(double)event.height); | 147 mViewSize = Vector(cast(double)event.width, cast(double)event.height); |
148 update_adjustments(); | 148 update_adjustments(); |
149 update_rulers(); | 149 update_rulers(); |
150 | 150 |
151 | 151 |
152 return true; | 152 return true; |
179 cr.fill(); | 179 cr.fill(); |
180 | 180 |
181 { | 181 { |
182 // Make the paper white, with a border | 182 // Make the paper white, with a border |
183 | 183 |
184 Point2 screen_page_left_bottom = model_to_screen(mPageLeftBottom); | 184 Point screen_page_left_bottom = model_to_screen(mPageLeftBottom); |
185 Point2 screen_page_right_top = model_to_screen(mPageRightTop); | 185 Point screen_page_right_top = model_to_screen(mPageRightTop); |
186 | 186 |
187 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); | 187 cr.setSourceRgba(1.0, 1.0, 1.0, 1.0); |
188 rectangle(cr, screen_page_left_bottom, screen_page_right_top); | 188 rectangle(cr, screen_page_left_bottom, screen_page_right_top); |
189 cr.fill(); | 189 cr.fill(); |
190 | 190 |
198 | 198 |
199 bool onButtonEvent(GdkEventButton * event, Widget widget) { | 199 bool onButtonEvent(GdkEventButton * event, Widget widget) { |
200 assert(widget is mDrawingArea); | 200 assert(widget is mDrawingArea); |
201 //writefln("Got button event\n"); | 201 //writefln("Got button event\n"); |
202 | 202 |
203 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); | 203 Point screen_point = Point(event.x + 0.5, event.y + 0.5); |
204 Point2 model_point = screen_to_model(screen_point); | 204 Point model_point = screen_to_model(screen_point); |
205 | 205 |
206 auto button_event = new ButtonEvent(gtk2tk_click(event.type), | 206 auto button_event = new ButtonEvent(gtk2tk_click(event.type), |
207 gtk2tk_button(event.button), | 207 gtk2tk_button(event.button), |
208 screen_point, | 208 screen_point, |
209 model_point, | 209 model_point, |
228 assert(widget is mDrawingArea); | 228 assert(widget is mDrawingArea); |
229 //writefln("Got motion notify\n"); | 229 //writefln("Got motion notify\n"); |
230 gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event); | 230 gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event); |
231 gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event); | 231 gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event); |
232 | 232 |
233 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); | 233 Point screen_point = Point(event.x + 0.5, event.y + 0.5); |
234 Point2 model_point = screen_to_model(screen_point); | 234 Point model_point = screen_to_model(screen_point); |
235 | 235 |
236 auto motion_event = new MotionEvent(screen_point, | 236 auto motion_event = new MotionEvent(screen_point, |
237 model_point, | 237 model_point, |
238 gtk2tk_mask(event.state)); | 238 gtk2tk_mask(event.state)); |
239 | 239 |
244 | 244 |
245 bool onScroll(GdkEventScroll * event, Widget widget) { | 245 bool onScroll(GdkEventScroll * event, Widget widget) { |
246 assert(widget is mDrawingArea); | 246 assert(widget is mDrawingArea); |
247 //writefln("Got scroll\n"); | 247 //writefln("Got scroll\n"); |
248 | 248 |
249 Point2 screen_point = Point2(event.x + 0.5, event.y + 0.5); | 249 Point screen_point = Point(event.x + 0.5, event.y + 0.5); |
250 Point2 model_point = screen_to_model(screen_point); | 250 Point model_point = screen_to_model(screen_point); |
251 | 251 |
252 auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction), | 252 auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction), |
253 screen_point, | 253 screen_point, |
254 model_point, | 254 model_point, |
255 gtk2tk_mask(event.state)); | 255 gtk2tk_mask(event.state)); |
261 | 261 |
262 void onValueChanged(Adjustment adjustment) { | 262 void onValueChanged(Adjustment adjustment) { |
263 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); | 263 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); |
264 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); | 264 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); |
265 | 265 |
266 Point2 view_left_bottom = Point2(gtk_adjustment_get_value(h_gtkAdjustment), | 266 Point view_left_bottom = Point(gtk_adjustment_get_value(h_gtkAdjustment), |
267 gtk_adjustment_get_value(v_gtkAdjustment)); | 267 gtk_adjustment_get_value(v_gtkAdjustment)); |
268 writefln("%s", view_left_bottom); | 268 writefln("%s", view_left_bottom); |
269 Vector2 model_size = screen_to_model(mViewSize); | 269 Vector model_size = screen_to_model(mViewSize); |
270 mViewCentre = view_left_bottom + model_size / 2.0; | 270 mViewCentre = view_left_bottom + model_size / 2.0; |
271 | 271 |
272 update_rulers(); | 272 update_rulers(); |
273 | 273 |
274 queueDraw(); | 274 queueDraw(); |
275 } | 275 } |
276 | 276 |
277 void update_rulers() { | 277 void update_rulers() { |
278 Vector2 model_size = screen_to_model(mViewSize); | 278 Vector model_size = screen_to_model(mViewSize); |
279 | 279 |
280 Point2 view_left_bottom = mViewCentre - model_size / 2.0; | 280 Point view_left_bottom = mViewCentre - model_size / 2.0; |
281 Point2 view_right_top = mViewCentre + model_size / 2.0; | 281 Point view_right_top = mViewCentre + model_size / 2.0; |
282 | 282 |
283 mHRuler.setRange(view_left_bottom.x, | 283 mHRuler.setRange(view_left_bottom.x, |
284 view_right_top.x, | 284 view_right_top.x, |
285 0.0, // TODO preserve the value | 285 0.0, // TODO preserve the value |
286 mZoom * 2000.0); | 286 mZoom * 2000.0); |
289 0.0, | 289 0.0, |
290 mZoom * 2000.0); | 290 mZoom * 2000.0); |
291 } | 291 } |
292 | 292 |
293 void update_adjustments() { | 293 void update_adjustments() { |
294 Vector2 model_size = screen_to_model(mViewSize); | 294 Vector model_size = screen_to_model(mViewSize); |
295 | 295 |
296 Point2 view_left_bottom = mViewCentre - model_size / 2.0; | 296 Point view_left_bottom = mViewCentre - model_size / 2.0; |
297 Point2 view_right_top = mViewCentre + model_size / 2.0; | 297 Point view_right_top = mViewCentre + model_size / 2.0; |
298 | 298 |
299 // Adjust the canvas size if necessary | 299 // Adjust the canvas size if necessary |
300 mCanvasLeftBottom = min_extents(mCanvasLeftBottom, view_left_bottom); | 300 mCanvasLeftBottom = min_extents(mCanvasLeftBottom, view_left_bottom); |
301 mCanvasRightTop = max_extents(mCanvasRightTop, view_right_top); | 301 mCanvasRightTop = max_extents(mCanvasRightTop, view_right_top); |
302 | 302 |
303 Vector2 canvas_size = mCanvasRightTop - mCanvasLeftBottom; | 303 Vector canvas_size = mCanvasRightTop - mCanvasLeftBottom; |
304 Vector2 page_size = mPageRightTop - mPageLeftBottom; | 304 Vector page_size = mPageRightTop - mPageLeftBottom; |
305 | 305 |
306 // Update the adjustments | 306 // Update the adjustments |
307 | 307 |
308 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); | 308 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); |
309 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); | 309 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); |
326 mHAdjustment.valueChanged(); | 326 mHAdjustment.valueChanged(); |
327 mVAdjustment.changed(); | 327 mVAdjustment.changed(); |
328 mVAdjustment.valueChanged(); | 328 mVAdjustment.valueChanged(); |
329 } | 329 } |
330 | 330 |
331 Point2 model_to_screen(Point2 model) { return ORIGIN + mViewSize / 2.0 + mZoom * (model - mViewCentre); } | 331 Point model_to_screen(Point model) { return ORIGIN + mViewSize / 2.0 + mZoom * (model - mViewCentre); } |
332 Point2 screen_to_model(Point2 screen) { return mViewCentre + (screen - mViewSize / 2.0 - ORIGIN) / mZoom; } | 332 Point screen_to_model(Point screen) { return mViewCentre + (screen - mViewSize / 2.0 - ORIGIN) / mZoom; } |
333 Vector2 model_to_screen(Vector2 model) { return mZoom * model; } | 333 Vector model_to_screen(Vector model) { return mZoom * model; } |
334 Vector2 screen_to_model(Vector2 screen) { return screen / mZoom; } | 334 Vector screen_to_model(Vector screen) { return screen / mZoom; } |
335 double model_to_screen(double model) { return mZoom * model; } | 335 double model_to_screen(double model) { return mZoom * model; } |
336 double screen_to_model(double screen) { return screen / mZoom; } | 336 double screen_to_model(double screen) { return screen / mZoom; } |
337 | 337 |
338 double clamp_zoom(double zoom) { return clamp(zoom, 0.1, 10.0); } | 338 double clamp_zoom(double zoom) { return clamp(zoom, 0.1, 10.0); } |
339 | 339 |
340 static const Point2 ORIGIN; | 340 static const Point ORIGIN; |
341 static const Vector2 INITIAL_PAGE_SIZE; | 341 static const Vector INITIAL_PAGE_SIZE; |
342 | 342 |
343 ICanvasEventHandler mEventHandler; | 343 ICanvasEventHandler mEventHandler; |
344 | 344 |
345 // Model units are in millimetres | 345 // Model units are in millimetres |
346 // Screen units are in pixels | 346 // Screen units are in pixels |
347 | 347 |
348 double mZoom; // pixels-per-mm | 348 double mZoom; // pixels-per-mm |
349 Point2 mViewCentre; // model: where in the model is the centre of our view | 349 Point mViewCentre; // model: where in the model is the centre of our view |
350 | 350 |
351 Point2 mCanvasLeftBottom; // model: bottom left corner of canvas | 351 Point mCanvasLeftBottom; // model: bottom left corner of canvas |
352 Point2 mCanvasRightTop; // model: top right corner of canvas | 352 Point mCanvasRightTop; // model: top right corner of canvas |
353 Point2 mPageLeftBottom; // model: bottom left corner of page | 353 Point mPageLeftBottom; // model: bottom left corner of page |
354 Point2 mPageRightTop; // model: top right corner of page | 354 Point mPageRightTop; // model: top right corner of page |
355 | 355 |
356 Vector2 mViewSize; // screen: size of view window in pixels | 356 Vector mViewSize; // screen: size of view window in pixels |
357 | 357 |
358 HRuler mHRuler; | 358 HRuler mHRuler; |
359 VRuler mVRuler; | 359 VRuler mVRuler; |
360 DrawingArea mDrawingArea; | 360 DrawingArea mDrawingArea; |
361 Adjustment mHAdjustment; | 361 Adjustment mHAdjustment; |