changeset 16:9e63308b749c

* Fix up public/private includes * Make Mask a struct
author David Bryant <daveb@acres.com.au>
date Mon, 13 Jul 2009 16:16:17 +0930
parents 2f79aab4d385
children c643c04e3f5e
files cairo_support.d canvas.d grid_layer.d gui.d icanvas.d page_layer.d standard_tools.d tk/events.d tk/geometry.d tk/gtk_support.d tk/types.d tool.d tool_layer.d
diffstat 13 files changed, 260 insertions(+), 213 deletions(-) [+]
line wrap: on
line diff
--- a/cairo_support.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/cairo_support.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,8 +1,9 @@
 module cairo_support;
 
-import tk.geometry;
-
-import cairo.Context;
+public {
+    import tk.geometry;
+    import cairo.Context;
+}
 
 void rectangle(Context cr, Rectangle rectangle) {
     cr.rectangle(rectangle.position.x, rectangle.position.y,
--- a/canvas.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/canvas.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,34 +1,36 @@
 module canvas;
 
-import std.stdio;
-import std.math;
+public {
+    import icanvas;
+    import tk.geometry;
+    import tk.events;
+}
 
-import cairo.Context;
-import cairo.Surface;
+private {
+    import tk.gtk_support;
+    import tk.misc;
 
-import gdk.Drawable;
+    import cairo.Surface;
+    import cairo_support;
+
+    import std.math;
+    import std.stdio;
 
-import gtk.Widget;
-import gtk.Toolbar;
-import gtk.Table;
-import gtk.HRuler;
-import gtk.VRuler;
-import gtk.Range;
-import gtk.HScrollbar;
-import gtk.VScrollbar;
-import gtk.DrawingArea;
-import gtk.Adjustment;
+    import gtk.Widget;
+    import gtk.Toolbar;
+    import gtk.Table;
+    import gtk.HRuler;
+    import gtk.VRuler;
+    import gtk.Range;
+    import gtk.HScrollbar;
+    import gtk.VScrollbar;
+    import gtk.DrawingArea;
+    import gtk.Adjustment;
 
-import tk.misc;
-import tk.geometry;
-import tk.types;
-import tk.events;
-import tk.gtk_support;
+    import gdk.Drawable;
 
-private import gtkc.gtk;
-
-import icanvas;
-import cairo_support;
+    import gtkc.gtk;
+}
 
 // x and y run right and up respectively
 
@@ -40,22 +42,11 @@
         mEventHandler = event_handler;
         mPPI = ppi;
 
-        const double MM_PER_INCH = 25.4;
-        mZoom = 0.25 * mPPI / MM_PER_INCH;
-
-        // Take the union of the bounds of each layer to
-        // determine the canvas size
-
-        Rectangle layer_bounds = Rectangle.DEFAULT;
-
-        foreach (ref layer; mLayers) {
-            layer_bounds = layer_bounds | layer.bounds;
-        }
-
-        assert(layer_bounds.valid);
-
-        mCanvasBounds = layer_bounds.moved(-layer_bounds.size).expanded(2.0 * layer_bounds.size);
-        mViewCentre = mCanvasBounds.centre;
+        /*
+        writefln("Layer bounds: %s", layer_bounds);
+        writefln("Canvas bounds: %s", mCanvasBounds);
+        writefln("View centre: %s", mViewCentre);
+        */
 
         // Create our child widgets and register callbacks
 
@@ -65,7 +56,7 @@
                0, 1,
                AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK,
                0, 0);
-        mHRuler.setMetric(GtkMetricType.CENTIMETERS);
+        mHRuler.setMetric(GtkMetricType.PIXELS);
 
         mVRuler = new VRuler;
         attach(mVRuler,
@@ -73,7 +64,7 @@
                1, 2,
                AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND,
                0, 0);
-        mVRuler.setMetric(GtkMetricType.CENTIMETERS);
+        mVRuler.setMetric(GtkMetricType.PIXELS);
 
         mDrawingArea = new DrawingArea;
         mDrawingArea.addOnRealize(&onRealize);
@@ -96,6 +87,7 @@
         mHAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
         mHAdjustment.addOnValueChanged(&onValueChanged);
         mHScrollbar = new HScrollbar(mHAdjustment);
+        mHScrollbar.setInverted(false);
         attach(mHScrollbar,
                1, 2,
                2, 3,
@@ -105,6 +97,7 @@
         mVAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
         mVAdjustment.addOnValueChanged(&onValueChanged);
         mVScrollbar = new VScrollbar(mVAdjustment);
+        mVScrollbar.setInverted(true);
         attach(mVScrollbar,
                2, 3,
                1, 2,
@@ -113,26 +106,23 @@
                0, 0);
     }
 
-    override void rel_zoom(Point screen_datum, double factor) {
+    override void rel_zoom(Point pixel_datum, double factor) {
         // Work out pixel distance from current centre to datum,
         // Do the zoom, then work out the new centre that keeps the
         // pixel distance the same
 
-        Point old_model_datum = screen_to_model(screen_datum);
-        Vector pixel_distance = model_to_screen(old_model_datum - mViewCentre);
+        Point old_model_datum = pixel_to_model(pixel_datum);
+        Vector pixel_distance = model_to_pixel(old_model_datum - mViewCentre);
         mZoom = clamp_zoom(factor * mZoom);
-        mViewCentre = old_model_datum - screen_to_model(pixel_distance);
-
-        //Point new_model_datum = screen_to_model(screen_datum);
+        mViewCentre = old_model_datum - pixel_to_model(pixel_distance);
 
         update_adjustments;
-        //update_rulers(new_model_datum);
         update_rulers;
         queueDraw;
     }
 
-    override void rel_pan(Vector screen_displacement) {
-        mViewCentre = mViewCentre + screen_to_model(screen_displacement);
+    override void rel_pan(Vector pixel_displacement) {
+        mViewCentre = mViewCentre + pixel_to_model(pixel_displacement);
 
         update_adjustments;
         update_rulers;
@@ -143,36 +133,36 @@
         return mZoom;
     }
 
-    override Point model_to_screen(Point model) const {
+    override Point model_to_pixel(Point model) const {
         return Point.DEFAULT + mViewSize / 2.0 + mZoom * (model - mViewCentre);
     }
 
-    override Point screen_to_model(Point screen) const {
-        return mViewCentre + (screen - mViewSize / 2.0 - Point.DEFAULT) / mZoom;
+    override Point pixel_to_model(Point pixel) const {
+        return mViewCentre + (pixel - mViewSize / 2.0 - Point.DEFAULT) / mZoom;
     }
 
-    override Vector model_to_screen(Vector model) const {
+    override Vector model_to_pixel(Vector model) const {
         return mZoom * model;
     }
 
-    override Vector screen_to_model(Vector screen) const {
-        return screen / mZoom;
+    override Vector pixel_to_model(Vector pixel) const {
+        return pixel / mZoom;
     }
 
-    override double model_to_screen(double model) const {
+    override double model_to_pixel(double model) const {
         return mZoom * model;
     }
 
-    override double screen_to_model(double screen) const {
-        return screen / mZoom;
+    override double pixel_to_model(double pixel) const {
+        return pixel / mZoom;
     }
 
-    override Rectangle model_to_screen(Rectangle model) const {
-        return Rectangle(model_to_screen(model.position), model_to_screen(model.size));
+    override Rectangle model_to_pixel(Rectangle model) const {
+        return Rectangle(model_to_pixel(model.position), model_to_pixel(model.size));
     }
 
-    override Rectangle screen_to_model(Rectangle model) const {
-        return Rectangle(screen_to_model(model.position), screen_to_model(model.size));
+    override Rectangle pixel_to_model(Rectangle model) const {
+        return Rectangle(pixel_to_model(model.position), pixel_to_model(model.size));
     }
 
     private {
@@ -185,10 +175,34 @@
         bool onConfigure(GdkEventConfigure * event, Widget widget) {
             assert(widget is mDrawingArea);
 
+            if (!mHadConfigure) {
+                const double MM_PER_INCH = 25.4;
+                mZoom = 0.25 * mPPI / MM_PER_INCH;
+
+                // Take the union of the bounds of each layer to
+                // determine the canvas size
+
+                Rectangle layer_bounds = Rectangle.DEFAULT;
+
+                foreach (ref layer; mLayers) {
+                    layer_bounds = layer_bounds | layer.bounds;
+                }
+
+                assert(layer_bounds.valid);
+
+                mCanvasBounds = layer_bounds.moved(-layer_bounds.size).expanded(2.0 * layer_bounds.size);
+                mViewCentre = mCanvasBounds.centre;
+
+                mHadConfigure = true;
+            }
+
             mViewSize = Vector(cast(double)event.width, cast(double)event.height);
             update_adjustments;
             update_rulers;
 
+            //writefln("Canvas bounds: %s", mCanvasBounds);
+            //writefln("View centre: %s", mViewCentre);
+
             return true;
         }
 
@@ -202,7 +216,7 @@
             //writefln("Got expose %dx%d\n", width, height);
 
             scope model_cr = new Context(dr);
-            scope screen_cr = new Context(dr);
+            scope pixel_cr = new Context(dr);
 
             Rectangle damage =
                 event is null ?
@@ -210,43 +224,43 @@
                 Rectangle(Point(cast(double)event.area.x, cast(double)event.area.y),
                           Vector(cast(double)event.area.width, cast(double)event.area.height));
 
-            model_cr.save; screen_cr.save; {
+            model_cr.save; pixel_cr.save; {
                 // Setup model context
 
                 rectangle(model_cr, damage);
                 model_cr.clip;
 
-                GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct();
-                GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct();
+                GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct;
+                GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct;
 
-                model_cr.translate(mCanvasBounds.min_corner.x - gtk_adjustment_get_value(h_gtkAdjustment),
-                                   mCanvasBounds.min_corner.y - gtk_adjustment_get_value(v_gtkAdjustment));
                 model_cr.scale(mZoom, -mZoom);
+                model_cr.translate(-gtk_adjustment_get_value(h_gtkAdjustment),
+                                   -gtk_adjustment_get_value(v_gtkAdjustment) - gtk_adjustment_get_page_size(v_gtkAdjustment));
 
-                // Setup screen context
+                // Setup pixel context
 
-                screen_cr.translate(0.0, mViewSize.y);
-                screen_cr.scale(1.0, -1.0);
-                rectangle(screen_cr, damage);
-                screen_cr.clip;
+                pixel_cr.translate(0.0, mViewSize.y);
+                pixel_cr.scale(1.0, -1.0);
+                rectangle(pixel_cr, damage);
+                pixel_cr.clip;
 
                 // Fill the background
 
-                screen_cr.save; {
+                pixel_cr.save; {
                     // Make the window light grey
-                    screen_cr.setSourceRgba(1.0, 1.0, 1.0, 0.7);
-                    rectangle(screen_cr, damage);
-                    screen_cr.fill;
-                } screen_cr.restore;
+                    pixel_cr.setSourceRgba(1.0, 1.0, 1.0, 0.7);
+                    rectangle(pixel_cr, damage);
+                    pixel_cr.fill;
+                } pixel_cr.restore;
 
                 // Draw each layer
 
                 foreach(ref layer; mLayers) {
-                    model_cr.save; screen_cr.save; {
-                        layer.draw(this, damage, model_cr, screen_cr);
-                    } screen_cr.restore; model_cr.restore;
+                    model_cr.save; pixel_cr.save; {
+                        layer.draw(this, damage, model_cr, pixel_cr);
+                    } pixel_cr.restore; model_cr.restore;
                 }
-            } screen_cr.restore; model_cr.restore;
+            } pixel_cr.restore; model_cr.restore;
 
             return true;
         }
@@ -255,12 +269,12 @@
             assert(widget is mDrawingArea);
             //writefln("Got button event\n");
 
-            Point screen_point = Point(event.x + 0.5, event.y + 0.5);
-            Point model_point = screen_to_model(screen_point);
+            Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5));
+            Point model_point = pixel_to_model(pixel_point);
 
             auto button_event = new ButtonEvent(gtk2tk_button_action(event.type),
                                                 gtk2tk_button_name(event.button),
-                                                screen_point,
+                                                pixel_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
 
@@ -273,12 +287,12 @@
             assert(widget is mDrawingArea);
             //writefln("Got button event\n");
 
-            Point screen_point = Point(event.x + 0.5, event.y + 0.5);
-            Point model_point = screen_to_model(screen_point);
+            Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5));
+            Point model_point = pixel_to_model(pixel_point);
 
             auto button_event = new ButtonEvent(gtk2tk_button_action(event.type),
                                                 gtk2tk_button_name(event.button),
-                                                screen_point,
+                                                pixel_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
 
@@ -303,10 +317,10 @@
             gtk_widget_event(mHRuler.getWidgetStruct(), cast(GdkEvent *)event);
             gtk_widget_event(mVRuler.getWidgetStruct(), cast(GdkEvent *)event);
 
-            Point screen_point = Point(event.x + 0.5, event.y + 0.5);
-            Point model_point = screen_to_model(screen_point);
+            Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5));
+            Point model_point = pixel_to_model(pixel_point);
 
-            auto motion_event = new MotionEvent(screen_point,
+            auto motion_event = new MotionEvent(pixel_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
 
@@ -319,11 +333,11 @@
             assert(widget is mDrawingArea);
             //writefln("Got scroll\n");
 
-            Point screen_point = Point(event.x + 0.5, event.y + 0.5);
-            Point model_point = screen_to_model(screen_point);
+            Point pixel_point = Point(event.x + 0.5, mViewSize.y - (event.y + 0.5));
+            Point model_point = pixel_to_model(pixel_point);
 
             auto scroll_event = new ScrollEvent(gtk2tk_direction(event.direction),
-                                                screen_point,
+                                                pixel_point,
                                                 model_point,
                                                 gtk2tk_mask(event.state));
 
@@ -336,11 +350,14 @@
             GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct;
             GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct;
 
-            Point view_left_bottom = Point(gtk_adjustment_get_value(h_gtkAdjustment),
-                                           gtk_adjustment_get_value(v_gtkAdjustment));
+            Point view_left_top = Point(gtk_adjustment_get_value(h_gtkAdjustment),
+                                        gtk_adjustment_get_value(v_gtkAdjustment));
+
+            Vector model_size = pixel_to_model(mViewSize);
+
             //writefln("%s", view_left_bottom);
-            Vector model_size = screen_to_model(mViewSize);
-            mViewCentre = view_left_bottom + model_size / 2.0;
+            mViewCentre = view_left_top + model_size / 2.0;
+            writefln("onValueChanged mViewCentre: %s", mViewCentre);
 
             update_rulers;
 
@@ -348,28 +365,32 @@
         }
 
         void update_rulers() {
-            Vector model_size = screen_to_model(mViewSize);
+            Vector model_size = pixel_to_model(mViewSize);
 
             Point view_left_bottom = mViewCentre - model_size / 2.0;
             Point view_right_top = mViewCentre + model_size / 2.0;
 
+            // Define these just to obtain the position
+            // below and we can preserve it
             double lower, upper, position, max_size;
 
+
             mHRuler.getRange(lower, upper, position, max_size);
+            writefln("HRuler: %f %f %f", view_left_bottom.x, view_right_top.x, position);
             mHRuler.setRange(view_left_bottom.x,
                              view_right_top.x,
                              position,
-                             mZoom * 10.0);
+                             mZoom * 50.0);
 
             mVRuler.getRange(lower, upper, position, max_size);
             mVRuler.setRange(view_right_top.y,
                              view_left_bottom.y,
                              position,
-                             mZoom * 10.0);
+                             mZoom * 50.0);
         }
 
         void update_adjustments() {
-            Vector model_size = screen_to_model(mViewSize);
+            Vector model_size = pixel_to_model(mViewSize);
 
             Point view_left_bottom = mViewCentre - model_size / 2.0;
             Point view_right_top = mViewCentre + model_size / 2.0;
@@ -380,11 +401,11 @@
 
             // Update the adjustments
 
-            GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct();
-            GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct();
+            GtkAdjustment * h_gtkAdjustment = mHAdjustment.getAdjustmentStruct;
+            GtkAdjustment * v_gtkAdjustment = mVAdjustment.getAdjustmentStruct;
 
             gtk_adjustment_set_lower(h_gtkAdjustment, mCanvasBounds.min_corner.x);
-            gtk_adjustment_set_upper(h_gtkAdjustment, mCanvasBounds.max_corner.y);
+            gtk_adjustment_set_upper(h_gtkAdjustment, mCanvasBounds.max_corner.x);
             gtk_adjustment_set_value(h_gtkAdjustment, view_left_bottom.x);
             gtk_adjustment_set_step_increment(h_gtkAdjustment, mCanvasBounds.size.x / 16.0);
             gtk_adjustment_set_page_increment(h_gtkAdjustment, mCanvasBounds.size.x / 4.0);
@@ -403,15 +424,16 @@
             mVAdjustment.valueChanged;
         }
 
-        double clamp_zoom(double zoom) { return clamp(zoom, 0.02, 50.0); }
+        double clamp_zoom(double zoom) { return clamp(zoom, 0.2, 10.0); }
+
+        bool mHadConfigure;
 
         // Model units are in millimetres
         // Screen units are in pixels
-
         double mZoom;               // pixels-per-model-unit (mm)
+        Vector mViewSize;           // pixel: size of view window in pixels
         Point mViewCentre;          // model: where in the model is the centre of our view
         Rectangle mCanvasBounds;    // model:
-        Vector mViewSize;           // screen: size of view window in pixels
 
         // Child widgets:
         HRuler mHRuler;
--- a/grid_layer.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/grid_layer.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,3 +1,5 @@
+module grid_layer;
+
 import icanvas;
 import tk.geometry;
 import cairo.Context;
--- a/gui.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/gui.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,21 +1,16 @@
 module gui;
 
-import icanvas;
-import canvas;
-import tool_layer;
-import tool;
-import standard_tools;
-import page_layer;
+private {
+    import canvas;
+    import tool_layer;
+    import standard_tools;
+    import page_layer;
 
-import gtk.Main;
-import gtk.MainWindow;
+    import gtk.Main;
+    import gtk.MainWindow;
 
-import tk.geometry;
-import tk.types;
-import tk.events;
-
-import std.stdio;
-import tk.geometry;
+    import std.stdio;
+}
 
 void main(string[] args) {
     Main.init(args);
@@ -29,7 +24,7 @@
     layers ~= tool_layer;
     auto canvas = new Canvas(layers, tool_layer, 120.0);
     window.add(canvas);
-    window.setDefaultSize(380, 480);
+    window.setDefaultSize(380, 380);
     window.showAll();
     Main.run();
 
--- a/icanvas.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/icanvas.d	Mon Jul 13 16:16:17 2009 +0930
@@ -5,19 +5,19 @@
 import cairo.Context;
 
 interface Viewport {
-    void rel_zoom(Point screen_datum, double factor);
-    void rel_pan(Vector screen_displacement);
+    void rel_zoom(Point pixel_datum, double factor);
+    void rel_pan(Vector pixel_displacement);
     //void damage(Rectangle area);
 
     double zoom() const;
-    Point model_to_screen(Point model) const;
-    Point screen_to_model(Point screen) const;
-    Vector model_to_screen(Vector model) const;
-    Vector screen_to_model(Vector screen) const;
-    Rectangle model_to_screen(Rectangle model) const;
-    Rectangle screen_to_model(Rectangle model) const;
-    double model_to_screen(double model) const;
-    double screen_to_model(double screen) const;
+    Point model_to_pixel(Point model) const;
+    Point pixel_to_model(Point pixel) const;
+    Vector model_to_pixel(Vector model) const;
+    Vector pixel_to_model(Vector pixel) const;
+    Rectangle model_to_pixel(Rectangle model) const;
+    Rectangle pixel_to_model(Rectangle model) const;
+    double model_to_pixel(double model) const;
+    double pixel_to_model(double pixel) const;
 }
 
 interface EventHandler {
@@ -43,7 +43,7 @@
 
     Rectangle bounds() const;
     //void zoom_changed
-    void draw(const Viewport viewport, in Rectangle damage, Context model_cr, Context screen_cr) const;
+    void draw(const Viewport viewport, in Rectangle damage, Context model_cr, Context pixel_cr) const;
 
     private {
         invariant string mName;
--- a/page_layer.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/page_layer.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,6 +1,4 @@
 import icanvas;
-import tk.geometry;
-import cairo.Context;
 import cairo_support;
 
 interface Page {
@@ -9,8 +7,8 @@
 class PageLayer : Layer, Page {
     this(in string name) {
         super(name);
-        mPageGeometry = Rectangle(Point.DEFAULT,
-                                  Vector(210.0, 297.0));
+        mPageGeometry = Rectangle(Point.DEFAULT, Vector(210.0, 297.0));
+        //mPageGeometry = Rectangle(Point.DEFAULT, Vector(100.0, 100.0));
     }
 
     override Rectangle bounds() const {
@@ -18,28 +16,27 @@
     }
 
     override void draw(const Viewport viewport, in Rectangle damage,
-                       Context model_cr, Context screen_cr) const {
+                       Context model_cr, Context pixel_cr) const {
         // Make the paper white, with a border
 
-        /*
-        model_cr.setSourceRgba(1.0, 1.0, 1.0, 1.0);
+        model_cr.setSourceRgba(1.0, 0.5, 1.0, 0.5);
         rectangle(model_cr, mPageGeometry);
         model_cr.fill();
 
-        model_cr.setSourceRgba(0.0, 0.0, 0.0, 1.0);
+        model_cr.setSourceRgba(0.3, 0.0, 0.0, 0.5);
         rectangle(model_cr, mPageGeometry);
-        rectangle(model_cr, Rectangle(mPageGeometry.position, mPageGeometry.size / 2.0));
         model_cr.stroke();
-        */
 
-        screen_cr.setSourceRgba(1.0, 1.0, 1.0, 1.0);
-        rectangle(screen_cr, viewport.model_to_screen(mPageGeometry));
-        screen_cr.fill();
+        /*
+        pixel_cr.setSourceRgba(1.0, 1.0, 0.5, 0.4);
+        rectangle(pixel_cr, viewport.model_to_pixel(mPageGeometry));
+        pixel_cr.fill();
 
-        screen_cr.setSourceRgba(0.0, 0.0, 0.0, 1.0);
-        rectangle(screen_cr, viewport.model_to_screen(mPageGeometry));
-        rectangle(screen_cr, viewport.model_to_screen(Rectangle(mPageGeometry.position, mPageGeometry.size / 2.0)));
-        screen_cr.stroke();
+        pixel_cr.setSourceRgba(0.0, 0.3, 0.0, 0.4);
+        rectangle(pixel_cr, viewport.model_to_pixel(mPageGeometry));
+        //rectangle(pixel_cr, viewport.model_to_pixel(Rectangle(mPageGeometry.position, mPageGeometry.size / 2.0)));
+        pixel_cr.stroke();
+        */
     }
 
     private {
--- a/standard_tools.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/standard_tools.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,11 +1,12 @@
 module standard_tools;
 
-import tool;
-import icanvas;
-import tk.types;
-import tk.events;
-import tk.geometry;
-import std.math;
+public {
+    import tool;
+}
+
+private {
+    import std.math;
+}
 
 final class PanTool : Tool {
     bool handle_button_press(Viewport viewport, in ButtonEvent event) {
--- a/tk/events.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tk/events.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,14 +1,16 @@
 module tk.events;
 
-import tk.types;
-import tk.geometry;
+public {
+    import tk.types;
+    import tk.geometry;
+}
 
 abstract class Event {
-    this(Mask mask) {
+    this(in Mask mask) {
         mMask = mask;
     }
 
-    const(Mask) mask() const { return mMask; }
+    Mask mask() const { return mMask; }
 
     private {
         Mask mMask;
@@ -16,7 +18,7 @@
 }
 
 final class CrossingEvent : Event {
-    this(Mask mask) {
+    this(in Mask mask) {
         super(mask);
     }
 
@@ -25,7 +27,7 @@
 }
 
 final class KeyEvent : Event {
-    this(string str, uint value, Mask mask) {
+    this(in string str, in uint value, in Mask mask) {
         super(mask);
         mStr = str;
         mValue = value;
@@ -44,7 +46,7 @@
 }
 
 abstract class PointerEvent : Event {
-    this(in Point screen_point, in Point model_point, Mask mask) {
+    this(in Point screen_point, in Point model_point, in Mask mask) {
         super(mask);
         mScreenPoint = screen_point;
         mModelPoint = model_point;
@@ -60,11 +62,11 @@
 }
 
 final class ButtonEvent : PointerEvent {
-    this(ButtonAction button_action,
-         ButtonName button_name,
-         Point screen_point,
-         Point model_point,
-         Mask mask) {   
+    this(in ButtonAction button_action,
+         in ButtonName button_name,
+         in Point screen_point,
+         in Point model_point,
+         in Mask mask) {   
         super(screen_point, model_point, mask);
         mButtonAction = button_action;
         mButtonName = button_name;
@@ -88,7 +90,7 @@
 final class MotionEvent : PointerEvent {
     this(in Point screen_point,
          in Point model_point,
-         Mask mask) {
+         in Mask mask) {
         super(screen_point, model_point, mask);
     }
 
@@ -102,7 +104,7 @@
     this(in ScrollDirection scroll_direction,
          in Point screen_point,
          in Point model_point,
-         Mask mask) {
+         in Mask mask) {
         super(screen_point, model_point, mask);
         mScrollDirection = scroll_direction;
     }
--- a/tk/geometry.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tk/geometry.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,8 +1,10 @@
 module tk.geometry;
 
-private import std.stdio;
-private import std.math;
-private import tk.misc;
+private {
+    import std.stdio;
+    import std.math;
+    import tk.misc;
+}
 
 struct Point {
     static immutable Point DEFAULT;
@@ -28,7 +30,7 @@
         return Vector(_x - p._x, _y - p._y);
     }
 
-    string toString() const {
+    string toString() {
         return std.string.format("(%f, %f)", _x, _y);
     }
 
@@ -84,7 +86,7 @@
         return sqrt(_x * _x + _y * _y);
     }
 
-    string toString() const {
+    string toString() {
         return std.string.format("[%f, %f]", _x, _y);
     }
 
@@ -200,7 +202,7 @@
         return _position + _size / 2.0;
     }
 
-    string toString() const {
+    string toString() {
         return std.string.format("{%s, %s}", _position, _size);
     }
 
--- a/tk/gtk_support.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tk/gtk_support.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,8 +1,12 @@
 module tk.gtk_support;
 
-import tk.types;
+public {
+    import tk.types;
+}
 
-static import gdk.Event;
+private {
+    static import gdk.Event;
+}
 
 ButtonAction gtk2tk_button_action(gdk.Event.EventType event_type) {
     switch (event_type) {
@@ -49,7 +53,9 @@
     if (state & gdk.Event.GdkModifierType.BUTTON4_MASK) modifiers ~= Modifier.UNUSED_BUTTON_1;
     if (state & gdk.Event.GdkModifierType.BUTTON5_MASK) modifiers ~= Modifier.UNUSED_BUTTON_2;
 
-    return new Mask(modifiers);
+    Mask m = Mask(modifiers);
+
+    return Mask(modifiers);
 }
 
 ScrollDirection gtk2tk_direction(gdk.Event.ScrollDirection direction) {
--- a/tk/types.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tk/types.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,8 +1,13 @@
 module tk.types;
 
-private import std.string;
-private import std.typecons;
-private import std.algorithm;
+public {
+    import std.string;
+}
+
+private {
+    import std.typecons;
+    import std.algorithm;
+}
 
 mixin(defineEnum!("ButtonAction",
                   "SINGLE_PRESS", "DOUBLE_PRESS", "TRIPLE_PRESS", "RELEASE"));
@@ -14,30 +19,28 @@
                   "SHIFT", "CAPS_LOCK", "CONTROL", "ALT", "NUM_LOCK", "META",
                   "SCROLL_LOCK", "LEFT_BUTTON", "MIDDLE_BUTTON", "RIGHT_BUTTON", "UNUSED_BUTTON_1", "UNUSED_BUTTON_2"));
 
-class Mask {
+struct Mask {
     this(in Modifier[] modifiers) {
-        _modifiers = modifiers.dup;
+        foreach (ref m; modifiers) {
+            _bits |= 1 << m;
+        }
     }
 
-    override string toString() const {
+    string toString() {
         string s;
 
-        foreach (Modifier m; _modifiers) {
-            if (s != "") s ~= "|";
-            s ~= enumToString(m);
+        for (int i = 0; i < uint.sizeof * 8; ++i) {
+            if (_bits & (1 << i)) {
+                if (s != "") s ~= "|";
+                s ~= enumToString(cast(Modifier)i);
+            }
         }
 
         return s;
     }
 
     bool is_set(Modifier m) const {
-        foreach (Modifier m2; _modifiers) {
-            if (m == m2) {
-                return true;
-            }
-        }
-
-        return false;
+        return _bits & (1 << m);
     }
 
     bool is_unset(Modifier m) const {
@@ -45,6 +48,6 @@
     }
 
     private {
-        Modifier[] _modifiers;
+        uint _bits;
     }
 }
--- a/tool.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tool.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,6 +1,9 @@
 module tool;
 
-import icanvas;
+public {
+    import icanvas;
+    import tk.events;
+}
 
 /*
 interface IToolStack {
@@ -10,7 +13,7 @@
 }
 */
 
-abstract class Tool : EventHandler {
+abstract class Tool {
     /*
     abstract bool is_sticky();
     abstract bool is_replaceable();
@@ -20,5 +23,19 @@
     abstract void start(IToolStack tool_stack);
     abstract void stop(IToolStack tool_stack);
     */
+
+    //void draw(const Viewport viewport, in Rectangle damage, Context model_cr, Context pixel_cr) const;
+
+    bool handle_button_press(Viewport viewport, in ButtonEvent event);
+    bool handle_button_release(Viewport viewport, in ButtonEvent event);
+    bool handle_motion(Viewport viewport, in MotionEvent event);
+    bool handle_scroll(Viewport viewport, in ScrollEvent event);
+    //bool handle_expose(Viewport viewport, ExposeEvent event);
+    //bool handle_enter(Viewport viewport, CrossingEvent event);
+    //bool handle_leave(Viewport viewport, CrossingEvent event);
+    //bool handle_focus_in(Viewport viewport, FocusEvent event);
+    //bool handle_focus_out(Viewport viewport, FocusEvent event);
+    bool handle_key_press(Viewport viewport, in KeyEvent event);
+    bool handle_key_release(Viewport viewport, in KeyEvent event);
 }
 
--- a/tool_layer.d	Sun Jul 12 13:23:06 2009 +0930
+++ b/tool_layer.d	Mon Jul 13 16:16:17 2009 +0930
@@ -1,14 +1,13 @@
 module tool_layer;
 
-import std.stdio;
+private {
+    import std.stdio;
+    import cairo_support;
+}
 
-import cairo.Context;
-import cairo_support;
-import tool;
-private import icanvas;
-private import tk.types;
-private import tk.geometry;
-private import tk.events;
+public {
+    import tool;
+}
 
 class ToolLayer : Layer, EventHandler {
     this(in Tool[] tools, in string name) {
@@ -62,7 +61,7 @@
     }
 
     override bool handle_motion(Viewport viewport, in MotionEvent event) {
-        // writefln("%s", event);
+        writefln("%s", event);
 
         if (mGrabbedTool is null) {
             foreach_reverse(ref tool; mTools) {