Mercurial > projects > mde
view mde/gui/widget/Widget.d @ 44:07bd1a09e161
Started implementing text rendering.
Can now position glyphs accurately and render them, in a very basic way.
A basic TextWidget.
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 16 May 2008 12:22:10 +0100 |
parents | 1530d9c04d4d |
children | 0fd51d2c6c8a |
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.Widget; public import mde.gui.widget.Ifaces; import mde.gui.exception; import mde.gui.renderer.IRenderer; import mde.resource.font; import tango.io.Stdout; /** 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 { // Base this(); all widgets must at least check data.length is correct. 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) { setSize (0,0); return data; } bool isWSizable () { return false; } bool isHSizable () { return false; } // Widget type should always be the first value. int[] getCreationData () { return [widgetType]; } // Most widgets don't use mutable data. int[] getMutableData () { return []; } void getCurrentSize (out int cw, out int ch) { cw = w; ch = h; } void setPosition (int nx, int ny) { x = nx; y = ny; } /* Return self, since we don't have child widgets and the method wouldn't have been called * unless the location was over us. Valid for all widgets without children. */ IWidget getWidget (int,int) { return this; } /* Dummy event method (widget doesn't respond to events) */ void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {} /* 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 int x, y; // position int w, h; // size } /** A base for fixed-size widgets. */ class FixedWidget : Widget { this (IWindow wind, int[] data) { w = wF; h = hF; super (wind, data); } int[] getCreationData () { return [widgetType, wF, hF]; } /* Not resizable, so return current size. */ void getMinimalSize (out int mw, out int mh) { mw = wF; mh = hF; } /* Ignore: a fixed size widget. */ void setSize (int nw, int nh) { w = (nw >= wF ? nw : wF); h = (nh >= hF ? nh : hF); } protected: int wF, hF; // The "fixed" size, i.e. the preferred & minimal size } /** A base for resizable widgets. */ class SizableWidget : Widget { this (IWindow wind, int[] data) { super (wind, data); } bool isWSizable () { return true; } bool isHSizable () { return true; } /* Return zero. */ void getMinimalSize (out int mw, out int mh) {} /* Set size: a fully resizable widget. */ void setSize (int nw, int nh) { w = (nw >= 0 ? nw : 0); h = (nh >= 0 ? nh : 0); } void draw () { super.draw; window.renderer.drawBlank (x,y, w,h); } } //BEGIN Widgets /// A fixed-size blank widget. class FixedBlankWidget : FixedWidget { this (IWindow wind, int[] data) { if (data.length != 3) throw new WidgetDataException; wF = data[1]; hF = data[2]; super (wind, data); } void draw () { super.draw; window.renderer.drawBlank (x,y, w,h); } } /// A completely resizable blank widget (initial size zero). class SizableBlankWidget : SizableWidget { this (IWindow wind, int[] data) { if (data.length != 1) throw new WidgetDataException; super (wind, data); } } /// First interactible widget class ButtonWidget : FixedWidget { bool pushed = false; // true if button is pushed in (visually) // pushed is not the same as the button being clicked but not yet released. // it is whether the mouse is over the button after being clicked. this (IWindow wind, int[] data) { if (data.length != 3) throw new WidgetDataException; wF = data[1]; hF = data[2]; super (wind, data); } void draw () { window.renderer.drawButton (x,y, w,h, pushed); } void clickEvent (ushort, ushort, ubyte b, bool state) { if (b == 1 && state == true) { pushed = true; window.requestRedraw; window.gui.addClickCallback (&clickWhileHeld); window.gui.addMotionCallback (&motionWhileHeld); } } // Called when a mouse motion/click event occurs while (held == true) bool clickWhileHeld (ushort cx, ushort cy, ubyte b, bool state) { if (b == 1 && state == false) { if (cx >= x && cx < x+w && cy >= y && cy < y+h) // button event Stdout ("Button clicked!").newline; pushed = false; window.requestRedraw; window.gui.removeCallbacks (cast(void*) this); return true; } return false; } void motionWhileHeld (ushort cx, ushort cy) { bool oldPushed = pushed; if (cx >= x && cx < x+w && cy >= y && cy < y+h) pushed = true; else pushed = false; if (oldPushed != pushed) window.requestRedraw; } } /// Basic text widget class TextWidget : FixedWidget { this (IWindow wind, int[] data) { if (data.length != 1) throw new WidgetDataException; wF = 100; //FIXME: set properly hF = 25; super (wind,data); } void draw () { super.draw(); if (font is null) font = Font.get("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"); font.drawStr (x,y, "Text Widget"); } protected: static Font font; } //END Widgets