changeset 11:fb571a3b1f0d

Checkpoint
author "David Bryant <bagnose@gmail.com>"
date Sat, 11 Jul 2009 23:32:22 +0930
parents 71ca82e0eb76
children a093c4fbdd43
files cairo_support.d canvas.d grid_layer.d gui.d icanvas.d page_layer.d
diffstat 6 files changed, 85 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/cairo_support.d	Sat Jul 11 22:49:41 2009 +0930
+++ b/cairo_support.d	Sat Jul 11 23:32:22 2009 +0930
@@ -4,7 +4,7 @@
 
 import cairo.Context;
 
-void draw_rectangle(Context cr, Rectangle rectangle) {
+void rectangle(Context cr, Rectangle rectangle) {
     cr.rectangle(rectangle.position.x, rectangle.position.y,
                  rectangle.size.x, rectangle.size.y);
 }
--- a/canvas.d	Sat Jul 11 22:49:41 2009 +0930
+++ b/canvas.d	Sat Jul 11 23:32:22 2009 +0930
@@ -33,26 +33,24 @@
 // x and y run right and up respectively
 
 class Canvas : Table, Viewport {
-    static this() {
-        ORIGIN = Point(0.0, 0.0);
-        INITIAL_PAGE_SIZE = Vector(210.0, 297.0);       // A4
-    }
-
-    this(EventHandler event_handler) {
+    this(in Layer[] layers, EventHandler event_handler, in double ppi) {
         super(3, 3, 0);
 
+        mLayers = layers.dup;
         mEventHandler = event_handler;
 
-        const double PPI = 120.0;
         const double MM_PER_INCH = 25.4;
-        mZoom = 0.25 * PPI / MM_PER_INCH;
+        mZoom = 0.25 * ppi / MM_PER_INCH;
+
+        Rectangle total_layer_bounds;
 
-        mPageLeftBottom = ORIGIN;
-        mPageRightTop = ORIGIN + INITIAL_PAGE_SIZE;
-        mViewCentre = ORIGIN + INITIAL_PAGE_SIZE / 2.0;
+        foreach (ref layer; mLayers) {
+            total_layer_bounds = total_layer_bounds | layer.bounds;
+        }
 
-        mCanvasLeftBottom = mPageLeftBottom - 3.0 * INITIAL_PAGE_SIZE;
-        mCanvasRightTop = mPageRightTop + 3.0 * INITIAL_PAGE_SIZE;
+        mCanvasLeftBottom = total_layer_bounds.min_corner - total_layer_bounds.size;
+        mCanvasRightTop = total_layer_bounds.max_corner + total_layer_bounds.size;
+        mViewCentre = mCanvasLeftBottom + (mCanvasRightTop - mCanvasLeftBottom) / 2.0;
 
         mHRuler = new HRuler();
         attach(mHRuler,
@@ -134,12 +132,15 @@
         queueDraw();
     }
 
-    override Point model_to_screen(Point model) const { return ORIGIN + mViewSize / 2.0 + mZoom * (model - mViewCentre); }
-    override Point screen_to_model(Point screen) const { return mViewCentre + (screen - mViewSize / 2.0 - ORIGIN) / mZoom; }
+    override double zoom() const { return mZoom; }
+    override Point model_to_screen(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 Vector model_to_screen(Vector model) const { return mZoom * model; }
     override Vector screen_to_model(Vector screen) const { return screen / mZoom; }
     override double model_to_screen(double model) const { return mZoom * model; }
     override double screen_to_model(double screen) const { return screen / mZoom; }
+    override Rectangle model_to_screen(Rectangle model) const { return Rectangle(model_to_screen(model.position), model_to_screen(model.size)); }
+    override Rectangle screen_to_model(Rectangle model) const { return Rectangle(screen_to_model(model.position), screen_to_model(model.size)); }
 
     private {
 
@@ -169,36 +170,27 @@
             //writefln("Got expose %dx%d\n", width, height);
 
             scope cr = new Context(dr);
+            Rectangle damage =
+                event is null ?
+                Rectangle(Point(0.0, 0.0), Vector(cast(double)width, cast(double)height)) :
+                Rectangle(Point(cast(double)event.area.x, cast(double)event.area.y),
+                          Vector(cast(double)event.area.width, cast(double)event.area.height));
 
-            if (event) {
-                cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height);
+            cr.save(); {
+                rectangle(cr, damage);
                 cr.clip();
-            }
 
-            // Make the window light grey
-            cr.setSourceRgba(1.0, 1.0, 1.0, 0.7);
-            if (event) {
-                cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height);
-            }
-            else {
-                cr.rectangle(0.0, 0.0, width, height);
-            }
-            cr.fill();
+                cr.save(); {
+                    // Make the window light grey
+                    cr.setSourceRgba(1.0, 1.0, 1.0, 0.7);
+                    rectangle(cr, damage);
+                    cr.fill();
+                } cr.restore();
 
-            {
-                // Make the paper white, with a border
-
-                Point screen_page_left_bottom = model_to_screen(mPageLeftBottom);
-                Point screen_page_right_top = model_to_screen(mPageRightTop);
-
-                cr.setSourceRgba(1.0, 1.0, 1.0, 1.0);
-                draw_rectangle(cr, Rectangle(screen_page_left_bottom, screen_page_right_top));
-                cr.fill();
-
-                cr.setSourceRgba(0.0, 0.0, 0.0, 1.0);
-                draw_rectangle(cr, Rectangle(screen_page_left_bottom, screen_page_right_top));
-                cr.stroke();
-            }
+                foreach(ref layer; mLayers) {
+                    layer.draw(this, damage, cr);
+                }
+            } cr.restore();
 
             return true;
         }
@@ -355,15 +347,12 @@
 
         double clamp_zoom(double zoom) { return clamp(zoom, 0.02, 50.0); }
 
-        static const Point ORIGIN;
-        static const Vector INITIAL_PAGE_SIZE;
-
         EventHandler mEventHandler;
 
         // Model units are in millimetres
         // Screen units are in pixels
 
-        double mZoom;               // pixels-per-mm
+        double mZoom;               // pixels-per-model-unit (mm)
         Point mViewCentre;          // model: where in the model is the centre of our view
 
         Point mCanvasLeftBottom;    // model: bottom left corner of canvas
@@ -381,5 +370,8 @@
         HScrollbar mHScrollbar;
         Adjustment mVAdjustment;
         VScrollbar mVScrollbar;
+
+        // Layers:
+        Layer[] mLayers;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grid_layer.d	Sat Jul 11 23:32:22 2009 +0930
@@ -0,0 +1,24 @@
+import icanvas;
+import tk.geometry;
+import cairo.Context;
+import cairo_support;
+import std.math;
+
+interface Grid {
+}
+
+class GridLayer : Layer, Grid {
+    override Rectangle bounds() const {
+        // We don't require any geometry
+        return Rectangle();
+    }
+
+    override void draw(const Viewport viewport, in Rectangle damage, Context cr) const {
+        double zoom = viewport.zoom;
+
+        double start_x = modf(damage.min_corner.x, zoom);
+    }
+
+    private {
+    }
+}
--- a/gui.d	Sat Jul 11 22:49:41 2009 +0930
+++ b/gui.d	Sat Jul 11 23:32:22 2009 +0930
@@ -1,9 +1,11 @@
 module gui;
 
+import icanvas;
 import canvas;
 import tool_stack;
 import tool;
 import standard_tools;
+import page_layer;
 
 import gtk.Main;
 import gtk.MainWindow;
@@ -22,7 +24,9 @@
     tools ~= new PanTool;
     tools ~= new ZoomTool;
     auto event_handler = new ToolStack(tools);
-    auto canvas = new Canvas(event_handler);
+    Layer[] layers;
+    layers ~= new PageLayer;
+    auto canvas = new Canvas(layers, event_handler, 120.0);
     window.add(canvas);
     window.setDefaultSize(420, 340);
     window.showAll();
--- a/icanvas.d	Sat Jul 11 22:49:41 2009 +0930
+++ b/icanvas.d	Sat Jul 11 23:32:22 2009 +0930
@@ -9,10 +9,13 @@
     void rel_pan(Vector screen_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;
 }
@@ -32,5 +35,7 @@
 }
 
 abstract class Layer {
+    Rectangle bounds() const;
+    //void zoom_changed
     void draw(const Viewport viewport, in Rectangle damage, Context cr) const;
 }
--- a/page_layer.d	Sat Jul 11 22:49:41 2009 +0930
+++ b/page_layer.d	Sat Jul 11 23:32:22 2009 +0930
@@ -7,23 +7,28 @@
 }
 
 class PageLayer : Layer, Page {
-    void draw(const Viewport viewport, in Rectangle damage, Context cr) const {
+    this() {
+        mPageGeometry = Rectangle(Point.DEFAULT,
+                                  Vector(210.0, 297.0));
+    }
+
+    override Rectangle bounds() const {
+        return mPageGeometry;
+    }
+
+    override void draw(const Viewport viewport, in Rectangle damage, Context cr) const {
         // Make the paper white, with a border
 
-        Point screen_page_left_bottom = viewport.model_to_screen(mPageLeftBottom);
-        Point screen_page_right_top = viewport.model_to_screen(mPageRightTop);
-
         cr.setSourceRgba(1.0, 1.0, 1.0, 1.0);
-        draw_rectangle(cr, Rectangle(screen_page_left_bottom, screen_page_right_top));
+        rectangle(cr, viewport.model_to_screen(mPageGeometry));
         cr.fill();
 
         cr.setSourceRgba(0.0, 0.0, 0.0, 1.0);
-        draw_rectangle(cr, Rectangle(screen_page_left_bottom, screen_page_right_top));
+        rectangle(cr, viewport.model_to_screen(mPageGeometry));
         cr.stroke();
     }
 
     private {
-        Point mPageLeftBottom;      // model: bottom left corner of page
-        Point mPageRightTop;        // model: top right corner of page
+        Rectangle mPageGeometry;
     }
 }