Browse Source

WIP: Replacing strings with IDs now compiling and running (puh). Producing... interesting results.

Michael Ragazzon 6 years ago
parent
commit
1ead58341e
70 changed files with 604 additions and 424 deletions
  1. 4 2
      Build/cmake/FileList.cmake
  2. 1 1
      Include/Rocket/Controls/ElementFormControlInput.h
  3. 1 1
      Include/Rocket/Controls/ElementFormControlTextArea.h
  4. 61 0
      Include/Rocket/Controls/ID.h
  5. 1 1
      Include/Rocket/Core/Animation.h
  6. 1 1
      Include/Rocket/Core/Core.h
  7. 2 0
      Include/Rocket/Core/Dictionary.h
  8. 2 2
      Include/Rocket/Core/FontEffectInstancer.h
  9. 4 5
      Include/Rocket/Core/ID.h
  10. 0 1
      Include/Rocket/Core/PropertyDictionary.h
  11. 1 0
      Include/Rocket/Core/StyleSheet.h
  12. 0 1
      Include/Rocket/Core/TypeConverter.h
  13. 4 0
      Include/Rocket/Core/Types.h
  14. 2 0
      Include/Rocket/Core/Variant.inl
  15. 34 33
      Samples/basic/animation/src/main.cpp
  16. 15 1
      Source/Controls/Controls.cpp
  17. 12 11
      Source/Controls/ElementDataGrid.cpp
  18. 5 5
      Source/Controls/ElementDataGridCell.cpp
  19. 10 9
      Source/Controls/ElementDataGridRow.cpp
  20. 2 1
      Source/Controls/ElementForm.cpp
  21. 2 1
      Source/Controls/ElementFormControl.cpp
  22. 1 1
      Source/Controls/ElementFormControlInput.cpp
  23. 7 7
      Source/Controls/ElementFormControlTextArea.cpp
  24. 9 8
      Source/Controls/ElementTabSet.cpp
  25. 3 3
      Source/Controls/ElementTextSelection.cpp
  26. 1 1
      Source/Controls/ElementTextSelection.h
  27. 83 0
      Source/Controls/ID.cpp
  28. 1 1
      Source/Controls/InputType.cpp
  29. 1 1
      Source/Controls/InputType.h
  30. 4 4
      Source/Controls/InputTypeButton.cpp
  31. 2 1
      Source/Controls/InputTypeCheckbox.cpp
  32. 2 1
      Source/Controls/InputTypeRadio.cpp
  33. 3 3
      Source/Controls/InputTypeText.cpp
  34. 1 1
      Source/Controls/InputTypeText.h
  35. 22 21
      Source/Controls/WidgetDropDown.cpp
  36. 30 29
      Source/Controls/WidgetSlider.cpp
  37. 26 25
      Source/Controls/WidgetTextInput.cpp
  38. 43 43
      Source/Core/Context.cpp
  39. 2 2
      Source/Core/DecoratorTiled.cpp
  40. 1 1
      Source/Core/Element.cpp
  41. 2 2
      Source/Core/ElementBackground.cpp
  42. 5 5
      Source/Core/ElementBorder.cpp
  43. 6 6
      Source/Core/ElementImage.cpp
  44. 1 1
      Source/Core/ElementImage.h
  45. 9 9
      Source/Core/ElementScroll.cpp
  46. 0 1
      Source/Core/ElementStyle.cpp
  47. 31 31
      Source/Core/ElementStyleCache.cpp
  48. 11 11
      Source/Core/ElementTextDefault.cpp
  49. 6 6
      Source/Core/ElementUtilities.cpp
  50. 1 1
      Source/Core/Event.cpp
  51. 3 3
      Source/Core/Factory.cpp
  52. 6 15
      Source/Core/FontDatabase.cpp
  53. 12 5
      Source/Core/FontEffectInstancer.cpp
  54. 2 2
      Source/Core/FontEffectOutlineInstancer.cpp
  55. 6 6
      Source/Core/FontEffectShadowInstancer.cpp
  56. 3 0
      Source/Core/FontEffectShadowInstancer.h
  57. 3 2
      Source/Core/ID.cpp
  58. 3 3
      Source/Core/LayoutBlockBox.cpp
  59. 1 1
      Source/Core/LayoutBlockBoxSpace.cpp
  60. 12 12
      Source/Core/LayoutEngine.cpp
  61. 2 2
      Source/Core/PropertyParserAnimation.cpp
  62. 1 1
      Source/Core/PropertyParserTransform.cpp
  63. 3 0
      Source/Core/PropertySpecification.cpp
  64. 12 14
      Source/Core/StyleSheetParser.cpp
  65. 1 1
      Source/Core/StyleSheetSpecification.cpp
  66. 1 1
      Source/Core/Transform.cpp
  67. 24 24
      Source/Core/WidgetSlider.cpp
  68. 8 7
      Source/Debugger/ElementInfo.cpp
  69. 7 7
      Source/Debugger/ElementLog.cpp
  70. 16 16
      Source/Debugger/Plugin.cpp

+ 4 - 2
Build/cmake/FileList.cmake

