view mde/gui/widget/Ifaces.d @ 66:f54ae4fc2b2f

Replaced IWidget.getMinimalSize(out w,out h) with minWidth() and minHeight().
author Diggory Hardy <diggory.hardy@gmail.com>
date Wed, 02 Jul 2008 17:10:07 +0100
parents 891211f034f2
children 159775502bb4
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/>. */

/** Window and widget interfaces. */
module mde.gui.widget.Ifaces;

public import mde.gui.renderer.IRenderer;
public import mde.gui.IGui;

/** Interface for Window, allowing widgets to call some of Window's methods.
 *
 * Contains the methods in Window available for widgets to call on their root.
 *
 * Notation:
 *  Positive/negative direction: along the x/y axis in this direction.
 *  Layout widget: a widget containing multiple sub-widges (which hence controls how they are laid
 *  out). */
interface IWindow : IWidget
{
    /** Widget ID type. Each ID is unique under this window.
     *
     * Type is int since this is the widget data type. */
    alias int widgetID;
    
    /** Get a widget by ID.
     *
     * Returns the widget with the given ID from the Window's widget list. If the widget hasn't yet
     * been created, creates it using the Window's widget creation data. */
    IWidget makeWidget (widgetID i);
    
    /** Get a string from the widgetString associative array. */
    char[] getWidgetString (int i);
    
    /** Add widget's saveData to the data to be saved, returning it's widgetID. */
    widgetID addCreationData (IWidget widget);
    
    /** Add a string to the widgetString associative array, returning it's index. */
    int addWidgetString (char[] str);
    
    /** Returns the window's gui. */
    IGui gui ();
    
    /** The widget/window needs redrawing. */
    void requestRedraw ();
    
    /** Get the window's renderer.
    *
    * Normally specific to the GUI, but widgets have no direct contact with the GUI and this
    * provides the possibility of per-window renderers (if desired). */
    IRenderer renderer ();
}

/** Interface for widgets.
 *
 * Note that Window also implements this interface so that widgets can interact with their parent
 * in a uniform way.
 *
 * A widget is a region of a GUI window which handles rendering and user-interaction for itself
 * and is able to communicate with it's window and parent/child widgets as necessary.
 *
 * A widget's constructor should have the prototype and doc explaining what initialization data is
 * used (excluding the widget ID, which every widget recieves):
 * ----------------------------------
 * /++ Constructor for a ... widget.
 *  +
 *  + Widget uses the initialisation data:
 *  + [widgetID, x, y]
 *  + where x is ... and y is ... +/
 * this (IWindow window, int[] data);
 * ----------------------------------
 * Where window is the root window (the window to which the widget belongs) and data is an array of
 * initialisation data. The method should throw a WidgetDataException (created without parameters)
 * if the data has wrong length or is otherwise invalid.
 *
 * The widget's size should be set either by it's this() method or by the first call to
 * setSize(). setSize() is called on all widgets immediately after their creation, and throwing an
 * exception at this point (but not on later calls to setSize) is an acceptible method of failure.
 */
//NOTE: add another this() without the data for default initialization, for the GUI editor?
interface IWidget
{
//BEGIN Load and save
    /** Called after creating widgets to adjust size & other mutable attributes from saved data.
     *
     * As for setSize, setPosition should be called afterwards.
     *
     * Each widget should call adjust on each of its sub-widgets in turn with data, each time
     * replacing data by the return value of the call. It should then take its own mutable data
     * from the beginning of the array and return the remainder of the array.
     *
     * Adjust should handle errors gracefully by reverting to default values and not throwing.
     * This is because the creation data and the user's mutable data may be stored separately and
     * become out-of-sync during an update. */
    int[] adjust (int[] data);
    
    /** Output data suitible for recreating the widget (data to be passed to this()).
     *
     * Function may need to call Window's addCreationData() and addWidgetString() methods to save
     * other data.
     *
     * Creation data is data only changed when the gui is edited. */
    int[] getCreationData ();
    
    /** Output data containing the widget's current adjustments (data to be passed to adjust()).
     *
     * Mutable data is data which can be changed during normal gui use, such as the size of
     * resizible widgets or current tab of a tab widget.
     *
     * Should be a concatenation of each sub-widget's mutable data and the widget's own. */
    int[] getMutableData ();
//END Load and save
    
//BEGIN Size and position
    /** is the width / height resizable?
     *
     * If not, the widget has fixed dimensions equal the output of getMinimalSize. */
    bool isWSizable ();
    bool isHSizable (); /// ditto
    
    /** The minimal size the widget could be shrunk to (or its fixed size).
     *
     * Takes into account child-widgets and any other contents. */
    wdim minWidth ();
    wdim minHeight ();	/// ditto
    
    /** Get the current size of the widget. */
    void getCurrentSize (out wdim w, out wdim h);
    
    /** Used to adjust the size.
     *
     * Params:
     *  nw/nh	= The new width/height
     *  dir	= Direction to resize from. This is only really applicable to layout widgets.
     *  	  It must be either -1 (start resizing from highest row/col index, decreasing the
     *  	  index as necessary), or +1 (resize from the lowest index, i.e. 0).
     *  	  Most widgets can simply ignore it.
     *
     * Implementation:
     * The size should be clamped to the widget's minimal size, i.e. the size set may be larger
     * than that given by the parameters. Conversely, the size should not be reduced to the
     * widget's maximal size (if any) but expanded as necessary (alignment to be implemented).
     * This should be true for both resizable and fixed widgets; fixed widgets may still be scaled
     * to fill a whole row/column in a layout widget.
     *
     * If the actual size is needed, call getCurrentSize afterwards. setPosition must be called
     * afterwards if the widget might be a layout widget. */
    void setWidth (wdim nw, int dir);
    void setHeight (wdim nh, int dir);	/// ditto
    
    /** Set the current position (i.e. called on init and move). */
    void setPosition (wdim x, wdim y);
//END Size and position
    
//BEGIN Events
    /** Recursively scan the widget tree to find the widget under (x,y).
     *
     * If called on a widget, that widget should assume the location is over itself, and so should
     * either return itself or the result of calling getWidget on the appropriate child widget.
     *
     * In the case of Window this may not be the case; it should check and return null if not under
     * (x,y).
     *
     * Note: use global coordinates (x,y) not coordinates relative to the widget. */
    IWidget getWidget (wdim x, wdim y);
    
    /** Receive a mouse click event.
     *
     * See mde.input.input.Input.MouseClickCallback for parameters. However, cx and cy are adjusted
     * to the Widget's local coordinates.
     *
     * Widget may assume coordinates are on the widget (caller must check). */
    void clickEvent (wdabs cx, wdabs cy, ubyte b, bool state);
//END Events
    
    /** Draw, using the stored values of x and y.
     *
     * Maybe later enforce clipping of all sub-widget drawing, particularly for cases where only
     * part of the widget is visible: scroll bars or a hidden window. */
    void draw ();
}