view mde/gui/widget/Widget.d @ 65:891211f034f2

Changes to widgets: widgets may now get strings as creation data. Strings for TextWidgets can be set in files (in a temporary mannor).
author Diggory Hardy <diggory.hardy@gmail.com>
date Sun, 29 Jun 2008 15:40:37 +0100
parents d43523ed4b62
children f54ae4fc2b2f
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.
 *
 * This module contains some base widget classes suitable for widget classes to inherit. However,
 * inheriting one of them is by no means necessary for a widget so long as the IWidget interface is
 * implemented. */
module mde.gui.widget.Widget;

public import mde.gui.widget.Ifaces;
import mde.gui.renderer.IRenderer;

/** An abstract base widget class.
*
* This abstract class, and the more concrete FixedWidget and ScalableWidget classes provides a
* useful basic implementation for widgets. Widgets need not inherit these (they only need implement
* IWidget); they are simply provided for convenience and to promote code reuse. */
abstract class Widget : IWidget
{
//BEGIN Load and save
    // Base this(). All widgets must check data.length is correct before calling this method.
    // The widget ID is saved to widgetType, for correct saving.
    this (IWindow wind, int[] data) {
        window = wind;
        widgetType = data[0];
    }
    
    // Most widgets don't need to do adjustments based on mutable data, however they usually do
    // still need to set their size.
    int[] adjust (int[] data) {
        setWidth (0,-1);
        setHeight (0,-1);
        return data;
    }
    
    // Widget type should always be the first value. Any widget using extra creation data will need
    // to reimplemnt this method.
    int[] getCreationData () {
        return [widgetType];
    }
    // Most widgets don't use mutable data.
    int[] getMutableData () {
        return [];
    }
//END Load and save
    
//BEGIN Size and position
    bool isWSizable () {    return false;   }
    bool isHSizable () {    return false;   }
    
    /* Return minimal/fixed size. */
    void getMinimalSize (out wdim a, out wdim b) {
        a = mw;
        b = mh;
    }
    
    void getCurrentSize (out wdim cw, out wdim ch) {
        cw = w;
        ch = h;
    }
    
    /* Set size: minimal size is (mw,mh). Note that both resizable and fixed widgets should allow
     * enlarging, so in both cases this is a correct implementation. */
    void setWidth (wdim nw, int) {
        w = (nw >= mw ? nw : mw);
    }
    void setHeight (wdim nh, int) {
        h = (nh >= mh ? nh : mh);
    }
    
    void setPosition (wdim nx, wdim ny) {
        x = nx;
        y = ny;
    }
//END Size and position
    
//BEGIN Events
    /* This method is only called when the location is over this widget; hence for all widgets
     * without children this method is valid. */
    IWidget getWidget (wdim,wdim) {
        return this;
    }
    
    /* Dummy event method (suitable for all widgets which don't respond to events). */
    void clickEvent (wdabs cx, wdabs cy, ubyte b, bool state) {}
//END Events
    
    /* Basic draw method: draw the background (all widgets should do this). */
    void draw () {
        window.renderer.drawWidgetBack (x,y, w,h);
    }
    
protected:
    final int widgetType;	// the type (stored for saving)
    IWindow window;		// the enclosing window
    wdim x, y;			// position
    wdim w, h;			// size
    wdim mw = 0, mh = 0;	// minimal or fixed size, depending on whether the widget is
    				// resizible; both types of widgets should actually be expandable.
}

/** A base for fixed-size widgets taking their size from the creation data. */
class FixedWidget : Widget {
    // Check data.length is at least 3 before calling!
    /** Constructor for a fixed-size [blank] widget.
     *
     * Widget uses the initialisation data:
     * [widgetID, w, h]
     * where w, h is the fixed size. */
    this (IWindow wind, int[] data) {
        mw = cast(wdim) data[1];
        mh = cast(wdim) data[2];
        super (wind, data);
        w = mw;
        h = mh;
    }
    
    int[] getCreationData () {
        return [widgetType, mw, mh];
    }
}
/** A base for resizable widgets. */
class SizableWidget : Widget {
    // Check data.length is at least 1 before calling!
    /// Constructor for a completely resizable [blank] widget.
    this (IWindow wind, int[] data) {
        super (wind, data);
    }
    
    bool isWSizable () {    return true;    }
    bool isHSizable () {    return true;    }
}