# HG changeset patch # User "David Bryant " # Date 1247320942 -34200 # Node ID fb571a3b1f0dcba5b595e0dbe055514ebe7ceeeb # Parent 71ca82e0eb76987ceae02e08abce6e7b51c64932 Checkpoint diff -r 71ca82e0eb76 -r fb571a3b1f0d cairo_support.d --- 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); } diff -r 71ca82e0eb76 -r fb571a3b1f0d canvas.d --- 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; } } diff -r 71ca82e0eb76 -r fb571a3b1f0d grid_layer.d --- /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 { + } +} diff -r 71ca82e0eb76 -r fb571a3b1f0d gui.d --- 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(); diff -r 71ca82e0eb76 -r fb571a3b1f0d icanvas.d --- 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; } diff -r 71ca82e0eb76 -r fb571a3b1f0d page_layer.d --- 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; } }