view mde/gui/widget/Widget.d @ 36:57d000574d75

Enabled drawing on demand, and made the polling interval configurable. Renamed mde.global to mde.imde. Enabled drawing on demand. Allowed options to take double values. Made the main loop's polling interval (sleep duration) settable from config files. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 02 May 2008 17:38:43 +0100
parents 6b4116e6355c
children 052df9b2fe07
line wrap: on
line source

/* LICENSE BLOCK
Part of mde: a Modular D game-oriented Engine
Copyright © 2007-2008 Diggory Hardy

This program is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either
version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>. */

/// GUI Widget module.
module mde.gui.widget.Widget;

public import mde.gui.widget.Ifaces;
import mde.gui.IGui;
import mde.gui.exception;

import gl = mde.gl.basic;

import tango.io.Stdout;

/** A base widget class. Widgets need not inherit this (they only need implement IWidget), but this
* class provides a useful basic implementation for widgets.
*
* Do not use directly (i.e. only for inheriting from).
*/
class Widget : IWidget
{
    /** Minimum size is zero. */
    void getMinimumSize (out int w, out int h) {}   // w,h initialised to 0
    /** Current size. */
    void getCurrentSize (out int w, out int h) {
        w = this.w;
        h = this.h;
    }
    
    void setPosition (int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    /** Return self, since we don't have child widgets and the method wouldn't have been called
    * unless the location was over us. Valid for all widgets without children. */
    IWidget getWidget (int,int) {
        return this;
    }
    
    /** Dummy event method (widget doesn't respond to events) */
    void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {}
    
    /** Basic draw method: draw the background (all widgets should do this) */
    void draw () {
        window.renderer.drawWidgetBack (x,y, w,h);
    }
    
protected:
    IWindow window;         // the enclosing window
    int x, y;               // position
    int w, h;               // size
}

//BEGIN Widgets
/// Draws a box. That's it.
class BoxWidget : Widget
{
    this (IWindow wind, IWidget, int[] data) {
        if (data.length != 2) throw new WidgetDataException;
        
        window = wind;
        
        w = data[0];
        h = data[1];
    }
    void draw () {
        gl.setColor(1f,0f,0f);
        window.renderer.drawBox (x,y, w,h);
    }
}

/// First interactible widget
class ButtonWidget : Widget
{
    bool pushed = false;    // true if button is pushed in (visually)
    // pushed is not the same as the button being clicked but not yet released.
    // it is whether the mouse is over the button after being clicked.
    
    this (IWindow wind, IWidget, int[] data) {
        if (data.length != 2) throw new WidgetDataException;
        
        window = wind;
        
        w = data[0];
        h = data[1];
    }
    
    void draw () {
        if (pushed)
            gl.setColor (1f, 0f, 1f);
        else
            gl.setColor (.6f, 0f, .6f);
        window.renderer.drawBox (x,y, w,h);
    }
    
    void getMinimumSize (out int w, out int h) {
        w = this.w; // button is not resizable
        h = this.h;
    }
    
    void clickEvent (ushort, ushort, ubyte b, bool state) {
        if (b == 1 && state == true) {
            pushed = true;
            window.gui.requestRedraw;
            window.gui.addClickCallback (&clickWhileHeld);
            window.gui.addMotionCallback (&motionWhileHeld);
        }
    }
    // Called when a mouse motion/click event occurs while (held == true)
    void clickWhileHeld (ushort cx, ushort cy, ubyte b, bool state) {
        if (cx >= x && cx < x+w && cy >= y && cy < y+h) // button event
            Stdout ("Button clicked!").newline;
        
        pushed = false;
        window.gui.requestRedraw;
        window.gui.removeCallbacks (cast(void*) this);
    }
    void motionWhileHeld (ushort cx, ushort cy) {
        bool oldPushed = pushed;
        if (cx >= x && cx < x+w && cy >= y && cy < y+h) pushed = true;
        else pushed = false;
        if (oldPushed != pushed)
            window.gui.requestRedraw;
    }
}
//END Widgets