changeset 157:bb9902910067

input_rework merged! Bad features: * Broken DND for zero-projekt. * Design short-comings.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Tue, 14 Oct 2008 07:41:48 +0000
parents 376b8afc9a18
children 63de2dea08e6
files clients/editor/listener.py clients/editor/plugins/mapeditor.py clients/pychan_demo/dynamic.py clients/pychan_demo/pychan_test.py clients/rio_de_hola/run.py clients/rio_de_hola/scripts/common/eventlistenerbase.py doc/dependencies/dirdeps.dot doc/dependencies/filedeps.dot doc/dependencies/moduledeps.png engine/core/controller/engine.cpp engine/core/eventchannel/eventchannel.i engine/core/eventchannel/eventmanager.cpp engine/core/eventchannel/eventmanager.h engine/core/eventchannel/key/ec_ikeyfilter.h engine/core/eventchannel/key/ec_key.h engine/core/eventchannel/sdl/ec_isdleventlistener.h engine/core/eventchannel/widget/ec_iwidgetcontroller.h engine/core/eventchannel/widget/ec_iwidgetlistener.h engine/core/eventchannel/widget/ec_widgetevent.h engine/core/gui/console/console.cpp engine/core/gui/console/console.h engine/core/gui/guilistener.cpp engine/core/gui/guilistener.h engine/core/gui/guilistener.i engine/core/gui/guimanager.cpp engine/core/gui/guimanager.h engine/core/gui/guimanager.i engine/core/gui/widgets/clicklabel.cpp engine/core/gui/widgets/clicklabel.h engine/core/gui/widgets/twobutton.cpp engine/core/gui/widgets/twobutton.h engine/core/gui/widgets/widgets.i engine/extensions/basicapplication.py engine/extensions/fife_compat.py engine/extensions/pychan/__init__.py engine/extensions/pychan/events.py engine/extensions/pychan/manager.py engine/extensions/pychan/widgets.py
diffstat 38 files changed, 922 insertions(+), 806 deletions(-) [+]
line wrap: on
line diff
--- a/clients/editor/listener.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/editor/listener.py	Tue Oct 14 07:41:48 2008 +0000
@@ -3,21 +3,14 @@
 import fife
 
 class EditorListener(fife.IKeyListener, fife.ICommandListener, fife.IMouseListener, 
-	              fife.ConsoleExecuter, fife.IWidgetListener):
+	              fife.ConsoleExecuter):
 	def __init__(self, app):
 		self.app = app
 		engine = app.engine
 		eventmanager = engine.getEventManager()
-		eventmanager.setNonConsumableKeys([
-			fife.Key.ESCAPE,
-			fife.Key.F10,
-			fife.Key.F9,
-			fife.Key.F8,
-			fife.Key.TAB,
-			fife.Key.LEFT,
-			fife.Key.RIGHT,
-			fife.Key.UP,
-			fife.Key.DOWN])
+		#eventmanager.setNonConsumableKeys([
+			#fife.Key.ESCAPE,
+			#fife.Key.TAB,])
 		
 		fife.IKeyListener.__init__(self)
 		eventmanager.addKeyListener(self)
@@ -27,8 +20,6 @@
 		eventmanager.addMouseListener(self)
 		fife.ConsoleExecuter.__init__(self)
 		engine.getGuiManager().getConsole().setConsoleExecuter(self)
-		fife.IWidgetListener.__init__(self)
-		eventmanager.addWidgetListener(self)
 	
 		self.engine = engine		
 		self.showTileOutline = True
--- a/clients/editor/plugins/mapeditor.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/editor/plugins/mapeditor.py	Tue Oct 14 07:41:48 2008 +0000
@@ -124,11 +124,11 @@
 	def __init__(self, engine):
 		self._engine = engine
 		eventmanager = self._engine.getEventManager()
-		eventmanager.setNonConsumableKeys([
-			fife.Key.LEFT,
-			fife.Key.RIGHT,
-			fife.Key.UP,
-			fife.Key.DOWN])
+		#eventmanager.setNonConsumableKeys([
+			#fife.Key.LEFT,
+			#fife.Key.RIGHT,
+			#fife.Key.UP,
+			#fife.Key.DOWN])
 		fife.IMouseListener.__init__(self)
 		eventmanager.addMouseListener(self)
 		fife.IKeyListener.__init__(self)
--- a/clients/pychan_demo/dynamic.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/pychan_demo/dynamic.py	Tue Oct 14 07:41:48 2008 +0000
@@ -19,15 +19,35 @@
 
 from pychan_test import PyChanExample
 
+class Test(object):
+	def __init__(self,button,text1,text2):
+		super(Test,self).__init__()
+		self.button = button
+		self.text1 = text1
+		self.text2 = text2
+		self.button.text = text1
+
+	def mouseEntered(self, event):
+		print event
+		self.button.text = self.text2
+
+	def mouseExited(self, event):
+		print event
+		self.button.text = self.text1
+
+
 class DynamicExample(PyChanExample):
 	def __init__(self):
 		super(DynamicExample,self).__init__('gui/dynamic.xml')
 		
 	def start(self):
 		self.widget = pychan.loadXML(self.xmlFile)
+		self.l = Test(self.widget.findChild(name="okButton"),"Ok?","Ok!")
 		self.widget.mapEvents({
 			'okButton'   :self.stop,
 			'addButton'  :self.addLabel,
+			'okButton/mouseEntered' : self.l.mouseEntered,
+			'okButton/mouseExited'  : self.l.mouseExited
 		})
 		self.labelBox = self.widget.findChild(name="labelBox")
 		self.widget.show()
--- a/clients/pychan_demo/pychan_test.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/pychan_demo/pychan_test.py	Tue Oct 14 07:41:48 2008 +0000
@@ -52,6 +52,9 @@
 			'slider': self.test_slider
 		}
 		self.gui.mapEvents(eventMap)
+		credits = self.gui.findChild(name="creditsLink")
+		credits.setEnterCallback(lambda w : credits._setText("CREDITS"))
+		credits.capture(lambda : credits._setText("Credits"), event_name="mouseExited")
 
 		from dynamic import DynamicExample
 		from styling import StylingExample
@@ -82,7 +85,6 @@
 
 	def showCredits(self):
 		print pychan.loadXML('gui/credits.xml').execute({ 'okButton' : "Yay!" })
-		
 	def test_slider(self):
 		self.slider_value._setText( str(self.slider.getValue()) )
 
--- a/clients/rio_de_hola/run.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/rio_de_hola/run.py	Tue Oct 14 07:41:48 2008 +0000
@@ -15,6 +15,7 @@
 if not os.path.exists('settings.xml'):
 	shutil.copyfile('settings-dist.xml', 'settings.xml')
 
+import fife_compat
 import fife, fifelog
 from scripts import world
 from scripts.common import eventlistenerbase
@@ -31,12 +32,7 @@
 		self.engine = engine
 		self.world = world
 		engine.getEventManager().setNonConsumableKeys([
-			fife.Key.ESCAPE,
-			fife.Key.F10,
-			fife.Key.LEFT,
-			fife.Key.RIGHT,
-			fife.Key.UP,
-			fife.Key.DOWN])
+			fife.Key.ESCAPE,])
 
 		self.quit = False
 		self.aboutWindow = None
@@ -50,6 +46,7 @@
 		self.rootpanel.show()
 
 	def keyPressed(self, evt):
+		print evt
 		keyval = evt.getKey().getValue()
 		keystr = evt.getKey().getAsString().lower()
 		consumed = False
--- a/clients/rio_de_hola/scripts/common/eventlistenerbase.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/clients/rio_de_hola/scripts/common/eventlistenerbase.py	Tue Oct 14 07:41:48 2008 +0000
@@ -1,6 +1,6 @@
 import fife
 
-class EventListenerBase(fife.IKeyListener, fife.ICommandListener, fife.IMouseListener, fife.ConsoleExecuter, fife.IWidgetListener):
+class EventListenerBase(fife.IKeyListener, fife.ICommandListener, fife.IMouseListener, fife.ConsoleExecuter):
 	def __init__(self, engine, regKeys=False, regCmd=False, regMouse=False, regConsole=False, regWidget=False):
 		self.eventmanager = engine.getEventManager()
 
@@ -16,9 +16,6 @@
 		fife.ConsoleExecuter.__init__(self)
 		if regConsole:
 			engine.getGuiManager().getConsole().setConsoleExecuter(self)
-		fife.IWidgetListener.__init__(self)
-		if regWidget:
-			self.eventmanager.addWidgetListener(self)
 
 
 	def mousePressed(self, evt):
--- a/doc/dependencies/dirdeps.dot	Sun Oct 12 20:30:09 2008 +0000
+++ b/doc/dependencies/dirdeps.dot	Tue Oct 14 07:41:48 2008 +0000
@@ -30,7 +30,7 @@
     style=filled;
     color=lightgrey;
     node [style=filled,color=white];
