فهرست منبع

WIP: Specify bubbling and default actions on dispatching events

Michael Ragazzon 6 سال پیش
والد
کامیت
246e1ecc78
50فایلهای تغییر یافته به همراه135 افزوده شده و 134 حذف شده
  1. 2 2
      Include/Rocket/Controls/ElementDataGrid.h
  2. 1 1
      Include/Rocket/Controls/ElementDataGridExpandButton.h
  3. 1 1
      Include/Rocket/Controls/ElementFormControlInput.h
  4. 1 1
      Include/Rocket/Controls/ElementTabSet.h
  5. 2 8
      Include/Rocket/Core/Context.h
  6. 1 1
      Include/Rocket/Core/Element.h
  7. 1 1
      Include/Rocket/Core/ElementScroll.h
  8. 3 1
      Include/Rocket/Core/Event.h
  9. 2 2
      Samples/invaders/src/ElementGame.h
  10. 2 2
      Samples/invaders/src/Event.h
  11. 1 1
      Samples/invaders/src/EventHandlerHighScore.h
  12. 1 1
      Samples/invaders/src/EventHandlerOptions.h
  13. 1 1
      Samples/invaders/src/EventHandlerStartGame.h
  14. 1 1
      Samples/luainvaders/src/ElementGame.cpp
  15. 4 4
      Samples/luainvaders/src/ElementGame.h
  16. 3 2
      Source/Controls/ElementDataGrid.cpp
  17. 6 3
      Source/Controls/ElementDataGridRow.cpp
  18. 1 1
      Source/Controls/ElementForm.cpp
  19. 1 1
      Source/Controls/ElementTabSet.cpp
  20. 1 1
      Source/Controls/InputTypeButton.h
  21. 1 1
      Source/Controls/InputTypeCheckbox.cpp
  22. 1 1
      Source/Controls/InputTypeRadio.cpp
  23. 1 1
      Source/Controls/InputTypeRadio.h
  24. 1 1
      Source/Controls/InputTypeRange.h
  25. 1 1
      Source/Controls/InputTypeSubmit.h
  26. 1 1
      Source/Controls/InputTypeText.h
  27. 1 1
      Source/Controls/WidgetDropDown.cpp
  28. 1 1
      Source/Controls/WidgetDropDown.h
  29. 1 1
      Source/Controls/WidgetSlider.cpp
  30. 1 1
      Source/Controls/WidgetSlider.h
  31. 1 1
      Source/Controls/WidgetTextInput.cpp
  32. 1 1
      Source/Controls/WidgetTextInput.h
  33. 35 35
      Source/Core/Context.cpp
  34. 5 5
      Source/Core/Element.cpp
  35. 3 3
      Source/Core/ElementDocument.cpp
  36. 2 2
      Source/Core/ElementHandle.cpp
  37. 2 2
      Source/Core/ElementHandle.h
  38. 2 2
      Source/Core/ElementImage.h
  39. 1 1
      Source/Core/ElementUtilities.cpp
  40. 2 2
      Source/Core/Event.cpp
  41. 19 15
      Source/Core/EventDispatcher.cpp
  42. 3 3
      Source/Core/EventDispatcher.h
  43. 5 8
      Source/Core/EventIterators.h
  44. 1 1
      Source/Core/Lua/Element.cpp
  45. 1 1
      Source/Core/Lua/LuaEventListener.h
  46. 1 1
      Source/Core/WidgetSlider.cpp
  47. 1 1
      Source/Core/WidgetSlider.h
  48. 1 1
      Source/Debugger/ElementInfo.h
  49. 2 2
      Source/Debugger/ElementLog.h
  50. 1 1
      Source/Debugger/Plugin.h

+ 2 - 2
Include/Rocket/Controls/ElementDataGrid.h

@@ -118,11 +118,11 @@ public:
 	ElementDataGridRow* GetRow(int index) const;
 
 protected:
-	virtual void OnUpdate();
+	virtual void OnUpdate() override;
 
 	virtual void OnResize() override;
 
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Gets the markup and content of the element.
 	/// @param content[out] The content of the element.

+ 1 - 1
Include/Rocket/Controls/ElementDataGridExpandButton.h

@@ -45,7 +45,7 @@ public:
 	virtual ~ElementDataGridExpandButton();
 
 protected:
-	void ProcessEvent(Core::Event& event);
+	void ProcessEvent(Core::Event& event) override;
 };
 
 }

+ 1 - 1
Include/Rocket/Controls/ElementFormControlInput.h

@@ -85,7 +85,7 @@ protected:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Include/Rocket/Controls/ElementTabSet.h

@@ -82,7 +82,7 @@ public:
 	int GetActiveTab() const;
 
 	/// Process the incoming event.
-	void ProcessEvent(Core::Event& event);
+	void ProcessEvent(Core::Event& event) override;
 
 	/// Called when the listener has been attached to a new Element
 	void OnAttach(Element* element);

+ 2 - 8
Include/Rocket/Core/Context.h

