view doodle/dia/tool_layer.d @ 60:e64baac3efb2

Attempt at a templatised palette
author David Bryant <bagnose@gmail.com>
date Tue, 10 Aug 2010 22:55:54 +0930
parents c63719604adb
children 20d6327c4a75
line wrap: on
line source

module doodle.dia.tool_layer;

public {
    import doodle.dia.tool;
}

private {
    import doodle.cairo.routines;
    import doodle.core.logging;
}

// This interface is used by the palette
interface IToolStack {
    void use(Tool tool);
}

interface IToolStackObserver {
    void toolChanged(Tool tool);
}

final class ToolLayer : Layer, IEventHandler, IToolStack {
    this(in Tool[] tools, IToolStackObserver observer, in string name = "Tool") {
        super(name);
        _tools = tools.dup;
        _observer = observer;
    }

    // IToolStack overrides:

    void use(Tool tool) {
        assert(_grabbedTool is null);
        message("using new tool: %s", tool.name);
        _tools ~= tool;
        _observer.toolChanged(tool);
    }

    // Layer overrides:

    override Rectangle bounds() const {
        return Rectangle();
    }

    override void draw(const IViewport viewport,
                       in Rectangle pixelDamage, scope Context pixelCr,
                       in Rectangle modelDamage, scope Context modelCr) const {
        if (_grabbedTool) {
            _grabbedTool.draw(viewport, pixelDamage, pixelCr);
        }
    }

    // EventHandler overrides:

    bool handleButtonPress(scope IViewport viewport, in ButtonEvent event) {
        // writefln("%s", event);

        if (_grabbedTool is null) {
            foreach_reverse(ref tool; _tools) {
                if (tool.handleButtonPress(viewport, event)) {
                    _grabbedTool = &tool;
                    _grabbedButton = event.buttonName;
                    break;
                }
            }
        }
        else {
            _grabbedTool.handleButtonPress(viewport, event);
        }

        return true;
    }

    bool handleButtonRelease(scope IViewport viewport, in ButtonEvent event) {
        // writefln("%s", event);

        if (_grabbedTool !is null) {
            _grabbedTool.handleButtonRelease(viewport, event);

            if (_grabbedButton == event.buttonName) {
                _grabbedTool = null;
            }
        }

        return true;
    }

    bool handleKeyPress(scope IViewport viewport, in KeyEvent event) {
        // writefln("%s", event);

        return true;
    }

    bool handleKeyRelease(scope IViewport viewport, in KeyEvent event) {
        // writefln("%s", event);

        return true;
    }

    bool handleMotion(scope IViewport viewport, in MotionEvent event) {
        //writefln("%s", event);

        if (_grabbedTool is null) {
            foreach_reverse(ref tool; _tools) {
                if (tool.handleMotion(viewport, event)) {
                    break;
                }
            }
        }
        else {
            _grabbedTool.handleMotion(viewport, event);
        }

        return true;
    }

    bool handleScroll(scope IViewport viewport, in ScrollEvent event) {
        // writefln("%s", event);

        if (_grabbedTool is null) {
            foreach_reverse(ref tool; _tools) {
                if (tool.handleScroll(viewport, event)) {
                    break;
                }
            }
        }
        else {
            _grabbedTool.handleScroll(viewport, event);
        }

        return true;
    }

    private {
        Tool[] _tools;
        IToolStackObserver _observer;

        Tool * _grabbedTool;
        ButtonName _grabbedButton;
    }
}