-    "eventchannel"; "eventchannel/base"; "eventchannel/command"; "eventchannel/key"; "eventchannel/mouse"; "eventchannel/sdl"; "eventchannel/source"; "eventchannel/trigger"; "eventchannel/widget"
+    "eventchannel"; "eventchannel/base"; "eventchannel/command"; "eventchannel/key"; "eventchannel/mouse"; "eventchannel/sdl"; "eventchannel/source"; "eventchannel/trigger"
     label = "eventchannel";
 }
 subgraph cluster_4 {
@@ -124,18 +124,15 @@
     "eventchannel" -> "eventchannel/mouse"
     "eventchannel" -> "eventchannel/sdl"
     "eventchannel" -> "eventchannel/trigger"
-    "eventchannel" -> "eventchannel/widget"
     "eventchannel" -> "util/base"
     "eventchannel/base" -> "eventchannel/source"
     "eventchannel/command" -> "eventchannel/base"
     "eventchannel/key" -> "eventchannel/base"
     "eventchannel/key" -> "eventchannel/source"
     "eventchannel/mouse" -> "eventchannel/base"
-    "eventchannel/widget" -> "eventchannel/base"
     "gui" -> "eventchannel/key"
     "gui" -> "eventchannel/mouse"
     "gui" -> "eventchannel/sdl"
-    "gui" -> "eventchannel/widget"
     "gui" -> "gui/base"
     "gui" -> "gui/console"
     "gui" -> "util/base"
--- a/doc/dependencies/filedeps.dot	Sun Oct 12 20:30:09 2008 +0000
+++ b/doc/dependencies/filedeps.dot	Tue Oct 14 07:41:48 2008 +0000
@@ -82,11 +82,11 @@
     "engine/core/eventchannel/command/ec_command.h" -> "eventchannel/base/ec_event.h"
     "engine/core/eventchannel/command/ec_icommandcontroller.h" -> "ec_icommandlistener.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/command/ec_command.h"
+    "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/key/ec_ikeyfilter.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/key/ec_key.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/key/ec_keyevent.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/mouse/ec_mouseevent.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/trigger/ec_trigger.h"
-    "engine/core/eventchannel/eventmanager.cpp" -> "eventchannel/widget/ec_widgetevent.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "eventmanager.h"
     "engine/core/eventchannel/eventmanager.cpp" -> "util/base/exception.h"
     "engine/core/eventchannel/eventmanager.h" -> "eventchannel/command/ec_command.h"
@@ -102,9 +102,7 @@
     "engine/core/eventchannel/eventmanager.h" -> "eventchannel/sdl/ec_isdleventcontroller.h"
     "engine/core/eventchannel/eventmanager.h" -> "eventchannel/sdl/ec_isdleventlistener.h"
     "engine/core/eventchannel/eventmanager.h" -> "eventchannel/trigger/ec_itriggercontroller.h"
-    "engine/core/eventchannel/eventmanager.h" -> "eventchannel/widget/ec_iwidgetcontroller.h"
-    "engine/core/eventchannel/eventmanager.h" -> "eventchannel/widget/ec_iwidgetlistener.h"
-    "engine/core/eventchannel/eventmanager.h" -> "eventchannel/widget/ec_widgetevent.h"
+    "engine/core/eventchannel/key/ec_ikeyfilter.h" -> "ec_keyevent.h"
     "engine/core/eventchannel/key/ec_keyevent.h" -> "ec_key.h"
     "engine/core/eventchannel/key/ec_keyevent.h" -> "eventchannel/base/ec_inputevent.h"
     "engine/core/eventchannel/key/ec_keyevent.h" -> "eventchannel/source/ec_ieventsource.h"
@@ -112,8 +110,6 @@
     "engine/core/eventchannel/source/ec_ieventsource.h" -> "ec_eventsourcetypes.h"
     "engine/core/eventchannel/trigger/ec_trigger.h" -> "ec_itriggercontroller.h"
     "engine/core/eventchannel/trigger/ec_trigger.h" -> "ec_itriggerlistener.h"
-    "engine/core/eventchannel/widget/ec_iwidgetcontroller.h" -> "ec_iwidgetlistener.h"
-    "engine/core/eventchannel/widget/ec_widgetevent.h" -> "eventchannel/base/ec_event.h"
     "engine/core/gui/base/gui_font.cpp" -> "gui_font.h"
     "engine/core/gui/base/gui_font.cpp" -> "util/structures/rect.h"
     "engine/core/gui/base/gui_font.cpp" -> "video/image.h"
@@ -149,22 +145,20 @@
     "engine/core/gui/console/console.cpp" -> "util/time/timemanager.h"
     "engine/core/gui/console/console.cpp" -> "video/renderbackend.h"
     "engine/core/gui/console/console.h" -> "util/time/timer.h"
+    "engine/core/gui/guilistener.cpp" -> "guilistener.h"
     "engine/core/gui/guimanager.cpp" -> "eventchannel/key/ec_keyevent.h"
     "engine/core/gui/guimanager.cpp" -> "eventchannel/mouse/ec_mouseevent.h"
-    "engine/core/gui/guimanager.cpp" -> "eventchannel/widget/ec_widgetevent.h"
     "engine/core/gui/guimanager.cpp" -> "gui/base/gui_font.h"
     "engine/core/gui/guimanager.cpp" -> "gui/base/gui_imageloader.h"
     "engine/core/gui/guimanager.cpp" -> "gui/console/console.h"
     "engine/core/gui/guimanager.cpp" -> "guimanager.h"
+    "engine/core/gui/guimanager.cpp" -> "util/base/exception.h"
     "engine/core/gui/guimanager.cpp" -> "util/log/logger.h"
     "engine/core/gui/guimanager.cpp" -> "video/fonts/fontbase.h"
     "engine/core/gui/guimanager.cpp" -> "video/fonts/subimagefont.h"
     "engine/core/gui/guimanager.cpp" -> "video/fonts/truetypefont.h"
     "engine/core/gui/guimanager.cpp" -> "video/renderbackend.h"
-    "engine/core/gui/guimanager.h" -> "eventchannel/key/ec_ikeylistener.h"
-    "engine/core/gui/guimanager.h" -> "eventchannel/mouse/ec_imouselistener.h"
     "engine/core/gui/guimanager.h" -> "eventchannel/sdl/ec_isdleventlistener.h"
-    "engine/core/gui/guimanager.h" -> "eventchannel/widget/ec_iwidgetlistener.h"
     "engine/core/gui/guimanager.h" -> "util/base/singleton.h"
     "engine/core/gui/widgets/clicklabel.cpp" -> "clicklabel.h"
     "engine/core/gui/widgets/clicklabel.cpp" -> "gui/base/gui_font.h"
Binary file doc/dependencies/moduledeps.png has changed
--- a/engine/core/controller/engine.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/controller/engine.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -207,13 +207,9 @@
 			m_gui_graphics = new SdlGuiGraphics(*m_imagepool);
 		}
 		FL_LOG(_log, "Constructing GUI manager");
-		m_guimanager = new GUIManager(m_eventmanager, *m_imagepool);
+		m_guimanager = new GUIManager(*m_imagepool);
+		FL_LOG(_log, "Events bind to GUI manager");
 		m_eventmanager->addSdlEventListener(m_guimanager);
-		// keep guimanager as the first key listener so that it can evaluate guichan hits
-		m_eventmanager->addKeyListener(m_guimanager);
-		// keep guimanager as the first mouse listener so that it can evaluate guichan hits
-		m_eventmanager->addMouseListener(m_guimanager);
-		FL_LOG(_log, "Events bind to GUI manager");
 
 		FL_LOG(_log, "Creating default font");
 		m_defaultfont = m_guimanager->setDefaultFont(
--- a/engine/core/eventchannel/eventchannel.i	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/eventchannel/eventchannel.i	Tue Oct 14 07:41:48 2008 +0000
@@ -29,12 +29,11 @@
 #include "eventchannel/key/ec_key.h"
 #include "eventchannel/key/ec_keyevent.h"
 #include "eventchannel/key/ec_ikeylistener.h"
+#include "eventchannel/key/ec_ikeyfilter.h"
 #include "eventchannel/source/ec_eventsourcetypes.h"
 #include "eventchannel/source/ec_ieventsource.h"
 #include "eventchannel/mouse/ec_mouseevent.h"
 #include "eventchannel/mouse/ec_imouselistener.h"
-#include "eventchannel/widget/ec_widgetevent.h"
-#include "eventchannel/widget/ec_iwidgetlistener.h"
 #include "eventchannel/eventmanager.h"
 %}
 
@@ -168,19 +167,11 @@
 		virtual ~IMouseListener();
 	};
 
-	class WidgetEvent: public Event {
+	%feature("director") IKeyFilter;
+	class IKeyFilter {
 	public:
-		virtual const std::string& getId();
-		virtual ~WidgetEvent();
-	private:
-		WidgetEvent();
-	};
-
-	%feature("director") IWidgetListener;
-	class IWidgetListener {
-	public:
-		virtual void onWidgetAction(WidgetEvent& evt) = 0;
-		virtual ~IWidgetListener();
+		virtual bool isFiltered(const KeyEvent& evt) = 0;
+		virtual ~IKeyFilter();
 	};
 
 	class EventManager {
@@ -193,11 +184,8 @@
 		void removeKeyListener(IKeyListener* listener);
 		void addMouseListener(IMouseListener* listener);
 		void removeMouseListener(IMouseListener* listener);
-		void addWidgetListener(IWidgetListener* listener);
-		void removeWidgetListener(IWidgetListener* listener);
 		EventSourceType getEventSourceType();
 		void dispatchCommand(Command& command);
-		void setNonConsumableKeys(const std::vector<int>& keys);
-		std::vector<int> getNonConsumableKeys();
+		void setKeyFilter(IKeyFilter* keyFilter);
 	};
 };
--- a/engine/core/eventchannel/eventmanager.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/eventchannel/eventmanager.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -31,8 +31,8 @@
 #include "util/base/exception.h"
 #include "eventchannel/key/ec_key.h"
 #include "eventchannel/key/ec_keyevent.h"
+#include "eventchannel/key/ec_ikeyfilter.h"
 #include "eventchannel/mouse/ec_mouseevent.h"
-#include "eventchannel/widget/ec_widgetevent.h"
 #include "eventchannel/command/ec_command.h"
 #include "eventchannel/trigger/ec_trigger.h"
 
@@ -45,10 +45,8 @@
 		m_keylisteners(),
 		m_mouselisteners(),
 		m_sdleventlisteners(),
-		m_widgetlisteners(),
-		m_pending_widgetlisteners(),
-		m_nonconsumablekeys(),
 		m_keystatemap(),
+		m_keyfilter(0),
 		m_mousestate(0),
 		m_mostrecentbtn(MouseEvent::EMPTY)
  	{
@@ -57,71 +55,6 @@
 	EventManager::~EventManager() {
 	}
 
-	void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
-		mouseevt.setX(sdlevt.button.x);
-		mouseevt.setY(sdlevt.button.y);
-		mouseevt.setButton(MouseEvent::EMPTY);
-		mouseevt.setType(MouseEvent::MOVED);
-		if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
-			switch (sdlevt.button.button) {
-				case SDL_BUTTON_LEFT:
-					mouseevt.setButton(MouseEvent::LEFT);
-					break;
-				case SDL_BUTTON_RIGHT:
-					mouseevt.setButton(MouseEvent::RIGHT);
-					break;
-				case SDL_BUTTON_MIDDLE:
-					mouseevt.setButton(MouseEvent::MIDDLE);
-					break;
-				default:
-					mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
-					break;
-			}
-
-
-			if (sdlevt.type == SDL_MOUSEBUTTONUP ) {
-
-				mouseevt.setType(MouseEvent::RELEASED);
-
-			} else {
-				mouseevt.setType(MouseEvent::PRESSED);
-			}
-
-			switch (sdlevt.button.button) {
-				case SDL_BUTTON_WHEELDOWN:
-					mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
-					break;
-				case SDL_BUTTON_WHEELUP:
-					mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
-					break;
-				default:
-					break;
-			}
-		}
-		if ((mouseevt.getType() == MouseEvent::MOVED) && m_mousestate) {
-			mouseevt.setType(MouseEvent::DRAGGED);
-			mouseevt.setButton(m_mostrecentbtn);
-		}
-	}
-
-	void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
-		if (sdlevt.type == SDL_KEYDOWN) {
-			keyevt.setType(KeyEvent::PRESSED);
-		} else if (sdlevt.type == SDL_KEYUP) {
-			keyevt.setType(KeyEvent::RELEASED);
-		} else {
-			throw EventException("Invalid event type in fillKeyEvent");
-		}
-		SDL_keysym keysym = sdlevt.key.keysym;
-
-		keyevt.setShiftPressed(keysym.mod & KMOD_SHIFT);
-		keyevt.setControlPressed(keysym.mod & KMOD_CTRL);
-		keyevt.setAltPressed(keysym.mod & KMOD_ALT);
-		keyevt.setMetaPressed(keysym.mod & KMOD_META);
-		keyevt.setNumericPad(keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS);
-		keyevt.setKey(Key(static_cast<Key::KeyType>(keysym.sym), keysym.unicode));
-	}
-
 	template<typename T>
 	void removeListener(std::vector<T>& vec, T& listener) {
 		vec.push_back(listener);
@@ -164,14 +97,6 @@
 		removeListener<ISdlEventListener*>(m_pending_sdldeletions, listener);
 	}
 
