# HG changeset patch # User daveb # Date 1281679084 -34200 # Node ID 31d10176415d2b796f134d49806346f9e19d56c9 # Parent 43cc2135ced0f89cc18f50c5e5807b48538abd63 Checkpoint diff -r 43cc2135ced0 -r 31d10176415d doodle/core/misc.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doodle/core/misc.d Fri Aug 13 15:28:04 2010 +0930 @@ -0,0 +1,20 @@ +module doodle.core.misc; + +// Basic routines. +// Note, most of these are probably provided by phobos. + +double min(in double a, in double b) { + return a < b ? a : b; +} + +double max(in double a, in double b) { + return a > b ? a : b; +} + +double clamp(in double v, in double min, in double max) { + assert(min < max); + + if (v < min) { return min; } + else if (v > max) { return max; } + else { return v; } +} diff -r 43cc2135ced0 -r 31d10176415d doodle/dia/icanvas.d --- a/doodle/dia/icanvas.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/dia/icanvas.d Fri Aug 13 15:28:04 2010 +0930 @@ -21,19 +21,12 @@ // FIXME get rid of these and accumulate damage during event handling void damageModel(in Rectangle area); // FIXME could be an inout parameter of the event handling, or a special scope Damage object that supports growth only void damagePixel(in Rectangle area); // FIXME as above +} - /* - // FIXME hoping we won't need anything like this - double zoom() const; - Point modelToPixel(in Point model) const; - Point pixelToModel(in Point pixel) const; - Vector modelToPixel(in Vector model) const; - Vector pixelToModel(in Vector pixel) const; - Rectangle modelToPixel(in Rectangle model) const; - Rectangle pixelToModel(in Rectangle model) const; - double modelToPixel(in double model) const; - double pixelToModel(in double pixel) const; - */ +final class Damage { + void increase(in Rectangle additional) { _rectangle = _rectangle | additional; } + Rectangle rectangle() const { return _rectangle; } + private Rectangle _rectangle; } interface IEventHandler { diff -r 43cc2135ced0 -r 31d10176415d doodle/fig/diagram_elements.d --- a/doodle/fig/diagram_elements.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/fig/diagram_elements.d Fri Aug 13 15:28:04 2010 +0930 @@ -34,10 +34,10 @@ class GraphConnector { } -class GraphNode : GraphElement { +final class GraphNode : GraphElement { } -class GraphEdge : GraphElement { +final class GraphEdge : GraphElement { private { GraphConnector[2] _anchors; } @@ -63,7 +63,7 @@ } */ -class RectanglePrimitive : GraphicPrimitive { +final class RectanglePrimitive : GraphicPrimitive { override void draw(in Rectangle damage, scope Context cr) const { rectangle(cr, bounds); } diff -r 43cc2135ced0 -r 31d10176415d doodle/fig/diagram_layer.d --- a/doodle/fig/diagram_layer.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/fig/diagram_layer.d Fri Aug 13 15:28:04 2010 +0930 @@ -11,7 +11,7 @@ super(name); } - // IDiagram overrides + // IDiagram overrides: void add(DiagramElement element) { _elements ~= element; diff -r 43cc2135ced0 -r 31d10176415d doodle/gtk/canvas.d --- a/doodle/gtk/canvas.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/gtk/canvas.d Fri Aug 13 15:28:04 2010 +0930 @@ -6,10 +6,10 @@ } private { + import doodle.core.misc; import doodle.core.logging; + import doodle.cairo.routines; import doodle.gtk.conversions; - import doodle.tk.misc; - import doodle.cairo.routines; import cairo.Surface; @@ -131,7 +131,7 @@ // value, lower, upper, step-inc, page-inc, page-size // Give the adjustments dummy values until we receive a configure _hAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5); - _hAdjustment.addOnValueChanged(&onValueChanged); + _hAdjustment.addOnValueChanged(&onAdjustmentValueChanged); _hScrollbar = new HScrollbar(_hAdjustment); _hScrollbar.setInverted(false); attach(_hScrollbar, @@ -142,7 +142,7 @@ 0, 0); _vAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5); - _vAdjustment.addOnValueChanged(&onValueChanged); + _vAdjustment.addOnValueChanged(&onAdjustmentValueChanged); _vScrollbar = new VScrollbar(_vAdjustment); _vScrollbar.setInverted(true); attach(_vScrollbar, @@ -219,7 +219,7 @@ void initialiseBounds() { Rectangle layerBounds = Rectangle.DEFAULT; - foreach (ref layer; _layers) { + foreach (layer; _layers) { layerBounds = layerBounds | layer.bounds; } @@ -245,7 +245,7 @@ void consolidateBounds() { Rectangle layerBounds = Rectangle.DEFAULT; - foreach (ref layer; _layers) { + foreach (layer; _layers) { layerBounds = layerBounds | layer.bounds; } @@ -300,41 +300,38 @@ //trace("Pixel damage: %s, model damage: %s", pixelDamage, modelDamage); modelCr.save; pixelCr.save; { - // Setup model context and clip + { + // Setup model context and clip + modelCr.translate(0.0, _viewSize.y); + modelCr.scale(_zoom, -_zoom); - GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct; - GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct; - - modelCr.scale(_zoom, -_zoom); - modelCr.translate(-gtk_adjustment_get_value(hGtkAdjustment), - -gtk_adjustment_get_value(vGtkAdjustment) - gtk_adjustment_get_page_size(vGtkAdjustment)); + immutable Vector modelSize = pixelToModel(_viewSize); + immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; + modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y); - rectangle(modelCr, modelDamage); - modelCr.clip; - - // Setup pixel context and clip + rectangle(modelCr, modelDamage); + modelCr.clip; + } - pixelCr.translate(0.0, _viewSize.y); - pixelCr.scale(1.0, -1.0); + { + // Setup pixel context and clip + pixelCr.translate(0.0, _viewSize.y); + pixelCr.scale(1.0, -1.0); - rectangle(pixelCr, pixelDamage); - pixelCr.clip; - - // Fill the background + rectangle(pixelCr, pixelDamage); + pixelCr.clip; + } pixelCr.save; { - // Make the window light grey + // Fill the background with light grey pixelCr.setSourceRgba(0.9, 0.9, 0.9, 1.0); rectangle(pixelCr, pixelDamage); pixelCr.fill; } pixelCr.restore; // Draw each layer - - foreach(ref layer; _layers) { - modelCr.save; pixelCr.save; { - layer.draw(this, pixelDamage, pixelCr, modelDamage, modelCr); - } pixelCr.restore; modelCr.restore; + foreach(layer; _layers) { + layer.draw(this, pixelDamage, pixelCr, modelDamage, modelCr); } } pixelCr.restore; modelCr.restore; @@ -393,7 +390,7 @@ ushort hardwareKeycode; ubyte group; uint bitfield0; - //uint isModifier : 1; + uint isModifier : 1; } */ bool onKeyPressEvent(GdkEventKey * event, Widget widget) { @@ -565,27 +562,23 @@ trace("onGrabNotify"); } - void onValueChanged(Adjustment adjustment) { + void onAdjustmentValueChanged(Adjustment adjustment) { GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct; GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct; - Point viewLeftTop = Point(gtk_adjustment_get_value(hGtkAdjustment), - gtk_adjustment_get_value(vGtkAdjustment)); + Point viewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment), + gtk_adjustment_get_value(vGtkAdjustment)); Vector modelSize = pixelToModel(_viewSize); - //writefln("%s", viewLeftBottom); - _viewCentre = viewLeftTop + modelSize / 2.0; - //writefln("onValueChanged _viewCentre: %s", _viewCentre); + _viewCentre = viewLeftBottom + modelSize / 2.0; updateRulers; - queueDraw; } void updateRulers() { immutable Vector modelSize = pixelToModel(_viewSize); - immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; immutable Point viewRightTop = _viewCentre + modelSize / 2.0; @@ -608,7 +601,6 @@ void updateAdjustments() { immutable Vector modelSize = pixelToModel(_viewSize); - immutable Point viewLeftBottom = _viewCentre - modelSize / 2.0; immutable Point viewRightTop = _viewCentre + modelSize / 2.0; @@ -685,8 +677,8 @@ bool _boundsValid; Rectangle _damage; // pixels - // Model units are in millimetres - // Screen units are in pixels + // Model units are millimetres + // Screen units are pixels double _zoom; // pixels-per-model-unit Vector _viewSize; // pixel: size of view window in pixels Point _viewCentre; // model: where in the model is the centre of our view diff -r 43cc2135ced0 -r 31d10176415d doodle/gtk/conversions.d --- a/doodle/gtk/conversions.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/gtk/conversions.d Fri Aug 13 15:28:04 2010 +0930 @@ -1,7 +1,7 @@ module doodle.gtk.conversions; public { - import doodle.tk.types; + import doodle.tk.events; } private { @@ -38,6 +38,7 @@ if (state & gdk.Event.GdkModifierType.CONTROL_MASK) modifiers ~= Modifier.CONTROL; if (state & gdk.Event.GdkModifierType.MOD1_MASK) modifiers ~= Modifier.ALT; if (state & gdk.Event.GdkModifierType.MOD2_MASK) modifiers ~= Modifier.META; + // Note, MOD 3-5 are currently omitted if (state & gdk.Event.GdkModifierType.BUTTON1_MASK) modifiers ~= Modifier.LEFT_BUTTON; if (state & gdk.Event.GdkModifierType.BUTTON2_MASK) modifiers ~= Modifier.MIDDLE_BUTTON; if (state & gdk.Event.GdkModifierType.BUTTON3_MASK) modifiers ~= Modifier.RIGHT_BUTTON; diff -r 43cc2135ced0 -r 31d10176415d doodle/tk/events.d --- a/doodle/tk/events.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/tk/events.d Fri Aug 13 15:28:04 2010 +0930 @@ -1,10 +1,61 @@ module doodle.tk.events; public { - import doodle.tk.types; import doodle.tk.geometry; } +private { + import std.typecons; +} + +mixin(defineEnum!("ButtonAction", + "SINGLE_PRESS", "DOUBLE_PRESS", "TRIPLE_PRESS", "RELEASE")); + +mixin(defineEnum!("ButtonName", + "LEFT", "MIDDLE", "RIGHT", "FOUR", "FIVE")); + +mixin(defineEnum!("ScrollDirection", + "UP", "DOWN", "LEFT", "RIGHT")); + +mixin(defineEnum!("Modifier", + "SHIFT", "CAPS_LOCK", "CONTROL", "ALT", "NUM_LOCK", "META", + "SCROLL_LOCK", "LEFT_BUTTON", "MIDDLE_BUTTON", "RIGHT_BUTTON", + "UNUSED_BUTTON_1", "UNUSED_BUTTON_2")); + +mixin(defineEnum!("CrossingMode", // FIXME what to do about GRAB2/UNGRAB2 + "NORMAL", "GRAB", "UNGRAB", "GRAB2", "UNGRAB2", "STATE_CHANGED")); + +struct Mask { + this(in Modifier[] modifiers) { + foreach (m; modifiers) { + _bits |= 1 << m; + } + } + + string toString() { + if (_bits == 0) { + return ""; + } + else { + string s = ""; + + for (int i = 0; i < _bits.sizeof * 8; ++i) { + if (_bits & (1 << i)) { + if (s.length != 0) s ~= "|"; + s ~= enumToString(cast(Modifier)i); + } + } + + return s; + } + } + + bool isSet(in Modifier m) const { return _bits & (1 << m); } + bool isUnset(in Modifier m) const { return !isSet(m); } + + private immutable ushort _bits; +} + // FIXME // Do we need FocusEvent. Note, it has no mask. // Hence would need to refactor hierarchy slightly, eg InputEvent diff -r 43cc2135ced0 -r 31d10176415d doodle/tk/geometry.d --- a/doodle/tk/geometry.d Thu Aug 12 22:43:42 2010 +0930 +++ b/doodle/tk/geometry.d Fri Aug 13 15:28:04 2010 +0930 @@ -3,7 +3,7 @@ private { import std.stdio; import std.math; - import doodle.tk.misc; + import doodle.core.misc; import doodle.core.logging; } @@ -397,7 +397,7 @@ if (computeIntersection(pa1, pa2, ua, pb1, pb2, ub)) { if (ua >= 0.0 && ua <= 1.0 && // inside of segment a ub >= 0.0 && ub <= 1.0) { // inside of segment b - // We could just have easily evaluated for line b... + // We could just as easily evaluated for line b... p = pa1 + ua * (pa2 - pa1); // p = pa2 + ub * (pb2 - pb1); return true; @@ -422,7 +422,7 @@ if (computeIntersection(pa1, pa2, ua, pb, pb + vb, ub)) { if (ua >= 0.0 && ua <= 1.0) { // inside of segment - // We could just have easily evaluated for line b... + // We could just as easily evaluated for line b... p = pa1 + ua * (pa2 - pa1); // p = pb + ub * vb; return true; diff -r 43cc2135ced0 -r 31d10176415d doodle/tk/misc.d --- a/doodle/tk/misc.d Thu Aug 12 22:43:42 2010 +0930 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -module doodle.tk.misc; - -// TODO move this to core - -double min(in double a, in double b) { - return a < b ? a : b; -} - -double max(in double a, in double b) { - return a > b ? a : b; -} - -double clamp(in double v, in double min, in double max) { - assert(min < max); - - if (v < min) { return min; } - else if (v > max) { return max; } - else { return v; } -} diff -r 43cc2135ced0 -r 31d10176415d doodle/tk/types.d --- a/doodle/tk/types.d Thu Aug 12 22:43:42 2010 +0930 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -module doodle.tk.types; - -public { - import std.string; -} - -private { - import std.typecons; - import std.algorithm; -} - -mixin(defineEnum!("ButtonAction", - "SINGLE_PRESS", "DOUBLE_PRESS", "TRIPLE_PRESS", "RELEASE")); - -mixin(defineEnum!("ButtonName", - "LEFT", "MIDDLE", "RIGHT", "FOUR", "FIVE")); - -mixin(defineEnum!("ScrollDirection", - "UP", "DOWN", "LEFT", "RIGHT")); - -mixin(defineEnum!("Modifier", - "SHIFT", "CAPS_LOCK", "CONTROL", "ALT", "NUM_LOCK", "META", - "SCROLL_LOCK", "LEFT_BUTTON", "MIDDLE_BUTTON", "RIGHT_BUTTON", - "UNUSED_BUTTON_1", "UNUSED_BUTTON_2")); - -mixin(defineEnum!("CrossingMode", // FIXME what to do about GRAB2/UNGRAB2 - "NORMAL", "GRAB", "UNGRAB", "GRAB2", "UNGRAB2", "STATE_CHANGED")); - -struct Mask { - this(in Modifier[] modifiers) { - foreach (ref m; modifiers) { - _bits |= 1 << m; - } - } - - string toString() { - string s = ""; - - // FIXME this is terrible - for (int i = 0; i < uint.sizeof * 8; ++i) { - if (_bits & (1 << i)) { - if (s.length != 0) s ~= "|"; - s ~= enumToString(cast(Modifier)i); - } - } - - return s; - } - - bool isSet(in Modifier m) const { - return _bits & (1 << m); - } - - bool isUnset(in Modifier m) const { - return !isSet(m); - } - - private { - uint _bits; - } -}