view mde/gui/widget/createWidget.d @ 77:3dfd934100f7

Continuing widget data changes started in last commit: all previous widgets work again now (but lacking saving).
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 29 Jul 2008 17:11:22 +0100
parents 25cb7420dc91
children ea58f277f487
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.createWidget;

import mde.gui.widget.Ifaces;
import mde.gui.exception : WidgetDataException;

// Widgets to create:
import mde.gui.widget.layout;
import mde.gui.widget.miscWidgets;
import mde.gui.widget.TextWidget;

/** Create a widget of type data[0] (see enum WIDGET_TYPES) under manager mgr, with initialisation
* data [1..$]. */
IChildWidget createWidget (IWidgetManager mgr, WidgetData data)
in {
    assert (mgr !is null, "createWidget: mgr is null");
} body {
    if (data.ints.length < 1) throw new WidgetDataException ("No widget data");
    int type = data.ints[0];    // type is first element of data
    
    mixin (binarySearch ("type", WIDGETS)); // creates widget by type as new *Widget (mgr, data);
    throw new WidgetDataException ("Bad widget type");
}

/+ for converting to a char[] name (unused)
static this() {
    WIDGET_NAMES = [
            FixedBlank : "FixedBlank",
            SizableBlank : "SizableBlank",
            Button : "Button",
            GridLayout : "GridLayout"
                    ];
}+/

private:
/// Widget types.
enum WIDGET_TYPE : int {
    WSIZABLE                = 0x1000,   // horizontally resizable
    HSIZABLE                = 0x2000,   // vertically resizable
    INTERACTIBLE            = 0x4000,   // any specific interaction
    LAYOUT                  = 0x8000,   // is a layout widget (i.e. has sub-widgets)?
    
    // Use widget names rather than usual capitals convention
    Unnamed                 = 0x0,      // Only for use by widgets not created with createWidget
    
    // blank: 0x1
    FixedBlank              = 0x1,
    SizableBlank            = WSIZABLE | HSIZABLE | 0x1,
    
    // buttons: 0x10
    Button                  = INTERACTIBLE | 0x10,
    
    // content: 0x20
    Text		    = 0x21,
    Int			    = 0x22,
    
    GridLayout              = LAYOUT | WSIZABLE | HSIZABLE | 0x4,
    TrialContentLayout      = LAYOUT | WSIZABLE | HSIZABLE | 0x5
}

//const char[][int] WIDGET_NAMES;

// Only used for binarySearch algorithm generation; must be ordered by numerical values.
const char[][] WIDGETS = [
        "FixedBlank",
        "Text",
        "Int",
        "SizableBlank",
        "Button",
        "GridLayout",
        "TrialContentLayout"];

/* Generates a binary search algorithm. */
char[] binarySearch (char[] var, char[][] consts) {
    if (consts.length > 3) {
        return "if (" ~ var ~ " <= WIDGET_TYPE." ~ consts[$/2 - 1] ~ ") {\n" ~
                binarySearch (var, consts[0 .. $/2]) ~
                "} else {\n" ~
                binarySearch (var, consts[$/2 .. $]) ~
                "}\n";
    } else {
        char[] ret;
        foreach (c; consts) {
            ret ~= "if (" ~ var ~ " == WIDGET_TYPE." ~ c ~ ") {\n" ~
                    "return new " ~ c ~ "Widget (mgr, data);\n" ~
                    "} else ";
        }
        ret = ret[0..$-6] ~ '\n';  // remove last else
        return ret;
    }
}