-	void EventManager::addWidgetListener(IWidgetListener* listener) {
-		addListener<IWidgetListener*>(m_pending_widgetlisteners, listener);
-	}
-
-	void EventManager::removeWidgetListener(IWidgetListener* listener) {
-		removeListener<IWidgetListener*>(m_pending_wldeletions, listener);
-	}
-
 	void EventManager::dispatchCommand(Command& command) {
 		if(!m_pending_commandlisteners.empty()) {
 			std::vector<ICommandListener*>::iterator i = m_pending_commandlisteners.begin();
@@ -209,15 +134,6 @@
 	}
 
 	void EventManager::dispatchKeyEvent(KeyEvent& evt) {
-		bool nonconsumablekey = false;
-		for (std::vector<int>::iterator it = m_nonconsumablekeys.begin();
-		     it != m_nonconsumablekeys.end(); ++it) {
-			if (*it == evt.getKey().getValue()) {
-				nonconsumablekey = true;
-				break;
-			}
-		}
-
 		if(!m_pending_keylisteners.empty()) {
 			std::vector<IKeyListener*>::iterator i = m_pending_keylisteners.begin();
 			while (i != m_pending_keylisteners.end()) {
@@ -255,25 +171,10 @@
 				default:
 					break;
 			}
-			if ((!nonconsumablekey) && (evt.isConsumed())) {
-				break;
-			}
 			++i;
 		}
 	}
 
-	void EventManager::fillModifiers(InputEvent& evt) {
-		evt.setAltPressed(m_keystatemap[Key::ALT_GR] |
-						m_keystatemap[Key::LEFT_ALT] |
-						m_keystatemap[Key::RIGHT_ALT]);
-		evt.setControlPressed(m_keystatemap[Key::LEFT_CONTROL] |
-							m_keystatemap[Key::RIGHT_CONTROL]);
-		evt.setMetaPressed(m_keystatemap[Key::LEFT_META] |
-							m_keystatemap[Key::RIGHT_META]);
-		evt.setShiftPressed(m_keystatemap[Key::LEFT_SHIFT] |
-							m_keystatemap[Key::RIGHT_SHIFT]);
-	}
-
 	void EventManager::dispatchMouseEvent(MouseEvent& evt) {
 		if(!m_pending_mouselisteners.empty()) {
 			std::vector<IMouseListener*>::iterator i = m_pending_mouselisteners.begin();
@@ -340,7 +241,8 @@
 		}
 	}
 
-	void EventManager::dispatchSdlEvent(SDL_Event& evt) {
+	bool EventManager::dispatchSdlEvent(SDL_Event& evt) {
+		bool ret = false;
 		if (!m_pending_sdleventlisteners.empty()) {
 			std::vector<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners.begin();
 			while(i != m_pending_sdleventlisteners.end()) {
@@ -368,49 +270,10 @@
 
 		std::vector<ISdlEventListener*>::iterator i = m_sdleventlisteners.begin();
 		while (i != m_sdleventlisteners.end()) {
-			(*i)->onSdlEvent(evt);
+			ret = ret || (*i)->onSdlEvent(evt);
 			++i;
 		}
-	}
-
-	void EventManager::dispatchWidgetEvent(WidgetEvent& evt) {
-		if(!m_pending_widgetlisteners.empty()) {
-			std::vector<IWidgetListener*>::iterator i = m_pending_widgetlisteners.begin();
-			while (i != m_pending_widgetlisteners.end()) {
-				m_widgetlisteners.push_back(*i);
-				++i;
-			}
-			m_pending_widgetlisteners.clear();
-		}
-
-		if (!m_pending_wldeletions.empty()) {
-			std::vector<IWidgetListener*>::iterator i = m_pending_wldeletions.begin();
-			while (i != m_pending_wldeletions.end()) {
-				std::vector<IWidgetListener*>::iterator j = m_widgetlisteners.begin();
-				while (j != m_widgetlisteners.end()) {
-					if(*j == *i) {
-						m_widgetlisteners.erase(j);
-						break;
-					}
-					++j;
-				}
-				++i;
-			}
-			m_pending_wldeletions.clear();
-		}
-
-		std::vector<IWidgetListener*>::iterator i = m_widgetlisteners.begin();
-		while (i != m_widgetlisteners.end()) {
-			(*i)->onWidgetAction(evt);
-			if (evt.isConsumed()) {
-				break;
-			}
-			++i;
-		}
-	}
-
-	void EventManager::onWidgetAction(WidgetEvent& evt) {
-		dispatchWidgetEvent(evt);
+		return ret;
 	}
 
 	bool EventManager::combineEvents(SDL_Event& event1, const SDL_Event& event2) {
@@ -430,14 +293,16 @@
 		return false;
 	}
 
-	void EventManager::processEvents(){
-		SDL_Event event, newevent;
-		bool has_event = SDL_PollEvent(&event);
-		while (has_event) {
-			has_event = SDL_PollEvent(&newevent);
-			if(has_event && combineEvents(event, newevent))
+	void EventManager::processEvents() {
+		// The double SDL_PollEvent calls don't throw away events,
+		// but try to combine (mouse motion) events.
+		SDL_Event event, next_event;
+		bool has_next_event = SDL_PollEvent(&event);
+		while (has_next_event) {
+			has_next_event = SDL_PollEvent(&next_event);
+			if(has_next_event && combineEvents(event, next_event))
 				continue;
-			dispatchSdlEvent(event);
+
 			switch (event.type) {
 				case SDL_QUIT: {
 					Command cmd;
@@ -446,85 +311,180 @@
 					dispatchCommand(cmd);
 					}
 					break;
-				case SDL_ACTIVEEVENT: {
-					Command cmd;
-					cmd.setSource(this);
-					SDL_ActiveEvent actevt = event.active;
-					if (actevt.state == SDL_APPMOUSEFOCUS)
-					{
-						if (actevt.gain)
-							cmd.setCommandType(CMD_MOUSE_FOCUS_GAINED);
-						else
-							cmd.setCommandType(CMD_MOUSE_FOCUS_LOST);
-					}
-					else if (actevt.state == SDL_APPINPUTFOCUS)
-					{
-						if (actevt.gain)
-							cmd.setCommandType(CMD_INPUT_FOCUS_GAINED);
-						else
-							cmd.setCommandType(CMD_INPUT_FOCUS_LOST);
-					}
-					else if (actevt.state == SDL_APPACTIVE)
-					{
-						if (actevt.gain)
-							cmd.setCommandType(CMD_APP_RESTORED);
-						else
-							cmd.setCommandType(CMD_APP_ICONIFIED);
-					}
-					dispatchCommand(cmd);
-					}
+
+				case SDL_ACTIVEEVENT:
+					processActiveEvent(event);
 					break;
+
 				case SDL_KEYDOWN:
-				case SDL_KEYUP: {
-					KeyEvent keyevt;
-					keyevt.setSource(this);
-					fillKeyEvent(event, keyevt);
-					m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
-					dispatchKeyEvent(keyevt);
-					}
+				case SDL_KEYUP:
+					processKeyEvent(event);
 					break;
+
 				case SDL_MOUSEBUTTONUP:
 				case SDL_MOUSEMOTION:
-				case SDL_MOUSEBUTTONDOWN: {
-					MouseEvent mouseevt;
-					mouseevt.setSource(this);
-					fillMouseEvent(event, mouseevt);
-					fillModifiers(mouseevt);
-					if (event.type == SDL_MOUSEBUTTONDOWN) {
-						m_mousestate |= static_cast<int>(mouseevt.getButton());
-						m_mostrecentbtn = mouseevt.getButton();
-					} else if (event.type == SDL_MOUSEBUTTONUP) {
-						m_mousestate &= ~static_cast<int>(mouseevt.getButton());
-					}
-					// fire scrollwheel events only once
-					if (event.button.button == SDL_BUTTON_WHEELDOWN || event.button.button == SDL_BUTTON_WHEELUP) {
-						if (event.type == SDL_MOUSEBUTTONUP) {
-							break;
-						}
-					}
-					dispatchMouseEvent(mouseevt);
-					}
+				case SDL_MOUSEBUTTONDOWN:
+					processMouseEvent(event);
 					break;
 			}
-			if(has_event)
-				event = newevent;
+			if(has_next_event)
+				event = next_event;
+		}
+		pollTriggers();
+	}
+
+	void EventManager::processActiveEvent(SDL_Event event) {
+		if(dispatchSdlEvent(event))
+			return;
+
+		Command cmd;
+		cmd.setSource(this);
+		SDL_ActiveEvent actevt = event.active;
+		if (actevt.state == SDL_APPMOUSEFOCUS)
+		{
+			if (actevt.gain)
+				cmd.setCommandType(CMD_MOUSE_FOCUS_GAINED);
+			else
+				cmd.setCommandType(CMD_MOUSE_FOCUS_LOST);
+		}
+		else if (actevt.state == SDL_APPINPUTFOCUS)
+		{
+			if (actevt.gain)
+				cmd.setCommandType(CMD_INPUT_FOCUS_GAINED);
+			else
+				cmd.setCommandType(CMD_INPUT_FOCUS_LOST);
+		}
+		else if (actevt.state == SDL_APPACTIVE)
+		{
+			if (actevt.gain)
+				cmd.setCommandType(CMD_APP_RESTORED);
+			else
+				cmd.setCommandType(CMD_APP_ICONIFIED);
+		}
+		dispatchCommand(cmd);
+	}
+
+	void EventManager::processKeyEvent(SDL_Event event) {
+		KeyEvent keyevt;
+		keyevt.setSource(this);
+		fillKeyEvent(event, keyevt);
+		m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
+
+		bool dispatchAsSdl = !keyevt.getKey().isFunctionKey();
+		if( dispatchAsSdl && m_keyfilter ) {
+			dispatchAsSdl = !m_keyfilter->isFiltered(keyevt);
+		}
+
+		if( dispatchAsSdl ) {
+			if( dispatchSdlEvent(event) )
+				return;
 		}
 
-		pollTriggers();
+		dispatchKeyEvent(keyevt);
+	}
+
+	void EventManager::processMouseEvent(SDL_Event event) {
+		if(dispatchSdlEvent(event))
+			return;
+
+		MouseEvent mouseevt;
+		mouseevt.setSource(this);
+		fillMouseEvent(event, mouseevt);
+		fillModifiers(mouseevt);
+		if (event.type == SDL_MOUSEBUTTONDOWN) {
+			m_mousestate |= static_cast<int>(mouseevt.getButton());
+			m_mostrecentbtn = mouseevt.getButton();
+		} else if (event.type == SDL_MOUSEBUTTONUP) {
+			m_mousestate &= ~static_cast<int>(mouseevt.getButton());
+		}
+		// fire scrollwheel events only once
+		if (event.button.button == SDL_BUTTON_WHEELDOWN || event.button.button == SDL_BUTTON_WHEELUP) {
+			if (event.type == SDL_MOUSEBUTTONUP) {
+				return;
+			}
+		}
+		dispatchMouseEvent(mouseevt);
+	}
+
+
+	void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
+		mouseevt.setX(sdlevt.button.x);
+		mouseevt.setY(sdlevt.button.y);
+		mouseevt.setButton(MouseEvent::EMPTY);
+		mouseevt.setType(MouseEvent::MOVED);
+		if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
+			switch (sdlevt.button.button) {
+				case SDL_BUTTON_LEFT:
+					mouseevt.setButton(MouseEvent::LEFT);
+					break;
+				case SDL_BUTTON_RIGHT:
+					mouseevt.setButton(MouseEvent::RIGHT);
+					break;
+				case SDL_BUTTON_MIDDLE:
+					mouseevt.setButton(MouseEvent::MIDDLE);
+					break;
+				default:
+					mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
+					break;
+			}
+
+			if (sdlevt.type == SDL_MOUSEBUTTONUP ) {
+				mouseevt.setType(MouseEvent::RELEASED);
+			} else {
+				mouseevt.setType(MouseEvent::PRESSED);
+			}
+
+			switch (sdlevt.button.button) {
+				case SDL_BUTTON_WHEELDOWN:
+					mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
+					break;
+				case SDL_BUTTON_WHEELUP:
+					mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
+					break;
+				default:
+					break;
+			}
+		}
+		if ((mouseevt.getType() == MouseEvent::MOVED) && m_mousestate) {
+			mouseevt.setType(MouseEvent::DRAGGED);
+			mouseevt.setButton(m_mostrecentbtn);
+		}
+	}
+
+	void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
+		if (sdlevt.type == SDL_KEYDOWN) {
+			keyevt.setType(KeyEvent::PRESSED);
+		} else if (sdlevt.type == SDL_KEYUP) {
+			keyevt.setType(KeyEvent::RELEASED);
+		} else {
+			throw EventException("Invalid event type in fillKeyEvent");
+		}
+		SDL_keysym keysym = sdlevt.key.keysym;
+
+		keyevt.setShiftPressed(keysym.mod & KMOD_SHIFT);
+		keyevt.setControlPressed(keysym.mod & KMOD_CTRL);
+		keyevt.setAltPressed(keysym.mod & KMOD_ALT);
+		keyevt.setMetaPressed(keysym.mod & KMOD_META);
+		keyevt.setNumericPad(keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS);
+		keyevt.setKey(Key(static_cast<Key::KeyType>(keysym.sym), keysym.unicode));
+	}
+	
+	void EventManager::fillModifiers(InputEvent& evt) {
+		evt.setAltPressed(m_keystatemap[Key::ALT_GR] |
+			m_keystatemap[Key::LEFT_ALT] |
+			m_keystatemap[Key::RIGHT_ALT]);
+		evt.setControlPressed(m_keystatemap[Key::LEFT_CONTROL] |
+			m_keystatemap[Key::RIGHT_CONTROL]);
+		evt.setMetaPressed(m_keystatemap[Key::LEFT_META] |
+			m_keystatemap[Key::RIGHT_META]);
+		evt.setShiftPressed(m_keystatemap[Key::LEFT_SHIFT] |
+			m_keystatemap[Key::RIGHT_SHIFT]);
 	}
 
 	EventSourceType EventManager::getEventSourceType() {
 		return ES_ENGINE;
 	}
 
-	void EventManager::setNonConsumableKeys(const std::vector<int>& keys) {
-		m_nonconsumablekeys = keys;
-	}
-
-	std::vector<int> EventManager::getNonConsumableKeys() {
-		return m_nonconsumablekeys;
-	}
-
 	void EventManager::registerTrigger(Trigger& trigger){
 		m_triggers.push_back(&trigger);
 	}
@@ -538,4 +498,8 @@
 			(*it)->pollTrigger();
 		}
 	}
+
+	void EventManager::setKeyFilter(IKeyFilter* keyFilter) {
+		m_keyfilter = keyFilter;
+	}
 }
