Mercurial > projects > mde
view mde/gui/widget/Ifaces.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/>. */ /** 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 /** Calculate the minimal size the widget could be shrunk to (or its fixed size), taking into * account child-widgets or other contents. */ void getMinimalSize (out wdim w, out wdim h); /** 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 (); }