view doodle/dia/grid_layer.d @ 84:cdd4fc728d94

Renamed Drawable to Renderer
author daveb
date Mon, 16 Aug 2010 17:23:09 +0930
parents d92b9f04b1e8
children 467febed7367
line wrap: on
line source

module doodle.dia.grid_layer;

public {
    import doodle.dia.icanvas;
}

private {
    import std.math;
}

private {
    double start(in double value, in double spacing) {
        real r = floor(value / spacing);
        return r * spacing;
    }
}

class GridLayer : Layer, IGrid {
    immutable double MIN_SPACING = 5.0;      // pixels

    this(in string name = "Grid") {
        super(name);
        _zoomValid = false;
    }

    // Layer overrides:

    override Rectangle bounds() const {
        // We don't require any geometry
        return Rectangle();
    }

    override void draw(in Rectangle screenDamage, scope Renderer screenRenderer,
                       in Rectangle modelDamage, scope Renderer modelRenderer) const {
        /+
        assert(_zoomValid);

        double xx = 1.0, yy = 1.0;
        modelCr.userToDeviceDistance(xx, yy);

        modelCr.save(); {
            modelCr.setSourceRgba(0.0, 0.0, 0.0, 0.3);
            modelCr.setLineWidth(0.5);

            {
                // vertical grid lines
                double x = start(modelDamage.corner0.x, _spacing);

                for (;;) {
                    vline(modelCr, x, modelDamage.corner0.y, modelDamage.corner1.y);

                    // Ensure 1 pixel wide FIXME is this naughty? We are sneaking
                    // through cairo to mix model and pixel coordinates...
                    modelCr.save(); {
                        modelCr.scale(1.0 / xx, 1.0 / yy);
                        modelCr.stroke();
                    } modelCr.restore();

                    if (x > modelDamage.corner1.x) {
                        break;
                    }

                    x += _spacing;
                }
            }

            {
                // horizontal grid lines
                double y = start(modelDamage.corner0.y, _spacing);

                for (;;) {
                    hline(modelCr, y, modelDamage.corner0.x, modelDamage.corner1.x);

                    // FIXME?
                    modelCr.save(); {
                        modelCr.scale(1.0 / xx, 1.0 / yy);
                        modelCr.stroke();
                    } modelCr.restore();

                    if (y > modelDamage.corner1.y) {
                        break;
                    }

                    y += _spacing;
                }
            }
        } modelCr.restore();
        +/
    }

    // IGrid overrides:

    override void zoomChanged(double zoom) {
        _zoom = zoom;
        _zoomValid = true;

        // FIXME compute spacing properly
        _spacing = 20.0 / _zoom;        // mm
    }

    // FIXME use inout parameter?
    override bool snap(in Point a, out Point b) const {
        b = a;
        return false;
    }

    private {
        bool _zoomValid;
        double _zoom;           // pixels per millimetre

        double _spacing;        // model spacing
    }
}