--- a/engine/core/eventchannel/eventmanager.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/eventchannel/eventmanager.h	Tue Oct 14 07:41:48 2008 +0000
@@ -52,10 +52,6 @@
 #include "eventchannel/sdl/ec_isdleventcontroller.h"
 #include "eventchannel/sdl/ec_isdleventlistener.h"
 
-#include "eventchannel/widget/ec_iwidgetcontroller.h"
-#include "eventchannel/widget/ec_iwidgetlistener.h"
-#include "eventchannel/widget/ec_widgetevent.h"
-
 #include "eventchannel/trigger/ec_itriggercontroller.h"
 
 namespace FIFE {
@@ -64,6 +60,7 @@
 	class InputEvent;
 	class MouseEvent;
 	class KeyEvent;
+	class IKeyFilter;
 
 	/**  Event Manager manages all events related to FIFE
 	 */
@@ -72,9 +69,7 @@
 		public IKeyController, 
 		public IMouseController, 
 		public ISdlEventController, 
-		public IWidgetController,
 		public IEventSource,
-		public IWidgetListener,
 		public ITriggerController {
 	public:
 		/** Constructor.
@@ -94,13 +89,7 @@
 		void removeMouseListener(IMouseListener* listener);
 		void addSdlEventListener(ISdlEventListener* listener);
 		void removeSdlEventListener(ISdlEventListener* listener);
-		void addWidgetListener(IWidgetListener* listener);
-		void removeWidgetListener(IWidgetListener* listener);
 		EventSourceType getEventSourceType();
-		void setNonConsumableKeys(const std::vector<int>& keys);
-		std::vector<int> getNonConsumableKeys();
-
-		void onWidgetAction(WidgetEvent& evt);
 
 		void registerTrigger(Trigger& trigger);
 		void unregisterTrigger(Trigger& trigger);
@@ -111,15 +100,25 @@
 		 */
 		void processEvents();
 
+		void setKeyFilter(IKeyFilter* keyFilter);
+
 	private:
+		// Helpers for processEvents
+		void processActiveEvent(SDL_Event event);
+		void processKeyEvent(SDL_Event event);
+		void processMouseEvent(SDL_Event event);
 		bool combineEvents(SDL_Event& event1, const SDL_Event& event2);
+
+		// Events dispatchers - only dispatchSdlevent may reject the event.
+		bool dispatchSdlEvent(SDL_Event& evt);
 		void dispatchKeyEvent(KeyEvent& evt);
 		void dispatchMouseEvent(MouseEvent& evt);
-		void dispatchSdlEvent(SDL_Event& evt);
-		void dispatchWidgetEvent(WidgetEvent& evt);
+
+		// Translate events
 		void fillModifiers(InputEvent& evt);
 		void fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt);
 		void fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt);
+
 		void pollTriggers();
 		
 		std::vector<ICommandListener*> m_commandlisteners;
@@ -138,12 +137,8 @@
 		std::vector<ISdlEventListener*> m_pending_sdleventlisteners;
 		std::vector<ISdlEventListener*> m_pending_sdldeletions;
 
-		std::vector<IWidgetListener*> m_widgetlisteners;
-		std::vector<IWidgetListener*> m_pending_widgetlisteners;
-		std::vector<IWidgetListener*> m_pending_wldeletions;
-
-		std::vector<int> m_nonconsumablekeys;
 		std::map<int, bool> m_keystatemap;
+		IKeyFilter* m_keyfilter;
 		int m_mousestate;
 		MouseEvent::MouseButtonType m_mostrecentbtn;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/eventchannel/key/ec_ikeyfilter.h	Tue Oct 14 07:41:48 2008 +0000
@@ -0,0 +1,55 @@
+/***************************************************************************
+ *   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_EVENTCHANNEL_IKEYFILTER_H
+#define FIFE_EVENTCHANNEL_IKEYFILTER_H
+
+// Standard C++ library includes
+//
+
+// 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 "ec_keyevent.h"
+
+namespace FIFE {
+	/**  Controller provides a way to receive events from the system
+	 * Using this interface, clients can subscribe themselves to receive events
+	 */
+	class IKeyFilter {
+	public:
+
+		/** Check whether a keyevent should be filtered out.
+		 * @param event They key event.
+		 */
+		virtual bool isFiltered(const KeyEvent& event) = 0;
+
+		virtual ~IKeyFilter() {}
+	};
+
+} //FIFE
+
+#endif
--- a/engine/core/eventchannel/key/ec_key.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/eventchannel/key/ec_key.h	Tue Oct 14 07:41:48 2008 +0000
@@ -296,6 +296,9 @@
 			return m_unicode != 0;
 		}
 		
+		bool isFunctionKey() const {
+			return m_key >= F1 && m_key <= F15;
+		}
 		
 		/** Gets the value of the key. 
 		 */
--- a/engine/core/eventchannel/sdl/ec_isdleventlistener.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/eventchannel/sdl/ec_isdleventlistener.h	Tue Oct 14 07:41:48 2008 +0000
@@ -46,7 +46,7 @@
 		/** Called when an SDL event is received from SDL
 		 * @param evt SDL event
 		 */
-		virtual void onSdlEvent(SDL_Event& evt) = 0;
+		virtual bool onSdlEvent(SDL_Event& evt) = 0;
 
 		virtual ~ISdlEventListener() {}
 	};
--- a/engine/core/eventchannel/widget/ec_iwidgetcontroller.h	Sun Oct 12 20:30:09 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/***************************************************************************
- *   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_EVENTCHANNEL_IWIDGET_CONTROLLER_H
-#define FIFE_EVENTCHANNEL_IWIDGET_CONTROLLER_H
-
-// Standard C++ library includes
-//
-
-// 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 "ec_iwidgetlistener.h"
-
-namespace FIFE {
-
-	/**  Controller provides a way to receive events from the system
-	 * Using this interface, clients can subscribe themselves to receive events
-	 */
-	class IWidgetController {
-	public:
-
-		/** Adds a listener to the controller
-		 * Listener will be notified via the corresponding events
-		 * @param listener listener to add
-		 */
-		virtual void addWidgetListener(IWidgetListener* listener) = 0;
-
-		/** Removes an added listener from the controller.
-		 * Listener will not be notified anymore via the corresponding events
-		 * @param listener listener to remove
-		 */
-		virtual void removeWidgetListener(IWidgetListener* listener) = 0;
-
-		virtual ~IWidgetController() {}
-	};
-
-} //FIFE
-
-#endif
--- a/engine/core/eventchannel/widget/ec_iwidgetlistener.h	Sun Oct 12 20:30:09 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/***************************************************************************
- *   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_EVENTCHANNEL_IWIDGETLISTENER_H
-#define FIFE_EVENTCHANNEL_IWIDGETLISTENER_H
-
-// Standard C++ library includes
-//
-
-// 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
-//
-
-namespace FIFE {
-	class WidgetEvent;
-
-	/**  Listener of widget events.
-	 * To be able to listen for widget events you must make a class which inherits 
-	 * from this class and implements its functions.
-	 */
-	class IWidgetListener {
-	public:
-		/**
-		 * Called when an action is recieved from a Widget. It is used
-		 * to be able to recieve a notification that an action has
-		 * occured.
-		 * @param evy the event of the action.
-		 */
-		virtual void onWidgetAction(WidgetEvent& evt) = 0;
-
-		virtual ~IWidgetListener() {}
-	};
-} //FIFE
-
-#endif
--- a/engine/core/eventchannel/widget/ec_widgetevent.h	Sun Oct 12 20:30:09 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/***************************************************************************
- *   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_EVENTCHANNEL_WIDGETEVENT_H
-#define FIFE_EVENTCHANNEL_WIDGETEVENT_H
-
-// Standard C++ library includes
-//
-
-// 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 "eventchannel/base/ec_event.h"
-
-namespace FIFE {
-	/**  Interface for widget events
-	 * Events are sent by different UI widgets
-	 */
-	class WidgetEvent: public Event {
-	public:
-		/** Constructor.
-		 */
-		WidgetEvent(): 
-			Event(),
-			m_id("") {}
-
-		/** Destructor.
-		 */
-		~WidgetEvent() {}
-
-		/**
-		 * Gets the id of the event.
-		 * @return the id of the event.
-		 */
-		const std::string& getId() const { return m_id; }
-		void setId(const std::string& id) { m_id = id; }
-
-		virtual void consume() { Event::consume(); }
-		virtual bool isConsumed() const { return Event::isConsumed(); }
-		virtual IEventSource* getSource() { return Event::getSource(); }
-		virtual void setSource(IEventSource* source) { Event::setSource(source); }
-		virtual gcn::Widget* getSourceWidget() { return Event::getSourceWidget(); }
-		virtual void setSourceWidget(gcn::Widget* widget) { Event::setSourceWidget(widget); }
-		virtual int getTimeStamp() const { return Event::getTimeStamp(); }
-		virtual void setTimeStamp(int timestamp ) { Event::setTimeStamp(timestamp); }
-		virtual const std::string& getName() const {
-			const static std::string eventName("WidgetEvent");
-			return eventName;
-		}
-		virtual std::string getDebugString() const { return Event::getDebugString(); }
-
-	private:
-		std::string m_id;
-	};
-
-} //FIFE
-
-#endif
--- a/engine/core/gui/console/console.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/console/console.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -78,6 +78,8 @@
 		m_animationTimer.setCallback( boost::bind(&Console::updateAnimation, this) );
 
 		m_toolsbutton->addActionListener(this);
