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,