@@ -41,17 +41,11 @@ namespace Rocket {
 namespace Core {
 
 class Stream;
-
-}
-}
-
-namespace Rocket {
-namespace Core {
-
 class ContextInstancer;
 class ElementDocument;
 class EventListener;
 class RenderInterface;
+enum class DefaultActionPhase;
 
 /**
 	A context for storing, rendering and processing RML documents. Multiple contexts can exist simultaneously.
@@ -333,7 +327,7 @@ private:
 	void ReleaseUnloadedDocuments();
 
 	// Sends the specified event to all elements in new_items that don't appear in old_items.
-	static void SendEvents(const ElementSet& old_items, const ElementSet& new_items, const String& event, const Dictionary& parameters, bool interruptible);
+	static void SendEvents(const ElementSet& old_items, const ElementSet& new_items, const String& event, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase);
 
 	friend class Element;
 	friend ROCKETCORE_API Context* CreateContext(const String&, const Vector2i&, RenderInterface*);

+ 1 - 1
Include/Rocket/Core/Element.h

@@ -493,7 +493,7 @@ public:
 	/// @param[in] parameters The event parameters.
 	/// @param[in] interruptible True if the propagation of the event be stopped.
 	/// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
-	bool DispatchEvent(const String& event, const Dictionary& parameters, bool interruptible = false);
+	bool DispatchEvent(const String& event, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase);
 
 	/// Scrolls the parent element's contents so that this element is visible.
 	/// @param[in] align_with_top If true, the element will align itself to the top of the parent element's window. If false, the element will be aligned to the bottom of the parent element's window.

+ 1 - 1
Include/Rocket/Core/ElementScroll.h

@@ -87,7 +87,7 @@ public:
 
 protected:
 	/// Handles the 'onchange' events for the scrollbars.
-	void ProcessEvent(Event& event);
+	void ProcessEvent(Event& event) override;
 
 private:
 	struct Scrollbar

+ 3 - 1
Include/Rocket/Core/Event.h

@@ -59,7 +59,7 @@ public:
 	/// Destructor
 	virtual ~Event();
 
-	enum EventPhase { PHASE_UNKNOWN, PHASE_CAPTURE, PHASE_TARGET, PHASE_BUBBLE };
+	enum EventPhase { PHASE_NONE, PHASE_CAPTURE = 1, PHASE_TARGET = 2, PHASE_BUBBLE = 4 };
 
 	/// Get the current propagation phase.
 	/// @return Current phase the event is in.
@@ -133,6 +133,8 @@ private:
 	friend class Factory;
 };
 
+enum class DefaultActionPhase { None, Target = Event::PHASE_TARGET, Bubble = Event::PHASE_BUBBLE, TargetAndBubble = (Target | Bubble) };
+
 }
 }
 

+ 2 - 2
Samples/invaders/src/ElementGame.h

@@ -44,12 +44,12 @@ public:
 	virtual ~ElementGame();
 
 	/// Intercepts and handles key events.
-	void ProcessEvent(Rocket::Core::Event& event);
+	void ProcessEvent(Rocket::Core::Event& event) override;
 
 	/// Receive notifications when child elements are added
 	/// This will only get called when we're added to the tree,
 	/// which allows us to bind to onload
-	void OnChildAdd(Rocket::Core::Element* element);
+	void OnChildAdd(Rocket::Core::Element* element) override;
 
 protected:
 	/// Updates the game.

+ 2 - 2
Samples/invaders/src/Event.h

@@ -41,10 +41,10 @@ public:
 	virtual ~Event();
 
 	/// Sends the event value through to Invader's event processing system.
-	virtual void ProcessEvent(Rocket::Core::Event& event);
+	virtual void ProcessEvent(Rocket::Core::Event& event) override;
 
 	/// Destroys the event.
-	virtual void OnDetach(Rocket::Core::Element* element);
+	virtual void OnDetach(Rocket::Core::Element* element) override;
 
 private:
 	Rocket::Core::String value;

+ 1 - 1
Samples/invaders/src/EventHandlerHighScore.h

@@ -39,7 +39,7 @@ public:
 	EventHandlerHighScore();
 	virtual ~EventHandlerHighScore();
 
-	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value);
+	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value) override;
 };
 
 #endif

+ 1 - 1
Samples/invaders/src/EventHandlerOptions.h

@@ -40,7 +40,7 @@ public:
 	EventHandlerOptions();
 	virtual ~EventHandlerOptions();
 
-	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value);
+	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value) override;
 };
 
 #endif

+ 1 - 1
Samples/invaders/src/EventHandlerStartGame.h

@@ -40,7 +40,7 @@ public:
 	EventHandlerStartGame();
 	virtual ~EventHandlerStartGame();
 
-	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value);
+	virtual void ProcessEvent(Rocket::Core::Event& event, const Rocket::Core::String& value) override;
 };
 
 #endif

+ 1 - 1
Samples/luainvaders/src/ElementGame.cpp

@@ -84,7 +84,7 @@ void ElementGame::OnUpdate()
 	game->Update();
 
 	if (game->IsGameOver())
-		DispatchEvent("gameover", Rocket::Core::Dictionary(), false);
+		DispatchEvent("gameover", Rocket::Core::Dictionary(), false, true, Rocket::Core::DefaultActionPhase::Target);
 }
 
 // Renders the game.

+ 4 - 4
Samples/luainvaders/src/ElementGame.h

@@ -44,18 +44,18 @@ public:
 	virtual ~ElementGame();
 
 	/// Intercepts and handles key events.
-	void ProcessEvent(Rocket::Core::Event& event);
+	void ProcessEvent(Rocket::Core::Event& event) override;
 
 	/// Receive notifications when child elements are added
 	/// This will only get called when we're added to the tree,
 	/// which allows us to bind to onload
-	void OnChildAdd(Rocket::Core::Element* element);
+	void OnChildAdd(Rocket::Core::Element* element) override;
 
 protected:
 	/// Updates the game.
-	virtual void OnUpdate();
+	virtual void OnUpdate() override;
 	/// Renders the game.
-	virtual void OnRender();
+	virtual void OnRender() override;
 
 private:
 	Game* game;

+ 3 - 2
Source/Controls/ElementDataGrid.cpp

@@ -139,7 +139,7 @@ void ElementDataGrid::AddColumn(const Rocket::Core::String& fields, const Rocket
 
 	Rocket::Core::Dictionary parameters;
 	parameters["index"] = (int)(columns.size() - 1);
-	DispatchEvent("columnadd", parameters);
+	DispatchEvent("columnadd", parameters, false, false, Core::DefaultActionPhase::Target);
 }
 
 // Returns the number of columns in this table
@@ -231,7 +231,8 @@ void ElementDataGrid::OnUpdate()
 	bool any_new_children = root->UpdateChildren();
 	if (any_new_children)
 	{
-		DispatchEvent("rowupdate", Rocket::Core::Dictionary());
+		// @performance: Does anyone really use this?
+		DispatchEvent("rowupdate", Rocket::Core::Dictionary(), false, true, Core::DefaultActionPhase::None);
 	}
 	
 	if (!body_visible && (!any_new_children || root->GetNumLoadedChildren() >= GetAttribute("min-rows", 0)))

+ 6 - 3
Source/Controls/ElementDataGridRow.cpp

@@ -408,7 +408,8 @@ void ElementDataGridRow::AddChildren(int first_row_added, int num_rows_added)
 	Rocket::Core::Dictionary parameters;
 	parameters["first_row_added"] = GetChildTableRelativeIndex(first_row_added);
 	parameters["num_rows_added"] = num_rows_added;
-	parent_grid->DispatchEvent("rowadd", parameters);
+	// @performance: Does anyone really use this?
+	parent_grid->DispatchEvent("rowadd", parameters, false, true, Core::DefaultActionPhase::None);
 }
 
 void ElementDataGridRow::RemoveChildren(int first_row_removed, int num_rows_removed)
@@ -437,7 +438,8 @@ void ElementDataGridRow::RemoveChildren(int first_row_removed, int num_rows_remo
 	Rocket::Core::Dictionary parameters;
 	parameters["first_row_removed"] = GetChildTableRelativeIndex(first_row_removed);
 	parameters["num_rows_removed"] = num_rows_removed;
-	parent_grid->DispatchEvent("rowremove", parameters);
+	// @performance: Does anyone really use this?
+	parent_grid->DispatchEvent("rowremove", parameters, false, true, Core::DefaultActionPhase::None);
 }
 
 void ElementDataGridRow::ChangeChildren(int first_row_changed, int num_rows_changed)
@@ -448,7 +450,8 @@ void ElementDataGridRow::ChangeChildren(int first_row_changed, int num_rows_chan
 	Rocket::Core::Dictionary parameters;
 	parameters["first_row_changed"] = GetChildTableRelativeIndex(first_row_changed);
 	parameters["num_rows_changed"] = num_rows_changed;
-	parent_grid->DispatchEvent("rowchange", parameters);
+	// @performance: Does anyone really use this?
+	parent_grid->DispatchEvent("rowchange", parameters, false, true, Core::DefaultActionPhase::None);
 }
 
 // Returns the number of rows under this row (children, grandchildren, etc)

+ 1 - 1
Source/Controls/ElementForm.cpp

@@ -86,7 +86,7 @@ void ElementForm::Submit(const Rocket::Core::String& name, const Rocket::Core::S
 			values[control_name] = control_value;
 	}
 
-	DispatchEvent("submit", values);
+	DispatchEvent("submit", values, true, true, Core::DefaultActionPhase::None);
 }
 
 }

+ 1 - 1
Source/Controls/ElementTabSet.cpp

@@ -132,7 +132,7 @@ void ElementTabSet::SetActiveTab(int tab_index)
 
 		Rocket::Core::Dictionary parameters;
 		parameters["tab_index"] = active_tab;
-		DispatchEvent("tabchange", parameters);
+		DispatchEvent("tabchange", parameters, false, true, Core::DefaultActionPhase::None);
 	}
 }
 

+ 1 - 1
Source/Controls/InputTypeButton.h

@@ -55,7 +55,7 @@ public:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Source/Controls/InputTypeCheckbox.cpp

@@ -56,7 +56,7 @@ bool InputTypeCheckbox::OnAttributeChange(const Core::AttributeNameList& changed
 
 		Rocket::Core::Dictionary parameters;
 		parameters["value"] = Rocket::Core::String(checked ? GetValue() : "");
-		element->DispatchEvent("change", parameters);
+		element->DispatchEvent("change", parameters, false, true, Core::DefaultActionPhase::None);
 	}
 
 	return true;

+ 1 - 1
Source/Controls/InputTypeRadio.cpp

@@ -63,7 +63,7 @@ bool InputTypeRadio::OnAttributeChange(const Core::AttributeNameList& changed_at
 
 		Rocket::Core::Dictionary parameters;
 		parameters["value"] = Rocket::Core::String(checked ? GetValue() : "");
-		element->DispatchEvent("change", parameters);
+		element->DispatchEvent("change", parameters, false, true, Core::DefaultActionPhase::None);
 	}
 
 	return true;

+ 1 - 1
Source/Controls/InputTypeRadio.h

@@ -59,7 +59,7 @@ public:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Source/Controls/InputTypeRange.h

@@ -64,7 +64,7 @@ public:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Source/Controls/InputTypeSubmit.h

@@ -51,7 +51,7 @@ public:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Source/Controls/InputTypeText.h

@@ -72,7 +72,7 @@ public:
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Sizes the dimensions to the element's inherent size.
 	/// @return True.

+ 1 - 1
Source/Controls/WidgetDropDown.cpp

@@ -205,7 +205,7 @@ void WidgetDropDown::SetSelection(int selection, bool force)
 
 		Rocket::Core::Dictionary parameters;
 		parameters["value"] = value;
-		parent_element->DispatchEvent("change", parameters);
+		parent_element->DispatchEvent("change", parameters, false, true, Core::DefaultActionPhase::None);
 	}
 }
 

+ 1 - 1
Source/Controls/WidgetDropDown.h

@@ -92,7 +92,7 @@ public:
 	int GetNumOptions() const;
 
 	/// Processes the incoming event.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 private:
 	typedef std::vector< SelectOption > OptionList;

+ 1 - 1
Source/Controls/WidgetSlider.cpp

@@ -186,7 +186,7 @@ void WidgetSlider::SetBarPosition(float _bar_position)
 
 	Rocket::Core::Dictionary parameters;
 	parameters["value"] = bar_position;
-	parent->DispatchEvent("change", parameters);
+	parent->DispatchEvent("change", parameters, false, true, Core::DefaultActionPhase::None);
 }
 
 // Returns the current position of the bar.

+ 1 - 1
Source/Controls/WidgetSlider.h

@@ -91,7 +91,7 @@ protected:
 	Core::Element* GetParent() const;
 
 	/// Handles events coming through from the slider's components.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Called when the slider's bar position is set or dragged.
 	/// @param[in] bar_position The new position of the bar (0 representing the start of the track, 1 representing the end).

+ 1 - 1
Source/Controls/WidgetTextInput.cpp

@@ -258,7 +258,7 @@ void WidgetTextInput::DispatchChangeEvent(bool linebreak)
 	Rocket::Core::Dictionary parameters;
 	parameters["value"] = GetElement()->GetAttribute< Rocket::Core::String >("value", "");
 	parameters["linebreak"] = Core::Variant(linebreak);
-	GetElement()->DispatchEvent("change", parameters);
+	GetElement()->DispatchEvent("change", parameters, false, true, Core::DefaultActionPhase::None);
 }
 
 // Processes the "keydown" and "textinput" event to write to the input field, and the "focus" and "blur" to set

+ 1 - 1
Source/Controls/WidgetTextInput.h

@@ -87,7 +87,7 @@ public:
 protected:
 	/// Processes the "keydown" and "textinput" event to write to the input field, and the "focus" and
 	/// "blur" to set the state of the cursor.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Adds a new character to the string at the cursor position.
 	/// @param[in] character The character to add to the string.

+ 35 - 35
Source/Core/Context.cpp

@@ -118,7 +118,7 @@ void Context::SetDimensions(const Vector2i& _dimensions)
 			{
 				document->DirtyLayout();
 				document->DirtyPosition();
-				document->DispatchEvent(RESIZE, Dictionary());
+				document->DispatchEvent(RESIZE, Dictionary(), false, false, DefaultActionPhase::None);
 			}
 		}
 		
@@ -274,7 +274,7 @@ ElementDocument* Context::LoadDocument(Stream* stream)
 	// values and layouting are not performed yet, resulting in default values when
 	// querying such information in the event handler.
 	PluginRegistry::NotifyDocumentLoad(document);
-	document->DispatchEvent(LOAD, Dictionary(), false);
+	document->DispatchEvent(LOAD, Dictionary(), false, false, DefaultActionPhase::None);
 
 	document->UpdateDocument();
 
@@ -314,7 +314,7 @@ void Context::UnloadDocument(ElementDocument* _document)
 	if (document->GetParentNode() == root)
 	{
 		// Dispatch the unload notifications.
-		document->DispatchEvent(UNLOAD, Dictionary(), false);
+		document->DispatchEvent(UNLOAD, Dictionary(), false, false, DefaultActionPhase::None);
 		PluginRegistry::NotifyDocumentUnload(document);
 
 		// Remove the document from the context.
@@ -493,9 +493,9 @@ bool Context::ProcessKeyDown(Input::KeyIdentifier key_identifier, int key_modifi
 	GenerateKeyModifierEventParameters(parameters, key_modifier_state);
 
 	if (focus)
-		return focus->DispatchEvent(KEYDOWN, parameters, true);
+		return focus->DispatchEvent(KEYDOWN, parameters, true, true, DefaultActionPhase::Bubble);
 	else
-		return root->DispatchEvent(KEYDOWN, parameters, true);
+		return root->DispatchEvent(KEYDOWN, parameters, true, true, DefaultActionPhase::Bubble);
 }
 
 // Sends a key up event into Rocket.
@@ -507,9 +507,9 @@ bool Context::ProcessKeyUp(Input::KeyIdentifier key_identifier, int key_modifier
 	GenerateKeyModifierEventParameters(parameters, key_modifier_state);
 
 	if (focus)
-		return focus->DispatchEvent(KEYUP, parameters, true);
+		return focus->DispatchEvent(KEYUP, parameters, true, true, DefaultActionPhase::Bubble);
 	else
-		return root->DispatchEvent(KEYUP, parameters, true);
+		return root->DispatchEvent(KEYUP, parameters, true, true, DefaultActionPhase::Bubble);
 }
 
 // Sends a single character of text as text input into Rocket.
@@ -520,9 +520,9 @@ bool Context::ProcessTextInput(word character)
 	parameters["data"] = character;
 
 	if (focus)
-		return focus->DispatchEvent(TEXTINPUT, parameters, true);
+		return focus->DispatchEvent(TEXTINPUT, parameters, true, true, DefaultActionPhase::Bubble);
 	else
-		return root->DispatchEvent(TEXTINPUT, parameters, true);
+		return root->DispatchEvent(TEXTINPUT, parameters, true, true, DefaultActionPhase::Bubble);
 }
 
 // Sends a string of text as text input into Rocket.
@@ -537,9 +537,9 @@ bool Context::ProcessTextInput(const String& string)
 		parameters["data"] = string[i];
 
 		if (focus)
-			consumed = focus->DispatchEvent(TEXTINPUT, parameters, true) && consumed;
+			consumed = focus->DispatchEvent(TEXTINPUT, parameters, true, true, DefaultActionPhase::Bubble) && consumed;
 		else
-			consumed = root->DispatchEvent(TEXTINPUT, parameters, true) && consumed;
+			consumed = root->DispatchEvent(TEXTINPUT, parameters, true, true, DefaultActionPhase::Bubble) && consumed;
 	}
 
 	return consumed;
@@ -576,11 +576,11 @@ void Context::ProcessMouseMove(int x, int y, int key_modifier_state)
 	{
 		if (hover)
 		{
-			hover->DispatchEvent(MOUSEMOVE, parameters, true);
+			hover->DispatchEvent(MOUSEMOVE, parameters, true, true, DefaultActionPhase::None);
 
 			if (drag_hover &&
 				drag_verbose)
-				drag_hover->DispatchEvent(DRAGMOVE, drag_parameters, true);
+				drag_hover->DispatchEvent(DRAGMOVE, drag_parameters, true, true, DefaultActionPhase::None);
 		}
 	}
 }
@@ -628,7 +628,7 @@ void Context::ProcessMouseButtonDown(int button_index, int key_modifier_state)
 		
 		// Call 'onmousedown' on every item in the hover chain, and copy the hover chain to the active chain.
 		if (hover)
-			propogate = hover->DispatchEvent(MOUSEDOWN, parameters, true);
+			propogate = hover->DispatchEvent(MOUSEDOWN, parameters, true, true, DefaultActionPhase::TargetAndBubble);
 
 		if (propogate)
 		{
@@ -639,7 +639,7 @@ void Context::ProcessMouseButtonDown(int button_index, int key_modifier_state)
 				float(click_time - last_click_time) < DOUBLE_CLICK_TIME)
 			{
 				if (hover)
-					propogate = hover->DispatchEvent(DBLCLICK, parameters, true);
+					propogate = hover->DispatchEvent(DBLCLICK, parameters, true, true, DefaultActionPhase::None);
 
 				last_click_element = NULL;
 				last_click_time = 0;
@@ -678,7 +678,7 @@ void Context::ProcessMouseButtonDown(int button_index, int key_modifier_state)
 	{
 		// Not the primary mouse button, so we're not doing any special processing.
 		if (hover)
-			hover->DispatchEvent(MOUSEDOWN, parameters, true);
+			hover->DispatchEvent(MOUSEDOWN, parameters, true, true, DefaultActionPhase::None);
 	}
 }
 
@@ -694,13 +694,13 @@ void Context::ProcessMouseButtonUp(int button_index, int key_modifier_state)
 	{
 		// The elements in the new hover chain have the 'onmouseup' event called on them.
 		if (hover)
-			hover->DispatchEvent(MOUSEUP, parameters, true);
+			hover->DispatchEvent(MOUSEUP, parameters, true, true, DefaultActionPhase::None);
 
 		// If the active element (the one that was being hovered over when the mouse button was pressed) is still being
 		// hovered over, we click it.
 		if (hover && active && active == FindFocusElement(*hover))
 		{
-			active->DispatchEvent(CLICK, parameters, true);
+			active->DispatchEvent(CLICK, parameters, true, true, DefaultActionPhase::None);
 		}
 
 		// Unset the 'active' pseudo-class on all the elements in the active chain; because they may not necessarily
@@ -722,12 +722,12 @@ void Context::ProcessMouseButtonUp(int button_index, int key_modifier_state)
 				{
 					if (drag_verbose)
 					{
-						drag_hover->DispatchEvent(DRAGDROP, drag_parameters, true);
-						drag_hover->DispatchEvent(DRAGOUT, drag_parameters, true);
+						drag_hover->DispatchEvent(DRAGDROP, drag_parameters, true, true, DefaultActionPhase::None);
+						drag_hover->DispatchEvent(DRAGOUT, drag_parameters, true, true, DefaultActionPhase::None);
 					}
 				}
 
-				drag->DispatchEvent(DRAGEND, drag_parameters, true);
+				drag->DispatchEvent(DRAGEND, drag_parameters, true, true, DefaultActionPhase::None);
 
 				ReleaseDragClone();
 			}
@@ -741,7 +741,7 @@ void Context::ProcessMouseButtonUp(int button_index, int key_modifier_state)
 	{
 		// Not the left mouse button, so we're not doing any special processing.
 		if (hover)
-			hover->DispatchEvent(MOUSEUP, parameters, true);
+			hover->DispatchEvent(MOUSEUP, parameters, true, true, DefaultActionPhase::None);
 	}
 }
 
@@ -754,7 +754,7 @@ bool Context::ProcessMouseWheel(float wheel_delta, int key_modifier_state)
 		GenerateKeyModifierEventParameters(scroll_parameters, key_modifier_state);
 		scroll_parameters["wheel_delta"] = wheel_delta;
 
-		return hover->DispatchEvent(MOUSESCROLL, scroll_parameters, true);
+		return hover->DispatchEvent(MOUSESCROLL, scroll_parameters, true, true, DefaultActionPhase::TargetAndBubble);
 	}
 
 	return true;
@@ -840,7 +840,7 @@ void Context::OnElementRemove(Element* element)
 
 	Dictionary parameters;
 	GenerateMouseEventParameters(parameters, -1);
-	SendEvents(old_hover_chain, hover_chain, MOUSEOUT, parameters, true);
+	SendEvents(old_hover_chain, hover_chain, MOUSEOUT, parameters, true, true, DefaultActionPhase::Target);
 }
 
 // Internal callback for when a new element gains focus
@@ -876,8 +876,8 @@ bool Context::OnFocusChange(Element* new_focus)
 	Dictionary parameters;
 
 	// Send out blur/focus events.
-	SendEvents(old_chain, new_chain, BLUR, parameters, false);
-	SendEvents(new_chain, old_chain, FOCUS, parameters, false);
+	SendEvents(old_chain, new_chain, BLUR, parameters, false, false, DefaultActionPhase::Target);
+	SendEvents(new_chain, old_chain, FOCUS, parameters, false, false, DefaultActionPhase::Target);
 
 	focus = new_focus;
 
@@ -911,7 +911,7 @@ void Context::GenerateClickEvent(Element* element)
 	Dictionary parameters;
 	GenerateMouseEventParameters(parameters, 0);
 
-	element->DispatchEvent(CLICK, parameters, true);
+	element->DispatchEvent(CLICK, parameters, true, true, DefaultActionPhase::TargetAndBubble);
 }
 
 // Updates the current hover elements, sending required events.
@@ -929,7 +929,7 @@ void Context::UpdateHoverChain(const Dictionary& parameters, const Dictionary& d
 				Dictionary drag_start_parameters = drag_parameters;
 				drag_start_parameters["mouse_x"] = old_mouse_position.x;
 				drag_start_parameters["mouse_y"] = old_mouse_position.y;
-				drag->DispatchEvent(DRAGSTART, drag_start_parameters);
+				drag->DispatchEvent(DRAGSTART, drag_start_parameters, false, true, DefaultActionPhase::None);
 				drag_started = true;
 
 				if (drag->GetComputedValues().drag == Style::Drag::Clone)
@@ -939,7 +939,7 @@ void Context::UpdateHoverChain(const Dictionary& parameters, const Dictionary& d
 				}
 			}
 
-			drag->DispatchEvent(DRAG, drag_parameters);
+			drag->DispatchEvent(DRAG, drag_parameters, false, true, DefaultActionPhase::None);
 		}
 	}
 
@@ -969,8 +969,8 @@ void Context::UpdateHoverChain(const Dictionary& parameters, const Dictionary& d
 	}
 
 	// Send mouseout / mouseover events.
-	SendEvents(hover_chain, new_hover_chain, MOUSEOUT, parameters, true);
-	SendEvents(new_hover_chain, hover_chain, MOUSEOVER, parameters, true);
+	SendEvents(hover_chain, new_hover_chain, MOUSEOUT, parameters, true, true, DefaultActionPhase::Target);
+	SendEvents(new_hover_chain, hover_chain, MOUSEOVER, parameters, true, true, DefaultActionPhase::Target);
 
 	// Send out drag events.
 	if (drag)
@@ -1001,8 +1001,8 @@ void Context::UpdateHoverChain(const Dictionary& parameters, const Dictionary& d
 			drag_verbose)
 		{
 			// Send out ondragover and ondragout events as appropriate.
-			SendEvents(drag_hover_chain, new_drag_hover_chain, DRAGOUT, drag_parameters, true);
-			SendEvents(new_drag_hover_chain, drag_hover_chain, DRAGOVER, drag_parameters, true);
+			SendEvents(drag_hover_chain, new_drag_hover_chain, DRAGOUT, drag_parameters, true, false, DefaultActionPhase::None);
+			SendEvents(new_drag_hover_chain, drag_hover_chain, DRAGOVER, drag_parameters, true, false, DefaultActionPhase::None);
 		}
 
 		drag_hover_chain.swap(new_drag_hover_chain);
@@ -1192,11 +1192,11 @@ void Context::ReleaseUnloadedDocuments()
 }
 
 // Sends the specified event to all elements in new_items that don't appear in old_items.
-void Context::SendEvents(const ElementSet& old_items, const ElementSet& new_items, const String& event, const Dictionary& parameters, bool interruptible)
+void Context::SendEvents(const ElementSet& old_items, const ElementSet& new_items, const String& event, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase)
 {
 	ElementList elements;
 	std::set_difference(old_items.begin(), old_items.end(), new_items.begin(), new_items.end(), std::back_inserter(elements));
-	RKTEventFunctor func(event, parameters, interruptible);
+	RKTEventFunctor func(event, parameters, interruptible, bubbles, default_action_phase);
 	std::for_each(elements.begin(), elements.end(), func);
 }
 

+ 5 - 5
Source/Core/Element.cpp

@@ -1088,7 +1088,7 @@ void Element::SetScrollLeft(float scroll_left)
 	scroll->UpdateScrollbar(ElementScroll::HORIZONTAL);
 	DirtyOffset();
 
-	DispatchEvent("scroll", Dictionary());
+	DispatchEvent("scroll", Dictionary(), false, true, DefaultActionPhase::None);
 }
 
 // Gets the top scroll offset of the element.
@@ -1104,7 +1104,7 @@ void Element::SetScrollTop(float scroll_top)
 	scroll->UpdateScrollbar(ElementScroll::VERTICAL);
 	DirtyOffset();
 
-	DispatchEvent("scroll", Dictionary());
+	DispatchEvent("scroll", Dictionary(), false, true, DefaultActionPhase::None);
 }
 
 // Gets the width of the scrollable content of the element; it includes the element padding but not its margin.
@@ -1307,9 +1307,9 @@ void Element::RemoveEventListener(const String& event, EventListener* listener,
 }
 
 // Dispatches the specified event
-bool Element::DispatchEvent(const String& event, const Dictionary& parameters, bool interruptible)
+bool Element::DispatchEvent(const String& event, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase)
 {
-	return event_dispatcher->DispatchEvent(this, event, parameters, interruptible);
+	return event_dispatcher->DispatchEvent(this, event, parameters, interruptible, bubbles, default_action_phase);
 }
 
 // Scrolls the parent element's contents so that this element is visible.
@@ -2465,7 +2465,7 @@ void Element::AdvanceAnimations()
 		animations.erase(it_completed, animations.end());
 
 		for (size_t i = 0; i < dictionary_list.size(); i++)
-			DispatchEvent(is_transition[i] ? TRANSITIONEND : ANIMATIONEND, dictionary_list[i]);
+			DispatchEvent(is_transition[i] ? TRANSITIONEND : ANIMATIONEND, dictionary_list[i], true, true, DefaultActionPhase::None);
 	}
 }
 

+ 3 - 3
Source/Core/ElementDocument.cpp

@@ -235,7 +235,7 @@ void ElementDocument::Show(int focus_flags)
 		}
 	}
 
-	DispatchEvent("show", Dictionary(), false);
+	DispatchEvent("show", Dictionary(), false, false, DefaultActionPhase::None);
 }
 
 void ElementDocument::Hide()
@@ -245,7 +245,7 @@ void ElementDocument::Hide()
 	// We should update the document now, so that the focusing below will get the correct visibility
 	UpdateDocument();
 
-	DispatchEvent("hide", Dictionary(), false);
+	DispatchEvent("hide", Dictionary(), false, false, DefaultActionPhase::None);
 	
 	if (context)
 	{
@@ -409,7 +409,7 @@ void ElementDocument::ProcessEvent(Event& event)
 {
 	Element::ProcessEvent(event);
 
-	// Process generic keyboard events for this window in capture phase
+	// Process generic keyboard events for this window in bubble phase
 	if (event.GetPhase() == Event::PHASE_BUBBLE && event == KEYDOWN)
 	{
 		int key_identifier = event.GetParameter<int>("key_identifier", Input::KI_UNKNOWN);

+ 2 - 2
Source/Core/ElementHandle.cpp

@@ -49,7 +49,7 @@ ElementHandle::~ElementHandle()
 {
 }
 
-void ElementHandle::OnAttributeChange(const PropertyNameList& changed_attributes)
+void ElementHandle::OnAttributeChange(const AttributeNameList& changed_attributes)
 {
 	Element::OnAttributeChange(changed_attributes);
 
@@ -136,7 +136,7 @@ void ElementHandle::ProcessEvent(Event& event)
 			Dictionary parameters;
 			parameters["handle_x"] = x;
 			parameters["handle_y"] = y;
-			DispatchEvent("handledrag", parameters);
+			DispatchEvent("handledrag", parameters, false, true, DefaultActionPhase::None);
 		}
 	}
 }

+ 2 - 2
Source/Core/ElementHandle.h

@@ -49,8 +49,8 @@ public:
 	virtual ~ElementHandle();
 
 protected:
-	virtual void OnAttributeChange(const AttributeNameList& changed_attributes);
-	virtual void ProcessEvent(Event& event);
+	virtual void OnAttributeChange(const AttributeNameList& changed_attributes) override;
+	virtual void ProcessEvent(Event& event) override;
 
 	Vector2i drag_start;
 	Vector2f move_original_position;

+ 2 - 2
Source/Core/ElementImage.h

@@ -85,11 +85,11 @@ protected:
 
 	/// Checks for changes to the image's source or dimensions.
 	/// @param[in] changed_attributes A list of attributes changed on the element.
-	virtual void OnAttributeChange(const AttributeNameList& changed_attributes);
+	virtual void OnAttributeChange(const AttributeNameList& changed_attributes) override;
 
 	/// Called when properties on the element are changed.
 	/// @param[in] changed_properties The properties changed on the element.
-	virtual void OnPropertyChange(const PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const PropertyNameList& changed_properties) override;
 
 private:
 	// Generates the element's geometry.

+ 1 - 1
Source/Core/ElementUtilities.cpp

@@ -149,7 +149,7 @@ void ElementUtilities::BindEventAttributes(Element* element)
 	// Check for and instance the on* events
 	for (const auto& pair: element->GetAttributes())
 	{
-		if (pair.first.substr(0, 2) == "on")
+		if (pair.first.size() > 2 && pair.first[0] == 'o' && pair.first[1] == 'n')
 		{
 			EventListener* listener = Factory::InstanceEventListener(pair.second.Get<String>(), element);
 			if (listener)

+ 2 - 2
Source/Core/Event.cpp

@@ -34,7 +34,7 @@ namespace Core {
 
 Event::Event()
 {
-	phase = PHASE_UNKNOWN;
+	phase = PHASE_NONE;
 	interruped = false;
 	interruptible = false;
 	current_element = NULL;
@@ -43,7 +43,7 @@ Event::Event()
 
 Event::Event(Element* _target_element, const String& _type, const Dictionary& _parameters, bool _interruptible) : type(_type), parameters(_parameters), target_element(_target_element), parameters_backup(_parameters), interruptible(_interruptible)
 {
-	phase = PHASE_UNKNOWN;
+	phase = PHASE_NONE;
 	interruped = false;
 	current_element = NULL;
 }

+ 19 - 15
Source/Core/EventDispatcher.cpp

@@ -54,17 +54,19 @@ EventDispatcher::~EventDispatcher()
 
 void EventDispatcher::AttachEvent(const String& type, EventListener* listener, bool in_capture_phase)
 {
-	// Look up the event
+	// See if event type exists already
 	Events::iterator event_itr = events.find(type);
 
-	// Ensure the event is in the event list
 	if (event_itr == events.end())
 	{
-		event_itr = events.emplace(type, Listeners()).first;
+		// No, add listener to new event type entry
+		event_itr = events.emplace(type, Listeners{ Listener(listener, in_capture_phase) }).first;
+	}
+	else
+	{
+		// Yes, add listener to the existing list of events for the type
+		(*event_itr).second.emplace_back(listener, in_capture_phase);
 	}
-
-	// Add the action to the events
-	(*event_itr).second.push_back(Listener(listener, in_capture_phase));
 
 	listener->OnAttach(element);
 }
@@ -110,9 +112,8 @@ void EventDispatcher::DetachAllEvents()
 		element->GetChild(i)->GetEventDispatcher()->DetachAllEvents();
 }
 
-bool EventDispatcher::DispatchEvent(Element* target_element, const String& name, const Dictionary& parameters, bool interruptible)
+bool EventDispatcher::DispatchEvent(Element* target_element, const String& name, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase)
 {
-	//Event event(target_element, name, parameters, interruptible);
 	Event* event = Factory::InstanceEvent(target_element, name, parameters, interruptible);
 	if (event == NULL)
 		return false;
@@ -135,7 +136,7 @@ bool EventDispatcher::DispatchEvent(Element* target_element, const String& name,
 	{
 		EventDispatcher* dispatcher = elements[i]->GetEventDispatcher();
 		event->SetCurrentElement(elements[i]);
-		dispatcher->TriggerEvents(event);
+		dispatcher->TriggerEvents(event, default_action_phase);
 	}
 
 	// Target phase - direct at the target
@@ -143,10 +144,10 @@ bool EventDispatcher::DispatchEvent(Element* target_element, const String& name,
 	{
 		event->SetPhase(Event::PHASE_TARGET);
 		event->SetCurrentElement(target_element);
-		TriggerEvents(event);
+		TriggerEvents(event, default_action_phase);
 	}
 
-	if (event->IsPropagating()) 
+	if (bubbles && event->IsPropagating())
 	{
 		event->SetPhase(Event::PHASE_BUBBLE);
 		// Bubble phase - target to root (normal event bindings)
@@ -154,7 +155,7 @@ bool EventDispatcher::DispatchEvent(Element* target_element, const String& name,
 		{
 			EventDispatcher* dispatcher = elements[i]->GetEventDispatcher();
 			event->SetCurrentElement(elements[i]);
-			dispatcher->TriggerEvents(event);
+			dispatcher->TriggerEvents(event, default_action_phase);
 		}
 	}
 
@@ -177,8 +178,11 @@ String EventDispatcher::ToString() const
 	return result;
 }
 
-void EventDispatcher::TriggerEvents(Event* event)
+void EventDispatcher::TriggerEvents(Event* event, DefaultActionPhase default_action_phase)
 {
+	const Event::EventPhase phase = event->GetPhase();
+	const bool do_default_action = ((int)phase & (int)default_action_phase);
+
 	// Look up the event
 	Events::iterator itr = events.find(event->GetType());
 
@@ -198,7 +202,7 @@ void EventDispatcher::TriggerEvents(Event* event)
 			}
 
 			// Send the event to the target element itself.
-			if (event->IsPropagating())
+			if (do_default_action && event->IsPropagating())
 				element->ProcessEvent(*event);
 
 			// Fire all listeners waiting for capture events.
@@ -223,7 +227,7 @@ void EventDispatcher::TriggerEvents(Event* event)
 		}
 	}
 
-	if (event->GetPhase() != Event::PHASE_CAPTURE)
+	if (do_default_action)
 	{
 		// Send the event to the target element.
 		element->ProcessEvent(*event);

+ 3 - 3
Source/Core/EventDispatcher.h

@@ -30,7 +30,6 @@
 
 #include "../../Include/Rocket/Core/String.h"
 #include "../../Include/Rocket/Core/Event.h"
-#include <map>
 
 namespace Rocket {
 namespace Core {
@@ -38,6 +37,7 @@ namespace Core {
 class Element;
 class EventListener;
 
+
 /**
 	The Event Dispatcher manages a list of event listeners (based on URL) and triggers the events via EventHandlers
 	whenever requested.
@@ -76,7 +76,7 @@ public:
 	/// @param[in] parameters The event parameters
 	/// @param[in] interruptible Can the event propagation be stopped
 	/// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
-	bool DispatchEvent(Element* element, const String& name, const Dictionary& parameters, bool interruptible);
+	bool DispatchEvent(Element* element, const String& name, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase);
 
 	/// Returns event types with number of listeners for debugging.
 	/// @return Summary of attached listeners.
@@ -95,7 +95,7 @@ private:
 	typedef SmallUnorderedMap< String, Listeners > Events;
 	Events events;
 
-	void TriggerEvents(Event* event);
+	void TriggerEvents(Event* event, DefaultActionPhase default_action_phase);
 };
 
 }

+ 5 - 8
Source/Core/EventIterators.h

@@ -43,22 +43,19 @@ namespace Core {
 class RKTEventFunctor
 {
 public:
-	RKTEventFunctor(const String& event, const Dictionary& parameters, bool interruptible)
-	{
-		this->event = event;
-		this->parameters = &parameters;
-		this->interruptible = interruptible;
-	}
+	RKTEventFunctor(const String& event, const Dictionary& parameters, bool interruptible, bool bubbles, DefaultActionPhase default_action_phase)
+		: event(event), parameters(&parameters), interruptible(interruptible), bubbles(bubbles), default_action_phase(default_action_phase) {}
 
 	void operator()(ElementReference& element)
 	{
-		element->DispatchEvent(event, *parameters, interruptible);
+		element->DispatchEvent(event, *parameters, interruptible, bubbles, default_action_phase);
 	}
 
 private:
 	String event;
 	const Dictionary* parameters;
-	bool interruptible;
+	bool interruptible, bubbles;
+	DefaultActionPhase default_action_phase;
 };
 
 /**

+ 1 - 1
Source/Core/Lua/Element.cpp

@@ -146,7 +146,7 @@ int ElementDispatchEvent(lua_State* L, Element* obj)
             break;
         }
     }
-    obj->DispatchEvent(event,params,false);
+    obj->DispatchEvent(event,params, false, true, DefaultActionPhase::None);
     return 0;
 }
 

+ 1 - 1
Source/Core/Lua/LuaEventListener.h

@@ -52,7 +52,7 @@ public:
     virtual ~LuaEventListener();
 
     /// Process the incoming Event
-	virtual void ProcessEvent(Event& event);
+	virtual void ProcessEvent(Event& event) override;
 private:
     //the lua-side function to call when ProcessEvent is called
     int luaFuncRef;

+ 1 - 1
Source/Core/WidgetSlider.cpp

@@ -192,7 +192,7 @@ void WidgetSlider::SetBarPosition(float _bar_position)
 	PositionBar();
 
 	Dictionary parameters = { {"value", bar_position} };
-	parent->DispatchEvent("scrollchange", parameters);
+	parent->DispatchEvent("scrollchange", parameters, false, true, DefaultActionPhase::None);
 }
 
 // Returns the current position of the bar.

+ 1 - 1
Source/Core/WidgetSlider.h

@@ -90,7 +90,7 @@ protected:
 	Element* GetParent() const;
 
 	/// Handles events coming through from the slider's components.
-	virtual void ProcessEvent(Event& event);
+	virtual void ProcessEvent(Event& event) override;
 
 	/// Called when the slider's bar position is set or dragged.
 	/// @param[in] bar_position The new position of the bar (0 representing the start of the track, 1 representing the end).

+ 1 - 1
Source/Debugger/ElementInfo.h

@@ -61,7 +61,7 @@ public:
 	void RenderSourceElement();
 
 protected:
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 private:
 	void SetSourceElement(Core::Element* new_source_element);

+ 2 - 2
Source/Debugger/ElementLog.h

@@ -55,8 +55,8 @@ public:
 	void AddLogMessage(Core::Log::Type type, const Core::String& message);
 
 protected:
-	virtual void OnRender();
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void OnRender() override;
+	virtual void ProcessEvent(Core::Event& event) override;
 
 private:
 	struct LogMessage

+ 1 - 1
Source/Debugger/Plugin.h

@@ -94,7 +94,7 @@ public:
 
 	/// Event handler for events from the debugger elements.
 	/// @param[in] event The event to process.
-	virtual void ProcessEvent(Core::Event& event);
+	virtual void ProcessEvent(Core::Event& event) override;
 
 	/// Access the singleton instance of the debugger
 	/// @return NULL or an instance of the plugin