* A sneaky spacing bug ComponentStackRework

Thu, 17 Sep 2020 13:47:51 +0300

author
cemkalyoncu
date
Thu, 17 Sep 2020 13:47:51 +0300
branch
ComponentStackRework
changeset 1443
11fc019aa4ae
parent 1442
9eed31b1a3f7
child 1444
53e69f1cea46

* A sneaky spacing bug
* Fixed one of the test cases
* A new test case for alignment accuracy
* Inputbox generator fixed

Source/Gorgon/ConsumableEvent.h file | annotate | diff | comparison | revisions
Source/Gorgon/Input.h file | annotate | diff | comparison | revisions
Source/Gorgon/Input/Input.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/ComponentStack.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Template.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/UI.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Window.h file | annotate | diff | comparison | revisions
Source/Gorgon/Utils/ConsumableEvent.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Generator.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Generator.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Inputbox.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/RadioButtons.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Registry.h file | annotate | diff | comparison | revisions
Source/Gorgon/Window.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/WindowManager/DWM/Input.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/WindowManager/X11/Input.cpp file | annotate | diff | comparison | revisions
Testing/Source/Manual/GraphicsHelper.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/ConsumableEvent.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/ConsumableEvent.h	Thu Sep 17 13:47:51 2020 +0300
@@ -228,6 +228,9 @@
 
 			std::lock_guard<std::mutex> g(access);
 			handlers.Add(handler);
+            
+            if(NewHandler)
+                NewHandler();
 
 			return reinterpret_cast<Token>(&handler);
 		}
@@ -409,6 +412,8 @@
 		
 		/// value for an empty token
 		static const Token EmptyToken;
+        
+        std::function<void()> NewHandler;
 		
 	private:
 
--- a/Source/Gorgon/Input.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Input.h	Thu Sep 17 13:47:51 2020 +0300
@@ -12,6 +12,12 @@
 	namespace Input {
 		/// A type to represent an input key
 		typedef int Key;
+        
+        
+        /// During keyevent this variable can be set to true, if done so, it
+        /// will allow character events even if key event is handled. However,
+        /// doing so will not direct the up event to the handler directly.
+        extern bool AllowCharEvent;
 		
 	}
 }
--- a/Source/Gorgon/Input/Input.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Input/Input.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -5,5 +5,8 @@
 	
 	namespace Keyboard {
 		Modifier CurrentModifier=Modifier::None;
+        
 	}
+	
+    bool AllowCharEvent = false;
 } }
--- a/Source/Gorgon/UI.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/UI.h	Thu Sep 17 13:47:51 2020 +0300
@@ -7,8 +7,21 @@
     /// Initializes the UI system. Creates a simple widget template
     /// generator based on the primary monitor resolution. Density
     /// controls the size of the widgets. Increased density leads
-    /// to smaller widgets. 120 leads to 12pt/16px on a FullHD monitor.
-    /// This is a very relaxed and easy to use and read size.
-    void Initialize(std::string fontname = "", int density = 120, int min = 10);
+    /// to smaller widgets. 7.5 leads to 12pt/16px on a FullHD monitor.
+    /// This is a very relaxed and easy to use and read size. 10 is
+    /// more or less standard density.
+    void Initialize(std::string fontname = "", float density = 7.5, int min = 9);
+    
+    /// Initializes the UI system. Creates a simple widget template
+    /// generator based on the primary monitor resolution. Density
+    /// controls the size of the widgets. Increased density leads
+    /// to smaller widgets. 7.5 leads to 12pt/16px on a FullHD monitor.
+    /// This is a very relaxed and easy to use and read size. 10 is
+    /// more or less standard density.
+    inline void Initialize(float density, int min = 9) {
+        Initialize("", density, min);
+    }
+    
+    
     
 } }
--- a/Source/Gorgon/UI/ComponentStack.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/UI/ComponentStack.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -2766,7 +2766,7 @@
                 else {
                     xrad = pcenter.X - comp.size.Width;
                 }
-
+                
                 //determine yrad and yoff according to the anchor point
                 if(IsTop(panch)) {
                     yrad = maxsize.Height - pcenter.Y - comp.size.Height;
@@ -2885,7 +2885,11 @@
                     )
                     finalpass = true;
 
-                if(anch) {
+                if(taglocations.count(temp.GetTag())) {
+                    comp.location = offset;
+                    comp.anchtoparent = true;
+                }
+                else if(anch) {
                     anchortoother(comp, temp, offset, margin, *anch, cont.GetOrientation());
                     comp.anchtoparent = false;
                 }
@@ -3361,7 +3365,7 @@
                 auto old = target->GetColor();
                 target->SetColor(color * c);
                 
-                target->Draw(comp.location+offset, comp.size, 0x80000000); //for debugging
+                //target->Draw(comp.location+offset, comp.size, 0x80000000); //for debugging
                 if(tagnowrap.count(temp.GetTag()))
                     th.GetRenderer().PrintNoWrap(*target, text, comp.location+offset, comp.size.Width);
                 else
--- a/Source/Gorgon/UI/Template.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/UI/Template.h	Thu Sep 17 13:47:51 2020 +0300
@@ -532,6 +532,19 @@
             else
                 return 0;
         }
+        
+        /// Sets the spacing required for this template. Organizer widgets
+        /// uses this spacing in order to layout the widgets.
+        void SetSpacing(int value) {
+            spacing = value;
+            ChangedEvent();
+        }
+        
+        /// Returns the spacing required for this template. Organizer widgets
+        /// uses this spacing in order to layout the widgets.
+        int GetSpacing() const {
+            return spacing;
+        }
 
 
         /// This event is fired whenever template or its components are changed.
@@ -547,6 +560,7 @@
         SizeMode xsizing = Free, ysizing = Free;
         Geometry::Size size;
         Geometry::Size additional = {0, 0};
+        int spacing = 4;
     };
 
     /// Defines an object according to the Box Model.
--- a/Source/Gorgon/UI/UI.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/UI/UI.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -9,13 +9,13 @@
     Widgets::Generator *generator = nullptr;
     
     //create a default widget registry.
-    void Initialize(std::string fontname, int density, int min) {
-        int fh = WindowManager::Monitor::Primary().GetSize().Width / density;
+    void Initialize(std::string fontname, float density, int min) {
+        int fh = int(std::round(sqrt(WindowManager::Monitor::Primary().GetSize().Width / (density+0.6f))));
         
         if(fh < min) 
             fh = min;
         
-        generator = new Widgets::SimpleGenerator(fh, fontname);
+        generator = new Widgets::SimpleGenerator(fh, fontname, true, density);
     }
     
 }
--- a/Source/Gorgon/UI/Window.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/UI/Window.h	Thu Sep 17 13:47:51 2020 +0300
@@ -27,9 +27,26 @@
         Window() : Gorgon::Window() {
         }
         
-        Window(Window &&) = default;
+        Window(Window &&other) : Gorgon::Window(std::move(other)), WidgetContainer(std::move(other)) {
+            KeyEvent.Unregister(inputtoken);
+            CharacterEvent.Unregister(chartoken);
+            
+            inputtoken = keyinit();
+            chartoken  = charinit();
+        }
         