@@ -68,7 +68,6 @@ set(Core_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserTransform.h
     ${PROJECT_SOURCE_DIR}/Source/Core/PropertyShorthandDefinition.h
     ${PROJECT_SOURCE_DIR}/Source/Core/StreamFile.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StringCache.h
     ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetFactory.h
     ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetNode.h
     ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetNodeSelector.h
@@ -150,6 +149,7 @@ set(Core_PUB_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Geometry.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/GeometryUtilities.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Header.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/ID.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Input.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Log.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Math.h
@@ -274,6 +274,7 @@ set(Core_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/Geometry.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryDatabase.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryUtilities.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/ID.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBox.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBoxSpace.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutEngine.cpp
@@ -301,7 +302,6 @@ set(Core_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/StreamFile.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/StreamMemory.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/String.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StringCache.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/StringUtilities.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheet.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetFactory.cpp
@@ -395,6 +395,7 @@ set(Controls_PUB_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Controls/ElementFormControlTextArea.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Controls/ElementTabSet.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Controls/Header.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Controls/ID.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Controls/SelectOption.h
 )
 
@@ -417,6 +418,7 @@ set(Controls_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Controls/ElementFormControlTextArea.cpp
     ${PROJECT_SOURCE_DIR}/Source/Controls/ElementTabSet.cpp
     ${PROJECT_SOURCE_DIR}/Source/Controls/ElementTextSelection.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Controls/ID.cpp
     ${PROJECT_SOURCE_DIR}/Source/Controls/InputType.cpp
     ${PROJECT_SOURCE_DIR}/Source/Controls/InputTypeButton.cpp
     ${PROJECT_SOURCE_DIR}/Source/Controls/InputTypeCheckbox.cpp

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

@@ -72,7 +72,7 @@ protected:
 	virtual void OnAttributeChange(const Core::AttributeNameList& changed_attributes);
 	/// Called when properties on the control are changed.
 	/// @param[in] changed_properties The properties changed on the element.
-	virtual void OnPropertyChange(const Core::PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const Core::PropertyIdList& changed_properties);
 
 	/// If we are the added element, this will pass the call onto our type handler.
 	/// @param[in] child The new member of the hierarchy.

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

@@ -105,7 +105,7 @@ protected:
 	virtual void OnAttributeChange(const Core::AttributeNameList& changed_attributes);
 	/// Called when properties on the control are changed.
 	/// @param[in] changed_properties The properties changed on the element.
-	virtual void OnPropertyChange(const Core::PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const Core::PropertyIdList& changed_properties);
 
 	/// Returns the text content of the element.
 	/// @param[out] content The content of the element.

+ 61 - 0
Include/Rocket/Controls/ID.h

@@ -0,0 +1,61 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETCONTROLSID_H
+#define ROCKETCONTROLSID_H
+
+#include "../Core/ID.h"
+
+namespace Rocket {
+namespace Controls {
+
+namespace PropertyId {
+
+	extern Core::PropertyId MinRows;
+	extern Core::PropertyId TabIndex;
+
+}
+
+namespace EventId {
+
+	extern Core::EventId Columnadd;
+	extern Core::EventId Rowadd;
+	extern Core::EventId Rowchange;
+	extern Core::EventId Rowremove;
+	extern Core::EventId Rowupdate;
+
+	extern Core::EventId Submit;
+	extern Core::EventId Change;
+
+	extern Core::EventId Tabchange;
+
+}
+
+}
+}
+
+#endif

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

@@ -33,7 +33,7 @@
 
 #include "String.h"
 #include "Tween.h"
-#include "../Source/Core/StringCache.h"
+#include "ID.h"
 
 namespace Rocket {
 namespace Core {

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

@@ -58,6 +58,7 @@
 #include "Geometry.h"
 #include "GeometryUtilities.h"
 #include "Input.h"
+#include "ID.h"
 #include "Log.h"
 #include "Plugin.h"
 #include "Property.h"
@@ -67,7 +68,6 @@
 #include "PropertySpecification.h"
 #include "RenderInterface.h"
 #include "String.h"
-#include "StringCache.h"
 #include "StyleSheet.h"
 #include "StyleSheetKeywords.h"
 #include "StyleSheetSpecification.h"

+ 2 - 0
Include/Rocket/Core/Dictionary.h

@@ -30,6 +30,8 @@
 
 #include "Header.h"
 #include "Variant.h"
+#include "ID.h"
+#include "Property.h"
 
 namespace Rocket {
 namespace Core {

+ 2 - 2
Include/Rocket/Core/FontEffectInstancer.h

@@ -74,13 +74,13 @@ protected:
 	/// @param[in] default_value The default value to be used.
 	/// @param[in] affects_generation True if this property affects the effect's texture data or glyph size, false if not.
 	/// @return The new property definition, ready to have parsers attached.
-	PropertyDefinition& RegisterProperty(const String& property_name, const String& default_value, bool affects_generation = true);
+	PropertyDefinition& RegisterProperty(const String& property_name, const String& default_value, bool affects_generation = true, PropertyId* out_property_id = nullptr);
 	/// Registers a shorthand property definition.
 	/// @param[in] shorthand_name The name to register the new shorthand property under.
 	/// @param[in] properties A comma-separated list of the properties this definition is shorthand for. The order in which they are specified here is the order in which the values will be processed.
 	/// @param[in] type The type of shorthand to declare.
 	/// @param True if all the property names exist, false otherwise.
-	bool RegisterShorthand(const String& shorthand_name, const String& property_names, PropertySpecification::ShorthandType type = PropertySpecification::AUTO);
+	bool RegisterShorthand(const String& shorthand_name, const PropertyIdList& property_ids, PropertySpecification::ShorthandType type = PropertySpecification::AUTO, PropertyId* out_property_id = nullptr);
 
 	// Releases the instancer.
 	virtual void OnReferenceDeactivate();

+ 4 - 5
Source/Core/StringCache.h → Include/Rocket/Core/ID.h

@@ -26,12 +26,10 @@
  */
 
  
-#ifndef ROCKETCORESTRINGCACHE_H
-#define ROCKETCORESTRINGCACHE_H
-
-#include "../../Include/Rocket/Core/String.h"
-#include "../../Include/Rocket/Core/Types.h"
+#ifndef ROCKETCOREID_H
+#define ROCKETCOREID_H
 
+#include "Types.h"
 
 namespace Rocket {
 namespace Core {
@@ -173,6 +171,7 @@ enum class EventId : uint16_t
 	Handledrag,
 	Resize,
 	Scroll,
+	Scrollchange,
 	Animationend,
 	Transitionend,
 

+ 0 - 1
Include/Rocket/Core/PropertyDictionary.h

@@ -42,7 +42,6 @@ namespace Core {
 	@author Peter Curry
  */
 
-using PropertyDictionary = PropertyMap;
 
 /// Merges the contents of another fully-specified property dictionary with this one.
 /// Properties defined in the new dictionary will overwrite those with the same name as

+ 1 - 0
Include/Rocket/Core/StyleSheet.h

@@ -41,6 +41,7 @@ class ElementDefinition;
 class StyleSheetNode;
 
 struct KeyframeBlock {
+	KeyframeBlock(float normalized_time) : normalized_time(normalized_time) {}
 	float normalized_time;  // [0, 1]
 	PropertyDictionary properties;
 };

+ 0 - 1
Include/Rocket/Core/TypeConverter.h

@@ -33,7 +33,6 @@
 #include "Log.h"
 #include "Stream.h"
 #include "StringUtilities.h"
-#include "StringCache.h"
 #include <typeinfo>
 #include <stdlib.h>
 #include <stdio.h>

+ 4 - 0
Include/Rocket/Core/Types.h

@@ -118,10 +118,14 @@ typedef std::vector< ElementAnimation > ElementAnimationList;
 // Unordered map
 template < typename Key, typename Value>
 using UnorderedMap = robin_hood::unordered_flat_map< Key, Value >;
+
 typedef UnorderedMap< PropertyId, Property > PropertyMap;
+using PropertyDictionary = PropertyMap;
+
 using Dictionary = UnorderedMap< String, Variant >;
 typedef Dictionary ElementAttributes;
 
+
 // Reference types
 typedef std::shared_ptr< Transform > TransformRef;
 

+ 2 - 0
Include/Rocket/Core/Variant.inl

@@ -35,6 +35,8 @@ inline Variant::Type Variant::GetType() const
 template< typename T >
 Variant::Variant(const T& t) : type(NONE)
 {
+	static_assert(!std::is_same<PropertyId, T>(), "type can't be PropertyId");
+	static_assert(!std::is_same<EventId, T>(), "type can't be EventId");
 	Set( t );
 }
 

+ 34 - 33
Samples/basic/animation/src/main.cpp

@@ -55,8 +55,8 @@ public:
 		{
 			{
 				//document->GetElementById("title")->SetInnerRML(title);
-				document->SetProperty("left", Property(position.x, Property::PX));
-				document->SetProperty("top", Property(position.y, Property::PX));
+				document->SetProperty(PropertyId::Left, Property(position.x, Property::PX));
+				document->SetProperty(PropertyId::Top, Property(position.y, Property::PX));
 				//document->Animate("opacity", Property(1.0f, Property::NUMBER), 1.5f, Tween{Tween::Quadratic, Tween::Out}, 1, true, 0.0f);
 			}
 
@@ -65,64 +65,64 @@ public:
 				auto el = document->GetElementById("start_game");
 				auto p1 = Transform::MakeProperty({ Transforms::Rotate2D{10.f}, Transforms::TranslateX{100.f} });
 				auto p2 = Transform::MakeProperty({ Transforms::Scale2D{3.f} });
-				el->Animate("transform", p1, 1.8f, Tween{ Tween::Elastic, Tween::InOut }, -1, true);
-				el->AddAnimationKey("transform", p2, 1.3f, Tween{ Tween::Elastic, Tween::InOut });
+				el->Animate(PropertyId::Transform, p1, 1.8f, Tween{ Tween::Elastic, Tween::InOut }, -1, true);
+				el->AddAnimationKey(PropertyId::Transform, p2, 1.3f, Tween{ Tween::Elastic, Tween::InOut });
 			}
 			{
 				auto el = document->GetElementById("high_scores");
-				el->Animate("margin-left", Property(0.f, Property::PX), 0.3f, Tween{ Tween::Sine, Tween::In }, 10, true, 1.f);
-				el->AddAnimationKey("margin-left", Property(100.f, Property::PX), 3.0f, Tween{ Tween::Circular, Tween::Out });
+				el->Animate(PropertyId::MarginLeft, Property(0.f, Property::PX), 0.3f, Tween{ Tween::Sine, Tween::In }, 10, true, 1.f);
+				el->AddAnimationKey(PropertyId::MarginLeft, Property(100.f, Property::PX), 3.0f, Tween{ Tween::Circular, Tween::Out });
 			}
 			{
 				auto el = document->GetElementById("options");
-				el->Animate("image-color", Property(Colourb(128, 255, 255, 255), Property::COLOUR), 0.3f, Tween{}, -1, false);
-				el->AddAnimationKey("image-color", Property(Colourb(128, 128, 255, 255), Property::COLOUR), 0.3f);
-				el->AddAnimationKey("image-color", Property(Colourb(0, 128, 128, 255), Property::COLOUR), 0.3f);
-				el->AddAnimationKey("image-color", Property(Colourb(64, 128, 255, 0), Property::COLOUR), 0.9f);
-				el->AddAnimationKey("image-color", Property(Colourb(255, 255, 255, 255), Property::COLOUR), 0.3f);
+				el->Animate(PropertyId::ImageColor, Property(Colourb(128, 255, 255, 255), Property::COLOUR), 0.3f, Tween{}, -1, false);
+				el->AddAnimationKey(PropertyId::ImageColor, Property(Colourb(128, 128, 255, 255), Property::COLOUR), 0.3f);
+				el->AddAnimationKey(PropertyId::ImageColor, Property(Colourb(0, 128, 128, 255), Property::COLOUR), 0.3f);
+				el->AddAnimationKey(PropertyId::ImageColor, Property(Colourb(64, 128, 255, 0), Property::COLOUR), 0.9f);
+				el->AddAnimationKey(PropertyId::ImageColor, Property(Colourb(255, 255, 255, 255), Property::COLOUR), 0.3f);
 			}
 			{
 				auto el = document->GetElementById("help");
-				el->Animate("margin-left", Property(100.f, Property::PX), 1.0f, Tween{ Tween::Quadratic, Tween::InOut }, -1, true);
+				el->Animate(PropertyId::MarginLeft, Property(100.f, Property::PX), 1.0f, Tween{ Tween::Quadratic, Tween::InOut }, -1, true);
 			}
 			{
 				auto el = document->GetElementById("exit");
 				PropertyDictionary pd;
-				StyleSheetSpecification::ParsePropertyDeclaration(pd, "transform", "translate(200px, 200px) rotate(1215deg)");
-				el->Animate("transform", *pd.GetProperty("transform"), 3.f, Tween{ Tween::Bounce, Tween::Out }, -1);
+				StyleSheetSpecification::ParsePropertyDeclaration(pd, PropertyId::Transform, "translate(200px, 200px) rotate(1215deg)");
+				el->Animate(PropertyId::Transform, pd[PropertyId::Transform], 3.f, Tween{ Tween::Bounce, Tween::Out }, -1);
 			}
 
 			// Transform tests
 			{
 				auto el = document->GetElementById("generic");
-				auto p = Transform::MakeProperty({ Transforms::TranslateY{50, Property::PX}, Transforms::Rotate3D{0.8f, 0, 1, 110, Property::DEG}});
-				el->Animate("transform", p, 1.3f, Tween{Tween::Quadratic, Tween::InOut}, -1, true);
+				auto p = Transform::MakeProperty({ Transforms::TranslateY{50, Property::PX}, Transforms::Rotate3D{0.8f, 0, 1, 110, Property::DEG} });
+				el->Animate(PropertyId::Transform, p, 1.3f, Tween{ Tween::Quadratic, Tween::InOut }, -1, true);
 			}
 			{
 				auto el = document->GetElementById("combine");
 				auto p = Transform::MakeProperty({ Transforms::Translate2D{50, 50, Property::PX}, Transforms::Rotate2D(1215) });
-				el->Animate("transform", p, 8.0f, Tween{}, -1, true);
+				el->Animate(PropertyId::Transform, p, 8.0f, Tween{}, -1, true);
 			}
 			{
 				auto el = document->GetElementById("decomposition");
 				auto p = Transform::MakeProperty({ Transforms::Translate2D{50, 50, Property::PX}, Transforms::Rotate2D(1215) });
-				el->Animate("transform", p, 8.0f, Tween{}, -1, true);
+				el->Animate(PropertyId::Transform, p, 8.0f, Tween{}, -1, true);
 			}
 
 			// Mixed units tests
 			{
 				auto el = document->GetElementById("abs_rel");
-				el->Animate("margin-left", Property(50.f, Property::PERCENT), 1.5f, Tween{}, -1, true);
+				el->Animate(PropertyId::MarginLeft, Property(50.f, Property::PERCENT), 1.5f, Tween{}, -1, true);
 			}
 			{
 				auto el = document->GetElementById("abs_rel_transform");
 				auto p = Transform::MakeProperty({ Transforms::TranslateX{0, Property::PX} });
-				el->Animate("transform", p, 1.5f, Tween{}, -1, true);
+				el->Animate(PropertyId::Transform, p, 1.5f, Tween{}, -1, true);
 			}
 			{
 				auto el = document->GetElementById("animation_event");
-				el->Animate("top", Property(Math::RandomReal(250.f), Property::PX), 1.5f, Tween{ Tween::Cubic, Tween::InOut });
-				el->Animate("left", Property(Math::RandomReal(250.f), Property::PX), 1.5f, Tween{ Tween::Cubic, Tween::InOut });
+				el->Animate(PropertyId::Top, Property(Math::RandomReal(250.f), Property::PX), 1.5f, Tween{ Tween::Cubic, Tween::InOut });
+				el->Animate(PropertyId::Left, Property(Math::RandomReal(250.f), Property::PX), 1.5f, Tween{ Tween::Cubic, Tween::InOut });
 			}
 
 			document->Show();
@@ -143,6 +143,7 @@ public:
 		  Replace Dictionary with unordered_flat_map: 40.0  [b04b4e5]
 		  Dirty flag for structure changes: 43.0  [fdf6f53]
 		  Replacing containers: 46.0  [c307140]
+		  Replacing lots of strings with IDs: 55.0
 		
 		*/
 		
@@ -233,8 +234,8 @@ void GameLoop()
 		static float ff = 0.0f;
 		ff += float(nudge)*0.3f;
 		auto el = window->GetDocument()->GetElementById("exit");
-		auto f = el->GetProperty<float>("margin-left");
-		el->SetProperty("margin-left", Rocket::Core::Property(ff, Rocket::Core::Property::PX));
+		auto f = el->GetProperty<float>(Rocket::Core::PropertyId::MarginLeft);
+		el->SetProperty(Rocket::Core::PropertyId::MarginLeft, Rocket::Core::Property(ff, Rocket::Core::Property::PX));
 		float f_left = el->GetAbsoluteLeft();
 		Rocket::Core::Log::Message(Rocket::Core::Log::LT_INFO, "margin-left: '%f'   abs: %f.", ff, f_left);
 		nudge = 0;
@@ -304,23 +305,23 @@ public:
 			else if (key_identifier == Rocket::Core::Input::KI_LEFT)
 			{
 				auto el = context->GetRootElement()->GetElementById("keyevent_response");
-				if (el) el->Animate("left", Property{ -200.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
+				if (el) el->Animate(PropertyId::Left, Property{ -200.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
 			}
 			else if (key_identifier == Rocket::Core::Input::KI_RIGHT)
 			{
 				auto el = context->GetRootElement()->GetElementById("keyevent_response");
-				if (el) el->Animate("left", Property{ 200.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
+				if (el) el->Animate(PropertyId::Left, Property{ 200.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
 			}
 			else if (key_identifier == Rocket::Core::Input::KI_UP)
 			{
 				auto el = context->GetRootElement()->GetElementById("keyevent_response");
 				auto offset_right = Property{ 200.f, Property::PX };
-				if (el) el->Animate("left", Property{ 0.f, Property::PX }, 0.5, Tween{ Tween::Cubic }, 1, true, 0, &offset_right);
+				if (el) el->Animate(PropertyId::Left, Property{ 0.f, Property::PX }, 0.5, Tween{ Tween::Cubic }, 1, true, 0, &offset_right);
 			}
 			else if (key_identifier == Rocket::Core::Input::KI_DOWN)
 			{
 				auto el = context->GetRootElement()->GetElementById("keyevent_response");
-				if (el) el->Animate("left", Property{ 0.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
+				if (el) el->Animate(PropertyId::Left, Property{ 0.f, Property::PX }, 0.5, Tween{ Tween::Cubic });
 			}
 		}
 		if (event == "click")
@@ -336,8 +337,8 @@ public:
 			auto el = event.GetTargetElement();
 			if (el->GetId() == "animation_event")
 			{
-				el->Animate("top", Property(Math::RandomReal(200.f), Property::PX), 1.2f, Tween{ Tween::Cubic, Tween::InOut });
-				el->Animate("left", Property(Math::RandomReal(100.f), Property::PERCENT), 0.8f, Tween{ Tween::Cubic, Tween::InOut });
+				el->Animate(Rocket::Core::PropertyId::Top, Property(Math::RandomReal(200.f), Property::PX), 1.2f, Tween{ Tween::Cubic, Tween::InOut });
+				el->Animate(Rocket::Core::PropertyId::Left, Property(Math::RandomReal(100.f), Property::PERCENT), 0.8f, Tween{ Tween::Cubic, Tween::InOut });
 			}
 		}
 	}
@@ -425,9 +426,9 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 	Shell::LoadFonts("assets/");
 
 	window = new DemoWindow("Animation sample", Rocket::Core::Vector2f(81, 100), context);
-	window->GetDocument()->AddEventListener("keydown", new Event("hello"));
-	window->GetDocument()->AddEventListener("keyup", new Event("hello"));
-	window->GetDocument()->AddEventListener("animationend", new Event("hello"));
+	window->GetDocument()->AddEventListener(Rocket::Core::EventId::Keydown, new Event("hello"));
+	window->GetDocument()->AddEventListener(Rocket::Core::EventId::Keyup, new Event("hello"));
+	window->GetDocument()->AddEventListener(Rocket::Core::EventId::Animationend, new Event("hello"));
 
 
 	Shell::EventLoop(GameLoop);

+ 15 - 1
Source/Controls/Controls.cpp

@@ -26,6 +26,7 @@
  */
 
 #include "../../Include/Rocket/Controls/Controls.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../../Include/Rocket/Core/ElementInstancerGeneric.h"
 #include "../../Include/Rocket/Core/Factory.h"
 #include "../../Include/Rocket/Core/StyleSheetSpecification.h"
@@ -41,6 +42,9 @@
 namespace Rocket {
 namespace Controls {
 
+// See ID.cpp (not exposed to header file)
+void InitialiseIDs();
+
 // Registers the custom element instancers.
 void RegisterElementInstancers()
 {
@@ -126,7 +130,9 @@ void Initialise()
 	// Prevent double initialisation
 	if (!initialised)
 	{
-		Core::StyleSheetSpecification::RegisterProperty("min-rows", "0", false, false).AddParser("number");
+		InitialiseIDs();
+
+		Core::StyleSheetSpecification::RegisterProperty(PropertyId::MinRows, "0", false, false).AddParser("number");
 
 		// Register the element instancers for our custom elements.
 		RegisterElementInstancers();
@@ -141,5 +147,13 @@ void Initialise()
 	}
 }
 
+
+
+namespace ControlsPropertyId {
+
+	Core::PropertyId ColumnAdd;
+
+}
+
 }
 }

+ 12 - 11
Source/Controls/ElementDataGrid.cpp

@@ -27,6 +27,7 @@
 
 #include "../../Include/Rocket/Controls/ElementDataGrid.h"
 #include "../../Include/Rocket/Controls/DataSource.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../../Include/Rocket/Core/Math.h"
 #include "../../Include/Rocket/Core/XMLParser.h"
 #include "../../Include/Rocket/Core/Event.h"
@@ -45,24 +46,24 @@ ElementDataGrid::ElementDataGrid(const Rocket::Core::String& tag) : Core::Elemen
 
 	// Create the row for the column headers:
 	header = dynamic_cast< ElementDataGridRow* >(Core::Factory::InstanceElement(this, "#rktctl_datagridrow", "datagridheader", attributes));
-	header->SetProperty("display", "block");
+	header->SetProperty(Core::PropertyId::Display, "block");
 	header->Initialise(this);
 	AppendChild(header);
 	header->RemoveReference();
 
 	body = Core::Factory::InstanceElement(this, "*", "datagridbody", attributes);
-	body->SetProperty("display", "none");
-	body->SetProperty("width", "auto");
+	body->SetProperty(Core::PropertyId::Display, "none");
+	body->SetProperty(Core::PropertyId::Width, "auto");
 	AppendChild(body);
 	body->RemoveReference();
 
 	body_visible = false;
 
 	root = dynamic_cast< ElementDataGridRow* >(Core::Factory::InstanceElement(this, "#rktctl_datagridrow", "datagridroot", attributes));
-	root->SetProperty("display", "none");
+	root->SetProperty(Core::PropertyId::Display, "none");
 	root->Initialise(this);
 
-	SetProperty("overflow", "auto");
+	SetProperty(Core::PropertyId::Overflow, "auto");
 
 	new_data_source = "";
 }
@@ -108,11 +109,11 @@ void ElementDataGrid::AddColumn(const Rocket::Core::String& fields, const Rocket
 	// The header elements are added to the header row at the top of the table.
 	if (header_element)
 	{
-		header_element->SetProperty("display", "inline-block");
+		header_element->SetProperty(Core::PropertyId::Display, "inline-block");
 
 		// Push all the width properties from the column onto the header element.
 		Rocket::Core::String width = header_element->GetAttribute<Rocket::Core::String>("width", "100%");
-		header_element->SetProperty("width", width);
+		header_element->SetProperty(Core::PropertyId::Width, width);
 
 		header->AppendChild(header_element);
 	}
@@ -139,7 +140,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(EventId::Columnadd, parameters);
 }
 
 // Returns the number of columns in this table
@@ -234,12 +235,12 @@ void ElementDataGrid::OnUpdate()
 	bool any_new_children = root->UpdateChildren();
 	if (any_new_children)
 	{
-		DispatchEvent("rowupdate", Rocket::Core::Dictionary());
+		DispatchEvent(EventId::Rowupdate, Rocket::Core::Dictionary());
 	}
 	
-	if (!body_visible && (!any_new_children || root->GetNumLoadedChildren() >= Rocket::Core::Math::RealToInteger(ResolveProperty("min-rows", 0))))
+	if (!body_visible && (!any_new_children || root->GetNumLoadedChildren() >= Rocket::Core::Math::RealToInteger(ResolveProperty(PropertyId::MinRows, 0))))
 	{
-		body->SetProperty("display", "block");
+		body->SetProperty(Core::PropertyId::Display, "block");
 		body_visible = true;
 	}
 	

+ 5 - 5
Source/Controls/ElementDataGridCell.cpp

@@ -40,7 +40,7 @@ ElementDataGridCell::ElementDataGridCell(const Rocket::Core::String& tag) : Core
 ElementDataGridCell::~ElementDataGridCell()
 {
 	if (header) {
-		header->RemoveEventListener("resize", this);
+		header->RemoveEventListener(Core::EventId::Resize, this);
 		header->RemoveReference();
 	}
 }
@@ -52,8 +52,8 @@ void ElementDataGridCell::Initialise(int _column, Core::Element* _header)
 	if (header)
 	{
 		header->AddReference();
-		header->AddEventListener("resize", this);
-		SetProperty("width", Core::Property(header->GetBox().GetSize(Core::Box::MARGIN).x, Core::Property::PX));
+		header->AddEventListener(Core::EventId::Resize, this);
+		SetProperty(Core::PropertyId::Width, Core::Property(header->GetBox().GetSize(Core::Box::MARGIN).x, Core::Property::PX));
 	}
 }
 
@@ -66,11 +66,11 @@ void ElementDataGridCell::ProcessEvent(Core::Event& event)
 {
 	Core::Element::ProcessEvent(event);
 
-	if (event == "resize")
+	if (event == Core::EventId::Resize)
 	{
 		if (event.GetTargetElement() == header)
 		{
-			SetProperty("width", Core::Property(header->GetBox().GetSize(Core::Box::MARGIN).x, Core::Property::PX));
+			SetProperty(Core::PropertyId::Width, Core::Property(header->GetBox().GetSize(Core::Box::MARGIN).x, Core::Property::PX));
 		}
 	}
 }

+ 10 - 9
Source/Controls/ElementDataGridRow.cpp

@@ -31,6 +31,7 @@
 #include "../../Include/Rocket/Controls/DataFormatter.h"
 #include "../../Include/Rocket/Controls/ElementDataGrid.h"
 #include "../../Include/Rocket/Controls/ElementDataGridCell.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../Core/Clock.h"
 
 namespace Rocket {
@@ -53,8 +54,8 @@ ElementDataGridRow::ElementDataGridRow(const Rocket::Core::String& tag) : Core::
 	dirty_children = false;
 	row_expanded = true;
 
-	SetProperty("white-space", "nowrap");
-	SetProperty("display", Rocket::Core::Property(Rocket::Core::DISPLAY_INLINE_BLOCK, Rocket::Core::Property::KEYWORD));
+	SetProperty(Core::PropertyId::WhiteSpace, "nowrap");
+	SetProperty(Core::PropertyId::Display, Rocket::Core::Property(Rocket::Core::DISPLAY_INLINE_BLOCK, Rocket::Core::Property::KEYWORD));
 }
 
 ElementDataGridRow::~ElementDataGridRow()
@@ -85,7 +86,7 @@ void ElementDataGridRow::Initialise(ElementDataGrid* _parent_grid, ElementDataGr
 	{
 		ElementDataGridCell* cell = dynamic_cast< ElementDataGridCell* >(Core::Factory::InstanceElement(this, "#rktctl_datagridcell", "datagridcell", cell_attributes));
 		cell->Initialise(i, header_row->GetChild(i));
-		cell->SetProperty("display", Rocket::Core::Property(Rocket::Core::DISPLAY_INLINE_BLOCK, Rocket::Core::Property::KEYWORD));
+		cell->SetProperty(Core::PropertyId::Display, Rocket::Core::Property(Rocket::Core::DISPLAY_INLINE_BLOCK, Rocket::Core::Property::KEYWORD));
 		AppendChild(cell);
 		cell->RemoveReference();
 	}
@@ -387,7 +388,7 @@ void ElementDataGridRow::AddChildren(int first_row_added, int num_rows_added)
 
 			if (!row_expanded)
 			{
-				new_row->SetProperty("display", "none");
+				new_row->SetProperty(Core::PropertyId::Display, "none");
 			}
 		}
 
@@ -411,7 +412,7 @@ 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);
+	parent_grid->DispatchEvent(EventId::Rowadd, parameters);
 }
 
 void ElementDataGridRow::RemoveChildren(int first_row_removed, int num_rows_removed)
@@ -443,7 +444,7 @@ 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);
+	parent_grid->DispatchEvent(EventId::Rowremove, parameters);
 }
 
 void ElementDataGridRow::ChangeChildren(int first_row_changed, int num_rows_changed)
@@ -454,7 +455,7 @@ 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);
+	parent_grid->DispatchEvent(EventId::Rowchange, parameters);
 }
 
 // Returns the number of rows under this row (children, grandchildren, etc)
@@ -671,7 +672,7 @@ void ElementDataGridRow::DirtyRow()
 // Sets this row's child rows to be visible.
 void ElementDataGridRow::Show()
 {
-	SetProperty("display", "inline-block");
+	SetProperty(Core::PropertyId::Display, "inline-block");
 
 	if (row_expanded)
 	{
@@ -685,7 +686,7 @@ void ElementDataGridRow::Show()
 // Sets this row's children to be invisible.
 void ElementDataGridRow::Hide()
 {
-	SetProperty("display", "none");
+	SetProperty(Core::PropertyId::Display, "none");
 
 	for (size_t i = 0; i < children.size(); i++)
 	{

+ 2 - 1
Source/Controls/ElementForm.cpp

@@ -29,6 +29,7 @@
 #include "../../Include/Rocket/Core/Dictionary.h"
 #include "../../Include/Rocket/Core/ElementUtilities.h"
 #include "../../Include/Rocket/Controls/ElementFormControl.h"
+#include "../../Include/Rocket/Controls/ID.h"
 
 namespace Rocket {
 namespace Controls {
@@ -86,7 +87,7 @@ void ElementForm::Submit(const Rocket::Core::String& name, const Rocket::Core::S
 			values[control_name] = control_value;
 	}
 
-	DispatchEvent("submit", values);
+	DispatchEvent(EventId::Submit, values);
 }
 
 }

+ 2 - 1
Source/Controls/ElementFormControl.cpp

@@ -26,13 +26,14 @@
  */
 
 #include "../../Include/Rocket/Controls/ElementFormControl.h"
+#include "../../Include/Rocket/Controls/ID.h"
 
 namespace Rocket {
 namespace Controls {
 
 ElementFormControl::ElementFormControl(const Rocket::Core::String& tag) : Core::Element(tag)
 {
-	SetProperty("tab-index", "auto");
+	SetProperty(PropertyId::TabIndex, "auto");
 }
 
 ElementFormControl::~ElementFormControl()

+ 1 - 1
Source/Controls/ElementFormControlInput.cpp

@@ -127,7 +127,7 @@ void ElementFormControlInput::OnAttributeChange(const Core::AttributeNameList& c
 }
 
 // Called when properties on the element are changed.
-void ElementFormControlInput::OnPropertyChange(const Core::PropertyNameList& changed_properties)
+void ElementFormControlInput::OnPropertyChange(const Core::PropertyIdList& changed_properties)
 {
 	ElementFormControl::OnPropertyChange(changed_properties);
 

+ 7 - 7
Source/Controls/ElementFormControlTextArea.cpp

@@ -39,8 +39,8 @@ ElementFormControlTextArea::ElementFormControlTextArea(const Rocket::Core::Strin
 {
 	widget = new WidgetTextInputMultiLine(this);
 
-	SetProperty("overflow", "auto");
-	SetProperty("white-space", "pre-wrap");
+	SetProperty(Core::PropertyId::Overflow, "auto");
+	SetProperty(Core::PropertyId::WhiteSpace, "pre-wrap");
 }
 
 ElementFormControlTextArea::~ElementFormControlTextArea()
@@ -151,9 +151,9 @@ void ElementFormControlTextArea::OnAttributeChange(const Core::AttributeNameList
 	if (changed_attributes.find("wrap") != changed_attributes.end())
 	{
 		if (GetWordWrap())
-			SetProperty("white-space", "pre-wrap");
+			SetProperty(Core::PropertyId::WhiteSpace, "pre-wrap");
 		else
-			SetProperty("white-space", "pre");
+			SetProperty(Core::PropertyId::WhiteSpace, "pre");
 	}
 
 	if (changed_attributes.find("rows") != changed_attributes.end() ||
@@ -168,12 +168,12 @@ void ElementFormControlTextArea::OnAttributeChange(const Core::AttributeNameList
 }
 
 // Called when properties on the control are changed.
-void ElementFormControlTextArea::OnPropertyChange(const Core::PropertyNameList& changed_properties)
+void ElementFormControlTextArea::OnPropertyChange(const Core::PropertyIdList& changed_properties)
 {
 	ElementFormControl::OnPropertyChange(changed_properties);
 
-	if (changed_properties.find("color") != changed_properties.end() ||
-		changed_properties.find("background-color") != changed_properties.end())
+	if (changed_properties.find(Core::PropertyId::Color) != changed_properties.end() ||
+		changed_properties.find(Core::PropertyId::BackgroundColor) != changed_properties.end())
 		widget->UpdateSelectionColours();
 }
 

+ 9 - 8
Source/Controls/ElementTabSet.cpp

@@ -26,6 +26,7 @@
  */
 
 #include "../../Include/Rocket/Controls/ElementTabSet.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../../Include/Rocket/Core/Math.h"
 #include "../../Include/Rocket/Core/Factory.h"
 
@@ -124,15 +125,15 @@ void ElementTabSet::SetActiveTab(int tab_index)
 		Core::Element* new_window = windows->GetChild(tab_index);
 
 		if (old_window)
-			old_window->SetProperty("display", "none");			
+			old_window->SetProperty(Core::PropertyId::Display, "none");
 		if (new_window)
-			new_window->SetProperty("display", "inline-block");
+			new_window->SetProperty(Core::PropertyId::Display, "inline-block");
 
 		active_tab = tab_index;
 
 		Rocket::Core::Dictionary parameters;
 		parameters["tab_index"] = active_tab;
-		DispatchEvent("tabchange", parameters);
+		DispatchEvent(EventId::Tabchange, parameters);
 	}
 }
 
@@ -180,8 +181,8 @@ void ElementTabSet::OnChildAdd(Core::Element* child)
 	if (child->GetParentNode() == GetChildByTag("tabs"))
 	{
 		// Set up the new button and append it
-		child->SetProperty("display", "inline-block");
-		child->AddEventListener("click", this);
+		child->SetProperty(Core::PropertyId::Display, "inline-block");
+		child->AddEventListener(Core::EventId::Click, this);
 
 		if (child->GetParentNode()->GetChild(active_tab) == child)
 			child->SetPseudoClass("selected", true);
@@ -190,11 +191,11 @@ void ElementTabSet::OnChildAdd(Core::Element* child)
 	if (child->GetParentNode() == GetChildByTag("panels"))
 	{
 		// Hide the new tab window
-		child->SetProperty("display", "none");
+		child->SetProperty(Core::PropertyId::Display, "none");
 		
 		// Make the new element visible if its the active tab
 		if (child->GetParentNode()->GetChild(active_tab) == child)
-			child->SetProperty("display", "inline-block");
+			child->SetProperty(Core::PropertyId::Display, "inline-block");
 	}
 }
 
@@ -205,7 +206,7 @@ void ElementTabSet::OnChildRemove(Core::Element* child)
 	// If its a tab, remove its event listener
 	if (child->GetParentNode() == GetChildByTag("tabs"))
 	{
-		child->RemoveEventListener("click", this);
+		child->RemoveEventListener(Core::EventId::Click, this);
 	}
 }
 

+ 3 - 3
Source/Controls/ElementTextSelection.cpp

@@ -47,7 +47,7 @@ void ElementTextSelection::SetWidget(WidgetTextInput* _widget)
 }
 
 // Processes 'color' and 'background-color' property changes.
-void ElementTextSelection::OnPropertyChange(const Rocket::Core::PropertyNameList& changed_properties)
+void ElementTextSelection::OnPropertyChange(const Rocket::Core::PropertyIdList& changed_properties)
 {
 	Element::OnPropertyChange(changed_properties);
 
@@ -55,8 +55,8 @@ void ElementTextSelection::OnPropertyChange(const Rocket::Core::PropertyNameList
 		return;
 
 	// Check for a colour change.
-	if (changed_properties.find("color") != changed_properties.end() ||
-		changed_properties.find("background-color") != changed_properties.end())
+	if (changed_properties.find(Core::PropertyId::Color) != changed_properties.end() ||
+		changed_properties.find(Core::PropertyId::BackgroundColor) != changed_properties.end())
 	{
 		widget->UpdateSelectionColours();
 	}

+ 1 - 1
Source/Controls/ElementTextSelection.h

@@ -54,7 +54,7 @@ public:
 
 protected:
 	/// Processes 'color' and 'background-color' property changes.
-	virtual void OnPropertyChange(const Rocket::Core::PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const Rocket::Core::PropertyIdList& changed_properties);
 
 private:
 	WidgetTextInput* widget;

+ 83 - 0
Source/Controls/ID.cpp

@@ -0,0 +1,83 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "../../Include/Rocket/Controls/ID.h"
+
+namespace Rocket {
+namespace Controls {
+
+
+// All ID values are undefined until Rocket::Controls::Initialise
+
+namespace PropertyId {
+
+Core::PropertyId MinRows;
+Core::PropertyId TabIndex;
+
+}
+
+namespace EventId {
+
+Core::EventId Columnadd;
+Core::EventId Rowadd;
+Core::EventId Rowchange;
+Core::EventId Rowremove;
+Core::EventId Rowupdate;
+
+Core::EventId Submit;
+Core::EventId Change;
+
+Core::EventId Tabchange;
+
+}
+
+// Called from Rocket::Controls::Initialise (not exposed to header file)
+void InitialiseIDs()
+{
+	{
+		using namespace PropertyId;
+		MinRows = Rocket::Core::CreateOrGetPropertyId("min-rows");
+		TabIndex = Rocket::Core::CreateOrGetPropertyId("tab-index");
+	}
+
+	{	
+		using namespace EventId;
+		Columnadd = Rocket::Core::CreateOrGetEventId("columnadd");
+		Rowadd = Rocket::Core::CreateOrGetEventId("rowadd");
+		Rowchange = Rocket::Core::CreateOrGetEventId("rowchange");
+		Rowremove = Rocket::Core::CreateOrGetEventId("rowremove");
+		Rowupdate = Rocket::Core::CreateOrGetEventId("rowupdate");
+
+		Submit = Rocket::Core::CreateOrGetEventId("submit");
+		Change = Rocket::Core::CreateOrGetEventId("change");
+
+		Tabchange = Rocket::Core::CreateOrGetEventId("tabchange");
+	}
+}
+
+}
+}

+ 1 - 1
Source/Controls/InputType.cpp

@@ -70,7 +70,7 @@ bool InputType::OnAttributeChange(const Core::AttributeNameList& ROCKET_UNUSED_P
 }
 
 // Called when properties on the control are changed.
-void InputType::OnPropertyChange(const Core::PropertyNameList& ROCKET_UNUSED_PARAMETER(changed_properties))
+void InputType::OnPropertyChange(const Core::PropertyIdList& ROCKET_UNUSED_PARAMETER(changed_properties))
 {
 	ROCKET_UNUSED(changed_properties);
 }

+ 1 - 1
Source/Controls/InputType.h

@@ -69,7 +69,7 @@ public:
 	virtual bool OnAttributeChange(const Core::AttributeNameList& changed_attributes);
 	/// Called when properties on the control are changed.
 	/// @param[in] changed_properties The properties changed on the element.
-	virtual void OnPropertyChange(const Core::PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const Core::PropertyIdList& changed_properties);
 
 	/// Called when the element is added into a hierarchy.
 	virtual void OnChildAdd();

+ 4 - 4
Source/Controls/InputTypeButton.cpp

@@ -81,8 +81,8 @@ void InputTypeButton::OnChildAdd()
 	if (document == NULL)
 		return;
 
-	document->AddEventListener("click", this, true);
-	document->AddEventListener("dblclick", this, true);
+	document->AddEventListener(Core::EventId::Click, this, true);
+	document->AddEventListener(Core::EventId::Dblclick, this, true);
 }
 
 // Called when the element is removed from a hierarchy.
@@ -90,8 +90,8 @@ void InputTypeButton::OnChildRemove()
 {
 	if (document != NULL)
 	{
-		document->RemoveEventListener("click", this, true);
-		document->RemoveEventListener("dblclick", this, true);
+		document->RemoveEventListener(Core::EventId::Click, this, true);
+		document->RemoveEventListener(Core::EventId::Dblclick, this, true);
 		document = NULL;
 	}
 }

+ 2 - 1
Source/Controls/InputTypeCheckbox.cpp

@@ -27,6 +27,7 @@
 
 #include "InputTypeCheckbox.h"
 #include "../../Include/Rocket/Controls/ElementFormControlInput.h"
+#include "../../Include/Rocket/Controls/ID.h"
 
 namespace Rocket {
 namespace Controls {
@@ -56,7 +57,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(EventId::Change, parameters);
 	}
 
 	return true;

+ 2 - 1
Source/Controls/InputTypeRadio.cpp

@@ -29,6 +29,7 @@
 #include "../../Include/Rocket/Controls/ElementFormControlInput.h"
 #include "../../Include/Rocket/Core/ElementUtilities.h"
 #include "../../Include/Rocket/Controls/ElementForm.h"
+#include "../../Include/Rocket/Controls/ID.h"
 
 namespace Rocket {
 namespace Controls {
@@ -63,7 +64,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(EventId::Change, parameters);
 	}
 
 	return true;

+ 3 - 3
Source/Controls/InputTypeText.cpp

@@ -88,10 +88,10 @@ bool InputTypeText::OnAttributeChange(const Core::AttributeNameList& changed_att
 }
 
 // Called when properties on the control are changed.
-void InputTypeText::OnPropertyChange(const Core::PropertyNameList& changed_properties)
+void InputTypeText::OnPropertyChange(const Core::PropertyIdList& changed_properties)
 {
-	if (changed_properties.find("color") != changed_properties.end() ||
-		changed_properties.find("background-color") != changed_properties.end())
+	if (changed_properties.find(Core::PropertyId::Color) != changed_properties.end() ||
+		changed_properties.find(Core::PropertyId::BackgroundColor) != changed_properties.end())
 		widget->UpdateSelectionColours();
 }
 

+ 1 - 1
Source/Controls/InputTypeText.h

@@ -65,7 +65,7 @@ public:
 	virtual bool OnAttributeChange(const Core::AttributeNameList& changed_attributes);
 	/// Called when properties on the control are changed.
 	/// @param[in] changed_properties The properties changed on the element.
-	virtual void OnPropertyChange(const Core::PropertyNameList& changed_properties);
+	virtual void OnPropertyChange(const Core::PropertyIdList& changed_properties);
 
 	/// Checks for necessary functional changes in the control as a result of the event.
 	/// @param[in] event The event to process.

+ 22 - 21
Source/Controls/WidgetDropDown.cpp

@@ -34,6 +34,7 @@
 #include "../../Include/Rocket/Core/Property.h"
 #include "../../Include/Rocket/Core/StyleSheetKeywords.h"
 #include "../../Include/Rocket/Controls/ElementFormControl.h"
+#include "../../Include/Rocket/Controls/ID.h"
 
 namespace Rocket {
 namespace Controls {
@@ -52,16 +53,16 @@ WidgetDropDown::WidgetDropDown(ElementFormControl* element)
 	value_element = Core::Factory::InstanceElement(element, "*", "selectvalue", Rocket::Core::XMLAttributes());
 	selection_element = Core::Factory::InstanceElement(parent_element, "*", "selectbox", Rocket::Core::XMLAttributes());
 
-	value_element->SetProperty("overflow", "hidden");
+	value_element->SetProperty(Core::PropertyId::Overflow, "hidden");
 
-	selection_element->SetProperty("visibility", "hidden");
-	selection_element->SetProperty("z-index", Core::Property(1.0f, Core::Property::NUMBER));
-	selection_element->SetProperty("clip", "none");
+	selection_element->SetProperty(Core::PropertyId::Visibility, "hidden");
+	selection_element->SetProperty(Core::PropertyId::ZIndex, Core::Property(1.0f, Core::Property::NUMBER));
+	selection_element->SetProperty(Core::PropertyId::Clip, "none");
 
-	parent_element->AddEventListener("click", this, true);
-	parent_element->AddEventListener("blur", this);
-	parent_element->AddEventListener("focus", this);
-	parent_element->AddEventListener("keydown", this, true);
+	parent_element->AddEventListener(Core::EventId::Click, this, true);
+	parent_element->AddEventListener(Core::EventId::Blur, this);
+	parent_element->AddEventListener(Core::EventId::Focus, this);
+	parent_element->AddEventListener(Core::EventId::Keydown, this, true);
 
 	// Add the elements to our parent element.
 	parent_element->AppendChild(button_element, false);
@@ -75,12 +76,12 @@ WidgetDropDown::~WidgetDropDown()
 	//   Not always a problem, but sometimes it invalidates the layout lock in Element::RemoveChild, which results in a permanently corrupted document.
 	//   However, we do need to remove events of children.
 	for(auto& option : options)
-		option.GetElement()->RemoveEventListener("click", this);
+		option.GetElement()->RemoveEventListener(Core::EventId::Click, this);
 
-	parent_element->RemoveEventListener("click", this, true);
-	parent_element->RemoveEventListener("blur", this);
-	parent_element->RemoveEventListener("focus", this);
-	parent_element->RemoveEventListener("keydown", this, true);
+	parent_element->RemoveEventListener(Core::EventId::Click, this, true);
+	parent_element->RemoveEventListener(Core::EventId::Blur, this);
+	parent_element->RemoveEventListener(Core::EventId::Focus, this);
+	parent_element->RemoveEventListener(Core::EventId::Keydown, this, true);
 
 	button_element->RemoveReference();
 	selection_element->RemoveReference();
@@ -205,7 +206,7 @@ void WidgetDropDown::SetSelection(int selection, bool force)
 
 		Rocket::Core::Dictionary parameters;
 		parameters["value"] = value;
-		parent_element->DispatchEvent("change", parameters);
+		parent_element->DispatchEvent(EventId::Change, parameters);
 	}
 }
 
@@ -222,10 +223,10 @@ int WidgetDropDown::AddOption(const Rocket::Core::String& rml, const Rocket::Cor
 	Core::Element* element = Core::Factory::InstanceElement(selection_element, "*", "option", Rocket::Core::XMLAttributes());
 
 	// Force to block display and inject the RML. Register a click handler so we can be notified of selection.
-	element->SetProperty("display", "block");
-	element->SetProperty("clip", "auto");
+	element->SetProperty(Core::PropertyId::Display, "block");
+	element->SetProperty(Core::PropertyId::Clip, "auto");
 	element->SetInnerRML(rml);
-	element->AddEventListener("click", this);
+	element->AddEventListener(Core::EventId::Click, this);
 
 	int option_index;
 	if (before < 0 ||
@@ -260,7 +261,7 @@ void WidgetDropDown::RemoveOption(int index)
 		return;
 
 	// Remove the listener and delete the option element.
-	options[index].GetElement()->RemoveEventListener("click", this);
+	options[index].GetElement()->RemoveEventListener(Core::EventId::Click, this);
 	selection_element->RemoveChild(options[index].GetElement());
 	options.erase(options.begin() + index);
 
@@ -331,7 +332,7 @@ void WidgetDropDown::ProcessEvent(Core::Event& event)
 				element = element->GetParentNode();
 			}
 
-			if (selection_element->GetProperty< int >("visibility") == Core::VISIBILITY_HIDDEN)
+			if (selection_element->GetProperty< int >(Core::PropertyId::Visibility) == Core::VISIBILITY_HIDDEN)
 				ShowSelectBox(true);
 			else
 				ShowSelectBox(false);
@@ -379,13 +380,13 @@ void WidgetDropDown::ShowSelectBox(bool show)
 {
 	if (show)
 	{
-		selection_element->SetProperty("visibility", "visible");
+		selection_element->SetProperty(Core::PropertyId::Visibility, "visible");
 		value_element->SetPseudoClass("checked", true);
 		button_element->SetPseudoClass("checked", true);
 	}
 	else
 	{
-		selection_element->SetProperty("visibility", "hidden");
+		selection_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 		value_element->SetPseudoClass("checked", false);
 		button_element->SetPseudoClass("checked", false);
 	}

+ 30 - 29
Source/Controls/WidgetSlider.cpp

@@ -28,6 +28,7 @@
 #include "WidgetSlider.h"
 #include "../../Include/Rocket/Core.h"
 #include "../../Include/Rocket/Controls/ElementFormControl.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../Core/Clock.h"
 
 namespace Rocket {
@@ -67,16 +68,16 @@ WidgetSlider::~WidgetSlider()
 		parent->RemoveChild(track);
 	}
 
-	parent->RemoveEventListener("blur", this);
-	parent->RemoveEventListener("focus", this);
-	parent->RemoveEventListener("keydown", this, true);
-	parent->RemoveEventListener("mousedown", this);
-	parent->RemoveEventListener("mouseup", this);
-	parent->RemoveEventListener("mouseout", this);
+	parent->RemoveEventListener(Core::EventId::Blur, this);
+	parent->RemoveEventListener(Core::EventId::Focus, this);
+	parent->RemoveEventListener(Core::EventId::Keydown, this, true);
+	parent->RemoveEventListener(Core::EventId::Mousedown, this);
+	parent->RemoveEventListener(Core::EventId::Mouseup, this);
+	parent->RemoveEventListener(Core::EventId::Mouseout, this);
 
-	parent->RemoveEventListener("drag", this);
-	parent->RemoveEventListener("dragstart", this);
-	parent->RemoveEventListener("dragend", this);
+	parent->RemoveEventListener(Core::EventId::Drag, this);
+	parent->RemoveEventListener(Core::EventId::Dragstart, this);
+	parent->RemoveEventListener(Core::EventId::Dragend, this);
 
 	for (int i = 0; i < 2; i++)
 	{
@@ -90,7 +91,7 @@ WidgetSlider::~WidgetSlider()
 // Initialises the slider to a given orientation.
 bool WidgetSlider::Initialise()
 {
-	parent->SetProperty("drag", "drag");
+	parent->SetProperty(Core::PropertyId::Drag, "drag");
 
 	// Create all of our child elements as standard elements, and abort if we can't create them.
 	track = Core::Factory::InstanceElement(parent, "*", "slidertrack", Rocket::Core::XMLAttributes());
@@ -99,8 +100,8 @@ bool WidgetSlider::Initialise()
 
 	arrows[0] = Core::Factory::InstanceElement(parent, "*", "sliderarrowdec", Rocket::Core::XMLAttributes());
 	arrows[1] = Core::Factory::InstanceElement(parent, "*", "sliderarrowinc", Rocket::Core::XMLAttributes());
-	arrows[0]->SetProperty("drag", "drag");
-	arrows[1]->SetProperty("drag", "drag");
+	arrows[0]->SetProperty(Core::PropertyId::Drag, "drag");
+	arrows[1]->SetProperty(Core::PropertyId::Drag, "drag");
 
 	if (track == NULL ||
 		bar == NULL ||
@@ -136,16 +137,16 @@ bool WidgetSlider::Initialise()
 
 	// Attach the listeners
 	// All listeners are attached to parent, ensuring that we don't get duplicate events when it bubbles from child to parent
-	parent->AddEventListener("blur", this);
-	parent->AddEventListener("focus", this);
-	parent->AddEventListener("keydown", this, true);
-	parent->AddEventListener("mousedown", this);
-	parent->AddEventListener("mouseup", this);
-	parent->AddEventListener("mouseout", this);
+	parent->AddEventListener(Core::EventId::Blur, this);
+	parent->AddEventListener(Core::EventId::Focus, this);
+	parent->AddEventListener(Core::EventId::Keydown, this, true);
+	parent->AddEventListener(Core::EventId::Mousedown, this);
+	parent->AddEventListener(Core::EventId::Mouseup, this);
+	parent->AddEventListener(Core::EventId::Mouseout, this);
 
-	parent->AddEventListener("drag", this);
-	parent->AddEventListener("dragstart", this);
-	parent->AddEventListener("dragend", this);
+	parent->AddEventListener(Core::EventId::Drag, this);
+	parent->AddEventListener(Core::EventId::Dragstart, this);
+	parent->AddEventListener(Core::EventId::Dragend, this);
 
 	return true;
 }
@@ -185,7 +186,7 @@ void WidgetSlider::SetBarPosition(float _bar_position)
 
 	Rocket::Core::Dictionary parameters;
 	parameters["value"] = bar_position;
-	parent->DispatchEvent("change", parameters);
+	parent->DispatchEvent(EventId::Change, parameters);
 }
 
 // Returns the current position of the bar.
@@ -313,7 +314,7 @@ void WidgetSlider::FormatBar(float bar_length)
 	Rocket::Core::Vector2f bar_box_content = bar_box.GetSize();
 	if (orientation == HORIZONTAL)
 	{
-		if (bar->GetLocalProperty("height") == NULL)
+		if (bar->GetLocalProperty(Core::PropertyId::Height) == NULL)
 			bar_box_content.y = parent->GetBox().GetSize().y;
 	}
 
@@ -325,16 +326,16 @@ void WidgetSlider::FormatBar(float bar_length)
 		{
 			float track_length = track_size.y - (bar_box.GetCumulativeEdge(Core::Box::CONTENT, Core::Box::TOP) + bar_box.GetCumulativeEdge(Core::Box::CONTENT, Core::Box::BOTTOM));
 
-			if (bar->GetLocalProperty("height") == NULL)
+			if (bar->GetLocalProperty(Core::PropertyId::Height) == NULL)
 			{
 				bar_box_content.y = track_length * bar_length;
 
 				// Check for 'min-height' restrictions.
-				float min_track_length = bar->ResolveProperty("min-height", track_length);
+				float min_track_length = bar->ResolveProperty(Core::PropertyId::MinHeight, track_length);
 				bar_box_content.y = Rocket::Core::Math::Max(min_track_length, bar_box_content.y);
 
 				// Check for 'max-height' restrictions.
-				float max_track_length = bar->ResolveProperty("max-height", track_length);
+				float max_track_length = bar->ResolveProperty(Core::PropertyId::MaxHeight, track_length);
 				if (max_track_length > 0)
 					bar_box_content.y = Rocket::Core::Math::Min(max_track_length, bar_box_content.y);
 			}
@@ -346,16 +347,16 @@ void WidgetSlider::FormatBar(float bar_length)
 		{
 			float track_length = track_size.x - (bar_box.GetCumulativeEdge(Core::Box::CONTENT, Core::Box::LEFT) + bar_box.GetCumulativeEdge(Core::Box::CONTENT, Core::Box::RIGHT));
 
-			if (bar->GetLocalProperty("width") == NULL)
+			if (bar->GetLocalProperty(Core::PropertyId::Width) == NULL)
 			{
 				bar_box_content.x = track_length * bar_length;
 
 				// Check for 'min-width' restrictions.
-				float min_track_length = bar->ResolveProperty("min-width", track_length);
+				float min_track_length = bar->ResolveProperty(Core::PropertyId::MinWidth, track_length);
 				bar_box_content.x = Rocket::Core::Math::Max(min_track_length, bar_box_content.x);
 
 				// Check for 'max-width' restrictions.
-				float max_track_length = bar->ResolveProperty("max-width", track_length);
+				float max_track_length = bar->ResolveProperty(Core::PropertyId::MaxWidth, track_length);
 				if (max_track_length > 0)
 					bar_box_content.x = Rocket::Core::Math::Min(max_track_length, bar_box_content.x);
 			}

+ 26 - 25
Source/Controls/WidgetTextInput.cpp

@@ -30,6 +30,7 @@
 #include "../../Include/Rocket/Core.h"
 #include "../../Include/Rocket/Controls/ElementFormControl.h"
 #include "../../Include/Rocket/Controls/Clipboard.h"
+#include "../../Include/Rocket/Controls/ID.h"
 #include "../../Include/Rocket/Core/SystemInterface.h"
 #include "../Core/Clock.h"
 
@@ -43,18 +44,18 @@ WidgetTextInput::WidgetTextInput(ElementFormControl* _parent) : internal_dimensi
 	keyboard_showed = false;
 	
 	parent = _parent;
-	parent->SetProperty("white-space", "pre");
-	parent->SetProperty("overflow", "hidden");
-	parent->SetProperty("drag", "drag");
+	parent->SetProperty(Core::PropertyId::WhiteSpace, "pre");
+	parent->SetProperty(Core::PropertyId::Overflow, "hidden");
+	parent->SetProperty(Core::PropertyId::Drag, "drag");
 	parent->SetClientArea(Rocket::Core::Box::CONTENT);
 
-	parent->AddEventListener("resize", this, true);
-	parent->AddEventListener("keydown", this, true);
-	parent->AddEventListener("textinput", this, true);
-	parent->AddEventListener("focus", this, true);
-	parent->AddEventListener("blur", this, true);
-	parent->AddEventListener("mousedown", this, true);
-	parent->AddEventListener("drag", this, true);
+	parent->AddEventListener(Core::EventId::Resize, this, true);
+	parent->AddEventListener(Core::EventId::Keydown, this, true);
+	parent->AddEventListener(Core::EventId::Textinput, this, true);
+	parent->AddEventListener(Core::EventId::Focus, this, true);
+	parent->AddEventListener(Core::EventId::Blur, this, true);
+	parent->AddEventListener(Core::EventId::Mousedown, this, true);
+	parent->AddEventListener(Core::EventId::Drag, this, true);
 
 	text_element = dynamic_cast< Core::ElementText* >(Core::Factory::InstanceElement(parent, "#text", "#text", Rocket::Core::XMLAttributes()));
 	selected_text_element = dynamic_cast< Core::ElementText* >(Core::Factory::InstanceElement(parent, "#text", "#text", Rocket::Core::XMLAttributes()));
@@ -99,13 +100,13 @@ WidgetTextInput::WidgetTextInput(ElementFormControl* _parent) : internal_dimensi
 
 WidgetTextInput::~WidgetTextInput()
 {
-	parent->RemoveEventListener("resize", this, true);
-	parent->RemoveEventListener("keydown", this, true);
-	parent->RemoveEventListener("textinput", this, true);
-	parent->RemoveEventListener("focus", this, true);
-	parent->RemoveEventListener("blur", this, true);
-	parent->RemoveEventListener("mousedown", this, true);
-	parent->RemoveEventListener("drag", this, true);
+	parent->RemoveEventListener(Core::EventId::Resize, this, true);
+	parent->RemoveEventListener(Core::EventId::Keydown, this, true);
+	parent->RemoveEventListener(Core::EventId::Textinput, this, true);
+	parent->RemoveEventListener(Core::EventId::Focus, this, true);
+	parent->RemoveEventListener(Core::EventId::Blur, this, true);
+	parent->RemoveEventListener(Core::EventId::Mousedown, this, true);
+	parent->RemoveEventListener(Core::EventId::Drag, this, true);
 
 	// Remove all the children added by the text widget.
 	parent->RemoveChild(text_element);
@@ -154,24 +155,24 @@ void WidgetTextInput::UpdateSelectionColours()
 	// Determine what the colour of the selected text is. If our 'selection' element has the 'color'
 	// attribute set, then use that. Otherwise, use the inverse of our own text colour.
 	Rocket::Core::Colourb colour;
-	const Rocket::Core::Property* colour_property = selection_element->GetLocalProperty("color");
+	const Rocket::Core::Property* colour_property = selection_element->GetLocalProperty(Core::PropertyId::Color);
 	if (colour_property != NULL)
 		colour = colour_property->Get< Rocket::Core::Colourb >();
 	else
 	{
-		colour = parent->GetProperty< Rocket::Core::Colourb >("color");
+		colour = parent->GetProperty< Rocket::Core::Colourb >(Core::PropertyId::Color);
 		colour.red = 255 - colour.red;
 		colour.green = 255 - colour.green;
 		colour.blue = 255 - colour.blue;
 	}
 
 	// Set the computed text colour on the element holding the selected text.
-	selected_text_element->SetProperty("color", Rocket::Core::Property(colour, Rocket::Core::Property::COLOUR));
+	selected_text_element->SetProperty(Core::PropertyId::Color, Rocket::Core::Property(colour, Rocket::Core::Property::COLOUR));
 
 	// If the 'background-color' property has been set on the 'selection' element, use that as the
 	// background colour for the selected text. Otherwise, use the inverse of the selected text
 	// colour.
-	colour_property = selection_element->GetLocalProperty("background-color");
+	colour_property = selection_element->GetLocalProperty(Core::PropertyId::BackgroundColor);
 	if (colour_property != NULL)
 		selection_colour = colour_property->Get< Rocket::Core::Colourb >();
 	else
@@ -242,7 +243,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(EventId::Change, parameters);
 }
 
 // Processes the "keydown" and "textinput" event to write to the input field, and the "focus" and "blur" to set
@@ -678,8 +679,8 @@ void WidgetTextInput::FormatElement()
 	Core::ElementScroll* scroll = parent->GetElementScroll();
 	float width = parent->GetBox().GetSize(Core::Box::PADDING).x;
 
-	int x_overflow_property = parent->GetProperty< int >("overflow-x");
-	int y_overflow_property = parent->GetProperty< int >("overflow-y");
+	int x_overflow_property = parent->GetProperty< int >(Core::PropertyId::OverflowX);
+	int y_overflow_property = parent->GetProperty< int >(Core::PropertyId::OverflowY);
 
 	if (x_overflow_property == Core::OVERFLOW_SCROLL)
 		scroll->EnableScrollbar(Core::ElementScroll::HORIZONTAL, width);
@@ -876,7 +877,7 @@ void WidgetTextInput::GenerateCursor()
 
 	cursor_size.x = 1;
 	cursor_size.y = (float) Core::ElementUtilities::GetLineHeight(text_element) + 2;
-	Core::GeometryUtilities::GenerateQuad(&vertices[0], &indices[0], Rocket::Core::Vector2f(0, 0), cursor_size, parent->GetProperty< Rocket::Core::Colourb >("color"));
+	Core::GeometryUtilities::GenerateQuad(&vertices[0], &indices[0], Rocket::Core::Vector2f(0, 0), cursor_size, parent->GetProperty< Rocket::Core::Colourb >(Core::PropertyId::Color));
 }
 
 void WidgetTextInput::UpdateCursorPosition()

+ 43 - 43
Source/Core/Context.cpp

@@ -50,7 +50,7 @@ Context::Context(const String& name) : name(name), dimensions(0, 0), mouse_posit
 	root = Factory::InstanceElement(NULL, "*", "#root", XMLAttributes());
 	root->SetId(name);
 	root->SetOffset(Vector2f(0, 0), NULL);
-	root->SetProperty(Z_INDEX, "0");
+	root->SetProperty(PropertyId::ZIndex, "0");
 
 	Element* element = Factory::InstanceElement(NULL, "body", "body", XMLAttributes());
 	cursor_proxy = dynamic_cast< ElementDocument* >(element);
@@ -279,7 +279,7 @@ ElementDocument* Context::LoadDocument(Stream* stream)
 	document->UpdateDocument();
 
 	PluginRegistry::NotifyDocumentLoad(document);
-	document->DispatchEvent(LOAD, Dictionary(), false);
+	document->DispatchEvent(EventId::Load, Dictionary(), false);
 
 	return document;
 }
@@ -317,7 +317,7 @@ void Context::UnloadDocument(ElementDocument* _document)
 	if (document->GetParentNode() == root)
 	{
 		// Dispatch the unload notifications.
-		document->DispatchEvent(UNLOAD, Dictionary(), false);
+		document->DispatchEvent(EventId::Unload, Dictionary(), false);
 		PluginRegistry::NotifyDocumentUnload(document);
 
 		// Remove the document from the context.
@@ -475,9 +475,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(EventId::Keydown, parameters, true);
 	else
-		return root->DispatchEvent(KEYDOWN, parameters, true);
+		return root->DispatchEvent(EventId::Keydown, parameters, true);
 }
 
 // Sends a key up event into Rocket.
@@ -489,9 +489,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(EventId::Keyup, parameters, true);
 	else
-		return root->DispatchEvent(KEYUP, parameters, true);
+		return root->DispatchEvent(EventId::Keyup, parameters, true);
 }
 
 // Sends a single character of text as text input into Rocket.
@@ -502,9 +502,9 @@ bool Context::ProcessTextInput(word character)
 	parameters["data"] = character;
 
 	if (focus)
-		return focus->DispatchEvent(TEXTINPUT, parameters, true);
+		return focus->DispatchEvent(EventId::Textinput, parameters, true);
 	else
-		return root->DispatchEvent(TEXTINPUT, parameters, true);
+		return root->DispatchEvent(EventId::Textinput, parameters, true);
 }
 
 // Sends a string of text as text input into Rocket.
@@ -519,9 +519,9 @@ bool Context::ProcessTextInput(const String& string)
 		parameters["data"] = string[i];
 
 		if (focus)
-			consumed = focus->DispatchEvent(TEXTINPUT, parameters, true) && consumed;
+			consumed = focus->DispatchEvent(EventId::Textinput, parameters, true) && consumed;
 		else
-			consumed = root->DispatchEvent(TEXTINPUT, parameters, true) && consumed;
+			consumed = root->DispatchEvent(EventId::Textinput, parameters, true) && consumed;
 	}
 
 	return consumed;
@@ -558,11 +558,11 @@ void Context::ProcessMouseMove(int x, int y, int key_modifier_state)
 	{
 		if (hover)
 		{
-			hover->DispatchEvent(MOUSEMOVE, parameters, true);
+			hover->DispatchEvent(EventId::Mousemove, parameters, true);
 
 			if (drag_hover &&
 				drag_verbose)
-				drag_hover->DispatchEvent(DRAGMOVE, drag_parameters, true);
+				drag_hover->DispatchEvent(EventId::Dragmove, drag_parameters, true);
 		}
 	}
 }
@@ -570,10 +570,10 @@ void Context::ProcessMouseMove(int x, int y, int key_modifier_state)
 static Element* FindFocusElement(Element* element)
 {
 	ElementDocument* owner_document = element->GetOwnerDocument();
-	if (!owner_document || owner_document->GetProperty< int >(FOCUS_PROPERTY) == FOCUS_NONE)
+	if (!owner_document || owner_document->GetProperty< int >(PropertyId::Focus) == FOCUS_NONE)
 		return NULL;
 	
-	while (element && element->GetProperty< int >(FOCUS_PROPERTY) == FOCUS_NONE)
+	while (element && element->GetProperty< int >(PropertyId::Focus) == FOCUS_NONE)
 	{
 		element = element->GetParentNode();
 	}
@@ -610,7 +610,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(EventId::Mousedown, parameters, true);
 
 		if (propogate)
 		{
@@ -621,7 +621,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(EventId::Dblclick, parameters, true);
 
 				last_click_element = NULL;
 				last_click_time = 0;
@@ -644,7 +644,7 @@ void Context::ProcessMouseButtonDown(int button_index, int key_modifier_state)
 			drag = hover;
 			while (drag)
 			{
-				int drag_style = drag->GetProperty(DRAG_PROPERTY)->value.Get< int >();
+				int drag_style = drag->GetProperty(PropertyId::Drag)->value.Get< int >();
 				switch (drag_style)
 				{
 					case DRAG_NONE:		drag = drag->GetParentNode(); continue;
@@ -660,7 +660,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(EventId::Mousedown, parameters, true);
 	}
 }
 
@@ -676,13 +676,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(EventId::Mouseup, parameters, true);
 
 		// 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(EventId::Click, parameters, true);
 		}
 
 		// Unset the 'active' pseudo-class on all the elements in the active chain; because they may not necessarily
@@ -703,12 +703,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(EventId::Dragdrop, drag_parameters, true);
+						drag_hover->DispatchEvent(EventId::Dragout, drag_parameters, true);
 					}
 				}
 
-				drag->DispatchEvent(DRAGEND, drag_parameters, true);
+				drag->DispatchEvent(EventId::Dragend, drag_parameters, true);
 
 				ReleaseDragClone();
 			}
@@ -722,7 +722,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(EventId::Mouseup, parameters, true);
 	}
 }
 
@@ -735,7 +735,7 @@ bool Context::ProcessMouseWheel(int 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(EventId::Mousescroll, scroll_parameters, true);
 	}
 
 	return true;
@@ -821,7 +821,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, EventId::Mouseout, parameters, true);
 }
 
 // Internal callback for when a new element gains focus
@@ -857,8 +857,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, EventId::Blur, parameters, false);
+	SendEvents(new_chain, old_chain, EventId::Focus, parameters, false);
 
 	focus = new_focus;
 
@@ -866,7 +866,7 @@ bool Context::OnFocusChange(Element* new_focus)
 	ElementDocument* document = focus->GetOwnerDocument();
 	if (document != NULL)
 	{
-		const Property* z_index_property = document->GetProperty(Z_INDEX);
+		const Property* z_index_property = document->GetProperty(PropertyId::ZIndex);
 		if (z_index_property->unit == Property::KEYWORD &&
 			z_index_property->value.Get< int >() == Z_INDEX_AUTO)
 			document->PullToFront();
@@ -893,7 +893,7 @@ void Context::GenerateClickEvent(Element* element)
 	Dictionary parameters;
 	GenerateMouseEventParameters(parameters, 0);
 
-	element->DispatchEvent(CLICK, parameters, true);
+	element->DispatchEvent(EventId::Click, parameters, true);
 }
 
 // Updates the current hover elements, sending required events.
@@ -911,17 +911,17 @@ 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(EventId::Dragstart, drag_start_parameters);
 				drag_started = true;
 
-				if (drag->GetProperty< int >(DRAG_PROPERTY) == DRAG_CLONE)
+				if (drag->GetProperty< int >(PropertyId::Drag) == DRAG_CLONE)
 				{
 					// Clone the element and attach it to the mouse cursor.
 					CreateDragClone(*drag);
 				}
 			}
 
-			drag->DispatchEvent(DRAG, drag_parameters);
+			drag->DispatchEvent(EventId::Drag, drag_parameters);
 		}
 	}
 
@@ -931,8 +931,8 @@ void Context::UpdateHoverChain(const Dictionary& parameters, const Dictionary& d
 	{
 		String new_mouse_cursor;
 
-		if (hover && hover->GetProperty(CURSOR)->unit != Property::KEYWORD)
-			new_mouse_cursor = hover->GetProperty< String >(CURSOR);
+		if (hover && hover->GetProperty(PropertyId::Cursor)->unit != Property::KEYWORD)
+			new_mouse_cursor = hover->GetProperty< String >(PropertyId::Cursor);
 
 		GetSystemInterface()->SetMouseCursor(new_mouse_cursor);
 	}
@@ -947,8 +947,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, EventId::Mouseout, parameters, true);
+	SendEvents(new_hover_chain, hover_chain, EventId::Mouseover, parameters, true);
 
 	// Send out drag events.
 	if (drag)
@@ -979,8 +979,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, EventId::Dragout, drag_parameters, true);
+			SendEvents(new_drag_hover_chain, drag_hover_chain, EventId::Dragover, drag_parameters, true);
 		}
 
 		drag_hover_chain.swap(new_drag_hover_chain);
@@ -1100,9 +1100,9 @@ void Context::CreateDragClone(Element* element)
 
 	// Set all the required properties and pseudo-classes on the clone.
 	drag_clone->SetPseudoClass("drag", true);
-	drag_clone->SetProperty(POSITION, "absolute");
-	drag_clone->SetProperty(LEFT, Property(element->GetAbsoluteLeft() - element->GetBox().GetEdge(Box::MARGIN, Box::LEFT) - mouse_position.x, Property::PX));
-	drag_clone->SetProperty(TOP, Property(element->GetAbsoluteTop() - element->GetBox().GetEdge(Box::MARGIN, Box::TOP) - mouse_position.y, Property::PX));
+	drag_clone->SetProperty(PropertyId::Position, "absolute");
+	drag_clone->SetProperty(PropertyId::Left, Property(element->GetAbsoluteLeft() - element->GetBox().GetEdge(Box::MARGIN, Box::LEFT) - mouse_position.x, Property::PX));
+	drag_clone->SetProperty(PropertyId::Top, Property(element->GetAbsoluteTop() - element->GetBox().GetEdge(Box::MARGIN, Box::TOP) - mouse_position.y, Property::PX));
 }
 
 // Releases the drag clone, if one exists.

+ 2 - 2
Source/Core/DecoratorTiled.cpp

@@ -118,9 +118,9 @@ Vector2f DecoratorTiled::Tile::GetDimensions(Element* element)
 void DecoratorTiled::Tile::GenerateGeometry(std::vector< Vertex >& vertices, std::vector< int >& indices, Element* element, const Vector2f& surface_origin, const Vector2f& surface_dimensions, const Vector2f& tile_dimensions) const
 {
 	RenderInterface* render_interface = element->GetRenderInterface();
-    float opacity = element->GetProperty<float>(OPACITY);
+    float opacity = element->GetProperty<float>(PropertyId::Opacity);
 
-    Colourb quad_colour = element->GetProperty<Colourb>(IMAGE_COLOR);
+    Colourb quad_colour = element->GetProperty<Colourb>(PropertyId::ImageColor);
 
     // Apply opacity
     quad_colour.alpha = (byte)(opacity * (float)quad_colour.alpha);

+ 1 - 1
Source/Core/Element.cpp

@@ -2541,7 +2541,7 @@ void Element::AdvanceAnimations()
 
 		for (auto it = it_completed; it != animations.end(); ++it)
 		{
-			dictionary_list.emplace_back(Dictionary({ { "property", it->GetPropertyId()} }));
+			dictionary_list.emplace_back(Dictionary({ { "property", GetName(it->GetPropertyId())} }));
 			is_transition.push_back(it->IsTransition());
 		}
 

+ 2 - 2
Source/Core/ElementBackground.cpp

@@ -67,8 +67,8 @@ void ElementBackground::DirtyBackground()
 void ElementBackground::GenerateBackground()
 {
 	// Fetch the new colour for the background. If the colour is transparent, then we don't render any background.
-	Colourb colour = element->GetProperty(BACKGROUND_COLOR)->value.Get< Colourb >();
-	float opacity = element->GetProperty<float>(OPACITY);
+	Colourb colour = element->GetProperty(PropertyId::BackgroundColor)->value.Get< Colourb >();
+	float opacity = element->GetProperty<float>(PropertyId::Opacity);
 
 	// Apply opacity
 	colour.alpha = (byte)(opacity * (float)colour.alpha);

+ 5 - 5
Source/Core/ElementBorder.cpp

@@ -90,13 +90,13 @@ void ElementBorder::GenerateBorder()
 		int* raw_indices = &indices[0];
 
 		Colourb border_colours[4];
-		border_colours[0] = element->GetProperty(BORDER_TOP_COLOR)->value.Get< Colourb >();
-		border_colours[1] = element->GetProperty(BORDER_RIGHT_COLOR)->value.Get< Colourb >();
-		border_colours[2] = element->GetProperty(BORDER_BOTTOM_COLOR)->value.Get< Colourb >();
-		border_colours[3] = element->GetProperty(BORDER_LEFT_COLOR)->value.Get< Colourb >();
+		border_colours[0] = element->GetProperty(PropertyId::BorderTopColor)->value.Get< Colourb >();
+		border_colours[1] = element->GetProperty(PropertyId::BorderRightColor)->value.Get< Colourb >();
+		border_colours[2] = element->GetProperty(PropertyId::BorderBottomColor)->value.Get< Colourb >();
+		border_colours[3] = element->GetProperty(PropertyId::BorderLeftColor)->value.Get< Colourb >();
 
 		// Apply opacity to the border
-		float opacity = element->GetProperty<float>(OPACITY);
+		float opacity = element->GetProperty<float>(PropertyId::Opacity);
 		for(int i = 0; i < 4; ++i) {
 			border_colours[i].alpha = (byte)(opacity * (float)border_colours[i].alpha);
 		}

+ 6 - 6
Source/Core/ElementImage.cpp

@@ -156,12 +156,12 @@ void ElementImage::OnAttributeChange(const Rocket::Core::AttributeNameList& chan
 		DirtyLayout();
 }
 
-void ElementImage::OnPropertyChange(const PropertyNameList& changed_properties)
+void ElementImage::OnPropertyChange(const PropertyIdList& changed_properties)
 {
     Element::OnPropertyChange(changed_properties);
 
-    if (changed_properties.find(IMAGE_COLOR) != changed_properties.end() ||
-        changed_properties.find(OPACITY) != changed_properties.end()) {
+    if (changed_properties.find(PropertyId::ImageColor) != changed_properties.end() ||
+        changed_properties.find(PropertyId::Opacity) != changed_properties.end()) {
         GenerateGeometry();
     }
 }
@@ -172,7 +172,7 @@ void ElementImage::ProcessEvent(Rocket::Core::Event& event)
 	Element::ProcessEvent(event);
 
 	if (event.GetTargetElement() == this &&
-		event == RESIZE)
+		event == EventId::Resize)
 	{
 		GenerateGeometry();
 	}
@@ -211,8 +211,8 @@ void ElementImage::GenerateGeometry()
 		texcoords[1] = Vector2f(1, 1);
 	}
 
-    float opacity = GetProperty<float>(OPACITY);
-	Colourb quad_colour = GetProperty<Colourb>(IMAGE_COLOR);
+    float opacity = GetProperty<float>(PropertyId::Opacity);
+	Colourb quad_colour = GetProperty<Colourb>(PropertyId::ImageColor);
     quad_colour.alpha = (byte)(opacity * (float)quad_colour.alpha);
 	
 	Vector2f quad_size = GetBox().GetSize(Rocket::Core::Box::CONTENT).Round();

+ 1 - 1
Source/Core/ElementImage.h

@@ -86,7 +86,7 @@ protected:
 
 	/// 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 PropertyIdList& changed_properties);
 
 	/// Regenerates the element's geometry on a resize event.
 	/// @param[in] event The event to process.

+ 9 - 9
Source/Core/ElementScroll.cpp

@@ -54,7 +54,7 @@ void ElementScroll::ClearScrollbars()
 	{
 		if (scrollbars[i].element != NULL)
 		{
-			scrollbars[i].element->RemoveEventListener("scrollchange", this);
+			scrollbars[i].element->RemoveEventListener(EventId::Scrollchange, this);
 			scrollbars[i] = Scrollbar();
 		}
 	}
@@ -82,7 +82,7 @@ void ElementScroll::EnableScrollbar(Orientation orientation, float element_width
 	if (!scrollbars[orientation].enabled)
 	{
 		CreateScrollbar(orientation);
-		scrollbars[orientation].element->SetProperty(VISIBILITY, "visible");
+		scrollbars[orientation].element->SetProperty(PropertyId::Visibility, "visible");
 		scrollbars[orientation].enabled = true;
 	}
 
@@ -97,7 +97,7 @@ void ElementScroll::EnableScrollbar(Orientation orientation, float element_width
 		if (box.GetSize().y < 0)
 			scrollbars[orientation].size = box.GetCumulativeEdge(Box::CONTENT, Box::LEFT) +
 										   box.GetCumulativeEdge(Box::CONTENT, Box::RIGHT) +
-										   scrollbars[orientation].element->ResolveProperty(HEIGHT, element_width);
+										   scrollbars[orientation].element->ResolveProperty(PropertyId::Height, element_width);
 		else
 			scrollbars[orientation].size = box.GetSize(Box::MARGIN).y;
 	}
@@ -108,7 +108,7 @@ void ElementScroll::DisableScrollbar(Orientation orientation)
 {
 	if (scrollbars[orientation].enabled)
 	{
-		scrollbars[orientation].element->SetProperty(VISIBILITY, "hidden");
+		scrollbars[orientation].element->SetProperty(PropertyId::Visibility, "hidden");
 		scrollbars[orientation].enabled = false;
 	}
 }
@@ -192,7 +192,7 @@ void ElementScroll::FormatScrollbars()
 		}
 
 		float slider_length = containing_block[1 - i];
-		float user_scrollbar_margin = scrollbars[i].element->ResolveProperty(SCROLLBAR_MARGIN, slider_length);
+		float user_scrollbar_margin = scrollbars[i].element->ResolveProperty(PropertyId::ScrollbarMargin, slider_length);
 		float min_scrollbar_margin = GetScrollbarSize(i == VERTICAL ? HORIZONTAL : VERTICAL);
 		slider_length -= Math::Max(user_scrollbar_margin, min_scrollbar_margin);
 
@@ -218,12 +218,12 @@ void ElementScroll::FormatScrollbars()
 		corner->SetBox(corner_box);
 		corner->SetOffset(containing_block - Vector2f(scrollbars[VERTICAL].size, scrollbars[HORIZONTAL].size), element, true);
 
-		corner->SetProperty(VISIBILITY, "visible");
+		corner->SetProperty(PropertyId::Visibility, "visible");
 	}
 	else
 	{
 		if (corner != NULL)
-			corner->SetProperty(VISIBILITY, "hidden");
+			corner->SetProperty(PropertyId::Visibility, "hidden");
 	}
 }
 
@@ -249,8 +249,8 @@ bool ElementScroll::CreateScrollbar(Orientation orientation)
 		return true;
 
 	scrollbars[orientation].element = Factory::InstanceElement(element, "*", orientation == VERTICAL ? "scrollbarvertical" : "scrollbarhorizontal", XMLAttributes());
-	scrollbars[orientation].element->AddEventListener("scrollchange", this);
-	scrollbars[orientation].element->SetProperty(CLIP, "1");
+	scrollbars[orientation].element->AddEventListener(EventId::Scrollchange, this);
+	scrollbars[orientation].element->SetProperty(PropertyId::Clip, "1");
 
 	scrollbars[orientation].widget = new WidgetSliderScroll(scrollbars[orientation].element);
 	scrollbars[orientation].widget->Initialise(orientation == VERTICAL ? WidgetSlider::VERTICAL : WidgetSlider::HORIZONTAL);

+ 0 - 1
Source/Core/ElementStyle.cpp

@@ -913,7 +913,6 @@ void ElementStyle::DirtyInheritedProperties(const PropertyIdList& properties)
 		element->GetChild(i)->GetStyle()->DirtyInheritedProperties(inherited_properties);
 
 	element->DirtyProperties(properties);
-	//element->OnPropertyChange(properties);
 }
 
 void ElementStyle::GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right )

+ 31 - 31
Source/Core/ElementStyleCache.cpp

@@ -150,28 +150,28 @@ void ElementStyleCache::GetOffsetProperties(const Property **o_top, const Proper
 	if (o_top)
 	{
 		if (!top)
-			top = style->GetProperty(TOP);
+			top = style->GetProperty(PropertyId::Top);
 		*o_top = top;
 	}
 
 	if (o_bottom)
 	{
 		if (!bottom)
-			bottom = style->GetProperty(BOTTOM);
+			bottom = style->GetProperty(PropertyId::Bottom);
 		*o_bottom = bottom;
 	}
 
 	if (o_left)
 	{
 		if (!left)
-			left = style->GetProperty(LEFT);
+			left = style->GetProperty(PropertyId::Left);
 		*o_left = left;
 	}
 
 	if (o_right)
 	{
 		if (!right)
-			right = style->GetProperty(RIGHT);
+			right = style->GetProperty(PropertyId::Right);
 		*o_right = right;
 	}
 }
@@ -181,28 +181,28 @@ void ElementStyleCache::GetBorderWidthProperties(const Property **o_border_top_w
 	if (o_border_top_width)
 	{
 		if (!border_top_width)
-			border_top_width = style->GetProperty(BORDER_TOP_WIDTH);
+			border_top_width = style->GetProperty(PropertyId::BorderTopWidth);
 		*o_border_top_width = border_top_width;
 	}
 
 	if (o_border_bottom_width)
 	{
 		if (!border_bottom_width)
-			border_bottom_width = style->GetProperty(BORDER_BOTTOM_WIDTH);
+			border_bottom_width = style->GetProperty(PropertyId::BorderBottomWidth);
 		*o_border_bottom_width = border_bottom_width;
 	}
 
 	if (o_border_left_width)
 	{
 		if (!border_left_width)
-			border_left_width = style->GetProperty(BORDER_LEFT_WIDTH);
+			border_left_width = style->GetProperty(PropertyId::BorderLeftWidth);
 		*o_border_left_width = border_left_width;
 	}
 
 	if (o_border_right_width)
 	{
 		if (!border_right_width)
-			border_right_width = style->GetProperty(BORDER_RIGHT_WIDTH);
+			border_right_width = style->GetProperty(PropertyId::BorderRightWidth);
 		*o_border_right_width = border_right_width;
 	}
 }
@@ -212,28 +212,28 @@ void ElementStyleCache::GetMarginProperties(const Property **o_margin_top, const
 	if (o_margin_top)
 	{
 		if (!margin_top)
-			margin_top = style->GetProperty(MARGIN_TOP);
+			margin_top = style->GetProperty(PropertyId::MarginTop);
 		*o_margin_top = margin_top;
 	}
 
 	if (o_margin_bottom)
 	{
 		if (!margin_bottom)
-			margin_bottom = style->GetProperty(MARGIN_BOTTOM);
+			margin_bottom = style->GetProperty(PropertyId::MarginBottom);
 		*o_margin_bottom = margin_bottom;
 	}
 
 	if (o_margin_left)
 	{
 		if (!margin_left)
-			margin_left = style->GetProperty(MARGIN_LEFT);
+			margin_left = style->GetProperty(PropertyId::MarginLeft);
 		*o_margin_left = margin_left;
 	}
 
 	if (o_margin_right)
 	{
 		if (!margin_right)
-			margin_right = style->GetProperty(MARGIN_RIGHT);
+			margin_right = style->GetProperty(PropertyId::MarginRight);
 		*o_margin_right = margin_right;
 	}
 }
@@ -243,28 +243,28 @@ void ElementStyleCache::GetPaddingProperties(const Property **o_padding_top, con
 	if (o_padding_top)
 	{
 		if (!padding_top)
-			padding_top = style->GetProperty(PADDING_TOP);
+			padding_top = style->GetProperty(PropertyId::PaddingTop);
 		*o_padding_top = padding_top;
 	}
 
 	if (o_padding_bottom)
 	{
 		if (!padding_bottom)
-			padding_bottom = style->GetProperty(PADDING_BOTTOM);
+			padding_bottom = style->GetProperty(PropertyId::PaddingBottom);
 		*o_padding_bottom = padding_bottom;
 	}
 
 	if (o_padding_left)
 	{
 		if (!padding_left)
-			padding_left = style->GetProperty(PADDING_LEFT);
+			padding_left = style->GetProperty(PropertyId::PaddingLeft);
 		*o_padding_left = padding_left;
 	}
 
 	if (o_padding_right)
 	{
 		if (!padding_right)
-			padding_right = style->GetProperty(PADDING_RIGHT);
+			padding_right = style->GetProperty(PropertyId::PaddingRight);
 		*o_padding_right = padding_right;
 	}
 }
@@ -274,14 +274,14 @@ void ElementStyleCache::GetDimensionProperties(const Property **o_width, const P
 	if (o_width)
 	{
 		if (!width)
-			width = style->GetProperty(WIDTH);
+			width = style->GetProperty(PropertyId::Width);
 		*o_width = width;
 	}
 
 	if (o_height)
 	{
 		if (!height)
-			height = style->GetProperty(HEIGHT);
+			height = style->GetProperty(PropertyId::Height);
 		*o_height = height;
 	}
 }
@@ -293,7 +293,7 @@ void ElementStyleCache::GetLocalDimensionProperties(const Property **o_width, co
 		if (!have_local_width)
 		{
 			have_local_width = true;
-			local_width = style->GetLocalProperty(WIDTH);
+			local_width = style->GetLocalProperty(PropertyId::Width);
 		}
 		*o_width = local_width;
 	}
@@ -303,7 +303,7 @@ void ElementStyleCache::GetLocalDimensionProperties(const Property **o_width, co
 		if (!have_local_height)
 		{
 			have_local_height = true;
-			local_height = style->GetLocalProperty(HEIGHT);
+			local_height = style->GetLocalProperty(PropertyId::Height);
 		}
 		*o_height = local_height;
 	}
@@ -314,14 +314,14 @@ void ElementStyleCache::GetOverflow(int *o_overflow_x, int *o_overflow_y)
 	if (o_overflow_x)
 	{
 		if (overflow_x < 0)
-			overflow_x = style->GetProperty(OVERFLOW_X)->Get< int >();
+			overflow_x = style->GetProperty(PropertyId::OverflowX)->Get< int >();
 		*o_overflow_x = overflow_x;
 	}
 
 	if (o_overflow_y)
 	{
 		if (overflow_y < 0)
-			overflow_y = style->GetProperty(OVERFLOW_Y)->Get< int >();
+			overflow_y = style->GetProperty(PropertyId::OverflowY)->Get< int >();
 		*o_overflow_y = overflow_y;
 	}
 }
@@ -329,63 +329,63 @@ void ElementStyleCache::GetOverflow(int *o_overflow_x, int *o_overflow_y)
 int ElementStyleCache::GetPosition()
 {
 	if (position < 0)
-		position = style->GetProperty(POSITION)->Get< int >();
+		position = style->GetProperty(PropertyId::Position)->Get< int >();
 	return position;
 }
 
 int ElementStyleCache::GetFloat()
 {
 	if (float_ < 0)
-		float_ = style->GetProperty(FLOAT)->Get< int >();
+		float_ = style->GetProperty(PropertyId::Float)->Get< int >();
 	return float_;
 }
 
 int ElementStyleCache::GetDisplay()
 {
 	if (display < 0)
-		display = style->GetProperty(DISPLAY)->Get< int >();
+		display = style->GetProperty(PropertyId::Display)->Get< int >();
 	return display;
 }
 
 int ElementStyleCache::GetWhitespace()
 {
 	if (whitespace < 0)
-		whitespace = style->GetProperty(WHITE_SPACE)->Get< int >();
+		whitespace = style->GetProperty(PropertyId::WhiteSpace)->Get< int >();
 	return whitespace;
 }
 
 int ElementStyleCache::GetPointerEvents()
 {
 	if (pointer_events < 0)
-		pointer_events = style->GetProperty(POINTER_EVENTS)->Get< int >();
+		pointer_events = style->GetProperty(PropertyId::PointerEvents)->Get< int >();
 	return pointer_events;
 }
 
 const Property *ElementStyleCache::GetLineHeightProperty()
 {
 	if (!line_height)
-		line_height = style->GetProperty(LINE_HEIGHT);
+		line_height = style->GetProperty(PropertyId::LineHeight);
 	return line_height;
 }
 
 int ElementStyleCache::GetTextAlign()
 {
 	if (text_align < 0)
-		text_align = style->GetProperty(TEXT_ALIGN)->Get< int >();
+		text_align = style->GetProperty(PropertyId::TextAlign)->Get< int >();
 	return text_align;
 }
 
 int ElementStyleCache::GetTextTransform()
 {
 	if (text_transform < 0)
-		text_transform = style->GetProperty(TEXT_TRANSFORM)->Get< int >();
+		text_transform = style->GetProperty(PropertyId::TextTransform)->Get< int >();
 	return text_transform;
 }
 
 const Property *ElementStyleCache::GetVerticalAlignProperty()
 {
 	if (!vertical_align)
-		vertical_align = style->GetProperty(VERTICAL_ALIGN);
+		vertical_align = style->GetProperty(PropertyId::VerticalAlign);
 	return vertical_align;
 }
 

+ 11 - 11
Source/Core/ElementTextDefault.cpp

@@ -286,23 +286,23 @@ void ElementTextDefault::OnPropertyChange(const PropertyIdList& changed_properti
 	bool colour_changed = false;
 	bool font_face_changed = false;
 
-	if (changed_properties.find(COLOR) != changed_properties.end() || 
-		changed_properties.find(OPACITY) != changed_properties.end())
+	if (changed_properties.find(PropertyId::Color) != changed_properties.end() || 
+		changed_properties.find(PropertyId::Opacity) != changed_properties.end())
 	{
 		// Fetch our (potentially) new colour.
-		Colourb new_colour = GetProperty(COLOR)->value.Get< Colourb >();
-		float opacity = GetProperty(OPACITY)->value.Get< float>();
+		Colourb new_colour = GetProperty(PropertyId::Color)->value.Get< Colourb >();
+		float opacity = GetProperty(PropertyId::Opacity)->value.Get< float>();
 		new_colour.alpha = byte(opacity * float(new_colour.alpha));
 		colour_changed = colour != new_colour;
 		if (colour_changed)
 			colour = new_colour;
 	}
 
-	if (changed_properties.find(FONT_FAMILY) != changed_properties.end() ||
-		changed_properties.find(FONT_CHARSET) != changed_properties.end() ||
-		changed_properties.find(FONT_WEIGHT) != changed_properties.end() ||
-		changed_properties.find(FONT_STYLE) != changed_properties.end() ||
-		changed_properties.find(FONT_SIZE) != changed_properties.end())
+	if (changed_properties.find(PropertyId::FontFamily) != changed_properties.end() ||
+		changed_properties.find(PropertyId::FontCharset) != changed_properties.end() ||
+		changed_properties.find(PropertyId::FontWeight) != changed_properties.end() ||
+		changed_properties.find(PropertyId::FontStyle) != changed_properties.end() ||
+		changed_properties.find(PropertyId::FontSize) != changed_properties.end())
 	{
 		font_face_changed = true;
 
@@ -310,9 +310,9 @@ void ElementTextDefault::OnPropertyChange(const PropertyIdList& changed_properti
 		font_dirty = true;
 	}
 
-	if (changed_properties.find(TEXT_DECORATION) != changed_properties.end())
+	if (changed_properties.find(PropertyId::TextDecoration) != changed_properties.end())
 	{
-		decoration_property = GetProperty< int >(TEXT_DECORATION);
+		decoration_property = GetProperty< int >(PropertyId::TextDecoration);
 		if (decoration_property != TEXT_DECORATION_NONE)
 		{
 			if (decoration_property != generated_decoration)

+ 6 - 6
Source/Core/ElementUtilities.cpp

@@ -116,11 +116,11 @@ void ElementUtilities::GetElementsByClassName(ElementList& elements, Element* ro
 FontFaceHandle* ElementUtilities::GetFontFaceHandle(Element* element)
 {
 	// Fetch the new font face.
-	String font_family = element->GetProperty(FONT_FAMILY)->value.Get< String >();
-	String font_charset = element->GetProperty(FONT_CHARSET)->value.Get< String >();
-	Font::Style font_style = (Font::Style) element->GetProperty(FONT_STYLE)->value.Get< int >();
-	Font::Weight font_weight = (Font::Weight) element->GetProperty(FONT_WEIGHT)->value.Get< int >();
-	int font_size = Math::RealToInteger(element->ResolveProperty(FONT_SIZE, 0));
+	String font_family = element->GetProperty(PropertyId::FontFamily)->value.Get< String >();
+	String font_charset = element->GetProperty(PropertyId::FontCharset)->value.Get< String >();
+	Font::Style font_style = (Font::Style) element->GetProperty(PropertyId::FontStyle)->value.Get< int >();
+	Font::Weight font_weight = (Font::Weight) element->GetProperty(PropertyId::FontWeight)->value.Get< int >();
+	int font_size = Math::RealToInteger(element->ResolveProperty(PropertyId::FontSize, 0));
 
 	FontFaceHandle* font = FontDatabase::GetFontFaceHandle(font_family, font_charset, font_style, font_weight, font_size);
 	return font;
@@ -193,7 +193,7 @@ void ElementUtilities::BindEventAttributes(Element* element)
 		{
 			EventListener* listener = Factory::InstanceEventListener(variant.Get<String>(), element);
 			if (listener)
-				element->AddEventListener(name.substr(2), listener, false);
+				element->AddEventListener(GetEventId(name.substr(2)), listener, false);
 		}
 	}
 }

+ 1 - 1
Source/Core/Event.cpp

@@ -34,7 +34,7 @@ namespace Core {
 
 Event::Event()
 {
-	event_id = InvalidEventId;
+	event_id = EventId::Invalid;
 	phase = PHASE_UNKNOWN;
 	interruped = false;
 	interruptible = false;

+ 3 - 3
Source/Core/Factory.cpp

@@ -365,7 +365,7 @@ Decorator* Factory::InstanceDecorator(const String& name, const PropertyDictiona
 		specificity = Math::Max(specificity, value.specificity);
 
 		// Check for the 'z-index' property; we don't want to send this through.
-		if (id == Z_INDEX)
+		if (id == PropertyId::ZIndex)
 			z_index = value.value.Get< float >();
 		else
 			property_specification.ParsePropertyDeclaration(parsed_properties, id, value.value.Get< String >(), value.source, value.source_line_number);
@@ -425,12 +425,12 @@ FontEffect* Factory::InstanceFontEffect(const String& name, const PropertyDictio
 		specificity = Math::Max(specificity, value.specificity);
 
 		// Check for the 'z-index' property; we don't want to send this through.
-		if (id == Z_INDEX)
+		if (id == PropertyId::ZIndex)
 		{
 			set_z_index = true;
 			z_index = value.value.Get< float >();
 		}
-		else if (id == COLOR)
+		else if (id == PropertyId::Color)
 		{
 			static PropertyParserColour colour_parser;
 

+ 6 - 15
Source/Core/FontDatabase.cpp

@@ -190,26 +190,17 @@ FontEffect* FontDatabase::GetFontEffect(const String& name, const PropertyDictio
 	//  * could be shared with decorators as well
 
 	// Generate a key so we can distinguish unique property sets quickly.
-	typedef std::list< std::pair< String, String > > PropertyList;
-	PropertyList sorted_properties;
-	for (PropertyMap::const_iterator property_iterator = properties.GetProperties().begin(); property_iterator != properties.GetProperties().end(); ++property_iterator)
+	typedef std::map< PropertyId, String > SortedPropertyValueList;
+	SortedPropertyValueList sorted_properties;
+	for (const auto& [id, value] : properties)
 	{
-		// Skip the font-effect declaration.
-		if (property_iterator->first == "font-effect")
-			continue;
-
-		PropertyList::iterator insert = sorted_properties.begin();
-		while (insert != sorted_properties.end() &&
-			   insert->first < property_iterator->first)
-		   ++insert;
-
-		sorted_properties.insert(insert, PropertyList::value_type(property_iterator->first, property_iterator->second.Get< String >()));
+		sorted_properties.emplace(id, value.Get<String>());
 	}
 
 	// Generate the font effect's key from the properties.
 	String key = name + ";";
-	for (PropertyList::iterator i = sorted_properties.begin(); i != sorted_properties.end(); ++i)
-		key += i->first + ":" + i->second + ";";
+	for (const auto& [id, value] : sorted_properties)
+		key += GetName(id) + ":" + value + ";";
 
 	// Check if we have a previously instanced effect.
 	FontEffectCache::iterator i = font_effect_cache.find(key);

+ 12 - 5
Source/Core/FontEffectInstancer.cpp

@@ -46,18 +46,25 @@ const PropertySpecification& FontEffectInstancer::GetPropertySpecification() con
 }
 
 // Registers a property for the font effect.
-PropertyDefinition& FontEffectInstancer::RegisterProperty(const String& property_name, const String& default_value, bool affects_generation)
+PropertyDefinition& FontEffectInstancer::RegisterProperty(const String& property_name, const String& default_value, bool affects_generation, PropertyId* out_property_id)
 {
+	PropertyId id = CreateOrGetPropertyId(ToLower(property_name));
+	if (out_property_id)
+		*out_property_id = id;
+
 	if (affects_generation)
-		volatile_properties.insert(ToLower(property_name));
+		volatile_properties.insert(id);
 
-	return properties.RegisterProperty(property_name, default_value, false, false);
+	return properties.RegisterProperty(id, default_value, false, false);
 }
 
 // Registers a shorthand property definition.
-bool FontEffectInstancer::RegisterShorthand(const String& shorthand_name, const String& property_names, PropertySpecification::ShorthandType type)
+bool FontEffectInstancer::RegisterShorthand(const String& shorthand_name, const PropertyIdList& property_ids, PropertySpecification::ShorthandType type, PropertyId* out_property_id)
 {
-	return properties.RegisterShorthand(shorthand_name, property_names, type);
+	PropertyId id = CreateOrGetPropertyId(ToLower(shorthand_name));
+	if (out_property_id)
+		*out_property_id = id;
+	return properties.RegisterShorthand(id, property_ids, type);
 }
 
 // Releases the instancer.

+ 2 - 2
Source/Core/FontEffectOutlineInstancer.cpp

@@ -46,8 +46,8 @@ FontEffectOutlineInstancer::~FontEffectOutlineInstancer()
 FontEffect* FontEffectOutlineInstancer::InstanceFontEffect(const String& ROCKET_UNUSED_PARAMETER(name), const PropertyDictionary& properties)
 {
 	ROCKET_UNUSED(name);
-
-	float width = properties.GetProperty("width")->Get< float >();
+	
+	float width = GetIf(properties, PropertyId::Width)->Get<float>();
 
 	FontEffectOutline* font_effect = new FontEffectOutline();
 	if (font_effect->Initialise(Math::RealToInteger(width)))

+ 6 - 6
Source/Core/FontEffectShadowInstancer.cpp

@@ -32,13 +32,13 @@
 namespace Rocket {
 namespace Core {
 
-FontEffectShadowInstancer::FontEffectShadowInstancer()
+FontEffectShadowInstancer::FontEffectShadowInstancer() : offset_x(PropertyId::Invalid), offset_y(PropertyId::Invalid)
 {
-	RegisterProperty("offset-x", "0", true)
+	RegisterProperty("offset-x", "0", true, &offset_x)
 		.AddParser("length");
-	RegisterProperty("offset-y", "0", true)
+	RegisterProperty("offset-y", "0", true, &offset_y)
 		.AddParser("length");
-	RegisterShorthand("offset", "offset-x, offset-y");
+	RegisterShorthand("offset", { offset_x, offset_y });
 }
 
 FontEffectShadowInstancer::~FontEffectShadowInstancer()
@@ -51,8 +51,8 @@ FontEffect* FontEffectShadowInstancer::InstanceFontEffect(const String& ROCKET_U
 	ROCKET_UNUSED(name);
 
 	Vector2i offset;
-	offset.x = Math::RealToInteger(properties.GetProperty("offset-x")->Get< float >());
-	offset.y = Math::RealToInteger(properties.GetProperty("offset-y")->Get< float >());
+	offset.x = Math::RealToInteger(GetIf(properties, offset_x)->Get< float >());
+	offset.y = Math::RealToInteger(GetIf(properties, offset_y)->Get< float >());
 
 	FontEffectShadow* font_effect = new FontEffectShadow();
 	if (font_effect->Initialise(offset))

+ 3 - 0
Source/Core/FontEffectShadowInstancer.h

@@ -56,6 +56,9 @@ public:
 
 	/// Releases the instancer.
 	virtual void Release();
+
+private:
+	PropertyId offset_x, offset_y;
 };
 
 }

+ 3 - 2
Source/Core/StringCache.cpp → Source/Core/ID.cpp

@@ -36,8 +36,8 @@ namespace Core {
 template <typename ID>
 class IdNameMap {
 
-	static std::vector<String> name_map;  // IDs are indices into the NameMap
-	static UnorderedMap<String, ID> reverse_map;
+	std::vector<String> name_map;  // IDs are indices into the NameMap
+	UnorderedMap<String, ID> reverse_map;
 
 protected:
 	IdNameMap(ID id_num_to_initialize) {
@@ -216,6 +216,7 @@ inline EventIdNameMap::EventIdNameMap() : IdNameMap(EventId::NumDefinedIds)
 	add(EventId::Handledrag, "handledrag");
 	add(EventId::Resize, "resize");
 	add(EventId::Scroll, "scroll");
+	add(EventId::Scrollchange, "scrollchange");
 	add(EventId::Animationend, "animationend");
 	add(EventId::Transitionend, "transitionend");
 

+ 3 - 3
Source/Core/LayoutBlockBox.cpp

@@ -90,7 +90,7 @@ LayoutBlockBox::LayoutBlockBox(LayoutEngine* _layout_engine, LayoutBlockBox* _pa
 			if (self_offset_parent != this)
 			{
 				// Get the next position within our offset parent's containing block.
-				parent->PositionBlockBox(position, box, element->GetProperty< int >(CLEAR));
+				parent->PositionBlockBox(position, box, element->GetProperty< int >(PropertyId::Clear));
 				element->SetOffset(position - (self_offset_parent->GetPosition() - offset_root->GetPosition()), self_offset_parent->GetElement());
 			}
 			else
@@ -544,8 +544,8 @@ float LayoutBlockBox::InternalContentWidth() const
 		if (element)
 		{
 			const Property* width = nullptr;
-			const Property* min_width = element->GetLocalProperty("min-width");
-			const Property* max_width = element->GetLocalProperty("max-width");
+			const Property* min_width = element->GetLocalProperty(PropertyId::MinWidth);
+			const Property* max_width = element->GetLocalProperty(PropertyId::MaxWidth);
 			element->GetLocalDimensionProperties(&width, nullptr);
 			if(width)
 			{

+ 1 - 1
Source/Core/LayoutBlockBoxSpace.cpp

@@ -76,7 +76,7 @@ float LayoutBlockBoxSpace::PositionBox(float cursor, Element* element)
 	}
 
 	// Shift the cursor down past to clear boxes, if necessary.
-	cursor = ClearBoxes(cursor, element->GetProperty< int >(CLEAR));
+	cursor = ClearBoxes(cursor, element->GetProperty< int >(PropertyId::Clear));
 
 	// Find a place to put this box.
 	Vector2f element_offset;

+ 12 - 12
Source/Core/LayoutEngine.cpp

@@ -241,13 +241,13 @@ void LayoutEngine::BuildBox(Box& box, float& min_height, float& max_height, Layo
 	float box_height = box.GetSize().y;
 	if (box_height < 0)
 	{
-		if (element->GetLocalProperty(MIN_HEIGHT) != NULL)
-			min_height = element->ResolveProperty(MIN_HEIGHT, containing_block.y);
+		if (element->GetLocalProperty(PropertyId::MinHeight) != NULL)
+			min_height = element->ResolveProperty(PropertyId::MinHeight, containing_block.y);
 		else
 			min_height = 0;
 
-		if (element->GetLocalProperty(MAX_HEIGHT) != NULL)
-			max_height = element->ResolveProperty(MAX_HEIGHT, containing_block.y);
+		if (element->GetLocalProperty(PropertyId::MaxHeight) != NULL)
+			max_height = element->ResolveProperty(PropertyId::MaxHeight, containing_block.y);
 		else
 			max_height = FLT_MAX;
 	}
@@ -263,13 +263,13 @@ float LayoutEngine::ClampWidth(float width, Element* element, float containing_b
 {
 	float min_width, max_width;
 
-	if (element->GetLocalProperty(MIN_WIDTH) != NULL)
-		min_width = element->ResolveProperty(MIN_WIDTH, containing_block_width);
+	if (element->GetLocalProperty(PropertyId::MinWidth) != NULL)
+		min_width = element->ResolveProperty(PropertyId::MinWidth, containing_block_width);
 	else
 		min_width = 0;
 
-	if (element->GetLocalProperty(MAX_WIDTH) != NULL)
-		max_width = element->ResolveProperty(MAX_WIDTH, containing_block_width);
+	if (element->GetLocalProperty(PropertyId::MaxWidth) != NULL)
+		max_width = element->ResolveProperty(PropertyId::MaxWidth, containing_block_width);
 	else
 		max_width = FLT_MAX;
 
@@ -281,13 +281,13 @@ float LayoutEngine::ClampHeight(float height, Element* element, float containing
 {
 	float min_height, max_height;
 
-	if (element->GetLocalProperty(MIN_HEIGHT) != NULL)
-		min_height = element->ResolveProperty(MIN_HEIGHT, containing_block_height);
+	if (element->GetLocalProperty(PropertyId::MinHeight) != NULL)
+		min_height = element->ResolveProperty(PropertyId::MinHeight, containing_block_height);
 	else
 		min_height = 0;
 
-	if (element->GetLocalProperty(MAX_HEIGHT) != NULL)
-		max_height = element->ResolveProperty(MAX_HEIGHT, containing_block_height);
+	if (element->GetLocalProperty(PropertyId::MaxHeight) != NULL)
+		max_height = element->ResolveProperty(PropertyId::MaxHeight, containing_block_height);
 	else
 		max_height = FLT_MAX;
 

+ 2 - 2
Source/Core/PropertyParserAnimation.cpp

@@ -258,7 +258,7 @@ static bool ParseTransition(Property & property, const StringList& transition_va
 					if (transition_list.transitions.size() > 0) // The all keyword can not be part of multiple definitions
 						return false;
 					transition_list.all = true;
-					target_property_ids.insert(ALL);
+					target_property_ids.insert(PropertyId::All);
 				}
 				else if (it->second.type == Keyword::TWEEN)
 				{
@@ -336,7 +336,7 @@ static bool ParseTransition(Property & property, const StringList& transition_va
 
 		for (const auto& id : target_property_ids)
 		{
-			if (id != InvalidPropertyId)
+			if (id != PropertyId::Invalid)
 			{
 				transition.property_id = id;
 				transition_list.transitions.push_back(transition);

+ 1 - 1
Source/Core/PropertyParserTransform.cpp

@@ -46,7 +46,7 @@ PropertyParserTransform::~PropertyParserTransform()
 // Called to parse a RCSS transform declaration.
 bool PropertyParserTransform::ParseValue(Property& property, const String& value, const ParameterMap& parameters) const
 {
-	if(value == NONE)
+	if(value == "none")
 	{
 		property.value = Variant(TransformRef());
 		property.unit = Property::TRANSFORM;

+ 3 - 0
Source/Core/PropertySpecification.cpp

@@ -164,6 +164,9 @@ const PropertyShorthandDefinition* PropertySpecification::GetShorthand(PropertyI
 // Parses a property declaration, setting any parsed and validated properties on the given dictionary.
 bool PropertySpecification::ParsePropertyDeclaration(PropertyDictionary& dictionary, PropertyId property_id, const String& property_value, const String& source_file, int source_line_number) const
 {
+	if (property_id == PropertyId::Invalid)
+		return false;
+
 	// Attempt to parse as a single property.
 	const PropertyDefinition* property_definition = GetProperty(property_id);
 

+ 12 - 14
Source/Core/StyleSheetParser.cpp

@@ -78,22 +78,18 @@ static void PostprocessKeyframes(KeyframesMap& keyframes_map)
 	{
 		Keyframes& keyframes = keyframes_pair.second;
 		auto& blocks = keyframes.blocks;
-		auto& property_names = keyframes.property_names;
+		auto& property_ids = keyframes.property_ids;
 
 		// Sort keyframes on selector value.
 		std::sort(blocks.begin(), blocks.end(), [](const KeyframeBlock& a, const KeyframeBlock& b) { return a.normalized_time < b.normalized_time; });
 
 		// Add all property names specified by any block
-		if(blocks.size() > 0) property_names.reserve(blocks.size() * blocks[0].properties.GetNumProperties());
+		if(blocks.size() > 0) property_ids.reserve(blocks.size() * blocks[0].properties.size());
 		for(auto& block : blocks)
 		{
-			for (auto& property : block.properties.GetProperties())
-				property_names.push_back(property.first);
+			for (auto& property : block.properties)
+				property_ids.insert(property.first);
 		}
-		// Remove duplicate property names
-		std::sort(property_names.begin(), property_names.end());
-		property_names.erase(std::unique(property_names.begin(), property_names.end()), property_names.end());
-		property_names.shrink_to_fit();
 	}
 
 }
@@ -106,7 +102,7 @@ bool StyleSheetParser::ParseKeyframeBlock(KeyframesMap& keyframes_map, const Str
 		Log::Message(Log::LT_WARNING, "Invalid keyframes identifier '%s' at %s:%d", identifier.c_str(), stream_file_name.c_str(), line_number);
 		return false;
 	}
-	if (properties.GetNumProperties() == 0)
+	if (properties.size() == 0)
 		return true;
 
 	StringList rule_list;
@@ -142,7 +138,7 @@ bool StyleSheetParser::ParseKeyframeBlock(KeyframesMap& keyframes_map, const Str
 		auto it = std::find_if(keyframes.blocks.begin(), keyframes.blocks.end(), [selector](const KeyframeBlock& keyframe_block) { return Math::AbsoluteValue(keyframe_block.normalized_time - selector) < 0.0001f; });
 		if (it == keyframes.blocks.end())
 		{
-			keyframes.blocks.push_back(KeyframeBlock{ selector });
+			keyframes.blocks.emplace_back( selector );
 			it = (keyframes.blocks.end() - 1);
 		}
 		else
@@ -151,7 +147,7 @@ bool StyleSheetParser::ParseKeyframeBlock(KeyframesMap& keyframes_map, const Str
 			it->properties = PropertyDictionary();
 		}
 
-		it->properties.Import(properties);
+		Import(it->properties, properties);
 	}
 
 	return true;
@@ -209,10 +205,11 @@ int StyleSheetParser::Parse(StyleSheetNode* node, KeyframesMap& keyframes, Strea
 			{
 				if (token == '{')
 				{
+					static const String& keyframes_str = GetName(PropertyId::Keyframes);
 					keyframes_identifier.clear();
-					if (pre_token_str.substr(0, KEYFRAMES.size()) == KEYFRAMES)
+					if (pre_token_str.substr(0, keyframes_str.size()) == keyframes_str)
 					{
-						keyframes_identifier = StringUtilities::StripWhitespace(pre_token_str.substr(KEYFRAMES.size()));
+						keyframes_identifier = StringUtilities::StripWhitespace(pre_token_str.substr(keyframes_str.size()));
 					}
 					state = State::KeyframesRules;
 				}
@@ -325,8 +322,9 @@ bool StyleSheetParser::ReadProperties(PropertyDictionary& properties)
 				if (character == ';')
 				{
 					value = StringUtilities::StripWhitespace(value);
+					PropertyId id = GetPropertyId(name);
 
-					if (!StyleSheetSpecification::ParsePropertyDeclaration(properties, name, value, stream_file_name, rule_line_number))
+					if (!StyleSheetSpecification::ParsePropertyDeclaration(properties, id, value, stream_file_name, rule_line_number))
 						Log::Message(Log::LT_WARNING, "Syntax error parsing property declaration '%s: %s;' in %s: %d.", name.c_str(), value.c_str(), stream_file_name.c_str(), line_number);
 
 					name.clear();

+ 1 - 1
Source/Core/StyleSheetSpecification.cpp

@@ -268,7 +268,7 @@ void StyleSheetSpecification::RegisterDefaultProperties()
 	RegisterProperty(Id::Cursor, "auto", true, false).AddParser("keyword", "auto").AddParser("string");
 
 	// Functional property specifications.
-	RegisterProperty(Id::DragProperty, "none", false, false).AddParser("keyword", "none, drag, drag-drop, block, clone");
+	RegisterProperty(Id::Drag, "none", false, false).AddParser("keyword", "none, drag, drag-drop, block, clone");
 	RegisterProperty(Id::TabIndex, "none", false, false).AddParser("keyword", "none, auto");
 	RegisterProperty(Id::Focus, "auto", true, false).AddParser("keyword", "none, auto");
 	RegisterProperty(Id::ScrollbarMargin, "0", false, false).AddParser("length");

+ 1 - 1
Source/Core/Transform.cpp

@@ -48,7 +48,7 @@ Transform::Transform(std::vector<Transforms::Primitive> primitives)
 Property Transform::MakeProperty(std::vector<Transforms::Primitive> primitives)
 {
 	Property p{ TransformRef{new Transform{primitives}}, Property::TRANSFORM };
-	p.definition = StyleSheetSpecification::GetProperty(TRANSFORM);
+	p.definition = StyleSheetSpecification::GetProperty(PropertyId::Transform);
 	return p;
 }
 

+ 24 - 24
Source/Core/WidgetSlider.cpp

@@ -63,20 +63,20 @@ WidgetSlider::~WidgetSlider()
 {
 	if (bar != NULL)
 	{
-		bar->RemoveEventListener(DRAG, this);
-		bar->RemoveEventListener(DRAGSTART, this);
+		bar->RemoveEventListener(EventId::Drag, this);
+		bar->RemoveEventListener(EventId::Dragstart, this);
 	}
 
 	if (track != NULL)
-		track->RemoveEventListener(CLICK, this);
+		track->RemoveEventListener(EventId::Click, this);
 
 	for (int i = 0; i < 2; i++)
 	{
 		if (arrows[i] != NULL)
 		{
-			arrows[i]->RemoveEventListener(MOUSEDOWN, this);
-			arrows[i]->RemoveEventListener(MOUSEUP, this);
-			arrows[i]->RemoveEventListener(MOUSEOUT, this);
+			arrows[i]->RemoveEventListener(EventId::Mousedown, this);
+			arrows[i]->RemoveEventListener(EventId::Mouseup, this);
+			arrows[i]->RemoveEventListener(EventId::Mouseout, this);
 		}
 	}
 }
@@ -105,7 +105,7 @@ bool WidgetSlider::Initialise(Orientation _orientation)
 	track = Factory::InstanceElement(parent, "*", "slidertrack", XMLAttributes());
 
 	bar = Factory::InstanceElement(parent, "*", "sliderbar", XMLAttributes());
-	bar->SetProperty(DRAG, DRAG);
+	bar->SetProperty(PropertyId::Drag, GetName(PropertyId::Drag));
 
 	arrows[0] = Factory::InstanceElement(parent, "*", "sliderarrowdec", XMLAttributes());
 	arrows[1] = Factory::InstanceElement(parent, "*", "sliderarrowinc", XMLAttributes());
@@ -143,16 +143,16 @@ bool WidgetSlider::Initialise(Orientation _orientation)
 	arrows[1]->RemoveReference();
 
 	// Attach the listeners as appropriate.
-	bar->AddEventListener(DRAG, this);
-	bar->AddEventListener(DRAGSTART, this);
+	bar->AddEventListener(EventId::Drag, this);
+	bar->AddEventListener(EventId::Dragstart, this);
 
-	track->AddEventListener(CLICK, this);
+	track->AddEventListener(EventId::Click, this);
 
 	for (int i = 0; i < 2; i++)
 	{
-		arrows[i]->AddEventListener(MOUSEDOWN, this);
-		arrows[i]->AddEventListener(MOUSEUP, this);
-		arrows[i]->AddEventListener(MOUSEOUT, this);
+		arrows[i]->AddEventListener(EventId::Mousedown, this);
+		arrows[i]->AddEventListener(EventId::Mouseup, this);
+		arrows[i]->AddEventListener(EventId::Mouseout, this);
 	}
 
 	return true;
@@ -193,7 +193,7 @@ void WidgetSlider::SetBarPosition(float _bar_position)
 
 	Dictionary parameters;
 	parameters.emplace("value", bar_position);
-	parent->DispatchEvent("scrollchange", parameters);
+	parent->DispatchEvent(EventId::Scrollchange, parameters);
 }
 
 // Returns the current position of the bar.
@@ -332,11 +332,11 @@ void WidgetSlider::FormatBar(float bar_length)
 				bar_box_content.y = track_length * bar_length;
 
 				// Check for 'min-height' restrictions.
-				float min_track_length = bar->ResolveProperty(MIN_HEIGHT, track_length);
+				float min_track_length = bar->ResolveProperty(PropertyId::MinHeight, track_length);
 				bar_box_content.y = Math::Max(min_track_length, bar_box_content.y);
 
 				// Check for 'max-height' restrictions.
-				float max_track_length = bar->ResolveProperty(MAX_HEIGHT, track_length);
+				float max_track_length = bar->ResolveProperty(PropertyId::MaxHeight, track_length);
 				if (max_track_length > 0)
 					bar_box_content.y = Math::Min(max_track_length, bar_box_content.y);
 			}
@@ -353,11 +353,11 @@ void WidgetSlider::FormatBar(float bar_length)
 				bar_box_content.x = track_length * bar_length;
 
 				// Check for 'min-width' restrictions.
-				float min_track_length = bar->ResolveProperty(MIN_WIDTH, track_length);
+				float min_track_length = bar->ResolveProperty(PropertyId::MinWidth, track_length);
 				bar_box_content.x = Math::Max(min_track_length, bar_box_content.x);
 
 				// Check for 'max-width' restrictions.
-				float max_track_length = bar->ResolveProperty(MAX_WIDTH, track_length);
+				float max_track_length = bar->ResolveProperty(PropertyId::MaxWidth, track_length);
 				if (max_track_length > 0)
 					bar_box_content.x = Math::Min(max_track_length, bar_box_content.x);
 			}
@@ -386,7 +386,7 @@ void WidgetSlider::ProcessEvent(Event& event)
 {
 	if (event.GetTargetElement() == bar)
 	{
-		if (event == DRAG)
+		if (event == EventId::Drag)
 		{
 			if (orientation == HORIZONTAL)
 			{
@@ -413,7 +413,7 @@ void WidgetSlider::ProcessEvent(Event& event)
 				}
 			}
 		}
-		else if (event == DRAGSTART)
+		else if (event == EventId::Dragstart)
 		{
 			if (orientation == HORIZONTAL)
 				bar_drag_anchor = event.GetParameter< int >("mouse_x", 0) - Math::RealToInteger(bar->GetAbsoluteOffset().x);
@@ -423,7 +423,7 @@ void WidgetSlider::ProcessEvent(Event& event)
 	}
 	else if (event.GetTargetElement() == track)
 	{
-		if (event == CLICK)
+		if (event == EventId::Click)
 		{
 			if (orientation == HORIZONTAL)
 			{
@@ -442,7 +442,7 @@ void WidgetSlider::ProcessEvent(Event& event)
 		}
 	}
 
-	if (event == MOUSEDOWN)
+	if (event == EventId::Mousedown)
 	{
 		if (event.GetTargetElement() == arrows[0])
 		{
@@ -457,8 +457,8 @@ void WidgetSlider::ProcessEvent(Event& event)
 			SetBarPosition(OnLineIncrement());
 		}
 	}
-	else if (event == MOUSEUP ||
-			 event == MOUSEOUT)
+	else if (event == EventId::Mouseup ||
+			 event == EventId::Mouseout)
 	{
 		if (event.GetTargetElement() == arrows[0])
 			arrow_timers[0] = -1;

+ 8 - 7
Source/Debugger/ElementInfo.cpp

@@ -135,15 +135,15 @@ void ElementInfo::ProcessEvent(Core::Event& event)
 				{
 					Core::Element* panel = target_element->GetNextSibling();
 					if (panel->IsVisible())
-						panel->SetProperty("display", "none");
+						panel->SetProperty(Core::PropertyId::Display, "none");
 					else
-						panel->SetProperty("display", "block");
+						panel->SetProperty(Core::PropertyId::Display, "block");
 					event.StopPropagation();
 				}
 				else if (event.GetTargetElement()->GetId() == "close_button")
 				{
 					if (IsVisible())
-						SetProperty("visibility", "hidden");
+						SetProperty(Core::PropertyId::Visibility, "hidden");
 				}
 				// Check if the id is in the form "a %d" or "c %d" - these are the ancestor or child labels.
 				else
@@ -275,7 +275,7 @@ void ElementInfo::UpdateSourceElement()
 					{
 						for (auto nvp : *local_properties)
 						{
-							auto& prop_name = nvp.first;
+							auto& prop_name = Core::GetName(nvp.first);
 							auto prop_value = nvp.second.ToString();
 							value += Core::CreateString(prop_name.size() + prop_value.size() + 12, "%s: %s; ", prop_name.c_str(), prop_value.c_str());
 						}
@@ -440,16 +440,17 @@ void ElementInfo::BuildElementPropertiesRML(Core::String& property_rml, Core::El
 	NamedPropertyMap property_map;
 
 	int property_index = 0;
-	Core::String property_name;
+	Core::PropertyId property_id;
 	Core::PseudoClassList property_pseudo_classes;
 	const Core::Property* property;
 
-	while (element->IterateProperties(property_index, property_pseudo_classes, property_name, property))
+	while (element->IterateProperties(property_index, property_pseudo_classes, property_id, property))
 	{
 		// Check that this property isn't overridden or just not inherited.
-		if (primary_element->GetProperty(property_name) != property)
+		if (primary_element->GetProperty(property_id) != property)
 			continue;
 
+		const Core::String& property_name = Core::GetName(property_id);
 		NamedPropertyMap::iterator i = property_map.find(property_pseudo_classes);
 		if (i == property_map.end())
 			property_map[property_pseudo_classes] = NamedPropertyList(1, NamedProperty(property_name, property));

+ 7 - 7
Source/Debugger/ElementLog.cpp

@@ -88,7 +88,7 @@ bool ElementLog::Initialise()
 	message_content = GetElementById("content");
 	if (message_content)
 	{
-		message_content->AddEventListener("resize", this);
+		message_content->AddEventListener(Core::EventId::Resize, this);
 	}
 
 	Core::StyleSheet* style_sheet = Core::Factory::InstanceStyleSheetString(Core::String(common_rcss) + Core::String(log_rcss));
@@ -104,7 +104,7 @@ bool ElementLog::Initialise()
 		return false;
 
 	beacon->SetId("rkt-debug-log-beacon");
-	beacon->SetProperty("visibility", "hidden");
+	beacon->SetProperty(Core::PropertyId::Visibility, "hidden");
 	beacon->SetInnerRML(beacon_rml);
 
 	// Remove the initial reference on the beacon.
@@ -112,7 +112,7 @@ bool ElementLog::Initialise()
 
 	Core::Element* button = beacon->GetFirstChild();
 	if (button != NULL)
-		beacon->GetFirstChild()->AddEventListener("click", this);
+		beacon->GetFirstChild()->AddEventListener(Core::EventId::Click, this);
 
 	style_sheet = Core::Factory::InstanceStyleSheetString(Core::String(common_rcss) + Core::String(beacon_rcss));
 	if (style_sheet == NULL)
@@ -164,7 +164,7 @@ void ElementLog::AddLogMessage(Core::Log::Type type, const Core::String& message
 			{
 				if (type < current_beacon_level)
 				{
-					beacon->SetProperty("visibility", "visible");
+					beacon->SetProperty(Core::PropertyId::Visibility, "visible");
 
 					current_beacon_level = type;
 					Rocket::Core::Element* beacon_button = beacon->GetFirstChild();
@@ -235,15 +235,15 @@ void ElementLog::ProcessEvent(Core::Event& event)
 			if (event.GetTargetElement() == beacon->GetFirstChild())
 			{
 				if (!IsVisible())
-					SetProperty("visibility", "visible");
+					SetProperty(Core::PropertyId::Visibility, "visible");
 
-				beacon->SetProperty("visibility", "hidden");
+				beacon->SetProperty(Core::PropertyId::Visibility, "hidden");
 				current_beacon_level = Core::Log::LT_MAX;
 			}
 			else if (event.GetTargetElement()->GetId() == "close_button")
 			{
 				if (IsVisible())
-					SetProperty("visibility", "hidden");
+					SetProperty(Core::PropertyId::Visibility, "hidden");
 			}
 			else
 			{

+ 16 - 16
Source/Debugger/Plugin.cpp

@@ -122,14 +122,14 @@ bool Plugin::SetContext(Core::Context* context)
 	{
 		if (debug_context != NULL)
 		{
-			debug_context->RemoveEventListener("click", info_element, true);
-			debug_context->RemoveEventListener("mouseover", info_element, true);
+			debug_context->RemoveEventListener(Core::EventId::Click, info_element, true);
+			debug_context->RemoveEventListener(Core::EventId::Mouseover, info_element, true);
 		}
 
 		if (context != NULL)
 		{
-			context->AddEventListener("click", info_element, true);
-			context->AddEventListener("mouseover", info_element, true);
+			context->AddEventListener(Core::EventId::Click, info_element, true);
+			context->AddEventListener(Core::EventId::Mouseover, info_element, true);
 		}
 
 		info_element->Reset();
@@ -143,9 +143,9 @@ bool Plugin::SetContext(Core::Context* context)
 void Plugin::SetVisible(bool visibility)
 {
 	if (visibility)
-		menu_element->SetProperty("visibility", "visible");
+		menu_element->SetProperty(Core::PropertyId::Visibility, "visible");
 	else
-		menu_element->SetProperty("visibility", "hidden");
+		menu_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 }
 
 // Returns the visibility of the debugger.
@@ -261,16 +261,16 @@ void Plugin::ProcessEvent(Core::Event& event)
 		if (event.GetTargetElement()->GetId() == "event-log-button")
 		{
 			if (log_element->IsVisible())
-				log_element->SetProperty("visibility", "hidden");
+				log_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 			else
-				log_element->SetProperty("visibility", "visible");
+				log_element->SetProperty(Core::PropertyId::Visibility, "visible");
 		}
 		else if (event.GetTargetElement()->GetId() == "debug-info-button")
 		{
 			if (info_element->IsVisible())
-				info_element->SetProperty("visibility", "hidden");
+				info_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 			else
-				info_element->SetProperty("visibility", "visible");
+				info_element->SetProperty(Core::PropertyId::Visibility, "visible");
 		}
 		else if (event.GetTargetElement()->GetId() == "outlines-button")
 		{
@@ -297,7 +297,7 @@ bool Plugin::LoadMenuElement()
 		return false;
 
 	menu_element->SetId("rkt-debug-menu");
-	menu_element->SetProperty("visibility", "hidden");
+	menu_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 	menu_element->SetInnerRML(menu_rml);
 
 	// Remove our reference on the document.
@@ -321,13 +321,13 @@ bool Plugin::LoadMenuElement()
 
 	// Attach to the buttons.
 	Core::Element* event_log_button = menu_element->GetElementById("event-log-button");
-	event_log_button->AddEventListener("click", this);
+	event_log_button->AddEventListener(Core::EventId::Click, this);
 
 	Core::Element* element_info_button = menu_element->GetElementById("debug-info-button");
-	element_info_button->AddEventListener("click", this);
+	element_info_button->AddEventListener(Core::EventId::Click, this);
 
 	Core::Element* outlines_button = menu_element->GetElementById("outlines-button");
-	outlines_button->AddEventListener("click", this);
+	outlines_button->AddEventListener(Core::EventId::Click, this);
 
 	return true;
 }
@@ -339,7 +339,7 @@ bool Plugin::LoadInfoElement()
 	if (info_element == NULL)
 		return false;
 
-	info_element->SetProperty("visibility", "hidden");
+	info_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 
 	if (!info_element->Initialise())
 	{
@@ -360,7 +360,7 @@ bool Plugin::LoadLogElement()
 	if (log_element == NULL)
 		return false;
 
-	log_element->SetProperty("visibility", "hidden");
+	log_element->SetProperty(Core::PropertyId::Visibility, "hidden");
 
 	if (!log_element->Initialise())
 	{