Mercurial > projects > mde
view mde/gui/WMScreen.d @ 159:b06b04c75e86
Finished last commit, rearranged code for the WidgetManager class.
There is now a GUI options section.
Created a third WidgetManager class called WidgetLoader to handle file loading/saving.
Moved most of the code in WMScreen's draw/clickEvent/motionEvent functions to WidgetManager.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Thu, 21 May 2009 20:55:10 +0200 |
parents | a86f8445ccc8 |
children | 7f7b2011b759 |
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/>. */ /****************************************************************************** * A gui manager class using mde.setup.Screen and mde.input.Input. * * This is the module to use externally to create a graphical user interface * (likely also with content modules). *****************************************************************************/ module mde.gui.WMScreen; import mde.gui.WidgetManager; import mde.gui.WidgetLoader; import mde.gui.widget.Ifaces; import mde.gui.renderer.createRenderer; import mde.setup.Screen; import mde.input.Input; import tango.util.log.Log : Log, Logger; private Logger logger; static this () { logger = Log.getLogger ("mde.gui.WMScreen"); } /****************************************************************************** * The widget manager. * * This provides a layer on top of WidgetLoader, handling input and rendering. * Other functionality is contained in the super class, to simplify supporting * new input/graphics libraries. * * Currently mouse coordinates are passed to widgets untranslated. It may make * sense to translate them and possibly drop events for some uses, such as if * the gui is drawn to a texture. * * Public non IWidget* methods should be thread-safe, even to the same * instance (by locking on a mutex). *****************************************************************************/ scope class WMScreen : AWidgetLoader, Screen.IDrawable { /** Construct a new widget manager. * * Must be run after static this. * * params: * fileName = Name of file specifying the gui, excluding path and extension. */ this (char[] file) { // Doesn't need a lock - cannot conflict with other class functions. super(file); Screen.addDrawable (this); // Events we want to know about: input = Input.singleton; input.addMouseClickCallback(&clickEvent) .addMouseMotionCallback(&motionEvent); } /** Draw the gui. */ void draw() { synchronized(mutex) { debug (mdeDrawEvents) logger.trace ("drawing"); wmDrawWidgets(); } } /** For mouse click events. */ void clickEvent (ushort usx, ushort usy, ubyte b, bool state) { try { mutex.lock; scope(exit) mutex.unlock; wmMouseClick (cast(wdabs) usx, cast(wdabs) usy, b, state); } catch (Exception e) { logger.error ("clickEvent: exception processing event: {}", e.msg); } } /** For mouse motion events. */ void motionEvent (ushort scx, ushort scy) { try { mutex.lock; scope(exit) mutex.unlock; wmMouseMotion (cast(wdabs) scx, cast(wdabs) scy); } catch (Exception e) { logger.error ("motionEvent: exception processing event: {}", e.msg); } } void sizeEvent (int nw, int nh) { // IDrawable function mutex.lock; scope(exit) mutex.unlock; w = cast(wdim) nw; h = cast(wdim) nh; if (w < mw) { logger.warn ("Min width for gui, {}, not met: {}", mw, w); w = mw; } if (h < mh) { logger.warn ("Min height for gui, {}, not met: {}", mh, h); h = mh; } if (!child) return; // if not created yet. child.setWidth (w, -1); child.setHeight (h, -1); child.setPosition (0,0); } protected: final override void setLetterCallback(void delegate(ushort, char[]) dlg) { input.setLetterCallback (dlg); } /* Second stage of widget loading. * Note: sizeEvent should be called with window size before this. */ final override void createRootWidget () { // The renderer needs to be created on the first load, but not after this. if (rend is null) rend = createRenderer (rendName); debug (mdeWidgets) logger.trace ("Creating root widget..."); child = makeWidget (this, "root"); debug (mdeWidgets) logger.trace ("Setting up root widget..."); child.setup (0, 3); mw = child.minWidth; mh = child.minHeight; if (w < mw) { logger.warn ("Min width for gui, {}, not met: {}", mw, w); w = mw; } if (h < mh) { logger.warn ("Min height for gui, {}, not met: {}", mh, h); h = mh; } debug (mdeWidgets) logger.trace ("Setting size and position of root widget..."); child.setWidth (w, -1); child.setHeight (h, -1); child.setPosition (0,0); debug (mdeWidgets) logger.trace ("Done creating root widget."); } final override void preSave () { if (keyFocus) { keyFocus.keyFocusLost; keyFocus = null; input.setLetterCallback (null); } } Input input; // input singleton }