-        Window &operator=(Window &&) = default;
+        Window &operator=(Window &&other) {
+            Gorgon::Window::operator =(std::move(other));
+            WidgetContainer::operator =(std::move(other));
+            
+            KeyEvent.Unregister(inputtoken);
+            CharacterEvent.Unregister(chartoken);
+            
+            inputtoken = keyinit();
+            chartoken  = charinit();
+            
+            return *this;
+        }
         
         virtual Geometry::Size GetInteriorSize() const override {
             return Gorgon::Window::GetSize();
@@ -81,16 +98,28 @@
 
 		decltype(KeyEvent)::Token keyinit() {
 			inputtoken = KeyEvent.Register([this](Input::Key key, float amount) {
-				return WidgetContainer::KeyEvent(key, amount);
+                return WidgetContainer::KeyEvent(key, amount);
 			});
+            
+            KeyEvent.NewHandler = [this]{
+                RegisterOnce([this] {
+                    this->KeyEvent.MoveToTop(this->inputtoken);
+                });
+            };
 
 			return inputtoken;
 		}
 
-		decltype(KeyEvent)::Token charinit() {
+		decltype(CharacterEvent)::Token charinit() {
 			chartoken = CharacterEvent.Register([this](Char c) {
 				return WidgetContainer::CharacterEvent(c);
 			});
+            
+            CharacterEvent.NewHandler = [this]{
+                RegisterOnce([this] {
+                    this->CharacterEvent.MoveToTop(this->chartoken);
+                });
+            };
 
 			return chartoken;
 		}
--- a/Source/Gorgon/Utils/ConsumableEvent.h	Tue Sep 15 18:32:31 2020 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1082 +0,0 @@
-//DESCRIPTION
-//	This file allows exposing event objects. Supports multiple events
-//	to be registered, unregister and different function signatures
-//	Event handlers are ordered and this order can be changed moreover
-//	handlers can stop chaining of the event. This system is suitable
-//	for events like mouse and keyboard events
-//	If C++0x feature lambda functionality is causing problems, define
-//	NOLAMBDA
-
-//REQUIRES:
-//	gge::utils::SortedCollection
-//	gge::utils::Any
-//	std::unordered_map
-
-//LICENSE
-//	This program is free software: you can redistribute it and/or modify
-//	it under the terms of the Lesser GNU General Public License as published by
-//	the Free Software Foundation, either version 3 of the License, or
-//	(at your option) any later version.
-//
-//	This program is distributed in the hope that it will be useful,
-//	but WITHOUT ANY WARRANTY; without even the implied warranty of
-//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//	Lesser GNU General Public License for more details.
-//
-//	You should have received a copy of the Lesser GNU General Public License
-//	along with this program. If not, see < http://www.gnu.org/licenses/ >.
-
-//COPYRIGHT
-//	Cem Kalyoncu, DarkGaze.Org (cemkalyoncu[at]gmail[dot]com)
-
-#pragma once
-
-
-#define CONSUMABLEEVENT_EXIST
-
-
-
-#include <string>
-
-#ifndef NOLAMBDA
-#	include <functional>
-#endif
-
-
-#include "UtilsBase.h"
-#include "Any.h"
-#include "SortedCollection.h"
-#include "EventChain.h"
-#include <unordered_map>
-
-
-
-namespace gge { namespace utils {
-
-
-
-
-	template<class O_, class P_> class ConsumableEvent;
-
-
-	namespace prvt { namespace consumableevent {
-
-		////Base of an event handler
-		template <class P_, class O_>
-		struct EventHandler {
-			Any data;
-
-			bool enabled;
-
-			EventHandler(Any data) : data(data), enabled(true) {}
-
-			virtual ~EventHandler() {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname)=0;
-		};
-
-		//These template functions provide pseudo inheritance for these functions
-		//every handler type must implement their of specialization
-		template <class F_,class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(F_ function, Any data) {
-			return NULL;
-		}
-		template <class F_, class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, F_ function, Any data) {
-			return NULL;
-		}
-
-		template <class F_,class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, F_ function) {
-			return false;
-		}
-		template <class F_, class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, F_ function) {
-			return false;
-		}
-		template <class F_, class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ &object, F_ function) {
-			return Compare(obj, &object, function);
-		}
-
-
-
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunction : public EventHandler<P_, O_> {
-			bool(*handler)(P_, O_ &, Any Data, std::string);
-
-			EventHandlerFunction(bool(*handler)(P_, O_ &, Any Data, std::string), Any data) : EventHandler<P_, O_>(data), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(params, caller, EventHandler<P_, O_>::data, eventname);
-			}
-
-		};
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(P_, O_ &, Any Data, std::string), Any data) {
-			return new EventHandlerFunction<P_, O_>(function, data);
-		}
-
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(P_, O_ &, Any Data, std::string)) {
-			if(!dynamic_cast<EventHandlerFunction<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunction<P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionPlain : public EventHandler<P_, O_> {
-			bool(*handler)(P_, O_ &);
-
-			EventHandlerFunctionPlain(bool(*handler)(P_, O_ &)) : EventHandler<P_, O_>(NULL), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(params, caller);
-			}
-
-			bool Compare(bool(*function)(P_, O_ &), void*) {
-				if(handler==function)
-					return true;
-			}
-		};
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(P_, O_ &), Any data) {
-			return new EventHandlerFunctionPlain<P_, O_>(function);
-		}
-
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(P_, O_ &)) {
-			if(!dynamic_cast<EventHandlerFunctionPlain<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionPlain<P_,O_>*>(obj)->handler;
-		}
-
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionEmpty : public EventHandler<P_, O_> {
-			bool(*handler)();
-
-			EventHandlerFunctionEmpty(bool(*handler)()) : EventHandler<P_, O_>(Any()), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)();
-			}
-
-			bool Compare(bool(*function)(), void*) {
-				if(handler==function)
-					return true;
-			}
-		};
-
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(), Any data) {
-			return new EventHandlerFunctionEmpty<P_, O_>(function);
-		}
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)()) {
-			if(!dynamic_cast<EventHandlerFunctionEmpty<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionEmpty<P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionObjectOnly : public EventHandler<P_, O_> {
-			bool(*handler)(O_ &);
-
-			EventHandlerFunctionObjectOnly(bool(*handler)(O_ &)) : EventHandler<P_, O_>(Any()), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(caller);
-			}
-
-			bool Compare(bool(*function)(O_ &), void*) {
-				if(handler==function)
-					return true;
-			}
-		};
-
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(O_ &), Any data) {
-			return new EventHandlerFunctionObjectOnly<P_, O_>(function);
-		}
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(O_ &)) {
-			if(!dynamic_cast<EventHandlerFunctionObjectOnly<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionObjectOnly<P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionParamOnly : public EventHandler<P_, O_> {
-			bool(*handler)(P_);
-
-			EventHandlerFunctionParamOnly(bool(*handler)(P_)) : EventHandler<P_, O_>(Any()), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(params);
-			}
-
-			bool Compare(bool(*function)(P_), void*) {
-				if(handler==function)
-					return true;
-			}
-		};
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(P_), Any data) {
-			return new EventHandlerFunctionParamOnly<P_, O_>(function);
-		}
-
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(P_)) {
-			if(!dynamic_cast<EventHandlerFunctionParamOnly<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionParamOnly<P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionDataOnly : public EventHandler<P_, O_> {
-			bool(*handler)(Any);
-
-			EventHandlerFunctionDataOnly(bool(*handler)(Any), Any data) : EventHandler<P_, O_>(data), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(EventHandler<P_, O_>::data);
-			}
-
-		};
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(Any Data), Any data) {
-			return new EventHandlerFunctionDataOnly<P_, O_>(function, data);
-		}
-
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(Any Data)) {
-			if(!dynamic_cast<EventHandlerFunctionDataOnly<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionDataOnly<P_,O_>*>(obj)->handler;
-		}
-
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerFunctionObjectAndData : EventHandler<P_, O_> {
-			bool(*handler)(O_ &, Any);
-
-			EventHandlerFunctionObjectAndData(bool(*handler)(O_ &, Any), Any data) : EventHandler<P_, O_>(data), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (*handler)(caller,EventHandler<P_, O_>::data);
-			}
-
-			bool Compare(bool(*function)(O_ &, Any), void*) {
-				if(handler==function)
-					return true;
-			}
-		};
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( bool(*function)(O_ &, Any), Any data) {
-			return new EventHandlerFunctionObjectAndData<P_, O_>(function,data);
-		}
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, bool(*function)(O_ &, Any)) {
-			if(!dynamic_cast<EventHandlerFunctionObjectAndData<P_,O_>*>(obj))
-				return false;
-
-			return function==dynamic_cast<EventHandlerFunctionObjectAndData<P_,O_>*>(obj)->handler;
-		}
-
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClass : public EventHandler<P_,O_> {
-			bool(R_::*handler)(P_, O_ &, Any, std::string);
-
-			R_ *object;
-
-			EventHandlerClass(R_ *object, bool(R_::*handler)(P_, O_ &, Any, std::string), Any data) : EventHandler<P_, O_>(data), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)(params, caller, EventHandler<P_,O_>::data, eventname);
-			}
-
-		};
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(P_, O_ &, Any, std::string), Any data) {
-			return new EventHandlerClass<R_, P_, O_>(object, function, data);
-		}
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)(P_, O_ &, Any, std::string)) {
-			if(!dynamic_cast<EventHandlerClass<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClass<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClass<R_, P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClassPlain : public EventHandler<P_,O_> {
-			bool(R_::*handler)(P_, O_ &);
-
-			R_ *object;
-
-			EventHandlerClassPlain(R_ *object, bool(R_::*handler)(P_, O_ &)) : EventHandler<P_, O_>(Any()), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)(params, caller);
-			}
-
-			bool Compare(bool(R_::*function)(P_, O_ &), void* object) {
-				if((void*)handler==function && this->object==object)
-					return true;
-			}
-		};
-
-
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(P_, O_ &), Any data) {
-			return new EventHandlerClassPlain<R_, P_, O_>(object, function);
-		}
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)(P_, O_ &)) {
-			if(!dynamic_cast<EventHandlerClassPlain<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClassPlain<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClassPlain<R_, P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClassEmpty : public EventHandler<P_,O_> {
-			bool(R_::*handler)();
-
-			R_ *object;
-
-			EventHandlerClassEmpty(R_ *object, bool(R_::*handler)()) : EventHandler<P_, O_>(Any()), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)();
-			}
-
-			bool Compare(bool(R_::*function)(), void* object) {
-				if((void*)handler==function && this->object==object)
-					return true;
-			}
-		};
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(), Any data) {
-			return new EventHandlerClassEmpty<R_, P_, O_>(object, function);
-		}
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)()) {
-			if(!dynamic_cast<EventHandlerClassEmpty<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClassEmpty<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClassEmpty<R_, P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClassObjectOnly : public EventHandler<P_,O_> {
-			bool(R_::*handler)(O_ &);
-
-			R_ *object;
-
-			EventHandlerClassObjectOnly(R_ *object, bool(R_::*handler)(O_ &)) : EventHandler<P_, O_>(Any()), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)(caller);
-			}
-
-			bool Compare(bool(R_::*function)(O_ &), void* object) {
-				if((void*)handler==function && this->object==object)
-					return true;
-			}
-		};
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(O_ &), Any data) {
-			return new EventHandlerClassObjectOnly<R_, P_, O_>(object, function);
-		}
-
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)(O_ &)) {
-			if(!dynamic_cast<EventHandlerClassObjectOnly<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClassObjectOnly<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClassObjectOnly<R_, P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClassParamOnly : public EventHandler<P_,O_> {
-			bool(R_::*handler)(P_);
-
-			R_ *object;
-
-			EventHandlerClassParamOnly(R_ *object, bool(R_::*handler)(P_ )) : EventHandler<P_, O_>(Any()), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)(params);
-			}
-
-			bool Compare(bool(R_::*function)(P_), void* object) {
-				if((void*)handler==function && this->object==object)
-					return true;
-			}
-		};
-
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(P_), Any data) {
-			return new EventHandlerClassParamOnly<R_, P_, O_>(object, function);
-		}
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)(P_)) {
-			if(!dynamic_cast<EventHandlerClassParamOnly<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClassParamOnly<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClassParamOnly<R_, P_,O_>*>(obj)->handler;
-		}
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class R_, class P_, class O_>
-		struct EventHandlerClassDataOnly : public EventHandler<P_,O_> {
-			bool(R_::*handler)(Any);
-
-			R_ *object;
-
-			EventHandlerClassDataOnly(R_ *object, bool(R_::*handler)(Any), Any data) : EventHandler<P_, O_>(data), object(object), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (object->*handler)(EventHandler<P_, O_>::data);
-			}
-
-			bool Compare(bool(R_::*function)(Any), void* object) {
-				if((void*)handler==function && this->object==object)
-					return true;
-			}
-		};
-
-
-		template <class R_, class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler(R_ *object, bool(R_::*function)(Any), Any data) {
-			return new EventHandlerClassDataOnly<R_, P_, O_>(object, function, data);
-		}
-		template <class R_, class P_, class O_>
-		bool Compare(EventHandler<P_,O_> *obj, R_ *object, bool(R_::*function)(Any)) {
-			if(!dynamic_cast<EventHandlerClassDataOnly<R_, P_,O_>*>(obj))
-				return false;
-
-			return object==dynamic_cast<EventHandlerClassDataOnly<R_, P_,O_>*>(obj)->object && function==dynamic_cast<EventHandlerClassDataOnly<R_, P_,O_>*>(obj)->handler;
-		}
-
-
-#ifndef NOLAMBDA
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerLambdaEmpty : public EventHandler<P_, O_> {
-			std::function<bool()> handler;
-
-			EventHandlerLambdaEmpty(std::function<bool()> handler) : EventHandler<P_, O_>(Any()), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (handler)();
-			}
-
-			bool Compare(std::function<bool()> function, void*) {
-				return false;
-			}
-		};
-
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( std::function<bool()> function, Any data) {
-			return new EventHandlerLambdaEmpty<P_, O_>(function);
-		}
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, std::function<bool()> function) {
-			return false;
-		}
-
-		////This is private event object that is used to
-		/// store function event handlers
-		template<class P_, class O_>
-		struct EventHandlerLambdaParamOnly : public EventHandler<P_, O_> {
-			std::function<bool(P_)> handler;
-
-			EventHandlerLambdaParamOnly(std::function<bool(P_)> handler) : EventHandler<P_, O_>(Any()), handler(handler) {}
-
-			virtual bool Fire(P_ params, O_ &caller, std::string eventname) {
-				return (handler)(params);
-			}
-
-			bool Compare(std::function<bool(P_)> function, void*) {
-				return false;
-			}
-		};
-
-
-		template <class P_, class O_>
-		EventHandler<P_, O_> *CreateEventHandler( std::function<bool(P_)> function, Any data) {
-			return new EventHandlerLambdaParamOnly<P_, O_>(function);
-		}
-		template <class P_, class O_>
-		bool Compare(EventHandler<P_, O_> *obj, std::function<bool(P_)> function) {
-			return false;
-		}
-#endif
-
-	} }
-
-
-	////ConsumableEvent class is used to create event objects
-	/// that can be multi-handled. It is a template
-	/// so an event definer can define parameters
-	/// that can be used. Every event has an object
-	/// that is the source of the event and a name
-	/// for the event. This information is given
-	/// in constructor.
-	template<class O_=Empty, class P_=empty_event_params>
-	class ConsumableEvent {
-		template<class O2_, class P2_> friend class ConsumableEvent;
-	public:
-
-#ifdef LINUX
-		typedef std::intptr_t Token;
-#else
-		typedef int Token;
-#endif
-		static const Token NullToken = 0;
-
-		//To be used by owner
-		std::vector<std::pair<P_, Token>> TokenList;
-
-		////Constructor
-		///@Name	: Name of the event
-		///@Object	: Source of the event
-		ConsumableEvent(std::string Name,O_ *Object=NULL) :
-		eventname(Name), object(Object)
-		{ }
-
-		////Constructor
-		///@Name	: Name of the event
-		///@Object	: Source of the event
-		ConsumableEvent(O_ *Object=NULL) :
-		eventname(""), object(Object)
-		{ }
-
-		////Constructor
-		///@Name	: Name of the event
-		///@Object	: Source of the event
-		ConsumableEvent(std::string Name,O_ &Object) :
-		eventname(Name), object(&Object)
-		{ }
-
-		////Constructor
-		///@Name	: Name of the event
-		///@Object	: Source of the event
-		ConsumableEvent(O_ &Object) :
-		eventname(""), object(&Object)
-		{ }
-
-		void SetToken(P_ params, Token t) {
-			for(auto it=TokenList.begin(); it!=TokenList.end(); ++it) {
-				if(it->first==params) {
-					it->second=t;
-					return;
-				}
-			}
-
-			TokenList.push_back(std::pair<P_, Token>(params, t));
-		}
-
-		Token FindToken(P_ params) const {
-			for(auto it=TokenList.begin(); it!=TokenList.end(); ++it) {
-				if(it->first==params) {
-					return it->second;
-				}
-			}
-
-			return NullToken;
-		}
-
-		void RemoveToken(P_ params) {
-			for(auto it=TokenList.begin(); it!=TokenList.end(); ++it) {
-				if(it->first==params) {
-					TokenList.erase(it);
-					return;
-				}
-			}
-		}
-
-		////Registers an event handler. Every event handler
-		/// can specify EventHandler<P_, O_>::data to be passed to handler
-		/// that can be used to identify who is registered
-		/// the event. This function returns event token
-		/// that can be used to remove this handler. The
-		/// token is not an id or sequential number
-		/// therefore, it should not be altered to find other
-		/// handlers. Handler function template is
-		/// void Handler(Parameters params, CallerObject* object, any EventHandler<P_, O_>::data, std::string eventname)
-		///@handler	: handler function
-		///@data	: data to be passed to handler
-		template<class F_>
-		Token Register(F_ *handler, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(handler, data)
-			);
-		}
-
-		////Registers an event handler. Every event handler
-		/// can specify EventHandler<P_, O_>::data to be passed to handler
-		/// that can be used to identify who is registered
-		/// the event. This function returns event token
-		/// that can be used to remove this handler. The
-		/// token is not an id or sequential number
-		/// therefore, it should not be altered to find other
-		/// handlers. Handler function template is
-		/// void Handler(Parameters params, CallerObject* object, any EventHandler<P_, O_>::data, std::string eventname)
-		///@handler	: handler function
-		///@data	: data to be passed to handler
-		template<class F_>
-		Token Register(F_ *handler, int order, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(handler, data),
-				order
-			);
-		}
-
-
-		////Registers a class event handler. This handler
-		/// should be a non static function of
-		/// the given object. Event handler
-		/// can specify EventHandler<P_, O_>::data to be passed to handler
-		/// that can be used to identify who is registered
-		/// the event. This function returns event token
-		/// that can be used to remove this handler. The
-		/// token is not an id or sequential number
-		/// therefore, it should not be altered to find other
-		/// handlers. Handler function full template is
-		/// void Handler(Parameters params, CallerObject* object, any EventHandler<P_, O_>::data, std::string eventname)
-		/// EventParams parameters)
-		///@receiver: handler object
-		///@handler	: handler function
-		///@data	: data to be passed to handler
-		template<class R_, class F_>
-		Token Register(R_ *receiver, F_ handler, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<R_, P_, O_>(receiver, handler, data)
-			);
-		}
-		template<class R_, class F_>
-		Token Register(R_ *receiver, F_ handler, int order, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<R_, P_, O_>(receiver, handler, data),
-				order
-			);
-		}
-
-		////Registers a class event handler. This handler
-		/// should be a non static function of
-		/// the given object. Event handler
-		/// can specify data to be passed to handler
-		/// that can be used to identify who is registered
-		/// the event. This function returns event token
-		/// that can be used to remove this handler. The
-		/// token is not an id or sequential number
-		/// therefore, it should not be altered to find other
-		/// handlers. Handler function full template is
-		/// void Handler(Parameters params, CallerObject* object, any data, std::string eventname)
-		/// EventParams parameters)
-		///@receiver: handler object
-		///@handler	: handler function
-		///@data	: EventHandler<P_, O_>::data to be passed to handler
-		template<class R_, class F_>
-		Token Register(R_ &receiver, F_ handler, Any data=Any()) {
-			return Register(&receiver, handler, data);
-		}
-		template<class R_, class F_>
-		Token Register(R_ &receiver, F_ handler, int order, Any data=Any()) {
-			return Register(&receiver, handler, order, data);
-		}
-
-		template<class R_, class F_>
-		Token RegisterClass(R_ *receiver, F_ handler, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<R_, P_, O_>(receiver, handler, data)
-			);
-		}
-
-		template<class R_, class F_>
-		Token RegisterClass(R_ *receiver, F_ handler, int order, Any data=Any()) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<R_, P_, O_>(receiver, handler, data),
-				order
-			);
-		}
-
-		template<class R_, class F_>
-		Token RegisterClass(R_ &receiver, F_ handler, Any data=Any()) {
-			return RegisterClass(receiver, handler, data);
-		}
-
-		template<class R_, class F_>
-		Token RegisterClass(R_ &receiver, F_ handler, int order, Any data=Any()) {
-			return RegisterClass(receiver, handler, order, data);
-		}
-
-#ifndef NOLAMBDA
-		template <class F_>
-		typename count_arg<F_, 0, Token>::type RegisterLambda(F_ handler, int order) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(std::function<bool()>(handler), Any()),
-				order
-			);
-		}
-		template <class F_>
-		typename count_arg<F_, 1, Token>::type RegisterLambda(F_ handler, int order) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(std::function<bool(P_)>(handler), Any()),
-				order
-			);
-		}
-		template <class F_>
-		typename count_arg<F_, 0, Token>::type RegisterLambda(F_ handler) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(std::function<bool()>(handler), Any())
-			);
-		}
-		template <class F_>
-		typename count_arg<F_, 1, Token>::type RegisterLambda(F_ handler) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<P_, O_>(std::function<bool(P_)>(handler), Any())
-			);
-		}
-#endif
-
-		template<class R_>
-		Token LinkTo(ConsumableEvent<R_, P_> &target) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<ConsumableEvent<R_, P_>, P_, O_>(
-					&target,
-					(bool(ConsumableEvent<R_,P_>::*)(P_))&ConsumableEvent<R_, P_>::Fire,
-					Any()
-				)
-			);
-		}
-
-		template<class R_>
-		Token LinkTo(ConsumableEvent<R_, P_> &target, int order) {
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<ConsumableEvent<R_, P_>, P_, O_>(
-					&target,
-					(bool(ConsumableEvent<R_,P_>::*)(P_))&ConsumableEvent<R_, P_>::Fire,
-					Any()
-				),
-				order
-			);
-		}
-
-		template<class R_>
-		Token DoubleLink(ConsumableEvent<R_, P_> &target) {
-			typedef bool(ConsumableEvent<O_,P_>::*MyFire	)(P_) ;
-			typedef bool(ConsumableEvent<R_,P_>::*TargetFire)(P_);
-
-			target.RegisterClass< ConsumableEvent<O_, P_>, MyFire >(
-				this,
-				(MyFire) &ConsumableEvent<R_, P_>::linkedfire,
-				NULL
-			);
-
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<ConsumableEvent<R_, P_>, P_, O_>(
-					&target,
-					(TargetFire) &ConsumableEvent<R_, P_>::linkedfire,
-					NULL
-				)
-			);
-		}
-
-		template<class R_>
-
-		Token DoubleLink(ConsumableEvent<R_, P_> &target, int order) {
-			typedef bool(ConsumableEvent<O_,P_>::*MyFire	)(P_) ;
-			typedef bool(ConsumableEvent<R_,P_>::*TargetFire)(P_);
-
-			target.RegisterClass< ConsumableEvent<O_, P_>, MyFire >(
-				this,
-				(MyFire) &ConsumableEvent<R_, P_>::linkedfire,
-				order,
-				Any()
-			);
-
-			return AddHandler(
-				prvt::consumableevent::CreateEventHandler<ConsumableEvent<R_, P_>, P_, O_>(
-					&target,
-					(TargetFire) &ConsumableEvent<R_, P_>::linkedfire,
-					Any()
-				), order
-			);
-		}
-
-		////Unregisters the given event handler using handler function
-		template<class F_>
-		Token Find(F_ handler) {
-			for(auto it=events.First(); it.IsValid(); it.Next()) {
-				if(Compare(&(*it), handler)) {
-
-					return reinterpret_cast<Token> (&it.GetWrapper());
-				}
-			}
-		}
-
-		////Unregisters the given handler referenced by the object and function
-		template<class R_, class F_>
-		Token Find(R_ *obj, F_ handler) {
-			for(auto it=events.First(); it.IsValid(); it.Next()) {
-				if(Compare(&(*it), obj, handler)) {
-
-					return reinterpret_cast<Token> (&it.GetWrapper());
-				}
-			}
-		}
-
-		////Unregisters the given event handler using handler function
-		template<class F_>
-		void Unregister(F_ handler) {
-			for(auto it=events.First(); it.IsValid(); it.Next()) {
-				if(Compare(&(*it), handler)) {
-					Unregister(reinterpret_cast<Token>(&it.GetWrapper()));
-					return;
-				}
-			}
-		}
-
-		////Unregisters the given handler referenced by the object and function
-		template<class R_, class F_>
-		void Unregister(R_ *obj, F_ handler) {
-			for(auto it=events.First(); it.IsValid(); it.Next()) {
-				if(Compare(&(*it),obj, handler)) {
-					Unregister(reinterpret_cast<Token>(&it.GetWrapper()));
-					return;
-				}
-			}
-		}
-
-		template<class R_, class F_>
-		void UnregisterClass(R_ &obj, F_ handler) {
-			Unregister(&obj, handler);
-		}
-
-		////Unregisters the given handler referenced by the object and function
-		template<class R_, class F_>
-		void UnregisterClass(R_ *obj, F_ handler) {
-			for(auto it=events.First(); it.IsValid(); it.Next()) {
-				if(Compare(&(*it), obj, handler)) {
-					Unregister(reinterpret_cast<Token>(&it.GetWrapper()));
-					return;
-				}
-			}
-		}
-
-		////Unregisters the given handler referenced by the object and function
-		template<class R_, class F_>
-		void Unregister(R_ &obj, F_ handler) {
-			Unregister(&obj, handler);
-		}
-
-		////Unregisters a given handler token
-		void Unregister(Token token) {
-			for(auto i=TokenList.begin();i!=TokenList.end();++i) {
-				if(i->second==token)
-					i->second=NullToken;
-			}
-
-			reinterpret_cast< ITEMTYPE_* >(token)->Delete();
-		}
-
-		void MakeFirst(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			item->setOrder(events.LowestOrder()-1);
-		}
-
-		void MakeLast(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			item->setOrder(events.HighestOrder()-1);
-		}
-
-		int GetOrder(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			return item->getOrder();
-		}
-
-		bool IsFirst(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			return item==events.getOrderedFirst();
-		}
-
-		bool IsLast(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			return item==events.getOrderedLast();
-		}
-
-		void SetOrder(Token token, int order) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			item->Reorder(order);
-		}
-
-		void Enable(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			item->Get().enabled=true;
-		}
-
-		void Disable(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			item->Get().enabled=false;
-		}
-
-		bool IsEnabled(Token token) {
-			ITEMTYPE_ *item=reinterpret_cast<ITEMTYPE_*>(token);
-
-			return item->Get().enabled;
-		}
-
-		bool Fire(Token token, P_ params) {
-			if(token==NullToken)
-				return false;
-
-			return reinterpret_cast< ITEMTYPE_* >(token)->Get().Fire(params, *this->object, eventname);
-		}
-
-		bool Fire(Token token) {
-			return Fire(token, P_());
-		}
-
-		////This function triggers the event causing all
-		/// handlers to be called
-		Token operator()(P_ params) {
-			return Fire(params);
-		}
-
-		////This function triggers the event causing all
-		/// handlers to be called
-		Token operator()() {
-			return Fire();
-		}
-
-		////This function triggers the event causing all
-		/// handlers to be called
-		Token Fire(P_ params) {
-			for(auto it=events.First();it.IsValid();it.Next()) {
-				if(it->enabled)
-					if(it->Fire(params, *this->object, eventname))
-						return reinterpret_cast<Token>(&it.GetWrapper());
-			}
-
-			return 0;
-		}
-
-		////This function triggers the event causing all
-		/// handlers to be called
-		Token Fire() {
-			return Fire(P_());
-		}
-
-		const std::string &GetName() const { return eventname; }
-
-		void SetName(const std::string &name) {
-			eventname=name;
-		}
-
-		~ConsumableEvent() {
-			events.Destroy();
-
-		}
-
-	protected:
-		typedef typename SortedCollection<prvt::consumableevent::EventHandler<P_, O_>, int>::Wrapper ITEMTYPE_ ;
-		typedef prvt::consumableevent::EventHandler<P_, O_> HANDLER_;
-		////Name of the event
-		std::string eventname;
-		////Source of the events
-		O_ *object;
-		////Collection of event handlers
-		SortedCollection<HANDLER_,int> events;
-
-		////Unregisters a given handler token
-		void RemoveHandler(ITEMTYPE_ *object) {
-			object->Delete();
-		}
-		Token AddHandler(HANDLER_ *object) {
-			ITEMTYPE_ *item = &events.Add(object);
-
-			return reinterpret_cast<Token>(item);
-		}
-		Token AddHandler(HANDLER_ *object, int order) {
-			ITEMTYPE_ *item = &events.Add(object, order);
-
-			return reinterpret_cast<Token>(item);
-		}
-
-
-	private:
-		//copy constructor is disabled
-		ConsumableEvent(const ConsumableEvent<O_, P_> &);
-
-		//assignment operator is disabled
-		ConsumableEvent<O_,P_> operator =(const ConsumableEvent<O_, P_> &);
-
-		bool checklinkedfire(HANDLER_ *object) {
-			prvt::consumableevent::EventHandlerClassParamOnly<ConsumableEvent, P_, O_> *obj=dynamic_cast<prvt::consumableevent::EventHandlerClassParamOnly<ConsumableEvent, P_, O_> *>(object);
-
-			if(obj!=NULL) {
-				ConsumableEvent *ec;
-				ec=dynamic_cast<ConsumableEvent*>(obj->object);
-				if(ec!=NULL && obj->handler == &ConsumableEvent::linkedfire)
-					return true;
-			}
-
-			return false;
-		}
-
-		bool linkedfire(P_ params) {
-			for(auto it=events.First;it.IsValid();it.Next()) {
-				if(it->enabled && !checklinkedfire(it))
-					if(it->Fire(params, *this->object, eventname))
-						return true;
-			}
-
-			return false;
-		}
-
-	};
-} }
--- a/Source/Gorgon/Widgets/Generator.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Widgets/Generator.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -23,7 +23,7 @@
 
 namespace Gorgon { namespace Widgets { 
 
-    SimpleGenerator::SimpleGenerator(int fontsize, std::string fontname, bool activate) : Generator(activate) {
+    SimpleGenerator::SimpleGenerator(int fontsize, std::string fontname, bool activate, float density) : Generator(activate), Density(density) {
         Init(fontsize, fontname);
     }
     
@@ -124,7 +124,7 @@
         
         int totalh = regularrenderer->GetLineGap();
         
-        Spacing = (int)std::round((float)totalh / 5);
+        Spacing = (int)std::round((float)totalh / (2 * Density / 3));
         Focus.Spacing = std::max(1, Spacing / 2);
 
         BorderedWidgetHeight = 
@@ -186,10 +186,8 @@
 
     Graphics::BitmapRectangleProvider &SimpleGenerator::DisabledBorder() {
         if(!disabledborder) {
-            auto c = Background.Regular;
-            c.Blend(Background.Disabled);
-            auto c2 = Border.Color;
-            c2.Blend(Border.Disabled);
+            auto c = Background.Disabled;
+            auto c2 = Border.Disabled;
 
             disabledborder = makeborder(c2, c);
         }
@@ -448,6 +446,7 @@
         Geometry::Size defsize = {WidgetWidth, BorderedWidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         
@@ -530,8 +529,6 @@
         setuptext(Forecolor.Regular.BlendWith(Forecolor.Disabled), UI::ComponentCondition::Disabled);
 
         setupfocus(temp.AddGraphics(4, UI::ComponentCondition::Focused));
-        
-        temp.Name = String::Concat("Button ", rand()%100);
 
         return temp;
     }
@@ -557,6 +554,7 @@
         iconsize += Geometry::Size(externalspacing) * 2;
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         
         temp.SetSize(iconsize);
         
@@ -645,6 +643,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         temp.AddContainer(0, UI::ComponentCondition::Always)
@@ -761,6 +760,7 @@
     UI::Template SimpleGenerator::CheckboxButton() {
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(BorderedWidgetHeight, BorderedWidgetHeight);
         
 
@@ -857,6 +857,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         temp.AddContainer(0, UI::ComponentCondition::Always)
@@ -864,7 +865,6 @@
             .AddIndex(2) //Focus
         ;
         
-        
         auto &cont = temp.AddContainer(1, UI::ComponentCondition::Always)
             .AddIndex(3) //Box symbol
             .AddIndex(4) //Tick
@@ -884,12 +884,12 @@
         state2.SetPositioning(UI::ComponentTemplate::Absolute);
         state2.SetAnchor(UI::Anchor::None, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
         
-        int outer_r = ObjectHeight / 2;
-        int borderstart_r = outer_r - ObjectBorder;
-        float inner_r = borderstart_r - Spacing / 2.f;
+        float outer_r = ObjectHeight / 2.f - 0.5;
+        int borderstart_r = int(ceil(outer_r - ObjectBorder));
+        float inner_r = std::max(outer_r - ObjectBorder - std::max(Spacing / 2.f, 1.5f), 1.5f);
         
         Geometry::Size bmpsize = {ObjectHeight + 2, ObjectHeight + 2};
-        Geometry::Pointf center = {float(outer_r + 1), float(outer_r + 1)};
+        Geometry::Pointf center = {float(outer_r + 1.5f), float(outer_r + 1.5f)};
         
         auto box = [&](auto color) {
             auto icon = new Graphics::Bitmap(bmpsize);
@@ -953,6 +953,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         auto &cont = temp.AddContainer(0, UI::ComponentCondition::Always, UI::ComponentCondition::Disabled)
@@ -986,6 +987,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         auto &cont = temp.AddContainer(0, UI::ComponentCondition::Always, UI::ComponentCondition::Disabled)
@@ -1019,6 +1021,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, BorderedWidgetHeight * 10 + Spacing * 9};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         temp.AddContainer(0, UI::ComponentCondition::Always)
@@ -1051,6 +1054,7 @@
         }
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         
@@ -1118,125 +1122,84 @@
     }
     
     UI::Template SimpleGenerator::Inputbox() {
-        Geometry::Size defsize = {WidgetWidth * 2 + Spacing, BorderedWidgetHeight};
+        Geometry::Size defsize = {WidgetWidth, BorderedWidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
+        
+        
+        temp.AddContainer(0, UI::ComponentCondition::Always)
+            .AddIndex(1) //border
+            .AddIndex(2) //boxed content
+        ;
+        
+        auto setupborder = [&](auto &anim, UI::ComponentCondition condition) {
+            auto &bg = temp.AddContainer(1, condition);
+            bg.Background.SetAnimation(anim);
+            bg.SetSize(100, 100, UI::Dimension::Percent);
+            bg.SetPositioning(UI::ComponentTemplate::Absolute);
+        };
 
-        {
-            auto &bg = temp.AddContainer(0, UI::ComponentCondition::Always);
-            bg.AddIndex(5);
-        }
-
-        {
-            auto &bg = temp.AddContainer(0, UI::ComponentCondition::Readonly);
-            bg.AddIndex(6);
-        }
+        setupborder(NormalEditBorder(), UI::ComponentCondition::Always);
+        setupborder(HoverEditBorder(), UI::ComponentCondition::Hover);
+        setupborder(NormalBorder(), UI::ComponentCondition::Readonly);
+        setupborder(DisabledBorder(), UI::ComponentCondition::Disabled);
+        
+        auto &boxed = temp.AddContainer(2, UI::ComponentCondition::Always)
+            .AddIndex(3) //clip
+            .AddIndex(4) //focus
+        ;
+        boxed.SetSize(100, 100, UI::Dimension::Percent);
+        boxed.SetBorderSize(Border.Width);
+        boxed.SetPadding(std::max(Border.Radius / 2, Focus.Spacing));
+        boxed.SetPositioning(UI::ComponentTemplate::Absolute);
+        
+        auto &clip = temp.AddContainer(3, UI::ComponentCondition::Always)
+            .AddIndex(5)
+        ;
+        clip.SetClip(true);
+        clip.SetPadding(Focus.Spacing + Focus.Width);
+        clip.SetSize(100, 100, UI::Dimension::Percent);
+        clip.SetAnchor(UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter);
+        
+        //Contents
+        auto &content = temp.AddContainer(5, UI::ComponentCondition::Always)
+            .AddIndex(6) //text
+            .AddIndex(7) //selection
+            .AddIndex(8) //caret
+        ;
+        content.SetSize(100, 100, UI::Dimension::Percent);
+        content.SetPositioning(UI::ComponentTemplate::Absolute);
+        content.SetAnchor(UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter);
+        content.SetTag(UI::ComponentTemplate::ViewPortTag);
+        
+        
+        //Text
+        auto setuptext = [&](Graphics::RGBA color, UI::ComponentCondition condition) {
+            auto &txt = temp.AddTextholder(6, condition);
+            txt.SetRenderer(RegularFont);
+            txt.SetColor(color);
+            txt.SetAnchor(UI::Anchor::MiddleRight, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
+            txt.SetDataEffect(UI::ComponentTemplate::Text);
+            txt.SetSize(100, 100, UI::Dimension::Percent);
+            txt.SetPositioning(UI::ComponentTemplate::Absolute);
+            txt.SetTag(UI::ComponentTemplate::ContentsTag);
+        };
+        
+        setuptext(Forecolor.Regular, UI::ComponentCondition::Always);
+        setuptext(Forecolor.Regular.BlendWith(Forecolor.Hover), UI::ComponentCondition::Hover);
+        setuptext(Forecolor.Regular.BlendWith(Forecolor.Down), UI::ComponentCondition::Down);
+        setuptext(Forecolor.Regular.BlendWith(Forecolor.Disabled), UI::ComponentCondition::Disabled);
         
         {
-            auto &bg_n = temp.AddContainer(5, UI::ComponentCondition::Always);
-            bg_n.SetPadding(Spacing + Border.Width , UI::Dimension::Pixel);
-            bg_n.AddIndex(1);
-            bg_n.AddIndex(2);
-            bg_n.AddIndex(3);
-            bg_n.AddIndex(4);
-            bg_n.SetSize(100, 100, UI::Dimension::Percent);
-            bg_n.SetClip(true); //!Shadow
-            bg_n.Background.SetAnimation(NormalEditBorder());
-        }
-
-        {
-            auto &bg_h = temp.AddContainer(5, UI::ComponentCondition::Hover);
-            bg_h.SetPadding(Spacing + Border.Width);
-            bg_h.AddIndex(1);
-            bg_h.AddIndex(2);
-            bg_h.AddIndex(3);
-            bg_h.AddIndex(4);
-            bg_h.SetSize(100, 100, UI::Dimension::Percent);
-            bg_h.SetClip(true); //!Shadow
-            bg_h.Background.SetAnimation(HoverEditBorder());
-        }
-
-        {
-            auto &bg_r = temp.AddContainer(6, UI::ComponentCondition::Readonly);
-            bg_r.SetPadding(Spacing + Border.Width);
-            bg_r.AddIndex(1);
-            bg_r.AddIndex(2);
-            bg_r.AddIndex(3);
-            bg_r.AddIndex(4);
-            bg_r.SetSize(100, 100, UI::Dimension::Percent);
-            bg_r.SetClip(true); //!Shadow
-            bg_r.Background.SetAnimation(DisabledBorder());
-        }
-
-        {
-            auto &bg_d = temp.AddContainer(5, UI::ComponentCondition::Disabled);
-            bg_d.SetPadding(Spacing + Border.Width);
-            bg_d.AddIndex(1);
-            bg_d.AddIndex(2);
-            bg_d.AddIndex(3);
-            bg_d.AddIndex(4);
-            bg_d.SetSize(100, 100, UI::Dimension::Percent);
-            bg_d.SetClip(true); //!Shadow
-            bg_d.Background.SetAnimation(DisabledBorder());
-        }
-        
-        {
-            auto &foc = temp.AddContainer(1, UI::ComponentCondition::Focused);
-            foc.Background.SetAnimation(FocusBorder());
-            foc.SetIndent(-Focus.Width*2);
-            foc.SetSize(100, 100, UI::Dimension::Percent);
-            foc.SetPositioning(foc.Absolute);
-            foc.SetAnchor(UI::Anchor::None, UI::Anchor::MiddleCenter, UI::Anchor::MiddleCenter);
-        }
-
-        {
-            auto &txt_n = temp.AddTextholder(2, UI::ComponentCondition::Always);
-            txt_n.SetRenderer(RegularFont);
-            txt_n.SetColor(Forecolor.Regular);
-            txt_n.SetAnchor(UI::Anchor::MiddleRight, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
-            txt_n.SetDataEffect(UI::ComponentTemplate::Text);
-            txt_n.SetTag(txt_n.ContentsTag);
-            txt_n.SetSize({100, UI::Dimension::Percent}, lettervsize.first+lettervsize.second);
-            txt_n.SetSizing(UI::ComponentTemplate::Fixed);
-        }
-
-        {
-            
-            auto c = Forecolor.Regular;
-            c.Blend(Forecolor.Hover);
-            auto &txt_h = temp.AddTextholder(2, UI::ComponentCondition::Hover);
-            txt_h.SetRenderer(RegularFont);
-            txt_h.SetColor(c);
-            txt_h.SetAnchor(UI::Anchor::MiddleRight, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
-            txt_h.SetDataEffect(UI::ComponentTemplate::Text);
-            txt_h.SetTag(txt_h.ContentsTag);
-            txt_h.SetSize({100, UI::Dimension::Percent}, lettervsize.first+lettervsize.second);
-            txt_h.SetSizing(UI::ComponentTemplate::Fixed);
-        }
-
-        {
-            auto c = Forecolor.Regular;
-            c.Blend(Forecolor.Disabled);
-            auto &txt_d = temp.AddTextholder(2, UI::ComponentCondition::Disabled);
-            txt_d.SetRenderer(RegularFont);
-            txt_d.SetColor(c);
-            txt_d.SetAnchor(UI::Anchor::MiddleRight, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
-            txt_d.SetDataEffect(UI::ComponentTemplate::Text);
-            txt_d.SetTag(txt_d.ContentsTag);
-            txt_d.SetSize({100, UI::Dimension::Percent}, lettervsize.first+lettervsize.second);
-            txt_d.SetSizing(UI::ComponentTemplate::Fixed);
-        }
-
-        {
             auto &anim = *new Graphics::BitmapAnimationProvider();
-            int h = lettervsize.first + lettervsize.second;
-            auto &img = *new Graphics::Bitmap({std::min((int)std::round(Border.Width/2.f), 1), h});
-            img.ForAllPixels([&img, this, h](int x, int y) {
+            auto &img = *new Graphics::Bitmap({std::min((int)std::round(Border.Width/2.f), 1), ObjectHeight});
+            img.ForAllPixels([&img, this](int x, int y) {
                 img(x, y, 0) = Border.Color.R;
                 img(x, y, 1) = Border.Color.G;
                 img(x, y, 2) = Border.Color.B;
-                img(x, y, 3) = (y >= (asciivsize.first - 1) && y <= (lettervsize.first + regularrenderer->GetBaseLine()+1)) * Border.Color.A;
+                img(x, y, 3) = /*(y >= (asciivsize.first - 1) && y <= (lettervsize.first + regularrenderer->GetBaseLine()+1)) **/ Border.Color.A;
             });
             drawables.Add(img);
             img.Prepare();
@@ -1249,7 +1212,7 @@
             anim.Add(img2, 300);
             providers.Add(anim);
             
-            auto &caret = temp.AddGraphics(3, UI::ComponentCondition::Focused);
+            auto &caret = temp.AddGraphics(8, UI::ComponentCondition::Focused);
             caret.Content.SetAnimation(anim);
             caret.SetPosition(0, 0, UI::Dimension::Pixel);
             caret.SetPositioning(caret.Absolute);
@@ -1262,18 +1225,18 @@
         {
             auto &img = *new Graphics::BlankImage(8, 8, Background.Selected);
             
-            int h = RegularFont.GetGlyphRenderer().GetHeight();
-            
-            auto &selection = temp.AddGraphics(4, UI::ComponentCondition::Focused);
+            auto &selection = temp.AddGraphics(7, UI::ComponentCondition::Focused);
             selection.Content.SetDrawable(img);
             selection.SetPosition(0, 0, UI::Dimension::Pixel);
             selection.SetPositioning(selection.Absolute);
             selection.SetAnchor(UI::Anchor::None, UI::Anchor::MiddleLeft, UI::Anchor::MiddleLeft);
             selection.SetTag(selection.SelectionTag);
-            selection.SetSize(10, lettervsize.second + lettervsize.first + 1);
+            selection.SetSize(0, ObjectHeight);
             selection.SetSizing(UI::ComponentTemplate::Fixed);
         }
         
+        setupfocus(temp.AddGraphics(4, UI::ComponentCondition::Focused));
+        
         return temp;
     }
 
@@ -1281,6 +1244,7 @@
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
         UI::Template temp;
+        temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
         {
--- a/Source/Gorgon/Widgets/Generator.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Widgets/Generator.h	Thu Sep 17 13:47:51 2020 +0300
@@ -106,8 +106,8 @@
     class SimpleGenerator : public Generator {
     public:
         
-        /// Initializes the generator
-        explicit SimpleGenerator(int fontsize, std::string fontname = "", bool activate = true);
+        /// Initializes the generator. Density controls the spacing between elements
+        explicit SimpleGenerator(int fontsize, std::string fontname = "", bool activate = true, float density = 7.5);
         
         /// Creates a non-working simple generator. Calls to any function other than Init
         /// is undefined behaviour.
@@ -245,6 +245,10 @@
         
         /// This is the height of a non-bordered widget
         int WidgetHeight = 24;
+        
+        /// This controls the automatic spacing. After chaning this member
+        /// you need to call UpdateDimensions to get the desired effect.
+        float Density = 7.5;
 
     private:
         Graphics::BitmapRectangleProvider *makeborder(Graphics::RGBA border, Graphics::RGBA bg, int missingedge = 0, int borderwidth = -1, int borderradius = -1);
--- a/Source/Gorgon/Widgets/Inputbox.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Widgets/Inputbox.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -2,6 +2,7 @@
 
 #include "../Graphics/Font.h"
 #include "../WindowManager.h"
+#include "../UI.h"
 
 namespace Gorgon { namespace Widgets { namespace internal {
     
@@ -188,6 +189,10 @@
             return true;
 
         if(state) {
+            //tab and escape are always passed through
+            if(key == Keycodes::Tab || key == Keycodes::Escape)
+                return false;
+            
             if(Input::Keyboard::CurrentModifier == Modifier::None) {
                 switch(key) {
                 case Keycodes::Home:
@@ -262,8 +267,12 @@
                 }
             }
         }
+        
+        if(state && !Input::Keyboard::CurrentModifier.IsModified()) {
+            Input::AllowCharEvent = true;
+        }
 
-        return false;
+        return !Input::Keyboard::CurrentModifier.IsModified();
     }
 
     bool Inputbox_base::CharacterEvent(Char c) {
@@ -338,8 +347,6 @@
         else
             pos += sellen.glyph;
 
-        //std::cout<<selstart.glyph<<"\t"<<selstart.byte<<"\t|\t"<<sellen.glyph<<"\t"<<sellen.byte<<"\t|\t"<<glyphcount<<std::endl;
-
         Geometry::Point location;
         auto textsize = renderer.GetSize(display);
         
@@ -352,10 +359,13 @@
             targetsize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
         }
         
+        
+        bool inarea = false;
         if(targetsize.Width > textsize.Width) {
             scrolloffset = 0;
 
             stack.SetTagLocation(UI::ComponentTemplate::ContentsTag, {scrolloffset, 0});
+            inarea = true;
         }
         
         if(display == "") {
@@ -377,29 +387,32 @@
             stack.SetTagLocation(UI::ComponentTemplate::ContentsTag, {scrolloffset, 0});
         }
 
-        stack.SetTagLocation(UI::ComponentTemplate::CaretTag, {location.X + scrolloffset, location.Y});
+        if(display == "") {
+            stack.RemoveTagLocation(UI::ComponentTemplate::CaretTag);
+        }
+        else {
+            stack.SetTagLocation(UI::ComponentTemplate::CaretTag, {location.X + scrolloffset, location.Y});
+        }
         
         if(stack.IndexOfTag(UI::ComponentTemplate::SelectionTag) != -1) {
-            auto selbounds = stack.TagBounds(UI::ComponentTemplate::SelectionTag);
             if(sellen.byte == 0) {
-                stack.SetTagSize(UI::ComponentTemplate::SelectionTag, {0, selbounds.Height()});
+                stack.RemoveTagSize(UI::ComponentTemplate::SelectionTag);
             }
             else {
                 auto srclocation = renderer.GetPosition(display, stack.TagBounds(UI::ComponentTemplate::ContentsTag).Width(), selstart.glyph, false).BottomLeft();
                 
                 if(srclocation.X < location.X) {
                     stack.SetTagLocation(UI::ComponentTemplate::SelectionTag, {srclocation.X + scrolloffset, 0});
-                    stack.SetTagSize(UI::ComponentTemplate::SelectionTag, {location.X - srclocation.X, selbounds.Height()});
+                    stack.SetTagSize(UI::ComponentTemplate::SelectionTag, {location.X - srclocation.X, 0});
                 }
                 else {
                     stack.SetTagLocation(UI::ComponentTemplate::SelectionTag, {location.X + scrolloffset, 0});
-                    stack.SetTagSize(UI::ComponentTemplate::SelectionTag, {srclocation.X - location.X, selbounds.Height()});
+                    stack.SetTagSize(UI::ComponentTemplate::SelectionTag, {srclocation.X - location.X, 0});
                 }
             }
         }
     }
 
-
     void Inputbox_base::focused() {
         UI::ComponentStackWidget::focused();
         
--- a/Source/Gorgon/Widgets/RadioButtons.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Widgets/RadioButtons.h	Thu Sep 17 13:47:51 2020 +0300
@@ -20,9 +20,15 @@
     class RadioButtons : public UI::WidgetBase, protected UI::RadioControl<T_, W_>, public UI::WidgetContainer {
         friend class UI::WidgetContainer;
     public:
-        explicit RadioButtons(const UI::Template &temp) : temp(temp) { this->own = true; }
+        explicit RadioButtons(const UI::Template &temp) : temp(temp) { 
+            spacing = temp.GetSpacing();
+            this->own = true;
+        }
         
-        explicit RadioButtons(Registry::TemplateType type = Registry::Radio_Regular) : temp(Registry::Active()[type]) {  this->own = true; }
+        explicit RadioButtons(Registry::TemplateType type = Registry::Radio_Regular) : temp(Registry::Active()[type]) {  
+            spacing = temp.GetSpacing();
+            this->own = true; 
+        }
 
         
         /// Radio buttons height is automatically adjusted. Only width will be used.
@@ -77,10 +83,10 @@
             if(GetWidth() < c.GetWidth())
                 SetWidth(c.GetWidth());
             
-            contents.SetHeight(GetHeight() + c.GetHeight() + spacing);
-            
             if(IsVisible())
                 this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
+                
+            contents.SetHeight(this->widgets.Last()->GetBounds().Bottom);
             
             boundschanged();
             childboundschanged(&c);
@@ -103,7 +109,7 @@
                 if(IsVisible())
                     this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
                 
-                contents.SetHeight(this->widgets.Last()->GetBounds().Bottom + 1);
+                contents.SetHeight(this->widgets.Last()->GetBounds().Bottom);
                 
                 boundschanged();
                 childboundschanged(&elm);
--- a/Source/Gorgon/Widgets/Registry.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Widgets/Registry.h	Thu Sep 17 13:47:51 2020 +0300
@@ -3,12 +3,12 @@
 #include "../UI/Template.h"
 
 namespace Gorgon { namespace Widgets {
-   
+
     
     /**
-     * This class stores templates for elements. Once a registry is active
-     * all created widgets will use the specified registry for templates.
-     */
+    * This class stores templates for elements. Once a registry is active
+    * all created widgets will use the specified registry for templates.
+    */
     class Registry {
     public:
         
@@ -74,11 +74,10 @@
             
             return *templates[type];
         }
-        
-	
-		virtual int GetSpacing()const = 0;
+    
+        virtual int GetSpacing()const = 0;
 
-		virtual int GetEmSize()const = 0;
+        virtual int GetEmSize()const = 0;
 
     protected:
 
@@ -101,9 +100,9 @@
     
     
     /**
-     * This registry contains preset templates. You are required to set all the templates
-     * otherwise, missing templates will be generated completely empty. 
-     */
+    * This registry contains preset templates. You are required to set all the templates
+    * otherwise, missing templates will be generated completely empty. 
+    */
     class PresetRegistry : public Registry {
     public:
         
@@ -115,33 +114,33 @@
             templates[type] = &temp;
         }
         
-		void SetSpacing(const int tspacing) {
-			spacing = tspacing;
-		}
+        void SetSpacing(const int tspacing) {
+            spacing = tspacing;
+        }
 
-		void SetEmSize(const int size) {
-			emsize = size;
+        void SetEmSize(const int size) {
+            emsize = size;
 
-		}
+        }
 
-		virtual int GetSpacing()const override {
-			return spacing;
-		}
+        virtual int GetSpacing()const override {
+            return spacing;
+        }
 
-		virtual int GetEmSize()const override {
-			return emsize;
-		}
+        virtual int GetEmSize()const override {
+            return emsize;
+        }
 
     protected:
         virtual UI::Template &generate(Gorgon::Widgets::Registry::TemplateType) override {
             return *new UI::Template();
         }
-		
-		int spacing = 5;
+        
+        int spacing = 5;
 
-		int emsize = 14;
+        int emsize = 14;
 
     };
     
-	
+    
 } }
--- a/Source/Gorgon/Window.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/Window.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -46,6 +46,27 @@
 		}
         else
             windows.Remove(other);
+        
+        //events
+		FocusedEvent.Swap(other.FocusedEvent);
+
+		LostFocusEvent.Swap(other.LostFocusEvent);
+
+		DestroyedEvent.Swap(other.DestroyedEvent);
+
+		ClosingEvent.Swap(other.ClosingEvent);
+
+		MovedEvent.Swap(other.MovedEvent);
+
+		ResizedEvent.Swap(other.ResizedEvent);
+
+		MinimizedEvent.Swap(other.MinimizedEvent);
+
+		RestoredEvent.Swap(other.RestoredEvent);
+		
+		KeyEvent.Swap(other.KeyEvent);
+
+		CharacterEvent.Swap(other.CharacterEvent);
 
 		updatedataowner();
 		other.updatedataowner();
--- a/Source/Gorgon/WindowManager/DWM/Input.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/WindowManager/DWM/Input.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -326,8 +326,10 @@
 		//if the key is repeating, do not repeat keyevent.
 		if(!(lParam&1<<30)) {
 			data->pressedkeys.insert(key);
+            
+            Input::AllowCharEvent = false;
 			auto token = data->parent->KeyEvent(key, true);
-			if(token!=ConsumableEvent<Window, Input::Key, bool>::EmptyToken) {
+			if(token!=ConsumableEvent<Window, Input::Key, bool>::EmptyToken && !Input::AllowCharEvent) {
 				data->handlers[key] = token;
 
 				return;
@@ -526,4 +528,4 @@
 		}
 	}
 
-} }
\ No newline at end of file
+} }
--- a/Source/Gorgon/WindowManager/X11/Input.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Source/Gorgon/WindowManager/X11/Input.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -349,8 +349,9 @@
                 break;
         }
         auto ggekey = WindowManager::mapx11key(key, event.xkey.keycode);
+        Input::AllowCharEvent = false;
         auto token = wind.KeyEvent(ggekey, true);
-        if(token != wind.KeyEvent.EmptyToken) {
+        if(token != wind.KeyEvent.EmptyToken && !Input::AllowCharEvent) {
             data->handlers[ggekey]=token;
             
             return;
--- a/Testing/Source/Manual/GraphicsHelper.h	Tue Sep 15 18:32:31 2020 +0300
+++ b/Testing/Source/Manual/GraphicsHelper.h	Thu Sep 17 13:47:51 2020 +0300
@@ -26,41 +26,40 @@
 template<class W_>
 class basic_Application {
 public:
-	basic_Application(std::string appname, std::string title, std::string helptext, int tilesize=25, int colmod = 0x10) :
-		appname(appname)
-	{
-		std::cout<<"Current working directory: ";
+    basic_Application(std::string appname, std::string title, std::string helptext, int tilesize=25, int colmod = 0x10) :
+        appname(appname)
+    {
+        std::cout<<"Current working directory: ";
 #ifdef WIN32
-		system("cd");
+        system("cd");
 #else
-		system("pwd");
+        system("pwd");
 #endif
-		std::cout<<std::endl;
+        std::cout<<std::endl;
 
-		Gorgon::Initialize(appname);
+        Gorgon::Initialize(appname);
 
-		wind ={{800, 600}, appname, title, true};
+        wind ={{800, 600}, appname, title, true};
 
-		//Gorgon::GL::log.InitializeConsole();
+        //Gorgon::GL::log.InitializeConsole();
 
-		Graphics::Initialize();
+        Graphics::Initialize();
         UI::Initialize();
 
-
-		wind.ClosingEvent.Register([] { exit(0); });
+        wind.ClosingEvent.Register([] { exit(0); });
 
         l.setname("BG");
-		wind.Add(l);
+        wind.Add(l);
 
-		if(icon.Import("icon.png")) {
-			ico = WM::Icon{icon.GetData()};
-			wind.SetIcon(ico);
-		}
+        if(icon.Import("icon.png")) {
+            ico = WM::Icon{icon.GetData()};
+            wind.SetIcon(ico);
+        }
         wind.setname("Wind");
 
-		bgimage = BGImage(tilesize, tilesize, colmod, colmod*3);
-		bgimage.Prepare();
-		bgimage.DrawIn(l);
+        bgimage = BGImage(tilesize, tilesize, colmod, colmod*3);
+        bgimage.Prepare();
+        bgimage.DrawIn(l);
     
         int sz = 11;
 #ifdef WIN32
@@ -102,37 +101,37 @@
             bmpfnt->AutoKern();
         }
         
-		sty.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
-		sty.SetColor({0.6f, 1.f, 1.f});
-		sty.JustifyLeft();
+        sty.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
+        sty.SetColor({0.6f, 1.f, 1.f});
+        sty.JustifyLeft();
 
-		stylarge.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
-		stylarge.SetColor({1.f, 1.f, 1.f});
-		stylarge.AlignCenter();
+        stylarge.UseFlatShadow({0.f, 1.0f}, {1.f, 1.f});
+        stylarge.SetColor({1.f, 1.f, 1.f});
+        stylarge.AlignCenter();
 
-		sty.SetTabWidthInLetters(4);
-		sty.SetParagraphSpacing(4);
-		sty.Print(l,
-				  helptext
-				  , 600, 10, wind.GetWidth()-605
-		);
+        sty.SetTabWidthInLetters(4);
+        sty.SetParagraphSpacing(4);
+        sty.Print(l,
+                helptext
+                , 600, 10, wind.GetWidth()-605
+        );
 
-		wind.KeyEvent.Register([](Input::Key key, bool state) {
-			if(!state && (key == 27 || key == 65307))
-				exit(0);
+        wind.KeyEvent.Register([](Input::Key key, bool state) {
+            if(!state && (key == 27 || key == 65307))
+                exit(0);
 
-			return false;
-		});
-	}
+            return false;
+        });
+    }
 
-	W_ wind;
-	Graphics::Layer l;
-	Bitmap bgimage, icon;
-	Graphics::FreeType fnt, fntlarge;
+    W_ wind;
+    Graphics::Layer l;
+    Bitmap bgimage, icon;
+    Graphics::FreeType fnt, fntlarge;
     Graphics::StyledRenderer sty = {fnt}, stylarge = {fntlarge};
     WM::Icon ico;
 
-	std::string appname;
+    std::string appname;
 };
 
 using Application = basic_Application<Gorgon::Window>;
@@ -289,44 +288,44 @@
 }
 
 inline Graphics::Bitmap Rectangle(int w, int h) {
-	Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
+    Graphics::Bitmap b({w, h}, Graphics::ColorMode::Alpha);
 
-	for(int y=0; y<h; y++) {
-		for(int x=0; x<w; x++) {
-			b(x, y, 0) = 255;
-		}
-	}
+    for(int y=0; y<h; y++) {
+        for(int x=0; x<w; x++) {
+            b(x, y, 0) = 255;
+        }
+    }
 
-	return b;
+    return b;
 }
 
 inline Graphics::Bitmap Pattern(int f) {
-	Graphics::Bitmap b({2, 2}, Graphics::ColorMode::Alpha);
+    Graphics::Bitmap b({2, 2}, Graphics::ColorMode::Alpha);
 
-	b.Clear();
+    b.Clear();
 
-	if(f>0)
-		b(0, 0, 0) = 255;
-	if(f>1)
-		b(1, 1, 0) = 255;
-	if(f>2)
-		b(1, 0, 0) = 255;
-	if(f>3)
-		b(0, 1, 0) = 255;
+    if(f>0)
+        b(0, 0, 0) = 255;
+    if(f>1)
+        b(1, 1, 0) = 255;
+    if(f>2)
+        b(1, 0, 0) = 255;
+    if(f>3)
+        b(0, 1, 0) = 255;
 
-	return b;
+    return b;
 }
 
 inline Graphics::Bitmap BGImage(int w, int h, Byte col1, Byte col2) {
-	Graphics::Bitmap bgimage({w*2, h*2}, Graphics::ColorMode::Grayscale);
+    Graphics::Bitmap bgimage({w*2, h*2}, Graphics::ColorMode::Grayscale);
 
-	for(int x = 0; x<w*2; x++) {
-		for(int y = 0; y<h*2; y++) {
-			if((x/w) != (y/h))
-				bgimage({x, y}, 0) = col1;
-			else
-				bgimage({x, y}, 0) = col2;
-		}
+    for(int x = 0; x<w*2; x++) {
+        for(int y = 0; y<h*2; y++) {
+            if((x/w) != (y/h))
+                bgimage({x, y}, 0) = col1;
+            else
+                bgimage({x, y}, 0) = col2;
+        }
     }
     
     return bgimage;
--- a/Testing/Source/Manual/UI_Generate.cpp	Tue Sep 15 18:32:31 2020 +0300
+++ b/Testing/Source/Manual/UI_Generate.cpp	Thu Sep 17 13:47:51 2020 +0300
@@ -37,16 +37,16 @@
     basic_Application<UI::Window> app("uitest", "UI Generator Test", helptext, 1, 0x80);
 
     ///Blank Panel & elements with Registry & Regulars 
-    Widgets::SimpleGenerator generator;
+    /*Widgets::SimpleGenerator generator;
     generator.Init(13);
     //generator.Border.Radius = 0;
     generator.UpdateBorders();
     generator.UpdateDimensions();
-    generator.Activate();
+    generator.Activate();*/
 
     Widgets::Panel blank/*(Gorgon::Widgets::Registry::Panel_Blank)*/;
     blank.SetHeight(600);
-    Gorgon::Widgets::Button btn("Save as",Gorgon::Widgets::Registry::Button_Regular);
+    Gorgon::Widgets::Button btn("Save Âj",Gorgon::Widgets::Registry::Button_Regular);
     Gorgon::Widgets::Button icnbtn("+", Gorgon::Widgets::Registry::Button_Icon);
     Gorgon::Widgets::Button icnbtn2("Âj", Gorgon::Widgets::Registry::Button_Icon);
     Gorgon::Widgets::Button icnbtn3("X", Gorgon::Widgets::Registry::Button_Icon);

mercurial