view mde/gui/widget/createWidget.d @ 85:56c0ddd90193

Intermediate commit (not stable). Changes to init system.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 11 Sep 2008 11:33:51 +0100
parents ea58f277f487
children b525ff28774b
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;
import mde.gui.widget.Floating;
import tango.util.log.Log : Log, Logger;

private Logger logger;
static this () {
    logger = Log.getLogger ("mde.gui.widget.createWidget");
}

/** Create a widget.
 *
 * Usually called by the widget manager's makeWidget function.
 *
 * Widget created of type data.ints[0] (see enum WIDGET_TYPES), with one of the following CTORs:
 * ---
 * this (IWidgetManager mgr, WidgetData data);
 * // Called if (data.ints[0] & WIDGET_TYPES.TAKES_PARENT):
 * this (IWidgetManager mgr, WidgetData data, IParentWidget parent);
 * ---
 *************************************************************************************************/
IChildWidget createWidget (IWidgetManager mgr, WidgetData data, IParentWidget parent)
in {
    assert (mgr !is null, "createWidget: mgr is null");
} body {
    if (data.ints.length < 1) {
        logger.error ("No int data; creating a debug widget");
        data.ints = [WIDGET_TYPE.Debug];
    }
    int type = data.ints[0];    // type is first element of data
    
    //pragma (msg, binarySearch ("type", WIDGETS));
    mixin (binarySearch ("type", WIDGETS)); // creates widget by type: new XWidget (mgr, data [, parent]);
    
    // Not returned a new widget...
    logger.error ("Bad widget type: {}; creating a debug widget instead.",type);
    return new DebugWidget (mgr, data);
}

/+ 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 {
    TAKES_PARENT            = 0x4000,   // CTOR takes reference to its parent
    PARENT                  = 0x8000,   // widget can have children
    
    // Use widget names rather than usual capitals convention
    Unnamed                 = 0x0,      // Only for use by widgets not created with createWidget
    
    // blank: 0x1
    FixedBlank              = 0x1,
    SizableBlank            = 0x2,
    Debug                   = 0xF,
    
    // buttons: 0x10
    Button                  = 0x10,
    
    // content: 0x20
    Text		    = 0x21,
    Int			    = 0x22,
    
    GridLayout              = PARENT | 0x100,
    TrialContentLayout      = PARENT | 0x110,
    
    FloatingArea            = PARENT | 0x200,
}

//const char[][int] WIDGET_NAMES;

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

/* 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" ~
                    "   debug (mdeWidgets) logger.trace (\"Creating new "~c~"Widget.\");\n" ~
                    "   static if (WIDGET_TYPE."~c~" & WIDGET_TYPE.TAKES_PARENT)\n" ~
                    "       return new " ~ c ~ "Widget (mgr, data, parent);\n" ~
                    "   else\n" ~
                    "       return new " ~ c ~ "Widget (mgr, data);\n" ~
                    "} else ";
        }
        ret = ret[0..$-6] ~ '\n';  // remove last else
        return ret;
    }
}