Mercurial > fife-parpg
changeset 177:3fb17daa1b27
* Added ToggleButton widget
* Modified editor to use togglebuttons in toolbox
author | cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 25 Jan 2009 20:17:41 +0000 |
parents | 542213eebe73 |
children | 7dc59bd3d6b1 |
files | clients/editor/content/gui/tools.xml clients/editor/plugins/mapeditor.py engine/core/gui/widgets/togglebutton.cpp engine/core/gui/widgets/togglebutton.h engine/core/gui/widgets/widgets.i engine/extensions/pychan/widgets.py |
diffstat | 6 files changed, 652 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/clients/editor/content/gui/tools.xml Sun Jan 25 19:48:41 2009 +0000 +++ b/clients/editor/content/gui/tools.xml Sun Jan 25 20:17:41 2009 +0000 @@ -1,8 +1,8 @@ <Window title="" titlebar_height="15" margins="0,0"> <VBox padding="0"> - <ImageButton hover_image="icons/hand.png" up_image="icons/hand.png" down_image="icons/hand.png" name="btnSelect" offset="1,1" helptext="Select cells on layer" /> - <ImageButton hover_image="icons/select_layer.png" up_image="icons/select_layer.png" down_image="icons/select_layer.png" name="btnMove" offset="1,1" helptext="Moves instances" /> - <ImageButton hover_image="icons/add_instance.png" up_image="icons/add_instance.png" down_image="icons/add_instance.png" name="btnInsert" offset="1,1" helptext="Adds new instances based on currently selected object" /> - <ImageButton hover_image="icons/quit.png" up_image="icons/quit.png" down_image="icons/quit.png" name="btnDelete" offset="1,1" helptext="Deletes instances" /> + <ToggleButton group="toolbuttons" hover_image="icons/hand.png" up_image="icons/hand.png" down_image="icons/hand.png" name="btnSelect" offset="1,1" helptext="Select cells on layer" /> + <ToggleButton group="toolbuttons" hover_image="icons/select_layer.png" up_image="icons/select_layer.png" down_image="icons/select_layer.png" name="btnMove" offset="1,1" helptext="Moves instances" /> + <ToggleButton group="toolbuttons" hover_image="icons/add_instance.png" up_image="icons/add_instance.png" down_image="icons/add_instance.png" name="btnInsert" offset="1,1" helptext="Adds new instances based on currently selected object" /> + <ToggleButton group="toolbuttons" hover_image="icons/quit.png" up_image="icons/quit.png" down_image="icons/quit.png" name="btnDelete" offset="1,1" helptext="Deletes instances" /> </VBox> </Window>
--- a/clients/editor/plugins/mapeditor.py Sun Jan 25 19:48:41 2009 +0000 +++ b/clients/editor/plugins/mapeditor.py Sun Jan 25 20:17:41 2009 +0000 @@ -85,16 +85,25 @@ self._toolbar.hide() def _enableBtn(self, enabled, btn): - pass - + btn.toggled = enabled; + + def enableSelect(self, enabled): + self._enableBtn(enabled, self._toolbar.findChild(name='btnSelect')) + + def enableMove(self, enabled): + self._enableBtn(enabled, self._toolbar.findChild(name='btnMove')) + def enableInsert(self, enabled): self._enableBtn(enabled, self._toolbar.findChild(name='btnInsert')) - + def enableDelete(self, enabled): self._enableBtn(enabled, self._toolbar.findChild(name='btnDelete')) - def enableSelect(self, enabled): - self._enableBtn(enabled, self._toolbar.findChild(name='btnSelect')) + def disableAll(self): + self.enableDelete(False) + self.enableSelect(False) + self.enableInsert(False) + self.enableMove(False) class StatusBar(object): def __init__(self, screenw, screenh): @@ -157,8 +166,8 @@ rb = self._engine.getRenderBackend() self._statusbar = StatusBar(rb.getWidth(), rb.getHeight()) self._toolbar = Toolbar(cbwa(self._setMode, VIEWING), cbwa(self._setMode, MOVING), - cbwa(self._setMode, INSERTING), cbwa(self._setMode, REMOVING), - self._statusbar.showTooltip, self._statusbar.hideTooltip) + cbwa(self._setMode, INSERTING), cbwa(self._setMode, REMOVING), + self._statusbar.showTooltip, self._statusbar.hideTooltip) self._toolbar.show() self._setMode(NOTHING_LOADED) @@ -173,10 +182,24 @@ def _setMode(self, mode): if (mode != NOTHING_LOADED) and (not self._camera): self._statusbar.setStatus('Please load map first') + self._toolbar.disableAll() return if (mode == INSERTING) and (not self._object): self._statusbar.setStatus('Please select object first') - return + mode = self._mode + + # Update toolbox buttons + if (mode == INSERTING): + self._toolbar.enableInsert(True) + elif mode == VIEWING: + self._toolbar.enableSelect(True) + elif mode == REMOVING: + self._toolbar.enableDelete(True) + elif mode == MOVING: + self._toolbar.enableMove(True) + else: + self._toolbar.disableAll() + self._mode = mode print "Entered mode " + mode self._statusbar.setStatus(mode.replace('_', ' ').capitalize())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/gui/widgets/togglebutton.cpp Sun Jan 25 20:17:41 2009 +0000 @@ -0,0 +1,267 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ +/*************************************************************************** + * Note! Group and groupmap borrows heavily from ideas of Guichan library * + * version 0.8.1 * + ***************************************************************************/ + + + +// Standard C++ library includes +#include <cassert> + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include <iostream> + +#include <guichan/mouseevent.hpp> + +#include "togglebutton.h" + + +namespace gcn { + ToggleButton::GroupMap ToggleButton::m_groupMap; + + ToggleButton::ToggleButton(Image *up_file , Image *down_file, Image *hover_file, const std::string& caption, const std::string& group): + Button(), + m_upImage(up_file), + m_downImage(down_file), + m_hoverImage(hover_file), + x_downoffset(0), + y_downoffset(0), + m_helptext(""), + m_group(group) { + + m_hoverImage = hover_file; + setFrameSize(0); + setGroup(m_group); + adjustSize(); + mCaption = caption; + m_toggled = false; + + addActionListener(this); + } + + ToggleButton::~ToggleButton() { + setGroup(""); // Remove button from group + } + + void ToggleButton::setDownOffset(int x, int y) { + x_downoffset = x; + y_downoffset = y; + } + + void ToggleButton::draw(Graphics *graphics) { + Color faceColor = getBaseColor(); + Color highlightColor; + Color shadowColor; + int alpha = getBaseColor().a; + + Image* img = NULL; + int xoffset = 0; + int yoffset = 0; + + if (isPressed() || m_toggled) { + faceColor = faceColor - 0x303030; + faceColor.a = alpha; + highlightColor = faceColor - 0x303030; + highlightColor.a = alpha; + shadowColor = faceColor + 0x303030; + shadowColor.a = alpha; + + if( m_downImage ) { + img = m_downImage; + xoffset = x_downoffset; + yoffset = y_downoffset; + } + } else if(mHasMouse) { + faceColor = faceColor + 0x303030; + faceColor.a = alpha; + highlightColor = faceColor + 0x303030; + highlightColor.a = alpha; + shadowColor = faceColor - 0x303030; + shadowColor.a = alpha; + + if ( m_hoverImage ) { + img = m_hoverImage; + } + } else{ + highlightColor = faceColor + 0x303030; + highlightColor.a = alpha; + shadowColor = faceColor - 0x303030; + shadowColor.a = alpha; + + if (m_upImage) { + img = m_upImage; + } + } + + + graphics->setColor(faceColor); + graphics->fillRectangle(Rectangle(1, 1, getDimension().width-1, getHeight() - 1)); + + graphics->setColor(highlightColor); + graphics->drawLine(0, 0, getWidth() - 1, 0); + graphics->drawLine(0, 1, 0, getHeight() - 1); + + graphics->setColor(shadowColor); + graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1); + graphics->drawLine(1, getHeight() - 1, getWidth() - 1, getHeight() - 1); + + graphics->setColor(getForegroundColor()); + + if (img) { + graphics->drawImage(img, xoffset, yoffset); + } + + int textX; + int textY = getHeight() / 2 - getFont()->getHeight() / 2; + switch (getAlignment()) + { + case Graphics::LEFT: + textX = 4; + break; + case Graphics::CENTER: + textX = getWidth() / 2; + break; + case Graphics::RIGHT: + textX = getWidth() - 4; + break; + default: + throw GCN_EXCEPTION("Unknown alignment."); + } + + graphics->setFont(getFont()); + if (mCaption.size() > 0) { + if (isPressed()) + graphics->drawText(getCaption(), textX + 1, + textY + 1, getAlignment()); + else + graphics->drawText(getCaption(), textX, textY, getAlignment()); + } + } + + void ToggleButton::action(const ActionEvent& actionEvent) { + setToggled(!m_toggled); + } + + void ToggleButton::adjustSize() { + int w = 0; + int h = w; + if( m_upImage ) { + w = m_upImage->getWidth(); + h = m_upImage->getHeight(); + } + if( m_downImage ) { + w = std::max(m_downImage->getWidth(), w); + h = std::max(m_downImage->getHeight(), h); + } + if( m_hoverImage ) { + w = std::max(m_hoverImage->getWidth(), w); + h = std::max(m_hoverImage->getHeight(), h); + } + setWidth(w); + setHeight(h); + } + + void ToggleButton::setUpImage(Image* image) { + m_upImage = image; + adjustSize(); + } + + void ToggleButton::setDownImage(Image* image) { + m_downImage = image; + adjustSize(); + } + + void ToggleButton::setHoverImage(Image* image) { + m_hoverImage = image; + adjustSize(); + } + + bool ToggleButton::isToggled() const { + return m_toggled; + } + + void ToggleButton::setToggled(bool toggled) { + if (toggled && m_group != "") { + // untoggle all buttons in group + GroupIterator iter, iterEnd; + iterEnd = m_groupMap.upper_bound(m_group); + + for (iter = m_groupMap.lower_bound(m_group); iter != iterEnd; iter++) { + if (iter->second->isToggled()) { + iter->second->setToggled(false); + } + } + } + + m_toggled = toggled; + } + + void ToggleButton::setGroup(const std::string &group) { + // Remove button from previous group + if (m_group != "") { + GroupIterator iter, iterEnd; + iterEnd = m_groupMap.upper_bound(m_group); + + for (iter = m_groupMap.lower_bound(m_group); iter != iterEnd; iter++) { + if (iter->second == this) { + m_groupMap.erase(iter); + break; + } + } + } + + // Add button to new group + if (group != "") { + m_groupMap.insert( std::pair<std::string, ToggleButton *>(group, this)); + } + + m_group = group; + } + + const std::string &ToggleButton::getGroup() const { + return m_group; + } + + int ToggleButton::getDownXOffset() const { + return x_downoffset; + } + + int ToggleButton::getDownYOffset() const { + return y_downoffset; + } + + void ToggleButton::setHelpText(const std::string& txt) { + m_helptext = txt; + } + + const std::string& ToggleButton::getHelpText() { + return m_helptext; + } +} +/* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/gui/widgets/togglebutton.h Sun Jan 25 20:17:41 2009 +0000 @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_GUICHAN_ADDON_TOGGLEBUTTON_H +#define FIFE_GUICHAN_ADDON_TOGGLEBUTTON_H + +// Standard C++ library includes +#include <string> +#include <map> + +// 3rd party library includes +#include <guichan.hpp> +#include <guichan/actionlistener.hpp> + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder + +namespace gcn { + /** + * An implementation of a toggleable button. + * + * If the button is in a group, all other buttons in that group will be untoggled + * when a button gets toggled. If the button is already toggled, you can untoggle + * it by clicking on it. + * + */ + class ToggleButton : public Button, public ActionListener { + public: + /** + * Constructor + * + * @param up_image Image displayed when the button isn't toggled + * @param down_image Image displayed when the button is toggled + * @param hover_file Image displayed when the mouse cursor is over button + * @param caption Text to be displayed on button + * @param group The group the button belongs to + */ + ToggleButton(Image *up_image = 0, Image *down_image = 0, Image *hover_image = 0, const std::string& caption = "", const std::string& group = ""); + + /** + * Destructor + */ + ~ToggleButton(); + + /** + * Draws the button + */ + void draw(Graphics *graphics); + + /** + * Adjust size to fit image + */ + void adjustSize(); + + /** + * Sets the image that will be displayed when the button isn't toggled + * + * @param image Image to be displayed + */ + void setUpImage(Image* image); + + /** + * Sets the image that will be displayed when the button is toggled or pressed + * + * @param image Image to be displayed + */ + void setDownImage(Image* image); + + /** + * Sets the image which will be displayed when the mouse cursor is over the button + * + * @param image Image to be displayed + */ + void setHoverImage(Image* image); + + /** + * Sets the number of pixels the image or text will be offset from + * the top left corner of button when the button is pressed or toggled. + * + * @param x Offset from left + * @param y Offset from top + * @see getDownXOffset + * @see getDownYOffset + */ + void setDownOffset(int x, int y); + + /** + * Gets the number of pixels the image or text will be offset + * from the left of button when the button is pressed or toggled. + * + * @return Offset from left when button is pressed + * @see setDownOffset + */ + int getDownXOffset() const; + + /** + * Gets the number of pixels the image or text will be offset + * from the top of button when the button is pressed or toggled. + * + * @return Offset from top when button is pressed + * @see setDownOffset + */ + int getDownYOffset() const; + + /** + * Sets the help text for the button + * + * @param txt The help text + * + * @see getHelpText + */ + void setHelpText(const std::string& txt); + + /** + * Gets the help text for the button + * + * @return The help text + * + * @see setHelpText + */ + const std::string& getHelpText(); + + /** + * Checks if the radio button is selected. + * + * @return True if the radio button is selecte, false otherwise. + * @see setSelected + */ + bool isToggled() const; + + /** + * Sets the radio button to selected or not. + * + * @param selected True if the radio button should be selected, + * false otherwise. + * @see isSelected + */ + void setToggled(bool toggled); + + // From Guichan 0.8.1 + /** + * Sets the group the toggle button should belong to. Note that + * a toggle button group is unique per application, not per Gui object + * as the group is stored in a static map. + * + * @param group The name of the group. + * @see getGroup + */ + void setGroup(const std::string &group); + + /** + * Gets the group the toggle button belongs to. + * + * @return The group the toggle button belongs to. + * @see setGroup + */ + const std::string &getGroup() const; + + protected: + // Inherited from gcn::Widget + /** + * Toggle button when it is activated + * + * @param actionEvent ActionEvent object + */ + void action(const ActionEvent& actionEvent); + + private: + // Image to be used when the button is not toggle + Image *m_upImage; + + // Image to be used when the button is toggled or pressed + Image *m_downImage; + + // Image to be used when the mouse cursor is over the image + Image *m_hoverImage; + + // Number of pixels the image/text will be offset from the top left + // corner, when the button is pressed or toggled + int x_downoffset; + int y_downoffset; + + // Help text for the button + std::string m_helptext; + + /** + * Whether the button is toggled or not. + */ + bool m_toggled; + + //-- From Guichan 0.8.1 -- + /** + * Holds the group of the toggle button. + */ + std::string m_group; + + /** + * Typedef. + */ + typedef std::multimap<std::string, ToggleButton *> GroupMap; + + /** + * Typedef. + */ + typedef GroupMap::iterator GroupIterator; + + /** + * Holds all available toggle button groups. + */ + static GroupMap m_groupMap; + }; + +} + +#endif +/* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
--- a/engine/core/gui/widgets/widgets.i Sun Jan 25 19:48:41 2009 +0000 +++ b/engine/core/gui/widgets/widgets.i Sun Jan 25 20:17:41 2009 +0000 @@ -22,7 +22,9 @@ %module fife %{ #include <guichan.hpp> +#include <guichan/mouseevent.hpp> #include "gui/widgets/twobutton.h" +#include "gui/widgets/togglebutton.h" #include "gui/widgets/clicklabel.h" #include "gui/widgets/icon2.hpp" %} @@ -193,6 +195,29 @@ void setDownOffset(int x, int y); int getDownXOffset(); int getDownYOffset(); + void setHelpText(const std::string& txt); + const std::string& getHelpText(); + }; + + %feature("notabstract") ToggleButton; + class ToggleButton: public Widget { + public: + ToggleButton(Image *up_image = 0, Image *down_image = 0, Image *hover_image = 0, const char * caption = "", const char * group = ""); + ~ToggleButton(); + virtual void setCaption(const std::string& caption); + virtual const std::string& getCaption() const; + virtual void setAlignment(Graphics::Alignment alignment); + virtual Graphics::Alignment getAlignment() const; + void setUpImage(Image* image); + void setDownImage(Image* image); + void setHoverImage(Image* image); + void setDownOffset(int x, int y); + int getDownXOffset() const; + int getDownYOffset() const; + bool isToggled() const; + void setToggled(bool toggled); + void setGroup(const std::string &group); + const std::string &getGroup() const; void setHelpText(const std::string& txt); const std::string& getHelpText();
--- a/engine/extensions/pychan/widgets.py Sun Jan 25 19:48:41 2009 +0000 +++ b/engine/extensions/pychan/widgets.py Sun Jan 25 20:17:41 2009 +0000 @@ -1207,6 +1207,94 @@ self.height = max(self._upimage.getHeight(),self._downimage.getHeight(),self._hoverimage.getHeight()) + self.margins[1]*2 self.width = max(self._upimage.getWidth(),self._downimage.getWidth(),self._hoverimage.getWidth()) + self.margins[1]*2 +class ToggleButton(BasicTextWidget): + """ + A basic push button that can be toggled. + + Unfortunately a bit of code duplication from ImageButton. + + New Attributes + ============== + + - group: String: The group the button belongs to. Only one button in each group will be toggled at one time. + - toggled: Boolean: Whether the button is toggled or not. + """ + + ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [Attr('up_image'),Attr('down_image'),PointAttr('offset'),Attr('helptext'),Attr('hover_image'),Attr('group')] + + def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),group="",**kwargs): + + self.real_widget = fife.ToggleButton() + super(ToggleButton,self).__init__(**kwargs) + self.group = group + self.up_image = up_image + self.down_image = down_image + self.hover_image = hover_image + self.offset = offset + + def _setGroup(self,group): + self.real_widget.setGroup( group ) + + def _getGroup(self): + return self.real_widget.getGroup() + group = property(_getGroup,_setGroup) + + def _setToggled(self, toggled): + self.real_widget.setToggled( toggled ) + + def _isToggled(self): + return self.real_widget.isToggled() + toggled = property(_isToggled, _setToggled) + + ### + # I didn't want to do this, but this is just cut and paste from the ImageButton class: + ### + + def _setUpImage(self,image): + self._upimage_source = image + try: + self._upimage = get_manager().loadImage(image) + self.real_widget.setUpImage( self._upimage ) + except: + self._upimage = _DummyImage() + def _getUpImage(self): return self._upimage_source + up_image = property(_getUpImage,_setUpImage) + + def _setDownImage(self,image): + self._downimage_source = image + try: + self._downimage = get_manager().loadImage(image) + self.real_widget.setDownImage( self._downimage ) + except: + self._downimage = _DummyImage() + def _getDownImage(self): return self._downimage_source + down_image = property(_getDownImage,_setDownImage) + + def _setHoverImage(self,image): + self._hoverimage_source = image + try: + self._hoverimage = get_manager().loadImage(image) + self.real_widget.setHoverImage( self._hoverimage ) + except: + self._hoverimage = _DummyImage() + def _getHoverImage(self): return self._hoverimage_source + hover_image = property(_getHoverImage,_setHoverImage) + + def _setOffset(self, offset): + self.real_widget.setDownOffset(offset[0], offset[1]) + def _getOffset(self): + return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset()) + offset = property(_getOffset,_setOffset) + + def _setHelpText(self, txt): + self.real_widget.setHelpText(txt) + def _getHelpText(self): + return self.real_widget.getHelpText() + helptext = property(_getHelpText,_setHelpText) + + def resizeToContent(self): + self.height = max(self._upimage.getHeight(),self._downimage.getHeight(),self._hoverimage.getHeight()) + self.margins[1]*2 + self.width = max(self._upimage.getWidth(),self._downimage.getWidth(),self._hoverimage.getWidth()) + self.margins[1]*2 class CheckBox(BasicTextWidget): """ @@ -1729,6 +1817,7 @@ "CheckBox" : CheckBox, "RadioButton" : RadioButton, "ImageButton" : ImageButton, + "ToggleButton" : ToggleButton, #Complexer Widgets / Text io "TextField" : TextField,