+		m_toolsbutton->setFocusable(false);
+		m_input->addFocusListener(this);
 
 		GuiFont* font = GUIManager::instance()->createFont();
 		font->setColor(255,255,255);
@@ -299,5 +301,9 @@
 		m_input->setFont(font);
 		m_output->setFont(font);
 	}
+
+	void Console::focusLost(const gcn::Event& ) {
+		hide();
+	}
 }
 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
--- a/engine/core/gui/console/console.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/console/console.h	Tue Oct 14 07:41:48 2008 +0000
@@ -61,7 +61,7 @@
 
 	/** Ingame Console
 	 */
-	class Console : public gcn::Container, public gcn::ActionListener {
+	class Console : public gcn::Container, public gcn::ActionListener, public gcn::FocusListener {
 		public:
 			/** Constructor
 			 */
@@ -138,6 +138,9 @@
 			 */
 			void setIOFont(GuiFont* font);
 
+			/** Hide if we loose focus
+			*/
+			void focusLost(const gcn::Event& event);
 		private:
 
 			bool m_isAttached;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/gui/guilistener.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -0,0 +1,43 @@
+/***************************************************************************
+ *   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          *
+ ***************************************************************************/
+
+// Standard C++ library includes
+#include <iostream>
+
+// 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 "guilistener.h"
+
+
+namespace FIFE {
+
+	GUIEventListener::GUIEventListener() {
+	}
+
+	GUIEventListener::~GUIEventListener() {
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/gui/guilistener.h	Tue Oct 14 07:41:48 2008 +0000
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   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_VIDEO_GUI_GUILISTENER_H
+#define FIFE_VIDEO_GUI_GUILISTENER_H
+
+// Standard C++ library includes
+#include <set>
+
+// 3rd party library includes
+#include <guichan.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 FIFE {
+
+	class GUIEventListener 
+		: public gcn::MouseListener, public gcn::KeyListener, public gcn::ActionListener {
+	public:
+		GUIEventListener();
+		virtual ~GUIEventListener();
+		virtual void action(const gcn::ActionEvent& actionEvent) {};
+	};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/gui/guilistener.i	Tue Oct 14 07:41:48 2008 +0000
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *   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          *
+ ***************************************************************************/
+
+%module fife
+%{
+#include <guichan.hpp>
+#include "gui/guilistener.h"
+%}
+
+namespace gcn {
+
+	%nodefaultctor;
+	class MouseListener {
+	public:
+	};
+
+	class KeyListener {
+	public:
+	};
+
+	class ActionListener {
+	public:
+	};
+	%clearnodefaultctor;
+}
+
+namespace FIFE {
+
+	%feature("director") GUIEventListener;
+	class GUIEventListener : 
+		public gcn::MouseListener, public gcn::KeyListener, public gcn::ActionListener {
+	public:
+		 GUIEventListener();
+		 virtual ~GUIEventListener();
+
+		/* Mouse events */
+		virtual void mouseEntered(gcn::MouseEvent& mouseEvent);
+		virtual void mouseExited(gcn::MouseEvent& mouseEvent);
+		virtual void mousePressed(gcn::MouseEvent& mouseEvent);
+		virtual void mouseReleased(gcn::MouseEvent& mouseEvent);
+		virtual void mouseClicked(gcn::MouseEvent& mouseEvent);
+		virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+		virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+		virtual void mouseMoved(gcn::MouseEvent& mouseEvent);
+		virtual void mouseDragged(gcn::MouseEvent& mouseEvent);
+
+		virtual void action(const gcn::ActionEvent& actionEvent);
+
+	};
+
+}
--- a/engine/core/gui/guimanager.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/guimanager.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -32,6 +32,7 @@
 // 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 "util/base/exception.h"
 #include "util/log/logger.h"
 #include "video/renderbackend.h"
 #include "gui/base/gui_imageloader.h"
@@ -40,7 +41,6 @@
 #include "video/fonts/fontbase.h"
 #include "video/fonts/truetypefont.h"
 #include "video/fonts/subimagefont.h"
-#include "eventchannel/widget/ec_widgetevent.h"
 #include "eventchannel/key/ec_keyevent.h"
 #include "eventchannel/mouse/ec_mouseevent.h"
 
@@ -50,24 +50,26 @@
 namespace FIFE {
 	static Logger _log(LM_GUI);
 
-	GUIManager::GUIManager(IWidgetListener* widgetlistener, ImagePool& pool) : 
+	GUIManager::GUIManager(ImagePool& pool) :
 		m_gcn_gui(new gcn::Gui()), 
 		m_focushandler(0),
-        	m_gcn_topcontainer(new gcn::Container()), 
-        	m_imgloader(new GuiImageLoader(pool)) , 
-        	m_input(new gcn::SDLInput()),
-        	m_console(0),
-        	m_fonts(),
-		m_widgetlistener(widgetlistener),
+		m_gcn_topcontainer(new gcn::Container()),
+		m_imgloader(new GuiImageLoader(pool)) ,
+		m_input(new gcn::SDLInput()),
+		m_console(0),
+		m_fonts(),
 		m_pool(pool),
 		m_logic_executed(false) {
-		
-		m_gcn_gui->setTop(m_gcn_topcontainer);
-		m_gcn_topcontainer->setOpaque(false);
+
 		m_gcn_gui->setInput(m_input);
+		gcn::Image::setImageLoader(m_imgloader);
 
-		gcn::Image::setImageLoader(m_imgloader);
+		m_gcn_gui->setTop(m_gcn_topcontainer);
 		m_focushandler = m_gcn_topcontainer->_getFocusHandler();
+
+		m_gcn_topcontainer->setOpaque(false);
+		m_gcn_topcontainer->setFocusable(false);
+		m_had_mouse = false;
 	}
 
 	GUIManager::~GUIManager() {
@@ -83,13 +85,54 @@
 		}
 	}
 
-	void GUIManager::onSdlEvent(SDL_Event& evt) {
+	bool GUIManager::onSdlEvent(SDL_Event& evt) {
 		gcn::SDLInput *input = dynamic_cast<gcn::SDLInput*>(m_gcn_gui->getInput());
 		if (!input) {
 			FL_WARN(_log, "GUIManager, GuichanGUI->getInput == 0 ... discarding events!");
-			return;
+			return false;
 		}
-		input->pushInput(evt);
+
+		switch(evt.type) {
+			case SDL_MOUSEBUTTONDOWN:
+			case SDL_MOUSEBUTTONUP:
+				if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) {
+					input->pushInput(evt);
+					return true;
+				}
+				m_focushandler->focusNone();
+				return false;
+
+			case SDL_MOUSEMOTION:
+				if( m_gcn_topcontainer->getWidgetAt(evt.button.x,evt.button.y) ) {
+					m_had_mouse = true;
+					input->pushInput(evt);
+					return true;
+				}
+				if( m_had_mouse ) {
+					m_had_mouse = false;
+					input->pushInput(evt);
+					return true;
+				}
+				return false;
+
+			case SDL_KEYDOWN:
+			case SDL_KEYUP:
+				if(m_focushandler->getFocused()) {
+					input->pushInput(evt);
+					return true;
+				}
+				return false;
+
+			case SDL_ACTIVEEVENT:
+				if( evt.active.state & SDL_APPMOUSEFOCUS ) {
+					input->pushInput(evt);
+					return true;
+				}
+				return false;
+
+			default:
+				return false;
+		}
 	}
 
 	void GUIManager::resizeTopContainer(unsigned int x, unsigned int y, unsigned int width, unsigned int height) {
@@ -176,56 +219,85 @@
 	}
 
 	void GUIManager::turn() {
-		if (!m_logic_executed) {
-			// Due to a BUG in Guichan we need to catch GCN exceptions
-			// This is a potentially dangerous workaround put in place
-			// until we upgrade to Guichan 0.8.0
-			// See here: http://code.google.com/p/guichan/issues/detail?id=24
-			try {
-				m_gcn_gui->logic();
-			} catch( const gcn::Exception& e) {
-				FL_WARN(_log, LMsg("GUIManager, discarding gcn::Exception: ") << e.getMessage());
-			}
-		}
+		if (!m_logic_executed)
+			m_gcn_gui->logic();
+		m_logic_executed = false;
 		m_gcn_gui->draw();
-		m_logic_executed = false;
 	}
 
-	void GUIManager::action(const gcn::ActionEvent & event) {
-		WidgetEvent wevt;
-		wevt.setId(event.getId());
-		wevt.setSourceWidget(event.getSource());
-		m_widgetlistener->onWidgetAction(wevt);
+	KeyEvent GUIManager::translateKeyEvent(const gcn::KeyEvent& gcnevt) {
+		KeyEvent keyevt;
+		if(gcnevt.getType() == gcn::KeyEvent::PRESSED)
+			keyevt.setType(KeyEvent::PRESSED);
+		else if(gcnevt.getType() == gcn::KeyEvent::RELEASED)
+			keyevt.setType(KeyEvent::RELEASED);
+		else
+			throw EventException("Invalid event type in fillKeyEvent");
+		keyevt.setShiftPressed(gcnevt.isShiftPressed());
+		keyevt.setControlPressed(gcnevt.isControlPressed());
+		keyevt.setAltPressed(gcnevt.isAltPressed());
+		keyevt.setMetaPressed(gcnevt.isMetaPressed());
+		keyevt.setNumericPad(gcnevt.isNumericPad());
+		keyevt.setKey(Key(static_cast<Key::KeyType>(gcnevt.getKey().getValue()), gcnevt.getKey().getValue()));
+		return keyevt;
 	}
 
-	void GUIManager::evaluateKeyEventConsumption(KeyEvent& evt) {
-		gcn::Widget* w = m_focushandler->getFocused();
-		if (w) {
-			evt.consumedByWidgets();
+	MouseEvent GUIManager::translateMouseEvent(const gcn::MouseEvent& gcnevt) {
+		MouseEvent mouseevt;
+		mouseevt.setShiftPressed(gcnevt.isShiftPressed());
+		mouseevt.setControlPressed(gcnevt.isControlPressed());
+		mouseevt.setAltPressed(gcnevt.isAltPressed());
+		mouseevt.setMetaPressed(gcnevt.isMetaPressed());
+		mouseevt.setX(gcnevt.getX());
+		mouseevt.setY(gcnevt.getY());
+
+		switch(gcnevt.getType()) {
+			case gcn::MouseEvent::PRESSED:
+				mouseevt.setType(MouseEvent::PRESSED);
+				break;
+			case gcn::MouseEvent::RELEASED:
+				mouseevt.setType(MouseEvent::RELEASED);
+				break;
+			case gcn::MouseEvent::MOVED:
+				mouseevt.setType(MouseEvent::MOVED);
+				break;
+			case gcn::MouseEvent::CLICKED:
+				mouseevt.setType(MouseEvent::CLICKED);
+				break;
+			case gcn::MouseEvent::ENTERED:
+				mouseevt.setType(MouseEvent::ENTERED);
+				break;
+			case gcn::MouseEvent::EXITED:
+				mouseevt.setType(MouseEvent::EXITED);
+				break;
+			case gcn::MouseEvent::DRAGGED:
+				mouseevt.setType(MouseEvent::DRAGGED);
+				break;
+			case gcn::MouseEvent::WHEEL_MOVED_DOWN:
+				mouseevt.setType(MouseEvent::WHEEL_MOVED_DOWN);
+				break;
+			case gcn::MouseEvent::WHEEL_MOVED_UP:
+				mouseevt.setType(MouseEvent::WHEEL_MOVED_UP);
+				break;
+			default:
+				mouseevt.setType(MouseEvent::UNKNOWN_EVENT);
 		}
-	}
 
-	void GUIManager::evaluateMouseEventConsumption(MouseEvent& evt) {
-		gcn::Widget* w = m_gcn_topcontainer->getWidgetAt(evt.getX(), evt.getY());
-		if (w && w->isVisible()) {
-			evt.consumedByWidgets();
+		switch(gcnevt.getButton()) {
+			case gcn::MouseInput::LEFT:
+				mouseevt.setButton(MouseEvent::LEFT);
+				break;
+			case gcn::MouseInput::RIGHT:
+				mouseevt.setButton(MouseEvent::RIGHT);
+				break;
+			case gcn::MouseInput::MIDDLE:
+				mouseevt.setButton(MouseEvent::MIDDLE);
+				break;
+			default:
+				mouseevt.setButton(MouseEvent::UNKNOWN_BUTTON);
+				break;
 		}
+		return mouseevt;
 	}
 
-	void GUIManager::mousePressed(MouseEvent& evt) {
- 		evaluateMouseEventConsumption(evt);
-		if (!evt.isConsumedByWidgets()) {
-			m_focushandler->focusNone();
-		}
-	}
-	
-	void GUIManager::mouseDragged(MouseEvent& evt) {
-		try {
-			m_gcn_gui->logic();
-			m_logic_executed = true;
-		} catch( const gcn::Exception& e) {
-			FL_WARN(_log, LMsg("GUIManager, discarding gcn::Exception: ") << e.getMessage());
-		}
-		evaluateMouseEventConsumption(evt);
-	}
 }
--- a/engine/core/gui/guimanager.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/guimanager.h	Tue Oct 14 07:41:48 2008 +0000
@@ -34,9 +34,8 @@
 // Second block: files included from the same folder
 #include "util/base/singleton.h"
 #include "eventchannel/sdl/ec_isdleventlistener.h"
-#include "eventchannel/mouse/ec_imouselistener.h"
-#include "eventchannel/key/ec_ikeylistener.h"
-#include "eventchannel/widget/ec_iwidgetlistener.h"
+// #include "eventchannel/mouse/ec_imouselistener.h"
+// #include "eventchannel/key/ec_ikeylistener.h"
 
 namespace gcn {
 
@@ -65,15 +64,12 @@
 	 */
 	class GUIManager : 
 		public DynamicSingleton<GUIManager>, 
-		public ISdlEventListener,
-		public IKeyListener,
-		public IMouseListener,
-		public gcn::ActionListener
+		public ISdlEventListener
 		 {
 		public:
 			/** Constructor.
 			 */
-			GUIManager(IWidgetListener* widgetListener, ImagePool& pool);
+			GUIManager(ImagePool& pool);
 			/** Destructor.
 			 */
 			virtual ~GUIManager();
@@ -140,27 +136,12 @@
 			 */
 			void releaseFont(GuiFont* font);
 
-			/** Callback from guichan
-			 */
-			void action(const gcn::ActionEvent & event);
+			bool onSdlEvent(SDL_Event& evt);
 
-			void onSdlEvent(SDL_Event& evt);
-			void keyPressed(KeyEvent& evt) { evaluateKeyEventConsumption(evt); }
-			void keyReleased(KeyEvent& evt) { evaluateKeyEventConsumption(evt); }
-			void mouseEntered(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseExited(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mousePressed(MouseEvent& evt);
-			void mouseReleased(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseClicked(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseWheelMovedUp(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseWheelMovedDown(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseMoved(MouseEvent& evt) { evaluateMouseEventConsumption(evt); }
-			void mouseDragged(MouseEvent& evt);
+			KeyEvent translateKeyEvent(const gcn::KeyEvent& evt);
+			MouseEvent translateMouseEvent(const gcn::MouseEvent& evt);
 
 		private:
-			void evaluateKeyEventConsumption(KeyEvent& evt);
-			void evaluateMouseEventConsumption(MouseEvent& evt);
-
 			// The Guichan GUI.
 			gcn::Gui* m_gcn_gui;
 			// Focus handler for input management
@@ -178,8 +159,9 @@
 			// Added widgets
 			std::set<gcn::Widget*> m_widgets;
 
-			// instance whom to deliver widget events coming from guichan
-			IWidgetListener* m_widgetlistener;
+			// Used to accept mouse motion events that leave widget space
+			bool m_had_mouse;
+
 			// pool used for images
 			ImagePool& m_pool;
 
--- a/engine/core/gui/guimanager.i	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/guimanager.i	Tue Oct 14 07:41:48 2008 +0000
@@ -27,25 +27,23 @@
 
 namespace gcn {
 	class Widget;
-	class ActionEvent;
-	class ActionListener {
-	public:
-		virtual void action(const ActionEvent& actionEvent) = 0;
-	};
 }
 namespace FIFE {
 	class Console;
 	
 	%feature("notabstract") GUIManager;
-	class GUIManager: public gcn::ActionListener {
+	class GUIManager {
 	public:
 		Console* getConsole();
 		void add(gcn::Widget* widget);
 		void remove(gcn::Widget* widget);
 		GuiFont* createFont(const std::string& path, unsigned int size, const std::string& glyphs);
 		void releaseFont(GuiFont* font);
+
+		KeyEvent translateKeyEvent(const gcn::KeyEvent& evt);
+		MouseEvent translateMouseEvent(const gcn::MouseEvent& evt);
 		
 	private:
-		GUIManager(IWidgetListener* widgetListener);
+		GUIManager();
 	};
 }
--- a/engine/core/gui/widgets/clicklabel.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/widgets/clicklabel.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -40,7 +40,6 @@
 // 		setAlignment(Graphics::LEFT);
 		setTextWrapping(false);
 		setFrameSize(0);
-		m_listener = NULL;
 		addMouseListener(this);
 		addKeyListener(this);
 		addFocusListener(this);
@@ -53,7 +52,6 @@
 		setTextWrapping(false);
 		setCaption(caption);
 		setFrameSize(0);
-		m_listener = NULL;
 		addMouseListener(this);
 		addKeyListener(this);
 		addFocusListener(this);
@@ -141,19 +139,11 @@
 	
 	void ClickLabel::mouseExited(MouseEvent& mouseEvent)
 	{
-		// taken from TwoButton.cpp
-		if (m_listener) {
-			m_listener->mouseExited(*this);
-		}		
 		mHasMouse = false;
 	}
 	
 	void ClickLabel::mouseEntered(MouseEvent& mouseEvent)
 	{
-		// taken from TwoButton.cpp
-		if (m_listener) {
-			m_listener->mouseEntered(*this);
-		}		
 		mHasMouse = true;
 	}
 	
--- a/engine/core/gui/widgets/clicklabel.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/widgets/clicklabel.h	Tue Oct 14 07:41:48 2008 +0000
@@ -39,18 +39,6 @@
 
 namespace gcn {
 	
-	// taken from TwoButton.cpp
-	// FIXME: the listener code for Twobutton and Clicklabel is 
-	// a kind of a hack and shouldn't be necessary later. So if 
-	// eventmanager changes some day, this should be modified, too
-	class ClickLabel;
-	class ClickLabelListener {
-	public:
-		virtual ~ClickLabelListener() {}
-		virtual void mouseEntered(ClickLabel& btn) = 0;
-		virtual void mouseExited(ClickLabel& btn) = 0;
-	};	
-	
 	class ClickLabel : public Widget, public MouseListener, public KeyListener, public FocusListener {
 	public:
 		ClickLabel();
@@ -92,11 +80,6 @@
 	
 		virtual void keyReleased(KeyEvent& keyEvent);
 
-
-			// taken from TwoButton.cpp
-			void setListener(ClickLabelListener* listener) { m_listener = listener; }
-			ClickLabelListener* getListener() { return m_listener; }
-
 	protected:
 		void wrapText();
 
@@ -104,7 +87,6 @@
 		bool mTextWrapping;
 		std::string mCaption;
 		std::string mWrappedText;
-		ClickLabelListener* m_listener;		
 
 		bool mHasMouse;
 		bool mKeyPressed;
--- a/engine/core/gui/widgets/twobutton.cpp	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/widgets/twobutton.cpp	Tue Oct 14 07:41:48 2008 +0000
@@ -39,7 +39,6 @@
 		m_hoverImage(hover_file),
 		x_downoffset(0),
 		y_downoffset(0),
-		m_listener(NULL),
 		m_helptext("") {
 		m_hoverImage = hover_file;
 		setFrameSize(0);
@@ -139,19 +138,6 @@
 		adjustSize();
 	}
 		
-	void TwoButton::mouseEntered(MouseEvent& mouseEvent) {
-		if (m_listener) {
-			m_listener->mouseEntered(*this);
-		}
-		Button::mouseEntered(mouseEvent);
-	}
-	
-	void TwoButton::mouseExited(MouseEvent& mouseEvent) {
-		if (m_listener) {
-			m_listener->mouseExited(*this);
-		}
-		Button::mouseExited(mouseEvent);
-	}
 }
 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
 
--- a/engine/core/gui/widgets/twobutton.h	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/widgets/twobutton.h	Tue Oct 14 07:41:48 2008 +0000
@@ -36,13 +36,7 @@
 namespace gcn {
 
 	class TwoButton;
-	class TwoButtonListener {
-	public:
-		virtual ~TwoButtonListener() {}
-		virtual void mouseEntered(TwoButton& btn) = 0;
-		virtual void mouseExited(TwoButton& btn) = 0;
-	};
-	
+
 	class TwoButton : public Button {
 		public:
 			TwoButton(Image *up_image = 0, Image *down_image = 0, Image *hover_file = 0, const std::string& caption = "");
@@ -58,12 +52,6 @@
 			int getDownXOffset() { return x_downoffset; }
 			int getDownYOffset() { return y_downoffset; }
 			
-		        void mouseEntered(MouseEvent& mouseEvent);
-		        void mouseExited(MouseEvent& mouseEvent);
-			
-			void setListener(TwoButtonListener* listener) { m_listener = listener; }
-			TwoButtonListener* getListener() { return m_listener; }
-
 			void setHelpText(const std::string& txt) { m_helptext = txt; }
 			const std::string& getHelpText() { return m_helptext; }
 		
@@ -73,7 +61,6 @@
 			Image *m_hoverImage;
 			int x_downoffset;
 			int y_downoffset;
-			TwoButtonListener* m_listener;
 			std::string m_helptext;
 	};
 
--- a/engine/core/gui/widgets/widgets.i	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/core/gui/widgets/widgets.i	Tue Oct 14 07:41:48 2008 +0000
@@ -31,6 +31,8 @@
 	class Font;
 	class Image;
 	class ActionListener;
+	class MouseListener;
+	class KeyListener;
 
 	%nodefaultctor;
 	class Graphics {
@@ -117,6 +119,10 @@
 		virtual void focusPrevious() { };
 		virtual void addActionListener(ActionListener* actionListener);
 		virtual void removeActionListener(ActionListener* actionListener);
+		virtual void addMouseListener(MouseListener* actionListener);
+		virtual void removeMouseListener(MouseListener* actionListener);
+		virtual void addKeyListener(KeyListener* actionListener);
+		virtual void removeKeyListener(KeyListener* actionListener);
 /* 	protected: */
 		virtual void draw(Graphics* graphics) = 0;
 	};
@@ -171,16 +177,6 @@
 		virtual void adjustSize();
 		/*virtual bool isPressed() const;*/
 	};
-
-	
-	class TwoButton;
-	%feature("director") TwoButtonListener;
-	class TwoButtonListener {
-	public:
-		virtual ~TwoButtonListener();
-		virtual void mouseEntered(TwoButton& btn) = 0;
-		virtual void mouseExited(TwoButton& btn) = 0;
-	};
 		
 	%feature("notabstract") TwoButton;
 	class TwoButton: public Widget {
@@ -197,8 +193,6 @@
 		void setDownOffset(int x, int y);
 		int getDownXOffset();
 		int getDownYOffset();
-		void setListener(TwoButtonListener* listener);
-		TwoButtonListener* getListener();
 
 		void setHelpText(const std::string& txt);
 		const std::string& getHelpText();
@@ -379,15 +373,6 @@
 		virtual void resizeToContent();
 	};
 
-	class ClickLabel;
-	%feature("director") ClickLabelListener;
-	class ClickLabelListener {
-	public:
-		virtual ~ClickLabelListener();
-		virtual void mouseEntered(ClickLabel& btn) = 0;
-		virtual void mouseExited(ClickLabel& btn) = 0;
-	};
-
 	%feature("notabstract") ClickLabel;
 	%rename(Label) ClickLabel;
 	class ClickLabel: public Widget {
@@ -401,9 +386,6 @@
 		void setTextWrapping(bool);
 		virtual void setWidth(int width);
 		virtual void adjustSize();
-		
-		void setListener(ClickLabelListener* listener);
-		ClickLabelListener* getListener();		
 	};
 
 	%feature("notabstract") Icon2;
--- a/engine/extensions/basicapplication.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/extensions/basicapplication.py	Tue Oct 14 07:41:48 2008 +0000
@@ -20,7 +20,7 @@
 		self.app = app
 		self.engine = app.engine
 		eventmanager = self.engine.getEventManager()
-		eventmanager.setNonConsumableKeys([fife.Key.ESCAPE])
+		#eventmanager.setNonConsumableKeys([fife.Key.ESCAPE])
 		fife.IKeyListener.__init__(self)
 		eventmanager.addKeyListener(self)
 		self.quitRequested = False
--- a/engine/extensions/fife_compat.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/extensions/fife_compat.py	Tue Oct 14 07:41:48 2008 +0000
@@ -11,6 +11,7 @@
 
  - Animation.addFrame now expects a fife.ResourcePtr instead of an fife.Image
  - Pool.getIndex is just an alias for Pool.addResourceFromFile.
+ - EventManager.setNonConsumableKeys is superseeded by EventManager.setKeyFilter
 
 """
 
@@ -47,3 +48,28 @@
 	revision = 2617,
 	message  = "Use addResourceFromFile instead of getIndex"
 )
+
+def _compat_NonConsumableKeys():
+	class CompatKeyFilter(fife.IKeyFilter):
+		def __init__(self, keys):
+			fife.IKeyFilter.__init__(self)
+			self.keys = keys
+
+		def isFiltered(self, event):
+			return event.getKey().getValue() in self.keys
+
+	def _setNonConsumableKeys(self,keys):
+		deprecated(2636, "Write an IKeyFilter instead of using EventManager.setNonConsumableKeys.\n" +
+				 "You probably don't need it anyway")
+		self.compat_keyfilter = CompatKeyFilter(keys)
+		self.compat_keyfilter.__disown__()
+		self.setKeyFilter(self.compat_keyfilter)
+
+	def _getNonConsumableKeys(self,keys):
+		deprecated(2636, "Write an IKeyFilter instead of using EventManager.getNonConsumableKeys.")
+		return self.compat_keyfilter.keys
+
+	fife.EventManager.setNonConsumableKeys = _setNonConsumableKeys
+	fife.EventManager.getNonConsumableKeys = _getNonConsumableKeys
+
+_compat_NonConsumableKeys()
--- a/engine/extensions/pychan/__init__.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/extensions/pychan/__init__.py	Tue Oct 14 07:41:48 2008 +0000
@@ -20,11 +20,8 @@
 ----
  - Make setting parent attribute imply containment relation.
  - Finalize Widget.execute
- - ClickLabel/Label rework. (In progress)
 
  - Documentation ( Allways not enough :-( )
- - Completion of above features
- - Wrap missing widgets: Slider
  - Handle Image Fonts
  - Move Font config files to XML, too ...
  - Add support for fixed size 'Spacers'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/extensions/pychan/events.py	Tue Oct 14 07:41:48 2008 +0000
@@ -0,0 +1,204 @@
+#coding: utf-8
+
+"""
+PyChan event handling
+=====================
+
+Users shouldn't need to use this module directly.
+L{widgets.Widget.capture} and L{widgets.Widget.mapEvents} provide
+a convenient API to capture events.
+
+Nevertheless to understand how its supposed to work
+take a look at L{EventMapper} and L{EventListener}
+
+Available Events
+----------------
+
+"""
+
+import fife
+import exceptions
+import manager
+import tools
+
+EVENTS = [
+	"mouseEntered",
+	"mouseExited",
+	"mousePressed",
+	"mouseReleased",
+	"mouseClicked",
+	"mouseMoved",
+	"mouseDragged",
+	"action",
+	"keyPressed",
+	"keyReleased",
+]
+
+# Add the EVENTS to the docs.
+__doc__ += "".join([" - %s\n" % event for event in EVENTS])
+
+MOUSE_EVENT, KEY_EVENT, ACTION_EVENT = range(3)
+def getEventType(name):
+	if "mouse" in name:
+		return MOUSE_EVENT
+	if "key" in name:
+		return MOUSE_EVENT
+	return ACTION_EVENT
+
+
+CALLBACK_NONE_MESSAGE = """\
+You passed None as parameter to %s.capture, which would normally remove a mapped event.
+But there was no event mapped. Did you accidently call a function instead of passing it?
+"""
+
+class EventListener(fife.GUIEventListener):
+	"""
+	Redirector for event callbacks.
+	Use *only* from L{EventMapper}.
+
+	This class uses the SWIG director feature - overriden
+	virtual methods are called from C++ to - listen to
+	Guichan events.
+
+	When the module is first loaded the event handler
+	methods are auto-generated from the list L{EVENTS}.
+	This is effectively the same code as::
+	  def mouseEntered(self,event):
+	    self._redirectEvent("mouseEntered",event)
+
+	This way L{EVENTS} and the actually receivable events
+	are forced to be in sync.
+	"""
+	def __init__(self,debug=True):
+		super(EventListener,self).__init__()
+		self.events = {}
+		self.indent = 0
+		self.debug = debug
+		self.guimanager = manager.Manager.manager.guimanager
+
+	def _redirectEvent(self,name,event):
+		self.indent += 4
+		event = self.translateEvent(getEventType(name), event)
+		if name in self.events:
+			if self.debug: print "-"*self.indent, name
+			self.events[name]( event )
+		self.indent -= 4
+
+	def translateEvent(self,event_type,event):
+		if event_type == MOUSE_EVENT:
+			return self.guimanager.translateMouseEvent(event)
+		if event_type == KEY_EVENT:
+			return self.guimanager.translateKeyEvent(event)
+		return event
+
+def _redirect(name):
+	def redirectorFunc(self,event):
+		self._redirectEvent(name,event)
+	return redirectorFunc
+
+for event_name in EVENTS:
+	setattr(EventListener,event_name,_redirect(event_name))
+
+class EventMapper(object):
+	"""
+	Handles events and callbacks for L{widgets.Widget}
+	and derived classes.
+
+	Every PyChan widget has an L{EventMapper} instance
+	as attribute *event_mapper*.
+
+	This instance handles all necessary house-keeping.
+	Such an event mapper can be either *attached* or
+	*detached*. In its attached state an L{EventListener}
+	is added to the Guichan widget and will redirect
+	the events to the callbacks.
+
+	In its detached state no events are received from the
+	real Guichan widget.
+
+	The event mapper starts in the detached state.
+	When a new event is captured the mapper attaches itself
+	automatically. The widget doesn't need to handle that.
+	"""
+	def __init__(self,widget):
+		super(EventMapper,self).__init__()
+		self.widget = widget
+		self.listener = EventListener()
+		self.is_attached = False
+		self.debug = manager.Manager.manager.debug
+
+	def __del__(self):
+		self.detach()
+	def __repr__(self):
+		return "EventMapper(%s)" % repr(self.widget)
+
+	def attach(self):
+		"""
+		Start receiving events.
+		No need to call this manually.
+		"""
+
+		if self.is_attached:
+			return
+		if not self.listener.events:
+			return
+		if self.debug: print "Attach:",self
+		self.widget.real_widget.addMouseListener( self.listener )
+		self.widget.real_widget.addActionListener( self.listener )
+		self.is_attached = True
+
+	def detach(self):
+		"""
+		Stop receiving events.
+		No need to call this manually.
+		"""
+
+		if not self.is_attached:
+			return
+		if self.debug: print "Detach:",self
+		self.widget.real_widget.removeMouseListener( self.listener )
+		self.widget.real_widget.removeActionListener( self.listener )
+		self.is_attached = False
+
+	def capture(self,event_name,callback):
+		if event_name not in EVENTS:
+			raise exceptions.RuntimeError("Unknown eventname: " + event_name)
+
+		if callback is None and not self.isCaptured(event_name):
+			if self.debug:
+				print CALLBACK_NONE_MESSAGE % str(self.widget)
+			return
+
+		if callback is None:
+			del self.listener.events[event_name]
+			if not self.listener.events:
+				self.detach()
+			return
+
+		if not callable(callback):
+			raise RuntimeError("An event callback must be either a callable or None - not %s" % repr(callback))
+
+		def captured_f(event):
+			tools.applyOnlySuitable(callback,event=event,widget=self.widget)
+
+		self.listener.events[event_name] = captured_f
+		self.attach()
+
+	def isCaptured(self,event_name):
+		return event_name in self.listener.events
+
+	def getCapturedEvents(self):
+		return self.listener.events.keys()
+
+
+def splitEventDescriptor(name):
+	""" Utility function to split "widgetName/eventName" descriptions into tuples. """
+	L = name.split("/")
+	if len(L) == 1:
+		L = L[0],"action"
+	if len(L) != 2:
+		raise exceptions.RuntimeError("Invalid widgetname / eventname combination: " + name)
+	if L[1] not in EVENTS:
+		raise exceptions.RuntimeError("Unknown event name: " + name)
+	return L
+
--- a/engine/extensions/pychan/manager.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/extensions/pychan/manager.py	Tue Oct 14 07:41:48 2008 +0000
@@ -4,8 +4,9 @@
 import widgets
 import fonts
 from exceptions import *
+from traceback import print_exc
 
-class Manager(fife.IWidgetListener):
+class Manager(object):
 	manager = None
 
 	def __init__(self, engine, debug = False):
@@ -26,13 +27,12 @@
 		self.styles = {}
 		self.addStyle('default',DEFAULT_STYLE)
 
-		self.widgetEvents = {}
-		self.engine.getEventManager().addWidgetListener(self)
                 Manager.manager = self
 
+		# Setup synchronous dialogs
 		self.mainLoop = None
 		self.breakFromMainLoop = None
-		self.can_execute = True
+		self.can_execute = False
 
 	def setupModalExecution(self,mainLoop,breakFromMainLoop):
 		"""
@@ -128,15 +128,6 @@
 		index = self.engine.imagePool.addResourceFromFile(filename)
 		return fife.GuiImage(index,self.engine.imagePool)
 
-	def defaultWidgetAction(self,event):
-		if self.debug:
-			print "Event(%s) received." % event.getId()
-
-	def onWidgetAction(self, event):
-		#print event.getId(),self.widgetEvents
-		handler = self.widgetEvents.get( event.getId(), self.defaultWidgetAction )
-		handler( event )
-
 # Default Widget style.
 
 DEFAULT_STYLE = {
--- a/engine/extensions/pychan/widgets.py	Sun Oct 12 20:30:09 2008 +0000
+++ b/engine/extensions/pychan/widgets.py	Tue Oct 14 07:41:48 2008 +0000
@@ -9,6 +9,7 @@
 
 import fife, pythonize
 import tools
+import events
 from exceptions import *
 from attrs import Attr,PointAttr,ColorAttr,BoolAttr,IntAttr,FloatAttr
 
@@ -95,14 +96,14 @@
 			style = None, **kwargs):
 		
 		assert( hasattr(self,'real_widget') )
-		self._has_listener = False
+		self.event_mapper = events.EventMapper(self)
 		self._visible = False
 
 		# Data distribution & retrieval settings
 		self.accepts_data = False
 		self.accepts_initial_data = False
 
-		self._parent = parent
+		self.parent = parent
 
 		# This will also set the _event_id and call real_widget.setActionEventId
 		self.name = name
@@ -162,7 +163,7 @@
 				return False
 		return True
 
-	def capture(self, callback):
+	def capture(self, callback, event_name="action"):
 		"""
 		Add a callback to be executed when the widget event occurs on this widget.
 		
@@ -172,37 +173,18 @@
 		wether this widgets events are currently captured.
 
 		It might be useful to check out L{tools.callbackWithArguments}.
-		
+
+		@param callback: Event callback - may accept keyword arguments event and widget.
+		@paran event_name: The event to capture - may be one of L{events.EVENTS} and defaults to "action"
 		"""
-		if callback is None:
-			if not get_manager().widgetEvents.has_key(self._event_id):
-				if get_manager().debug:
-					print "You passed None as parameter to %s.capture, which would normally remove a mapped event." % str(self)
-					print "But there was no event mapped. Did you accidently call a function instead of passing it?"
-			else:
-				del get_manager().widgetEvents[self._event_id]
-			if self._has_listener:
-				self.real_widget.removeActionListener(get_manager().guimanager)
-			self._has_listener = None
-			return
-
-		if not callable(callback):
-			raise RuntimeError("An event callback must be either a callable or None - not %s" % repr(callback))
-
-		def captured_f(event):
-			tools.applyOnlySuitable(callback,event=event,widget=self)
-
-		get_manager().widgetEvents[self._event_id] = captured_f
-		if not self._has_listener:
-			self.real_widget.addActionListener(get_manager().guimanager)
-		self._has_listener = True
+		self.event_mapper.capture( event_name, callback )
 
 	def isCaptured(self):
 		"""
 		Check whether this widgets events are captured
 		(a callback is installed) or not.
 		"""
-		return self._has_listener
+		return bool(self.event_mapper.getCapturedEvents())
 
 	def show(self):
 		"""
@@ -223,7 +205,9 @@
 		if self._parent:
 			raise RuntimeError(Widget.HIDE_SHOW_ERROR)
 		if not self._visible: return
+
 		get_manager().hide(self)
+
 		self.afterHide()
 		self._visible = False
 
@@ -318,14 +302,27 @@
 		You can also pass C{None} instead of a callback, which will
 		disable the event completely.
 		
-		@param eventMap: A dictionary with widget names as keys and callbacks as values.
+		@param eventMap: A dictionary with widget/event names as keys and callbacks as values.
 		@param ignoreMissing: Normally this method raises an RuntimeError, when a widget
 		can not be found - this behaviour can be overriden by passing True here.
+
+		The keys in the dictionary are parsed as "widgetName/eventName" with the slash
+		separating the two. If no slash is found the eventName is assumed to be "action".
+
+		Example::
+		    guiElement.mapEvents({
+			"button" : guiElement.hide,
+			"button/mouseEntered" : toggleButtonColorGreen,
+			"button/mouseExited" :  toggleButtonColorBlue,
+		    })
+
 		"""
-		for name,func in eventMap.items():
+		for descr,func in eventMap.items():
+			name, event_name = events.splitEventDescriptor(descr)
+			print name, event_name
 			widget = self.findChild(name=name)
 			if widget:
-				widget.capture( func )
+				widget.capture( func, event_name = event_name )
 			elif not ignoreMissing:
 				raise RuntimeError("No widget with the name: %s" % name)
 
@@ -594,25 +591,21 @@
 		self.real_widget.setSelectionColor(color)
 	selection_color = property(_getSelectionColor,_setSelectionColor)
 
-	def _getName(self): return self._name
-	def _setName(self,name):
-		from pychan import manager
-		self._name = name
-		# Do not change the event id while we are captured.
-		if not self.isCaptured():
-			self._event_id = "%s(name=%s,id=%d)" % (str(self.__class__),name,id(self))
-		else:
-			# Print some notfication, so obscure behaviour might get debugged.
-			print "%s already captured, but changing the name attribute. Just a notification :-)" % str(self)
-		self.real_widget.setActionEventId(self._event_id)
-	name = property(_getName,_setName)
-
 	def _getStyle(self): return self._style
 	def _setStyle(self,style):
 		self._style = style
 		get_manager().stylize(self,style)
 	style = property(_getStyle,_setStyle)
 
+	def _getParent(self): return self._parent
+	def _setParent(self,parent):
+		self._parent = parent
+	parent = property(_getParent,_setParent)
+
+	def _setName(self,name): self._name = name
+	def _getName(self): return self._name
+	name = property(_getName,_setName)
+
 	x = property(_getX,_setX)
 	y = property(_getY,_setY)
 	width = property(_getWidth,_setWidth)
@@ -622,6 +615,32 @@
 	font = property(_getFont,_setFont)
 	border_size = property(_getBorderSize,_setBorderSize)
 
+	def setEnterCallback(self, cb):
+		"""
+		*DEPRECATED*
+
+		Callback is called when mouse enters the area of Widget
+		callback should have form of function(button)
+		"""
+		def callback(widget=None):
+			return cb(widget)
+		print "PyChan: You are using the DEPRECATED functionality: setEnterCallback."
+		self.capture(callback, event_name = "mouseEntered" )
+
+	def setExitCallback(self, cb):
+		"""
+		*DEPRECATED*
+
+		Callback is called when mouse exits the area of Widget
+		callback should have form of function(button)
+		"""
+		def callback(widget=None):
+			return cb(widget)
+		print "PyChan: You are using the DEPRECATED functionality: setExitCallback."
+		self.capture(callback, event_name = "mouseExited" )
+
+
+
 ### Containers + Layout code ###
 
 class Container(Widget):
@@ -654,7 +673,7 @@
 		super(Container,self).__init__(**kwargs)
 
 	def addChild(self, widget):
-		widget._parent = self
+		widget.parent = self
 		self.children.append(widget)
 		self.real_widget.add(widget.real_widget)
 
@@ -663,7 +682,7 @@
 			raise RuntimeError("%s does not have %s as direct child widget." % (str(self),str(widget)))
 		self.children.remove(widget)
 		self.real_widget.remove(widget.real_widget)
-		widget._parent = None
+		widget.parent = None
 
 	def add(self,*widgets):
 		print "PyChan: Deprecation warning: Please use 'addChild' or 'addChildren' instead."
@@ -1028,26 +1047,6 @@
 		return self._image
 	image = property(_getImage,_setImage)
 
-class LabelListener(fife.ClickLabelListener):
-	""" the listener class for label onMouse events
-	
-	@type	btn:	object
-	@param	btn:	the label widget
-	"""
-	def __init__(self, lbl):
-		fife.ClickLabelListener.__init__(self)
-		self.lbl = lbl
-		self.entercb = None
-		self.exitcb = None
-
-	def mouseEntered(self, lbl):
-		if self.entercb:
-			self.entercb(self.lbl)
-
-	def mouseExited(self, lbl):
-		if self.exitcb:
-			self.exitcb(self.lbl)
-
 class Label(BasicTextWidget):
 	"""
 	A basic label - displaying a string.
@@ -1070,8 +1069,6 @@
 		self.real_widget = fife.Label("")
 		self.wrap_text = wrap_text
 		super(Label,self).__init__(**kwargs)
-		self.listener = LabelListener(self)
-		self.real_widget.setListener(self.listener)
 		
 	def resizeToContent(self):
 		self.real_widget.setWidth( self.max_size[0] )
@@ -1084,20 +1081,6 @@
 	def _getTextWrapping(self): self.real_widget.isTextWrapping()
 	wrap_text = property(_getTextWrapping,_setTextWrapping)
 
-	def setEnterCallback(self, cb):
-		"""
-		Callback is called when mouse enters the area of Label
-		callback should have form of function(button)
-		"""
-		self.listener.entercb = cb
-
-	def setExitCallback(self, cb):
-		"""
-		Callback is called when mouse enters the area of Label
-		callback should have form of function(button)
-		"""
-		self.listener.exitcb = cb
-
 class ClickLabel(Label):
 	"""
 	Deprecated - use L{Label} instead.
@@ -1113,21 +1096,6 @@
 		self.real_widget = fife.Button("")
 		super(Button,self).__init__(**kwargs)
 
-class ImageButtonListener(fife.TwoButtonListener):
-	def __init__(self, btn):
-		fife.TwoButtonListener.__init__(self)
-		self.btn = btn
-		self.entercb = None
-		self.exitcb = None
-
-	def mouseEntered(self, btn):
-		if self.entercb:
-			self.entercb(self.btn)
-
-	def mouseExited(self, btn):
-		if self.exitcb:
-			self.exitcb(self.btn)
-
 class ImageButton(BasicTextWidget):
 	"""
 	A basic push button with three different images for the up, down and hover state.
@@ -1147,8 +1115,6 @@
 	def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),**kwargs):
 		self.real_widget = fife.TwoButton()
 		super(ImageButton,self).__init__(**kwargs)
-		self.listener = ImageButtonListener(self)
-		self.real_widget.setListener(self.listener)
 
 		self.up_image = up_image
 		self.down_image = down_image
@@ -1201,21 +1167,6 @@
 		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
 
-	def setEnterCallback(self, cb):
-		"""
-		Callback is called when mouse enters the area of ImageButton
-		callback should have form of function(button)
-		"""
-		self.listener.entercb = cb
-
-	def setExitCallback(self, cb):
-		"""
-		Callback is called when mouse enters the area of ImageButton
-		callback should have form of function(button)
-		"""
-		self.listener.exitcb = cb
-
-
 
 class CheckBox(BasicTextWidget):
 	"""
@@ -1548,11 +1499,13 @@
 
 	def addChild(self,widget):
 		self.content = widget
+		widget.parent = self
 
 	def removeChild(self,widget):
 		if self._content != widget:
 			raise RuntimeError("%s does not have %s as direct child widget." % (str(self),str(widget)))
 		self.content = None
+		widget.parent = None
 
 	def _setContent(self,content):
 		self.real_widget.setContent(content.real_widget)