comparison canvas.d @ 13:f0ade1b49fe7

Checkpoint
author "David Bryant <bagnose@gmail.com>"
date Sun, 12 Jul 2009 01:04:35 +0930
parents a093c4fbdd43
children 0b7e7d43a79d
comparison
equal deleted inserted replaced
12:a093c4fbdd43 13:f0ade1b49fe7
36 this(in Layer[] layers, EventHandler event_handler, in double ppi) { 36 this(in Layer[] layers, EventHandler event_handler, in double ppi) {
37 super(3, 3, 0); 37 super(3, 3, 0);
38 38
39 mLayers = layers.dup; 39 mLayers = layers.dup;
40 mEventHandler = event_handler; 40 mEventHandler = event_handler;
41 mPPI = ppi;
41 42
42 const double MM_PER_INCH = 25.4; 43 const double MM_PER_INCH = 25.4;
43 mZoom = 0.25 * ppi / MM_PER_INCH; 44 mZoom = 0.25 * mPPI / MM_PER_INCH;
45
46 // Take the union of the bounds of each layer to
47 // determine the canvas size
44 48
45 Rectangle total_layer_bounds; 49 Rectangle total_layer_bounds;
46 50
47 foreach (ref layer; mLayers) { 51 foreach (ref layer; mLayers) {
48 total_layer_bounds = total_layer_bounds | layer.bounds; 52 total_layer_bounds = total_layer_bounds | layer.bounds;
49 } 53 }
54
55 assert(total_layer_bounds.valid);
50 56
51 mCanvasLeftBottom = total_layer_bounds.min_corner - total_layer_bounds.size; 57 mCanvasLeftBottom = total_layer_bounds.min_corner - total_layer_bounds.size;
52 mCanvasRightTop = total_layer_bounds.max_corner + total_layer_bounds.size; 58 mCanvasRightTop = total_layer_bounds.max_corner + total_layer_bounds.size;
53 mViewCentre = mCanvasLeftBottom + (mCanvasRightTop - mCanvasLeftBottom) / 2.0; 59 mViewCentre = mCanvasLeftBottom + (mCanvasRightTop - mCanvasLeftBottom) / 2.0;
54 60
55 mHRuler = new HRuler(); 61 // Create our child widgets and register callbacks
62
63 mHRuler = new HRuler;
56 attach(mHRuler, 64 attach(mHRuler,
57 1, 2, 65 1, 2,
58 0, 1, 66 0, 1,
59 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK, 67 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK,
60 0, 0); 68 0, 0);
61 mHRuler.setMetric(GtkMetricType.CENTIMETERS); 69 mHRuler.setMetric(GtkMetricType.CENTIMETERS);
62 70
63 mVRuler = new VRuler(); 71 mVRuler = new VRuler;
64 attach(mVRuler, 72 attach(mVRuler,
65 0, 1, 73 0, 1,
66 1, 2, 74 1, 2,
67 AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND, 75 AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND,
68 0, 0); 76 0, 0);
69 mVRuler.setMetric(GtkMetricType.CENTIMETERS); 77 mVRuler.setMetric(GtkMetricType.CENTIMETERS);
70 78
71 mDrawingArea = new DrawingArea(); 79 mDrawingArea = new DrawingArea;
72 mDrawingArea.addOnRealize(&onRealize); 80 mDrawingArea.addOnRealize(&onRealize);
73 mDrawingArea.addOnConfigure(&onConfigure); 81 mDrawingArea.addOnConfigure(&onConfigure);
74 mDrawingArea.addOnExpose(&onExpose); 82 mDrawingArea.addOnExpose(&onExpose);
75 mDrawingArea.addOnButtonPress(&onButtonPress); 83 mDrawingArea.addOnButtonPress(&onButtonPress);
76 mDrawingArea.addOnButtonRelease(&onButtonRelease); 84 mDrawingArea.addOnButtonRelease(&onButtonRelease);
116 mZoom = clamp_zoom(factor * mZoom); 124 mZoom = clamp_zoom(factor * mZoom);
117 mViewCentre = old_model_datum - screen_to_model(pixel_distance); 125 mViewCentre = old_model_datum - screen_to_model(pixel_distance);
118 126
119 //Point new_model_datum = screen_to_model(screen_datum); 127 //Point new_model_datum = screen_to_model(screen_datum);
120 128
121 update_adjustments(); 129 update_adjustments;
122 //update_rulers(new_model_datum); 130 //update_rulers(new_model_datum);
123 update_rulers(); 131 update_rulers;
124 queueDraw(); 132 queueDraw;
125 } 133 }
126 134
127 override void rel_pan(Vector screen_displacement) { 135 override void rel_pan(Vector screen_displacement) {
128 mViewCentre = mViewCentre + screen_to_model(screen_displacement); 136 mViewCentre = mViewCentre + screen_to_model(screen_displacement);
129 137
130 update_adjustments(); 138 update_adjustments;
131 update_rulers(); 139 update_rulers;
132 queueDraw(); 140 queueDraw;
133 } 141 }
134 142
135 override double zoom() const { return mZoom; } 143 override double zoom() const {
136 override Point model_to_screen(Point model) const { return Point.DEFAULT + mViewSize / 2.0 + mZoom * (model - mViewCentre); } 144 return mZoom;
137 override Point screen_to_model(Point screen) const { return mViewCentre + (screen - mViewSize / 2.0 - Point.DEFAULT) / mZoom; } 145 }
138 override Vector model_to_screen(Vector model) const { return mZoom * model; } 146
139 override Vector screen_to_model(Vector screen) const { return screen / mZoom; } 147 override Point model_to_screen(Point model) const {
140 override double model_to_screen(double model) const { return mZoom * model; } 148 return Point.DEFAULT + mViewSize / 2.0 + mZoom * (model - mViewCentre);
141 override double screen_to_model(double screen) const { return screen / mZoom; } 149 }
142 override Rectangle model_to_screen(Rectangle model) const { return Rectangle(model_to_screen(model.position), model_to_screen(model.size)); } 150
143 override Rectangle screen_to_model(Rectangle model) const { return Rectangle(screen_to_model(model.position), screen_to_model(model.size)); } 151 override Point screen_to_model(Point screen) const {
152 return mViewCentre + (screen - mViewSize / 2.0 - Point.DEFAULT) / mZoom;
153 }
154
155 override Vector model_to_screen(Vector model) const {
156 return mZoom * model;
157 }
158
159 override Vector screen_to_model(Vector screen) const {
160 return screen / mZoom;
161 }
162
163 override double model_to_screen(double model) const {
164 return mZoom * model;
165 }
166
167 override double screen_to_model(double screen) const {
168 return screen / mZoom;
169 }
170
171 override Rectangle model_to_screen(Rectangle model) const {
172 return Rectangle(model_to_screen(model.position), model_to_screen(model.size));
173 }
174
175 override Rectangle screen_to_model(Rectangle model) const {
176 return Rectangle(screen_to_model(model.position), screen_to_model(model.size));
177 }
144 178
145 private { 179 private {
146 180
147 void onRealize(Widget widget) { 181 void onRealize(Widget widget) {
148 assert(widget is mDrawingArea); 182 assert(widget is mDrawingArea);
151 185
152 bool onConfigure(GdkEventConfigure * event, Widget widget) { 186 bool onConfigure(GdkEventConfigure * event, Widget widget) {
153 assert(widget is mDrawingArea); 187 assert(widget is mDrawingArea);
154 188
155 mViewSize = Vector(cast(double)event.width, cast(double)event.height); 189 mViewSize = Vector(cast(double)event.width, cast(double)event.height);
156 update_adjustments(); 190 update_adjustments;
157 update_rulers(); 191 update_rulers;
158 192
159 193
160 return true; 194 return true;
161 } 195 }
162 196
163 bool onExpose(GdkEventExpose * event, Widget widget) { 197 bool onExpose(GdkEventExpose * event, Widget widget) {
164 assert(widget is mDrawingArea); 198 assert(widget is mDrawingArea);
165 199
166 Drawable dr = mDrawingArea.getWindow(); 200 Drawable dr = mDrawingArea.getWindow;
167 201
168 int width, height; 202 int width, height;
169 dr.getSize(width, height); 203 dr.getSize(width, height);
170 //writefln("Got expose %dx%d\n", width, height); 204 //writefln("Got expose %dx%d\n", width, height);
171 205
176 event is null ? 210 event is null ?
177 Rectangle(Point(0.0, 0.0), Vector(cast(double)width, cast(double)height)) : 211 Rectangle(Point(0.0, 0.0), Vector(cast(double)width, cast(double)height)) :
178 Rectangle(Point(cast(double)event.area.x, cast(double)event.area.y), 212 Rectangle(Point(cast(double)event.area.x, cast(double)event.area.y),
179 Vector(cast(double)event.area.width, cast(double)event.area.height)); 213 Vector(cast(double)event.area.width, cast(double)event.area.height));
180 214
181 model_cr.save(); screen_cr.save(); { 215 model_cr.save; screen_cr.save; {
182 // Setup model context 216 // Setup model context
183 217
184 rectangle(model_cr, damage); 218 rectangle(model_cr, damage);
185 model_cr.clip(); 219 model_cr.clip;
186 220
187 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); 221 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct();
188 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); 222 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct();
189 223
190 model_cr.translate(mCanvasLeftBottom.x - gtk_adjustment_get_value(h_gtkAdjustment), 224 model_cr.translate(mCanvasLeftBottom.x - gtk_adjustment_get_value(h_gtkAdjustment),
191 mCanvasLeftBottom.y - gtk_adjustment_get_value(v_gtkAdjustment)); 225 mCanvasLeftBottom.y - gtk_adjustment_get_value(v_gtkAdjustment));
192 model_cr.scale(mZoom, mZoom); 226 model_cr.scale(mZoom, -mZoom);
193 227
194 // Setup screen context 228 // Setup screen context
195 229
230 screen_cr.translate(0.0, mViewSize.y);
231 screen_cr.scale(1.0, -1.0);
196 rectangle(screen_cr, damage); 232 rectangle(screen_cr, damage);
197 screen_cr.clip(); 233 screen_cr.clip;
198 234
199 // Fill the background 235 // Fill the background
200 236
201 screen_cr.save(); { 237 screen_cr.save; {
202 // Make the window light grey 238 // Make the window light grey
203 screen_cr.setSourceRgba(1.0, 1.0, 1.0, 0.7); 239 screen_cr.setSourceRgba(1.0, 1.0, 1.0, 0.7);
204 rectangle(screen_cr, damage); 240 rectangle(screen_cr, damage);
205 screen_cr.fill(); 241 screen_cr.fill;
206 } screen_cr.restore(); 242 } screen_cr.restore;
207 243
208 // Draw each layer 244 // Draw each layer
209 245
210 foreach(ref layer; mLayers) { 246 foreach(ref layer; mLayers) {
211 model_cr.save(); screen_cr.save(); { 247 model_cr.save; screen_cr.save; {
212 layer.draw(this, damage, model_cr, screen_cr); 248 layer.draw(this, damage, model_cr, screen_cr);
213 } screen_cr.restore(); model_cr.restore(); 249 } screen_cr.restore; model_cr.restore;
214 } 250 }
215 } screen_cr.restore(); model_cr.restore(); 251 } screen_cr.restore; model_cr.restore;
216 252
217 return true; 253 return true;
218 } 254 }
219 255
220 bool onButtonPress(GdkEventButton * event, Widget widget) { 256 bool onButtonPress(GdkEventButton * event, Widget widget) {
297 333
298 return true; 334 return true;
299 } 335 }
300 336
301 void onValueChanged(Adjustment adjustment) { 337 void onValueChanged(Adjustment adjustment) {
302 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct(); 338 GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct;
303 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct(); 339 GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct;
304 340
305 Point view_left_bottom = Point(gtk_adjustment_get_value(h_gtkAdjustment), 341 Point view_left_bottom = Point(gtk_adjustment_get_value(h_gtkAdjustment),
306 gtk_adjustment_get_value(v_gtkAdjustment)); 342 gtk_adjustment_get_value(v_gtkAdjustment));
307 //writefln("%s", view_left_bottom); 343 //writefln("%s", view_left_bottom);
308 Vector model_size = screen_to_model(mViewSize); 344 Vector model_size = screen_to_model(mViewSize);
309 mViewCentre = view_left_bottom + model_size / 2.0; 345 mViewCentre = view_left_bottom + model_size / 2.0;
310 346
311 update_rulers(); 347 update_rulers;
312 348
313 queueDraw(); 349 queueDraw;
314 } 350 }
315 351
316 void update_rulers() { 352 void update_rulers() {
317 Vector model_size = screen_to_model(mViewSize); 353 Vector model_size = screen_to_model(mViewSize);
318 354
363 gtk_adjustment_set_value(v_gtkAdjustment, view_left_bottom.y); 399 gtk_adjustment_set_value(v_gtkAdjustment, view_left_bottom.y);
364 gtk_adjustment_set_step_increment(v_gtkAdjustment, canvas_size.y / 10.0); 400 gtk_adjustment_set_step_increment(v_gtkAdjustment, canvas_size.y / 10.0);
365 gtk_adjustment_set_page_increment(v_gtkAdjustment, canvas_size.y / 5.0); 401 gtk_adjustment_set_page_increment(v_gtkAdjustment, canvas_size.y / 5.0);
366 gtk_adjustment_set_page_size(v_gtkAdjustment, model_size.y); 402 gtk_adjustment_set_page_size(v_gtkAdjustment, model_size.y);
367 403
368 mHAdjustment.changed(); 404 mHAdjustment.changed;
369 mHAdjustment.valueChanged(); 405 mHAdjustment.valueChanged;
370 mVAdjustment.changed(); 406 mVAdjustment.changed;
371 mVAdjustment.valueChanged(); 407 mVAdjustment.valueChanged;
372 } 408 }
373 409
374 double clamp_zoom(double zoom) { return clamp(zoom, 0.02, 50.0); } 410 double clamp_zoom(double zoom) { return clamp(zoom, 0.02, 50.0); }
375
376 EventHandler mEventHandler;
377 411
378 // Model units are in millimetres 412 // Model units are in millimetres
379 // Screen units are in pixels 413 // Screen units are in pixels
380 414
381 double mZoom; // pixels-per-model-unit (mm) 415 double mZoom; // pixels-per-model-unit (mm)
395 Adjustment mVAdjustment; 429 Adjustment mVAdjustment;
396 VScrollbar mVScrollbar; 430 VScrollbar mVScrollbar;
397 431
398 // Layers: 432 // Layers:
399 Layer[] mLayers; 433 Layer[] mLayers;
434 EventHandler mEventHandler;
435 double mPPI;
400 } 436 }
401 } 437 }