Mercurial > projects > doodle
diff doodle/gtk/canvas.d @ 70:0e61702c6ea6
Checkpoint
author | "David Bryant <bagnose@gmail.com>" |
---|---|
date | Sat, 14 Aug 2010 20:05:55 +0930 |
parents | d540f7e4af9e |
children | 0f7cf6c6f206 |
line wrap: on
line diff
--- a/doodle/gtk/canvas.d Sat Aug 14 19:39:58 2010 +0930 +++ b/doodle/gtk/canvas.d Sat Aug 14 20:05:55 2010 +0930 @@ -37,18 +37,6 @@ } // x and y run right and up respectively -// -// Model units are millimetres. -// -// _zoom -> pixels-per-model-unit -// _viewSize -> size of view window in pixels -// _viewCentre -> location in model corresponding to centre of view -// _canvasBounds -> size of the virtual canvas in model coordinates -// -// User operations: -// pan (middle click and drag) -// zoom about a point (hold control and move scroll wheel) -// resize the widget final class Canvas : Table, private IViewport { this(in Layer[] layers, IEventHandler eventHandler, IGrid grid, in double pixelsPerMillimetre) { @@ -213,21 +201,23 @@ private { - void initialiseBounds() { - Rectangle layerBounds = Rectangle.DEFAULT; + Rectangle layerBounds() { + Rectangle bounds = Rectangle.DEFAULT; + foreach (layer; _layers) { bounds = bounds | layer.bounds; } + assert(bounds.valid); + return bounds; + } - foreach (layer; _layers) { - layerBounds = layerBounds | layer.bounds; - } - - assert(layerBounds.valid); + void initialiseBounds() { + Rectangle lb = layerBounds; // FIXME use a function that grows a rectangle about its centre // and change 2.0 to a class-level constant - Rectangle paddedLayerBounds = expand(move(layerBounds, - layerBounds.size), 2.0 * layerBounds.size); + Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size); // + // FIXME 0.25 _zoom = 0.25 * _pixelsPerMillimetre; // ie 0.25 pixels represents a millimetre _canvasBounds = paddedLayerBounds; @@ -240,18 +230,12 @@ } void consolidateBounds() { - Rectangle layerBounds = Rectangle.DEFAULT; - - foreach (layer; _layers) { - layerBounds = layerBounds | layer.bounds; - } + Rectangle lb = layerBounds; - assert(layerBounds.valid); + // FIXME likewise as above + Rectangle paddedLayerBounds = expand(move(lb, - lb.size), 2.0 * lb.size); - Rectangle paddedLayerBounds = expand(move(layerBounds, - layerBounds.size), 2.0 * layerBounds.size); - - Vector z = _viewSize / _zoom; - Rectangle r = Rectangle(_viewCentre - z / 2.0, z); + Rectangle r = pixelToModel(_viewBounds); _canvasBounds = r | paddedLayerBounds; updateAdjustments; @@ -261,7 +245,7 @@ bool onConfigure(GdkEventConfigure * event, Widget widget) { assert(widget is _drawingArea); - _viewSize = Vector(cast(double)event.width, cast(double)event.height); + _viewBounds = Rectangle(Point(0.0, 0.0), Vector(cast(double)event.width, cast(double)event.height)); if (!_boundsValid) { initialiseBounds; @@ -288,8 +272,8 @@ Rectangle pixelDamage = event is null ? - Rectangle(Point(0.0, 0.0), _viewSize) : - Rectangle(Point(cast(double)event.area.x, _viewSize.y - cast(double)(event.area.y + event.area.height)), + _viewBounds : // XXX can we do something nice with the next line? + Rectangle(_viewBounds.position + Vector(cast(double)event.area.x, _viewBounds.h - cast(double)(event.area.y + event.area.height)), Vector(cast(double)event.area.width, cast(double)event.area.height)); Rectangle modelDamage = pixelToModel(pixelDamage); @@ -299,10 +283,11 @@ modelCr.save; pixelCr.save; { { // Setup model context and clip - modelCr.translate(0.0, _viewSize.y); + modelCr.translate(0.0, _viewBounds.h); modelCr.scale(_zoom, -_zoom); - immutable Vector modelSize = pixelToModel(_viewSize); + // XXX revisit + immutable Vector modelSize = pixelToModel(_viewBounds.size); immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y); @@ -312,7 +297,7 @@ { // Setup pixel context and clip - pixelCr.translate(0.0, _viewSize.y); + pixelCr.translate(0.0, _viewBounds.h); pixelCr.scale(1.0, -1.0); rectangle(pixelCr, pixelDamage); @@ -339,7 +324,7 @@ assert(widget is _drawingArea); //trace("Got button event\n"); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto buttonEvent = new ButtonEvent(gtk2tkButtonAction(event.type), @@ -358,7 +343,7 @@ bool onButtonRelease(GdkEventButton * event, Widget widget) { assert(widget is _drawingArea); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto buttonEvent = new ButtonEvent(gtk2tkButtonAction(event.type), @@ -424,7 +409,7 @@ gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event); gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto motionEvent = new MotionEvent(pixelPoint, @@ -442,7 +427,7 @@ assert(widget is _drawingArea); //writefln("Got scroll\n"); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto scrollEvent = new ScrollEvent(gtk2tkDirection(event.direction), @@ -487,7 +472,7 @@ bool onEnterNotify(GdkEventCrossing * event, Widget widget) { assert(widget is _drawingArea); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode), @@ -507,7 +492,7 @@ bool onLeaveNotify(GdkEventCrossing * event, Widget widget) { assert(widget is _drawingArea); - Point pixelPoint = Point(event.x + 0.5, _viewSize.y - (event.y + 0.5)); + Point pixelPoint = Point(event.x + 0.5, _viewBounds.h - (event.y + 0.5)); Point modelPoint = pixelToModel(pixelPoint); auto crossingEvent = new CrossingEvent(gtk2tkCrossingMode(event.mode), @@ -566,7 +551,7 @@ Point viewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment), gtk_adjustment_get_value(vGtkAdjustment)); - Vector modelSize = pixelToModel(_viewSize); + Vector modelSize = pixelToModel(_viewBounds.size); // XXX _viewCentre = viewLeftBottom + modelSize / 2.0; @@ -575,7 +560,7 @@ } void updateRulers() { - immutable Vector modelSize = pixelToModel(_viewSize); + immutable Vector modelSize = pixelToModel(_viewBounds.size); // XXX immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; immutable Point viewRightTop = _viewCentre + modelSize / 2.0; @@ -597,28 +582,28 @@ } void updateAdjustments() { - immutable Vector modelSize = pixelToModel(_viewSize); + immutable Vector modelSize = pixelToModel(_viewBounds.size); // XXX immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; immutable Point viewRightTop = _viewCentre + modelSize / 2.0; // Adjust the canvas size if necessary - _canvasBounds = Rectangle(minExtents(_canvasBounds.minCorner, viewLeftBottom), - maxExtents(_canvasBounds.maxCorner, viewRightTop)); + _canvasBounds = Rectangle(minExtents(_canvasBounds.corner0, viewLeftBottom), + maxExtents(_canvasBounds.corner1, viewRightTop)); // Update the adjustments GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct; GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct; - gtk_adjustment_set_lower(hGtkAdjustment, _canvasBounds.minCorner.x); - gtk_adjustment_set_upper(hGtkAdjustment, _canvasBounds.maxCorner.x); + gtk_adjustment_set_lower(hGtkAdjustment, _canvasBounds.corner0.x); + gtk_adjustment_set_upper(hGtkAdjustment, _canvasBounds.corner1.x); gtk_adjustment_set_value(hGtkAdjustment, viewLeftBottom.x); gtk_adjustment_set_step_increment(hGtkAdjustment, _canvasBounds.size.x / 16.0); gtk_adjustment_set_page_increment(hGtkAdjustment, _canvasBounds.size.x / 4.0); gtk_adjustment_set_page_size(hGtkAdjustment, modelSize.x); - gtk_adjustment_set_lower(vGtkAdjustment, _canvasBounds.minCorner.y); - gtk_adjustment_set_upper(vGtkAdjustment, _canvasBounds.maxCorner.y); + gtk_adjustment_set_lower(vGtkAdjustment, _canvasBounds.corner0.y); + gtk_adjustment_set_upper(vGtkAdjustment, _canvasBounds.corner1.y); gtk_adjustment_set_value(vGtkAdjustment, viewLeftBottom.y); gtk_adjustment_set_step_increment(vGtkAdjustment, _canvasBounds.size.y / 16.0); gtk_adjustment_set_page_increment(vGtkAdjustment, _canvasBounds.size.y / 4.0); @@ -634,7 +619,7 @@ if (_damage.valid) { int x, y, w, h; _damage.getQuantised(x, y, w, h); - _drawingArea.queueDrawArea(x, cast(int)_viewSize.y - (y + h), w, h); + _drawingArea.queueDrawArea(x, cast(int)_viewBounds.h - (y + h), w, h); _damage = Rectangle.DEFAULT; } } @@ -642,11 +627,11 @@ static double clampZoom(in double zoom) { return clamp(zoom, 0.2, 10.0); } Point modelToPixel(in Point model) const { - return Point.DEFAULT + _viewSize / 2.0 + _zoom * (model - _viewCentre); + return _viewBounds.centre + _zoom * (model - _viewCentre); } Point pixelToModel(in Point pixel) const { - return _viewCentre + (pixel - _viewSize / 2.0 - Point.DEFAULT) / _zoom; + return _viewCentre + (pixel - _viewBounds.centre) / _zoom; } Vector modelToPixel(in Vector model) const { @@ -677,9 +662,9 @@ // Model units are millimetres // Screen units are pixels double _zoom; // pixels-per-model-unit - Vector _viewSize; // pixel: size of view window in pixels + Rectangle _viewBounds; // pixel: bounds of the viewport in pixels Point _viewCentre; // model: where in the model is the centre of our view - Rectangle _canvasBounds; // model: + Rectangle _canvasBounds; // model: bounds of the canvas in millimetres // Child widgets: HRuler _hRuler;