Mercurial > projects > mde
view mde/gui/widget/ParentContent.d @ 156:36df0ffe34d2
Fix to reload translations.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Sat, 18 Apr 2009 21:51:03 +0200 |
parents | 4e8819b65882 |
children | f132e599043f |
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 pop-up widget, a switch (tab) widget, and a collapsible widget * (all parent widgets using content). * * Also a border widget (parent not using content). *****************************************************************************/ module mde.gui.widget.ParentContent; import mde.gui.widget.AParentWidget; import mde.gui.widget.layout; import mde.content.AStringContent; import mde.gui.exception; debug { import tango.util.log.Log : Log, Logger; private Logger logger; static this () { logger = Log.getLogger ("mde.gui.widget.ParentContent"); } } /****************************************************************************** * Widget which pops up a ContentListWidget created with its content. * * Is a button displaying a content string, just like DisplayContentWidget. * * Popped up widget is a ContentListWidget created from the same creation data. *****************************************************************************/ class PopupMenuWidget : APopupParentWidget { this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { content_ = cast(Content)c; WDCMinCheck (data, 3,1, content_); super (mgr, parent, id); //popup = mgr.makeWidget (this, data.strings[0], content_); popup = new ContentListWidget (mgr, this, id, data, c); subWidgets = [popup]; cIndex = data.ints[2]; if (cIndex == 0) content_.addCallback (&updateVal); adapter = mgr.renderer.getAdapter; adapter.text = content_.toString (cIndex); adapter.getDimensions (mw, mh); w = mw; h = mh; } override IContent content () { return content_; } override void recursionCheck (widgetID wID, IContent c) { if (wID is id && c is content_) throw new WidgetRecursionException (wID); parent.recursionCheck (wID, c); } override int clickEvent (wdabs, wdabs, ubyte b, bool state) { if (b == 1 && state == true) { if (!pushed) { parentIPPW.addChildIPPW (this); parentIPPW.menuActive = mgr.positionPopup (this, popup); pushed = true; } else if (!parentIPPW.parentMenuActive) { // if not a submenu parentIPPW.removeChildIPPW (this); } } return 0; } override void removedIPPW () { super.removedIPPW; pushed = false; } override void underMouse (bool state) { if (state && !pushed && parentIPPW.menuActive) { parentIPPW.addChildIPPW (this); menuActive = mgr.positionPopup (this, popup, parentIPPW.parentMenuActive); pushed = true; } } override void draw () { mgr.renderer.drawButton (x,y, w,h, pushed); adapter.draw (x,y); } protected: void updateVal (Content) { // callback adapter.text = content_.toString(cIndex); wdim omw = mw, omh = mh; adapter.getDimensions (mw, mh); if (omw != mw) parent.minWChange (this, mw); if (omh != mh) parent.minHChange (this, mh); } bool pushed = false; IRenderer.TextAdapter adapter; Content content_; int cIndex; } /** A "tab" widget: it doesn't display the tabs, but shows one of a number of * widgets dependant on an EnumContent. * * Sizability is set once. Min-size is updated when switching. */ class SwitchWidget : AParentWidget { this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { super (mgr, parent, id); content_ = cast(EnumContent) c; if (content_ is null || (subWidgets.length = content_.list.length) == 0) throw new ContentException (this); WDCheck (data, 1, subWidgets.length); foreach (i,sc; content_.list) subWidgets[i] = mgr.makeWidget (this, data.strings[i], sc); currentW = subWidgets[content_()]; content_.addCallback (&switchWidget); } override IContent content () { return content_; } override bool setup (uint n, uint flags) { bool r = super.setup (n, flags); if (r) { mw = currentW.minWidth; mh = currentW.minHeight; w = currentW.width; h = currentW.height; static if (SIZABILITY & SIZABILITY_ENUM.START_TRUE) isWS = isHS = true; foreach (i,sc; content_.list) { static if (SIZABILITY == SIZABILITY_ENUM.ANY_SUBWIDGETS) { isWS |= subWidgets[i].isWSizable; isHS |= subWidgets[i].isHSizable; } else static if (SIZABILITY == SIZABILITY_ENUM.ALL_SUBWIDGETS) { isWS &= subWidgets[i].isWSizable; isHS &= subWidgets[i].isHSizable; } } } return r; } override void minWChange (IChildWidget widget, wdim nmw) { if (widget !is currentW) return; mw = nmw; parent.minWChange (this, nmw); } override void minHChange (IChildWidget widget, wdim nmh) { if (widget !is currentW) return; mh = nmh; parent.minHChange (this, nmh); } override bool isWSizable () { return isWS; } override bool isHSizable () { return isHS; } override void setWidth (wdim nw, int dir) { w = (nw >= mw ? nw : mw); currentW.setWidth (w, dir); } override void setHeight (wdim nh, int dir) { h = (nh >= mh ? nh : mh); currentW.setHeight (h, dir); } override void setPosition (wdim nx, wdim ny) { x = nx; y = ny; currentW.setPosition (nx,ny); } override IChildWidget getWidget (wdim cx, wdim cy) { return currentW.getWidget (cx, cy); } override void draw () { currentW.draw; } protected: // callback on content_ void switchWidget (Content) { currentW = subWidgets[content_()]; mw = currentW.minWidth; mh = currentW.minHeight; parent.minWChange (this, mw); parent.minHChange (this, mh); // Parent may change size. If it doesn't, we must set child's size. // We can't tell if it did, so do it (call will be fast if size isn't // changed anyway). currentW.setWidth (w, -1); currentW.setHeight (h, -1); currentW.setPosition (x,y); } IChildWidget currentW; EnumContent content_; bool isWS, isHS; // no infrastructure for changing sizability, so need to fix it. } /** A collapsible widget: shows/hides a child dependant on a BoolContent. * * Sizability is set once. Min-size is changed (but cannot force size to 0). * * Uses its content as a switch, which means content cannot be passed through. * A builtin button would improve this. */ class CollapsibleWidget : AParentWidget { this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { super (mgr, parent, id); content_ = cast(BoolContent) c; WDCCheck (data, 1, 1, content_); subWidgets = [mgr.makeWidget (this, data.strings[0], c)]; content_.addCallback (&collapse); } override bool setup (uint n, uint flags) { bool r = super.setup (n, flags); if (r) { collapsed = content_(); if (!collapsed) { mw = subWidgets[0].minWidth; mh = subWidgets[0].minHeight; w = subWidgets[0].width; h = subWidgets[0].height; } } return r; } override IContent content () { return content_; } override void minWChange (IChildWidget widget, wdim nmw) { debug assert (widget is subWidgets[0]); mw = nmw; parent.minWChange (this, nmw); } override void minHChange (IChildWidget widget, wdim nmh) { debug assert (widget is subWidgets[0]); mh = nmh; parent.minHChange (this, nmh); } // Doesn't change: override bool isWSizable () { return subWidgets[0].isWSizable; } override bool isHSizable () { return subWidgets[0].isHSizable; } override void setWidth (wdim nw, int dir) { w = (nw >= mw ? nw : mw); if (!collapsed) subWidgets[0].setWidth (w, dir); } override void setHeight (wdim nh, int dir) { h = (nh >= mh ? nh : mh); if (!collapsed) subWidgets[0].setHeight (h, dir); } override void setPosition (wdim nx, wdim ny) { x = nx; y = ny; if (!collapsed) subWidgets[0].setPosition (nx,ny); } override IChildWidget getWidget (wdim cx, wdim cy) { if (!collapsed) return subWidgets[0].getWidget (cx, cy); else return this; } override void draw () { if (!collapsed) subWidgets[0].draw; } protected: // callback on content_ void collapse (Content) { collapsed = content_(); if (collapsed) { mw = mh = 0; } else { mw = subWidgets[0].minWidth; mh = subWidgets[0].minHeight; } parent.minWChange (this, mw); parent.minHChange (this, mh); if (collapsed) return; // set incase parent didn't: subWidgets[0].setWidth (w, -1); subWidgets[0].setHeight (h, -1); subWidgets[0].setPosition (x,y); } bool collapsed = false; BoolContent content_; } /** Puts a border around its child widget. * * This doesn't allow dragging like widgets in a floating area. * * data.ints[1] is interpreted as flags from IRenderer.Border.BTYPE. * data.strings[0] is an ID for the child widget. */ class BorderWidget : AParentWidget { this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data, IContent c) { super (mgr, parent, id); WDCheck (data, 2, 1); subWidgets = [mgr.makeWidget (this, data.strings[0], c)]; borderType = cast(BTYPE) data.ints[1]; } override bool setup (uint n, uint flags) { if (!subWidgets[0].setup (n, flags) && !(flags & 1)) return false; border = mgr.renderer.getBorder (borderType, false, false); mw = subWidgets[0].minWidth + border.x1 + border.x2; mh = subWidgets[0].minHeight + border.y1 + border.y2; if (w < mw || !subWidgets[0].isWSizable) w = mw; if (h < mh || !subWidgets[0].isHSizable) h = mh; return true; } override void setWidth (wdim nw, int) { debug assert (nw >= mw); w = nw; subWidgets[0].setWidth (w - border.x1 - border.x2, -1); } override void setHeight (wdim nh, int) { debug assert (nh >= mh); h = nh; subWidgets[0].setHeight (h - border.y1 - border.y2, -1); } override bool isWSizable () { return subWidgets[0].isWSizable; } override bool isHSizable () { return subWidgets[0].isHSizable; } override void setPosition (wdim nx, wdim ny) { x = nx; y = ny; subWidgets[0].setPosition (x + border.x1, y + border.y1); } override void minWChange (IChildWidget widget, wdim nmw) { debug assert (widget is subWidgets[0]); mw = nmw + border.x1 + border.x2; parent.minWChange (this, nmw); } override void minHChange (IChildWidget widget, wdim nmh) { debug assert (widget is subWidgets[0]); mh = nmh + border.y1 + border.y2; parent.minHChange (this, nmh); } override void draw () { mgr.renderer.drawBorder (&border, x, y, w, h); subWidgets[0].draw; } override IChildWidget getWidget (wdim cx, wdim cy) { debug assert (cx >= x && cx < x + w && cy >= y && cy < y + h, "getWidget: not on widget (code error)"); if (subWidgets[0].onSelf (cx, cy)) return subWidgets[0]; else return this; } protected: alias IRenderer.Border.BTYPE BTYPE; alias IRenderer.Border.RESIZE RESIZE; BTYPE borderType; // what type of border to put around the widget IRenderer.Border border; }