Browse Source

Reordered UIElement's attributes, common attributes got registered first. Enhanced Attribute Inspector to show UIElement's attributes for single selection case. Multiple selection is still WIP.

Wei Tjong Yao 12 years ago
parent
commit
a76a3b1ab7

+ 127 - 85
Bin/Data/Scripts/Editor/EditorNodeWindow.as

@@ -3,7 +3,6 @@
 
 
 Window@ attributeInspectorWindow;
 Window@ attributeInspectorWindow;
 UIElement@ parentContainer;
 UIElement@ parentContainer;
-UIElement@ nodeContainer;
 XMLFile@ nodeXMLResource;
 XMLFile@ nodeXMLResource;
 XMLFile@ componentXMLResource;
 XMLFile@ componentXMLResource;
 
 
@@ -14,31 +13,16 @@ const String STRIKED_OUT = "——";   // Two unicode EM DASH (U+2014)
 const ShortStringHash NODE_IDS_VAR("NodeIDs");
 const ShortStringHash NODE_IDS_VAR("NodeIDs");
 const ShortStringHash COMPONENT_IDS_VAR("ComponentIDs");
 const ShortStringHash COMPONENT_IDS_VAR("ComponentIDs");
 
 
+uint nodeContainerIndex = M_MAX_UNSIGNED;
 uint componentContainerStartIndex = 0;
 uint componentContainerStartIndex = 0;
-
-void AddNodeContainer()
-{
-    if (nodeContainer !is null)
-        return;
-
-    uint index = parentContainer.numChildren;
-    parentContainer.LoadXML(nodeXMLResource, uiStyle);
-    nodeContainer = GetContainer(index);
-    SubscribeToEvent(nodeContainer.GetChild("NewVarDropDown", true), "ItemSelected", "CreateNewVariable");
-    SubscribeToEvent(nodeContainer.GetChild("DeleteVarButton", true), "Released", "DeleteVariable");
-    ++componentContainerStartIndex;
-}
-
-void AddComponentContainer()
-{
-    parentContainer.LoadXML(componentXMLResource, uiStyle);
-}
+uint elementContainerIndex = M_MAX_UNSIGNED;
 
 
 void DeleteAllContainers()
 void DeleteAllContainers()
 {
 {
     parentContainer.RemoveAllChildren();
     parentContainer.RemoveAllChildren();
-    nodeContainer = null;
+    nodeContainerIndex = M_MAX_UNSIGNED;
     componentContainerStartIndex = 0;
     componentContainerStartIndex = 0;
+    elementContainerIndex = M_MAX_UNSIGNED;
 }
 }
 
 
 UIElement@ GetContainer(uint index)
 UIElement@ GetContainer(uint index)
@@ -46,11 +30,40 @@ UIElement@ GetContainer(uint index)
     return parentContainer.children[index];
     return parentContainer.children[index];
 }
 }
 
 
+UIElement@ GetNodeContainer()
+{
+    if (nodeContainerIndex != M_MAX_UNSIGNED)
+        return GetContainer(nodeContainerIndex);
+
+    nodeContainerIndex = parentContainer.numChildren;
+    parentContainer.LoadXML(nodeXMLResource, uiStyle);
+    UIElement@ container = GetContainer(nodeContainerIndex);
+    SubscribeToEvent(container.GetChild("NewVarDropDown", true), "ItemSelected", "CreateNewVariable");
+    SubscribeToEvent(container.GetChild("DeleteVarButton", true), "Released", "DeleteVariable");
+    ++componentContainerStartIndex;
+    return container;
+}
+
 UIElement@ GetComponentContainer(uint index)
 UIElement@ GetComponentContainer(uint index)
 {
 {
+    for (uint i = parentContainer.numChildren - componentContainerStartIndex; i <= index; ++i)
+        parentContainer.LoadXML(componentXMLResource, uiStyle);
     return parentContainer.children[componentContainerStartIndex + index];
     return parentContainer.children[componentContainerStartIndex + index];
 }
 }
 
 
+UIElement@ GetElementContainer()
+{
+    if (elementContainerIndex != M_MAX_UNSIGNED)
+        return GetContainer(elementContainerIndex);
+
+    elementContainerIndex = parentContainer.numChildren;
+    parentContainer.LoadXML(nodeXMLResource, uiStyle);
+    UIElement@ container = GetContainer(elementContainerIndex);
+    SubscribeToEvent(container.GetChild("NewVarDropDown", true), "ItemSelected", "CreateNewVariable");
+    SubscribeToEvent(container.GetChild("DeleteVarButton", true), "Released", "DeleteVariable");
+    return container;
+}
+
 void CreateAttributeInspectorWindow()
 void CreateAttributeInspectorWindow()
 {
 {
     if (attributeInspectorWindow !is null)
     if (attributeInspectorWindow !is null)
@@ -69,7 +82,6 @@ void CreateAttributeInspectorWindow()
     attributeInspectorWindow.SetPosition(ui.root.width - 20 - attributeInspectorWindow.width, 40);
     attributeInspectorWindow.SetPosition(ui.root.width - 20 - attributeInspectorWindow.width, 40);
     attributeInspectorWindow.opacity = uiMaxOpacity;
     attributeInspectorWindow.opacity = uiMaxOpacity;
     attributeInspectorWindow.BringToFront();
     attributeInspectorWindow.BringToFront();
-    UpdateAttributeInspector();
 
 
     SubscribeToEvent(attributeInspectorWindow.GetChild("CloseButton", true), "Released", "HideAttributeInspectorWindow");
     SubscribeToEvent(attributeInspectorWindow.GetChild("CloseButton", true), "Released", "HideAttributeInspectorWindow");
     SubscribeToEvent(attributeInspectorWindow, "LayoutUpdated", "HandleWindowLayoutUpdated");
     SubscribeToEvent(attributeInspectorWindow, "LayoutUpdated", "HandleWindowLayoutUpdated");
@@ -92,6 +104,8 @@ void HandleWindowLayoutUpdated()
     for (uint i = 0; i < parentContainer.numChildren; ++i)
     for (uint i = 0; i < parentContainer.numChildren; ++i)
     {
     {
         ListView@ list = GetContainer(i).GetChild("AttributeList");
         ListView@ list = GetContainer(i).GetChild("AttributeList");
+        if (list is null)
+            continue;
 
 
         // At the moment, only 'Is Enabled' container (place-holder + check box) is being created as child of the list view instead of as list item
         // At the moment, only 'Is Enabled' container (place-holder + check box) is being created as child of the list view instead of as list item
         // When window resize and so the list's width is changed, adjust the 'Is enabled' container width so that check box stays at the right most position
         // When window resize and so the list's width is changed, adjust the 'Is enabled' container width so that check box stays at the right most position
@@ -119,57 +133,46 @@ void UpdateAttributeInspector(bool fullUpdate = true)
 
 
     // If full update delete all containers and added them back as necessary
     // If full update delete all containers and added them back as necessary
     if (fullUpdate)
     if (fullUpdate)
-    {
         DeleteAllContainers();
         DeleteAllContainers();
-        AddNodeContainer();
-        AddComponentContainer();
-    }
 
 
-    Text@ nodeTitle = nodeContainer.GetChild("TitleText");
-    String nodeType;
-    if (editNodes.length == 0)
-        nodeTitle.text = "No node";
-    else if (editNode !is null)
-    {
-        String idStr;
-        if (editNode.id >= FIRST_LOCAL_ID)
-            idStr = " Local ID " + String(editNode.id - FIRST_LOCAL_ID);
-        else
-            idStr = " ID " + String(editNode.id);
-        nodeType = editNode.typeName;
-        nodeTitle.text = nodeType + idStr;
-    }
-    else
+    if (!editNodes.empty)
     {
     {
-        nodeType = editNodes[0].typeName;
-        nodeTitle.text = nodeType + " ID " + STRIKED_OUT + " (" + editNodes.length + "x)";
-    }
-    IconizeUIElement(nodeTitle, nodeType);
-
-    ListView@ list = nodeContainer.GetChild("AttributeList");
-    UpdateAttributes(ToSerializableArray(editNodes), list, fullUpdate);
+        UIElement@ container = GetNodeContainer();
 
 
-    if (fullUpdate)
-    {
-        //\TODO Avoid hardcoding
-        // Resize the node editor according to the number of variables, up to a certain maximum
-        uint maxAttrs = Clamp(list.contentElement.numChildren, MIN_NODE_ATTRIBUTES, MAX_NODE_ATTRIBUTES);
-        list.SetFixedHeight(maxAttrs * ATTR_HEIGHT + 2);
-        nodeContainer.SetFixedHeight(maxAttrs * ATTR_HEIGHT + 60);
-    }
+        Text@ nodeTitle = container.GetChild("TitleText");
+        String nodeType;
 
 
-    if (editComponents.empty)
-    {
-        Text@ componentTitle = GetComponentContainer(0).GetChild("TitleText");
-        if (selectedComponents.length <= 1)
-            componentTitle.text = "No component";
+        if (editNode !is null)
+        {
+            String idStr;
+            if (editNode.id >= FIRST_LOCAL_ID)
+                idStr = " Local ID " + String(editNode.id - FIRST_LOCAL_ID);
+            else
+                idStr = " ID " + String(editNode.id);
+            nodeType = editNode.typeName;
+            nodeTitle.text = nodeType + idStr;
+        }
         else
         else
-            componentTitle.text = selectedComponents.length + " components";
+        {
+            nodeType = editNodes[0].typeName;
+            nodeTitle.text = nodeType + " ID " + STRIKED_OUT + " (" + editNodes.length + "x)";
+        }
+        IconizeUIElement(nodeTitle, nodeType);
+
+        ListView@ list = container.GetChild("AttributeList");
+        UpdateAttributes(ToSerializableArray(editNodes), list, fullUpdate);
 
 
-        // Ensure there is no icon
-        IconizeUIElement(componentTitle, "");
+        if (fullUpdate)
+        {
+            //\TODO Avoid hardcoding
+            // Resize the node editor according to the number of variables, up to a certain maximum
+            uint maxAttrs = Clamp(list.contentElement.numChildren, MIN_NODE_ATTRIBUTES, MAX_NODE_ATTRIBUTES);
+            list.SetFixedHeight(maxAttrs * ATTR_HEIGHT + 2);
+            container.SetFixedHeight(maxAttrs * ATTR_HEIGHT + 60);
+        }
     }
     }
-    else
+
+    if (!editComponents.empty)
     {
     {
         uint numEditableComponents = editComponents.length / numEditableComponentsPerNode;
         uint numEditableComponents = editComponents.length / numEditableComponentsPerNode;
         String multiplierText;
         String multiplierText;
@@ -178,9 +181,6 @@ void UpdateAttributeInspector(bool fullUpdate = true)
 
 
         for (uint j = 0; j < numEditableComponentsPerNode; ++j)
         for (uint j = 0; j < numEditableComponentsPerNode; ++j)
         {
         {
-            if (j >= parentContainer.numChildren - componentContainerStartIndex)
-                AddComponentContainer();
-
             Text@ componentTitle = GetComponentContainer(j).GetChild("TitleText");
             Text@ componentTitle = GetComponentContainer(j).GetChild("TitleText");
             componentTitle.text = GetComponentTitle(editComponents[j * numEditableComponents]) + multiplierText;
             componentTitle.text = GetComponentTitle(editComponents[j * numEditableComponents]) + multiplierText;
             IconizeUIElement(componentTitle, editComponents[j * numEditableComponents].typeName);
             IconizeUIElement(componentTitle, editComponents[j * numEditableComponents].typeName);
@@ -194,33 +194,65 @@ void UpdateAttributeInspector(bool fullUpdate = true)
         }
         }
     }
     }
 
 
-    UpdateAttributeInspectorIcons();
+    if (!editUIElements.empty)
+    {
+        UIElement@ container = GetElementContainer();
+
+        Text@ titleText = container.GetChild("TitleText");
+        String elementType;
+
+        if (editUIElement !is null)
+        {
+            elementType = editUIElement.typeName;
+            titleText.text = elementType + " ID " + String(editUIElement.GetVar(UI_ELEMENT_ID_VAR).GetUInt());
+        }
+        else
+        {
+            elementType = editUIElements[0].typeName;
+            titleText.text = elementType + " ID " + STRIKED_OUT + " (" + editUIElements.length + "x)";
+        }
+        IconizeUIElement(titleText, elementType);
+
+        UpdateAttributes(editUIElements, container.GetChild("AttributeList"), fullUpdate);
+    }
+
+    if (parentContainer.numChildren > 0)
+        UpdateAttributeInspectorIcons();
+    else
+    {
+        // No editables, insert a dummy component container to show the information
+        Text@ titleText = GetComponentContainer(0).GetChild("TitleText");
+        titleText.text = "Select editable objects";
+    }
 }
 }
 
 
 void UpdateNodeAttributes()
 void UpdateNodeAttributes()
 {
 {
-    UpdateAttributes(ToSerializableArray(editNodes), nodeContainer.GetChild("AttributeList"), false);
+    UpdateAttributes(ToSerializableArray(editNodes), GetNodeContainer().GetChild("AttributeList"), false);
 }
 }
 
 
 void UpdateAttributeInspectorIcons()
 void UpdateAttributeInspectorIcons()
 {
 {
-    Text@ nodeTitle = nodeContainer.GetChild("TitleText");
-    if (editNode !is null)
-        SetIconEnabledColor(nodeTitle, editNode.enabled);
-    else if (editNodes.length > 0)
+    if (!editNodes.empty)
     {
     {
-        bool hasSameEnabledState = true;
-
-        for (uint i = 1; i < editNodes.length; ++i)
+        Text@ nodeTitle = GetNodeContainer().GetChild("TitleText");
+        if (editNode !is null)
+            SetIconEnabledColor(nodeTitle, editNode.enabled);
+        else if (editNodes.length > 0)
         {
         {
-            if (editNodes[i].enabled != editNodes[0].enabled)
+            bool hasSameEnabledState = true;
+
+            for (uint i = 1; i < editNodes.length; ++i)
             {
             {
-                hasSameEnabledState = false;
-                break;
+                if (editNodes[i].enabled != editNodes[0].enabled)
+                {
+                    hasSameEnabledState = false;
+                    break;
+                }
             }
             }
-        }
 
 
-        SetIconEnabledColor(nodeTitle, editNodes[0].enabled, !hasSameEnabledState);
+            SetIconEnabledColor(nodeTitle, editNodes[0].enabled, !hasSameEnabledState);
+        }
     }
     }
 
 
     if (!editComponents.empty)
     if (!editComponents.empty)
@@ -265,7 +297,7 @@ void PostEditAttribute(Array<Serializable@>@ serializables, uint index)
 
 
 void SetAttributeEditorID(UIElement@ attrEdit, Array<Serializable@>@ serializables)
 void SetAttributeEditorID(UIElement@ attrEdit, Array<Serializable@>@ serializables)
 {
 {
-    // All target serializables must be either nodes or components, so can check the first for the type
+    // All target serializables must be either nodes, ui-elements, or components
     Node@ node = cast<Node>(serializables[0]);
     Node@ node = cast<Node>(serializables[0]);
     Array<Variant> ids;
     Array<Variant> ids;
     if (node !is null)
     if (node !is null)
@@ -276,9 +308,19 @@ void SetAttributeEditorID(UIElement@ attrEdit, Array<Serializable@>@ serializabl
     }
     }
     else
     else
     {
     {
-        for (uint i = 0; i < serializables.length; ++i)
-            ids.Push(Variant(cast<Component>(serializables[i]).id));
-        attrEdit.vars[COMPONENT_IDS_VAR] = ids;
+        Component@ component = cast<Component>(serializables[0]);
+        if (component !is null)
+        {
+            for (uint i = 0; i < serializables.length; ++i)
+                ids.Push(Variant(cast<Component>(serializables[i]).id));
+            attrEdit.vars[COMPONENT_IDS_VAR] = ids;
+        }
+        else
+        {
+            for (uint i = 0; i < serializables.length; ++i)
+                ids.Push(cast<UIElement>(serializables[i]).GetVar(UI_ELEMENT_ID_VAR));
+            attrEdit.vars[COMPONENT_IDS_VAR] = ids;
+        }
     }
     }
 }
 }
 
 

+ 8 - 10
Bin/Data/Scripts/Editor/EditorScene.as

@@ -77,14 +77,13 @@ bool ResetScene()
 
 
     UpdateWindowTitle();
     UpdateWindowTitle();
     UpdateHierarchyItem(editorScene, true);
     UpdateHierarchyItem(editorScene, true);
-    UpdateAttributeInspector();
     ClearEditActions();
     ClearEditActions();
 
 
     suppressSceneChanges = false;
     suppressSceneChanges = false;
 
 
     ResetCamera();
     ResetCamera();
     CreateGizmo();
     CreateGizmo();
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -150,7 +149,6 @@ bool LoadScene(const String&in fileName)
 
 
     UpdateWindowTitle();
     UpdateWindowTitle();
     UpdateHierarchyItem(editorScene, true);
     UpdateHierarchyItem(editorScene, true);
-    UpdateAttributeInspector();
     ClearEditActions();
     ClearEditActions();
 
 
     suppressSceneChanges = false;
     suppressSceneChanges = false;
@@ -182,7 +180,7 @@ bool SaveScene(const String&in fileName)
 
 
     sceneModified = false;
     sceneModified = false;
     UpdateWindowTitle();
     UpdateWindowTitle();
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -450,7 +448,7 @@ bool ScenePaste()
             Node@ newNode = editorScene.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
             Node@ newNode = editorScene.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
             newNode.LoadXML(rootElem);
             newNode.LoadXML(rootElem);
             newNode.ApplyAttributes();
             newNode.ApplyAttributes();
-            
+
             // Create an undo action for the paste
             // Create an undo action for the paste
             CreateNodeAction action;
             CreateNodeAction action;
             action.Define(newNode);
             action.Define(newNode);
@@ -519,7 +517,7 @@ bool SceneToggleEnable()
         if (selectedComponents[i].numAttributes > 0 && selectedComponents[i].attributeInfos[0].name == "Is Enabled")
         if (selectedComponents[i].numAttributes > 0 && selectedComponents[i].attributeInfos[0].name == "Is Enabled")
             selectedComponents[i].enabled = !selectedComponents[i].enabled;
             selectedComponents[i].enabled = !selectedComponents[i].enabled;
     }
     }
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -592,8 +590,8 @@ bool SceneSelectAll()
         hierarchyList.SetSelections(indices);
         hierarchyList.SetSelections(indices);
         EndSelectionModify();
         EndSelectionModify();
     }
     }
-    
-    return true; 
+
+    return true;
 }
 }
 
 
 bool SceneUndo()
 bool SceneUndo()
@@ -616,7 +614,7 @@ bool SceneRedo()
             undoStack[undoStackPos].actions[i].Redo();
             undoStack[undoStackPos].actions[i].Redo();
         ++undoStackPos;
         ++undoStackPos;
     }
     }
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -648,7 +646,7 @@ void SaveEditActionGroup(EditActionGroup@ group)
     undoStack.Resize(undoStackPos);
     undoStack.Resize(undoStackPos);
     undoStack.Push(group);
     undoStack.Push(group);
     ++undoStackPos;
     ++undoStackPos;
-    
+
     SetSceneModified();
     SetSceneModified();
 }
 }
 
 

+ 1 - 1
Bin/Data/Scripts/Editor/EditorSceneWindow.as

@@ -743,7 +743,7 @@ void HandleCreateComponent(StringHash eventType, VariantMap& eventData)
         newComponent.ApplyAttributes();
         newComponent.ApplyAttributes();
         FocusComponent(newComponent);
         FocusComponent(newComponent);
     }
     }
-    
+
     SetSceneModified();
     SetSceneModified();
 }
 }
 
 

+ 0 - 2
Bin/Data/Scripts/Editor/EditorUIElement.as

@@ -87,7 +87,6 @@ void OpenUIElement(const String&in fileName)
     }
     }
 
 
     UpdateHierarchyItem(element, true);
     UpdateHierarchyItem(element, true);
-    UpdateAttributeInspector();
 
 
     suppressSceneChanges = false;
     suppressSceneChanges = false;
 }
 }
@@ -117,7 +116,6 @@ bool CloseAllUIElements()
 
 
     editorUIElement.RemoveAllChildren();
     editorUIElement.RemoveAllChildren();
     UpdateHierarchyItem(editorUIElement, true);
     UpdateHierarchyItem(editorUIElement, true);
-    UpdateAttributeInspector();
 
 
     suppressUIElementChanges = false;
     suppressUIElementChanges = false;
 
 

+ 1 - 1
Docs/ScriptAPI.dox

@@ -55,7 +55,7 @@ namespace Urho3D
 - void Print(uint, bool arg1 = false)
 - void Print(uint, bool arg1 = false)
 - void Print(float, bool arg1 = false)
 - void Print(float, bool arg1 = false)
 - void Print(bool, bool arg1 = false)
 - void Print(bool, bool arg1 = false)
-- void Print(Variant, bool arg1 = false)
+- void Print(const Variant&, bool arg1 = false)
 - void PrintCallStack(bool arg0 = false)
 - void PrintCallStack(bool arg0 = false)
 - String GetPath(const String&)
 - String GetPath(const String&)
 - String GetFileName(const String&)
 - String GetFileName(const String&)

+ 3 - 3
Engine/Engine/IOAPI.cpp

@@ -71,7 +71,7 @@ static void Print(bool value, bool error)
     Log::WriteRaw(String(value) + "\n", error);
     Log::WriteRaw(String(value) + "\n", error);
 }
 }
 
 
-static void Print(Variant value, bool error)
+static void Print(const Variant& value, bool error)
 {
 {
     Log::WriteRaw(value.ToString() + "\n", error);
     Log::WriteRaw(value.ToString() + "\n", error);
 }
 }
@@ -115,7 +115,7 @@ static void Print(int value, bool error) {}
 static void Print(unsigned value, bool error) {}
 static void Print(unsigned value, bool error) {}
 static void Print(float value, bool error) {}
 static void Print(float value, bool error) {}
 static void Print(bool value, bool error) {}
 static void Print(bool value, bool error) {}
-static void Print(Variant value, bool error) {}
+static void Print(const Variant& value, bool error) {}
 static void PrintCallStack(bool error) {}
 static void PrintCallStack(bool error) {}
 static void LogWrite(const String& str, bool error, Log* ptr) {}
 static void LogWrite(const String& str, bool error, Log* ptr) {}
 static void LogDebug(const String& str, Log* ptr) {}
 static void LogDebug(const String& str, Log* ptr) {}
@@ -154,7 +154,7 @@ static void RegisterLog(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("void Print(uint, bool error = false)", asFUNCTIONPR(Print, (unsigned, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(uint, bool error = false)", asFUNCTIONPR(Print, (unsigned, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(float, bool error = false)", asFUNCTIONPR(Print, (float, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(float, bool error = false)", asFUNCTIONPR(Print, (float, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(bool, bool error = false)", asFUNCTIONPR(Print, (bool, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(bool, bool error = false)", asFUNCTIONPR(Print, (bool, bool), void), asCALL_CDECL);
-    engine->RegisterGlobalFunction("void Print(Variant, bool error = false)", asFUNCTIONPR(Print, (Variant, bool), void), asCALL_CDECL);
+    engine->RegisterGlobalFunction("void Print(const Variant&in, bool error = false)", asFUNCTIONPR(Print, (const Variant&, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void PrintCallStack(bool error = false)", asFUNCTION(PrintCallStack), asCALL_CDECL);
     engine->RegisterGlobalFunction("void PrintCallStack(bool error = false)", asFUNCTION(PrintCallStack), asCALL_CDECL);
 }
 }
 
 

+ 4 - 6
Engine/Script/Script.cpp

@@ -363,8 +363,8 @@ void Script::DumpAPI()
 
 
 void Script::MessageCallback(const asSMessageInfo* msg)
 void Script::MessageCallback(const asSMessageInfo* msg)
 {
 {
-    String message = String(msg->section) + " (" + String(msg->row) + "," + String(msg->col) + ") " +
-        String(msg->message);
+    String message;
+    message.AppendWithFormat("%s:%d,%d %s", msg->section, msg->row, msg->col, msg->message);
     
     
     if (logMode_ == LOGMODE_IMMEDIATE)
     if (logMode_ == LOGMODE_IMMEDIATE)
     {
     {
@@ -393,10 +393,8 @@ void Script::MessageCallback(const asSMessageInfo* msg)
 
 
 void Script::ExceptionCallback(asIScriptContext* context)
 void Script::ExceptionCallback(asIScriptContext* context)
 {
 {
-    asIScriptFunction *function = context->GetExceptionFunction();
-    String message = "Exception '" + String(context->GetExceptionString()) + "' in '" +
-        String(function->GetDeclaration()) + "'\n";
-    message += GetCallStack(context);
+    String message;
+    message.AppendWithFormat("- Exception '%s' in '%s'\n%s", context->GetExceptionString(), context->GetExceptionFunction()->GetDeclaration(), GetCallStack(context).CString());
     
     
     asSMessageInfo msg;
     asSMessageInfo msg;
     msg.row = context->GetExceptionLineNumber(&msg.col, &msg.section);
     msg.row = context->GetExceptionLineNumber(&msg.col, &msg.section);

+ 9 - 9
Engine/UI/BorderImage.cpp

@@ -57,14 +57,14 @@ BorderImage::~BorderImage()
 void BorderImage::RegisterObject(Context* context)
 void BorderImage::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<BorderImage>();
     context->RegisterFactory<BorderImage>();
-    
+
+    COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
     ACCESSOR_ATTRIBUTE(BorderImage, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
     ACCESSOR_ATTRIBUTE(BorderImage, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Border", GetBorder, SetBorder, IntRect, IntRect::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Border", GetBorder, SetBorder, IntRect, IntRect::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTVECTOR2, "Hover Image Offset", GetHoverOffset, SetHoverOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTVECTOR2, "Hover Image Offset", GetHoverOffset, SetHoverOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     ACCESSOR_ATTRIBUTE(BorderImage, VAR_BOOL, "Tiled", IsTiled, SetTiled, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(BorderImage, VAR_BOOL, "Tiled", IsTiled, SetTiled, bool, true, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(BorderImage, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(BorderImage, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
-    COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
 }
 }
 
 
 void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
 void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
@@ -125,20 +125,20 @@ void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vert
     if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
     if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
         color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
         color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
         allOpaque = false;
         allOpaque = false;
-    
+
     UIBatch batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);
     UIBatch batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);
-    
+
     // Calculate size of the inner rect, and texture dimensions of the inner rect
     // Calculate size of the inner rect, and texture dimensions of the inner rect
     int x = GetIndentWidth();
     int x = GetIndentWidth();
     IntVector2 size = GetSize();
     IntVector2 size = GetSize();
     size.x_ -= x;
     size.x_ -= x;
     IntVector2 innerSize(
     IntVector2 innerSize(
-        Max(size.x_ - border_.left_ - border_.right_, 0), 
+        Max(size.x_ - border_.left_ - border_.right_, 0),
         Max(size.y_ - border_.top_ - border_.bottom_, 0));
         Max(size.y_ - border_.top_ - border_.bottom_, 0));
     IntVector2 innerTextureSize(
     IntVector2 innerTextureSize(
         Max(imageRect_.right_ - imageRect_.left_ - border_.left_ - border_.right_, 0),
         Max(imageRect_.right_ - imageRect_.left_ - border_.left_ - border_.right_, 0),
         Max(imageRect_.bottom_ - imageRect_.top_ - border_.top_ - border_.bottom_, 0));
         Max(imageRect_.bottom_ - imageRect_.top_ - border_.top_ - border_.bottom_, 0));
-    
+
     IntVector2 topLeft(imageRect_.left_, imageRect_.top_);
     IntVector2 topLeft(imageRect_.left_, imageRect_.top_);
     topLeft += offset;
     topLeft += offset;
 
 
@@ -171,7 +171,7 @@ void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vert
     if (border_.bottom_)
     if (border_.bottom_)
     {
     {
         if (border_.left_)
         if (border_.left_)
-            batch.AddQuad(x, border_.top_ + innerSize.y_, border_.left_, border_.bottom_, topLeft.x_, topLeft.y_ + border_.top_ + 
+            batch.AddQuad(x, border_.top_ + innerSize.y_, border_.left_, border_.bottom_, topLeft.x_, topLeft.y_ + border_.top_ +
                 innerTextureSize.y_);
                 innerTextureSize.y_);
         if (innerSize.x_)
         if (innerSize.x_)
             batch.AddQuad(x + border_.left_, border_.top_ + innerSize.y_, innerSize.x_, border_.bottom_, topLeft.x_ +
             batch.AddQuad(x + border_.left_, border_.top_ + innerSize.y_, innerSize.x_, border_.bottom_, topLeft.x_ +
@@ -180,9 +180,9 @@ void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vert
             batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_ + innerSize.y_, border_.right_, border_.bottom_,
             batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_ + innerSize.y_, border_.right_, border_.bottom_,
                 topLeft.x_ + border_.left_ + innerTextureSize.x_, topLeft.y_ + border_.top_ + innerTextureSize.y_);
                 topLeft.x_ + border_.left_ + innerTextureSize.x_, topLeft.y_ + border_.top_ + innerTextureSize.y_);
     }
     }
-    
+
     UIBatch::AddOrMerge(batch, batches);
     UIBatch::AddOrMerge(batch, batches);
-    
+
     // Reset hovering for next frame
     // Reset hovering for next frame
     hovering_ = false;
     hovering_ = false;
 }
 }

+ 10 - 10
Engine/UI/Button.cpp

@@ -52,19 +52,19 @@ Button::~Button()
 void Button::RegisterObject(Context* context)
 void Button::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Button>();
     context->RegisterFactory<Button>();
-    
+
+    COPY_BASE_ATTRIBUTES(Button, BorderImage);
     REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Pressed Image Offset", GetPressedOffset, SetPressedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Pressed Image Offset", GetPressedOffset, SetPressedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Label Offset", GetLabelOffset, SetLabelOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Label Offset", GetLabelOffset, SetLabelOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Delay", GetRepeatDelay, SetRepeatDelay, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Delay", GetRepeatDelay, SetRepeatDelay, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
-    COPY_BASE_ATTRIBUTES(Button, BorderImage);
 }
 }
 
 
 void Button::Update(float timeStep)
 void Button::Update(float timeStep)
 {
 {
     if (!hovering_ && pressed_)
     if (!hovering_ && pressed_)
         SetPressed(false);
         SetPressed(false);
-    
+
     // Send repeat events if pressed
     // Send repeat events if pressed
     if (pressed_ && repeatRate_ > 0.0f)
     if (pressed_ && repeatRate_ > 0.0f)
     {
     {
@@ -72,9 +72,9 @@ void Button::Update(float timeStep)
         if (repeatTimer_ <= 0.0f)
         if (repeatTimer_ <= 0.0f)
         {
         {
             repeatTimer_ += 1.0f / repeatRate_;
             repeatTimer_ += 1.0f / repeatRate_;
-            
+
             using namespace Pressed;
             using namespace Pressed;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             SendEvent(E_PRESSED, eventData);
             SendEvent(E_PRESSED, eventData);
@@ -89,7 +89,7 @@ void Button::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexDat
         offset += hoverOffset_;
         offset += hoverOffset_;
     if (pressed_ || selected_)
     if (pressed_ || selected_)
         offset += pressedOffset_;
         offset += pressedOffset_;
-    
+
     BorderImage::GetBatches(batches, vertexData, currentScissor, offset);
     BorderImage::GetBatches(batches, vertexData, currentScissor, offset);
 }
 }
 
 
@@ -101,9 +101,9 @@ void Button::OnHover(const IntVector2& position, const IntVector2& screenPositio
         if (!(buttons & MOUSEB_LEFT))
         if (!(buttons & MOUSEB_LEFT))
         {
         {
             SetPressed(false);
             SetPressed(false);
-            
+
             using namespace Released;
             using namespace Released;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             SendEvent(E_RELEASED, eventData);
             SendEvent(E_RELEASED, eventData);
@@ -118,9 +118,9 @@ void Button::OnClick(const IntVector2& position, const IntVector2& screenPositio
         SetPressed(true);
         SetPressed(true);
         repeatTimer_ = repeatDelay_;
         repeatTimer_ = repeatDelay_;
         hovering_ = true;
         hovering_ = true;
-        
+
         using namespace Pressed;
         using namespace Pressed;
-        
+
         VariantMap eventData;
         VariantMap eventData;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)this;
         SendEvent(E_PRESSED, eventData);
         SendEvent(E_PRESSED, eventData);

+ 5 - 5
Engine/UI/CheckBox.cpp

@@ -48,10 +48,10 @@ CheckBox::~CheckBox()
 void CheckBox::RegisterObject(Context* context)
 void CheckBox::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<CheckBox>();
     context->RegisterFactory<CheckBox>();
-    
+
+    COPY_BASE_ATTRIBUTES(CheckBox, BorderImage);
     ACCESSOR_ATTRIBUTE(CheckBox, VAR_BOOL,"Is Checked", IsChecked, SetChecked, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(CheckBox, VAR_BOOL,"Is Checked", IsChecked, SetChecked, bool, true, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(CheckBox, VAR_INTVECTOR2,"Checked Image Offset", GetCheckedOffset, SetCheckedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(CheckBox, VAR_INTVECTOR2,"Checked Image Offset", GetCheckedOffset, SetCheckedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
-    COPY_BASE_ATTRIBUTES(CheckBox, BorderImage);
 }
 }
 
 
 void CheckBox::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
 void CheckBox::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
@@ -61,7 +61,7 @@ void CheckBox::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexD
         offset += hoverOffset_;
         offset += hoverOffset_;
     if (checked_)
     if (checked_)
         offset += checkedOffset_;
         offset += checkedOffset_;
-    
+
     BorderImage::GetBatches(batches, vertexData, currentScissor, offset);
     BorderImage::GetBatches(batches, vertexData, currentScissor, offset);
 }
 }
 
 
@@ -76,9 +76,9 @@ void CheckBox::SetChecked(bool enable)
     if (enable != checked_)
     if (enable != checked_)
     {
     {
         checked_ = enable;
         checked_ = enable;
-        
+
         using namespace Toggled;
         using namespace Toggled;
-        
+
         VariantMap eventData;
         VariantMap eventData;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_STATE] = checked_;
         eventData[P_STATE] = checked_;

+ 12 - 12
Engine/UI/Cursor.cpp

@@ -55,7 +55,7 @@ Cursor::Cursor(Context* context) :
 {
 {
     // Show on top of all other UI elements
     // Show on top of all other UI elements
     priority_ = M_MAX_INT;
     priority_ = M_MAX_INT;
-    
+
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     {
     {
         CursorShapeInfo& info = shapeInfos_[i];
         CursorShapeInfo& info = shapeInfos_[i];
@@ -81,9 +81,9 @@ Cursor::~Cursor()
 void Cursor::RegisterObject(Context* context)
 void Cursor::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Cursor>();
     context->RegisterFactory<Cursor>();
-    
-    ACCESSOR_ATTRIBUTE(Cursor, VAR_VARIANTVECTOR, "Shapes", GetShapesAttr, SetShapesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
+
     COPY_BASE_ATTRIBUTES(Cursor, BorderImage);
     COPY_BASE_ATTRIBUTES(Cursor, BorderImage);
+    ACCESSOR_ATTRIBUTE(Cursor, VAR_VARIANTVECTOR, "Shapes", GetShapesAttr, SetShapesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
 }
 }
 
 
 void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot, bool osMouseVisible)
 void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot, bool osMouseVisible)
@@ -106,13 +106,13 @@ void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRe
         int imageWidth = image->GetWidth();
         int imageWidth = image->GetWidth();
         int width = imageRect.Width();
         int width = imageRect.Width();
         int height = imageRect.Height();
         int height = imageRect.Height();
-        
+
         // Assume little-endian for all the supported platforms
         // Assume little-endian for all the supported platforms
         unsigned rMask = 0x000000ff;
         unsigned rMask = 0x000000ff;
         unsigned gMask = 0x0000ff00;
         unsigned gMask = 0x0000ff00;
         unsigned bMask = 0x00ff0000;
         unsigned bMask = 0x00ff0000;
         unsigned aMask = 0xff000000;
         unsigned aMask = 0xff000000;
-        
+
         SDL_Surface* surface = (comp >= 3 ? SDL_CreateRGBSurface(0, width, height, comp * 8, rMask, gMask, bMask, aMask) : 0);
         SDL_Surface* surface = (comp >= 3 ? SDL_CreateRGBSurface(0, width, height, comp * 8, rMask, gMask, bMask, aMask) : 0);
         if (surface)
         if (surface)
         {
         {
@@ -143,12 +143,12 @@ void Cursor::SetShape(CursorShape shape)
         return;
         return;
 
 
     shape_ = shape;
     shape_ = shape;
-    
+
     CursorShapeInfo& info = shapeInfos_[shape_];
     CursorShapeInfo& info = shapeInfos_[shape_];
     texture_ = info.texture_;
     texture_ = info.texture_;
     imageRect_ = info.imageRect_;
     imageRect_ = info.imageRect_;
     SetSize(info.imageRect_.Size());
     SetSize(info.imageRect_.Size());
-    
+
     if (info.osCursor_)
     if (info.osCursor_)
         SDL_SetCursor(info.osCursor_);
         SDL_SetCursor(info.osCursor_);
 }
 }
@@ -158,7 +158,7 @@ void Cursor::SetShapesAttr(VariantVector value)
     unsigned index = 0;
     unsigned index = 0;
     if (!value.Size())
     if (!value.Size())
         return;
         return;
-    
+
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
     bool osMouseVisible = input->IsMouseVisible();
     bool osMouseVisible = input->IsMouseVisible();
 
 
@@ -181,14 +181,14 @@ void Cursor::SetShapesAttr(VariantVector value)
 VariantVector Cursor::GetShapesAttr() const
 VariantVector Cursor::GetShapesAttr() const
 {
 {
     VariantVector ret;
     VariantVector ret;
-    
+
     unsigned numShapes = 0;
     unsigned numShapes = 0;
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     {
     {
         if (shapeInfos_[i].imageRect_ != IntRect::ZERO)
         if (shapeInfos_[i].imageRect_ != IntRect::ZERO)
             ++numShapes;
             ++numShapes;
     }
     }
-    
+
     ret.Push(numShapes);
     ret.Push(numShapes);
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     for (unsigned i = 0; i < CS_MAX_SHAPES; ++i)
     {
     {
@@ -200,7 +200,7 @@ VariantVector Cursor::GetShapesAttr() const
             ret.Push(shapeInfos_[i].hotSpot_);
             ret.Push(shapeInfos_[i].hotSpot_);
         }
         }
     }
     }
-    
+
     return ret;
     return ret;
 }
 }
 
 
@@ -209,7 +209,7 @@ void Cursor::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexDat
     unsigned initialSize = vertexData.Size();
     unsigned initialSize = vertexData.Size();
     const IntVector2& offset = shapeInfos_[shape_].hotSpot_;
     const IntVector2& offset = shapeInfos_[shape_].hotSpot_;
     Vector2 floatOffset(-(float)offset.x_, -(float)offset.y_);
     Vector2 floatOffset(-(float)offset.x_, -(float)offset.y_);
-    
+
     BorderImage::GetBatches(batches, vertexData, currentScissor);
     BorderImage::GetBatches(batches, vertexData, currentScissor);
     for (unsigned i = initialSize; i < vertexData.Size(); i += 6)
     for (unsigned i = initialSize; i < vertexData.Size(); i += 6)
     {
     {

+ 41 - 41
Engine/UI/LineEdit.cpp

@@ -53,13 +53,13 @@ LineEdit::LineEdit(Context* context) :
     clipChildren_ = true;
     clipChildren_ = true;
     enabled_ = true;
     enabled_ = true;
     focusMode_ = FM_FOCUSABLE_DEFOCUSABLE;
     focusMode_ = FM_FOCUSABLE_DEFOCUSABLE;
-    
+
     text_ = CreateChild<Text>();
     text_ = CreateChild<Text>();
     text_->SetInternal(true);
     text_->SetInternal(true);
     cursor_ = CreateChild<BorderImage>();
     cursor_ = CreateChild<BorderImage>();
     cursor_->SetInternal(true);
     cursor_->SetInternal(true);
     cursor_->SetPriority(1); // Show over text
     cursor_->SetPriority(1); // Show over text
-    
+
     SubscribeToEvent(this, E_FOCUSED, HANDLER(LineEdit, HandleFocused));
     SubscribeToEvent(this, E_FOCUSED, HANDLER(LineEdit, HandleFocused));
     SubscribeToEvent(this, E_DEFOCUSED, HANDLER(LineEdit, HandleDefocused));
     SubscribeToEvent(this, E_DEFOCUSED, HANDLER(LineEdit, HandleDefocused));
 }
 }
@@ -71,7 +71,8 @@ LineEdit::~LineEdit()
 void LineEdit::RegisterObject(Context* context)
 void LineEdit::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<LineEdit>();
     context->RegisterFactory<LineEdit>();
-    
+
+    COPY_BASE_ATTRIBUTES(LineEdit, BorderImage);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_INT, "Max Length", GetMaxLength, SetMaxLength, unsigned, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_INT, "Max Length", GetMaxLength, SetMaxLength, unsigned, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Cursor Movable", IsCursorMovable, SetCursorMovable, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Cursor Movable", IsCursorMovable, SetCursorMovable, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Text Selectable", IsTextSelectable, SetTextSelectable, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Text Selectable", IsTextSelectable, SetTextSelectable, bool, true, AM_FILE);
@@ -79,13 +80,12 @@ void LineEdit::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_FLOAT, "Cursor Blink Rate", GetCursorBlinkRate, SetCursorBlinkRate, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_FLOAT, "Cursor Blink Rate", GetCursorBlinkRate, SetCursorBlinkRate, float, 1.0f, AM_FILE);
     ATTRIBUTE(LineEdit, VAR_INT, "Echo Character", echoCharacter_, 0, AM_FILE);
     ATTRIBUTE(LineEdit, VAR_INT, "Echo Character", echoCharacter_, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_FLOAT, "Double Click Interval", GetDoubleClickInterval, SetDoubleClickInterval, float, 0.5f, AM_FILE);
     ACCESSOR_ATTRIBUTE(LineEdit, VAR_FLOAT, "Double Click Interval", GetDoubleClickInterval, SetDoubleClickInterval, float, 0.5f, AM_FILE);
-    COPY_BASE_ATTRIBUTES(LineEdit, BorderImage);
 }
 }
 
 
 void LineEdit::ApplyAttributes()
 void LineEdit::ApplyAttributes()
 {
 {
     BorderImage::ApplyAttributes();
     BorderImage::ApplyAttributes();
-    
+
     // Set the text's position to match clipping, so that text left edge is not left partially hidden
     // Set the text's position to match clipping, so that text left edge is not left partially hidden
     text_->SetPosition(clipBorder_.left_, clipBorder_.top_);
     text_->SetPosition(clipBorder_.left_, clipBorder_.top_);
 }
 }
@@ -94,7 +94,7 @@ void LineEdit::Update(float timeStep)
 {
 {
     if (cursorBlinkRate_ > 0.0f)
     if (cursorBlinkRate_ > 0.0f)
         cursorBlinkTimer_ = fmodf(cursorBlinkTimer_ + cursorBlinkRate_ * timeStep, 1.0f);
         cursorBlinkTimer_ = fmodf(cursorBlinkTimer_ + cursorBlinkRate_ * timeStep, 1.0f);
-    
+
     // Update cursor position if font has changed
     // Update cursor position if font has changed
     if (text_->GetFont() != lastFont_ || text_->GetFontSize() != lastFontSize_)
     if (text_->GetFont() != lastFont_ || text_->GetFontSize() != lastFontSize_)
     {
     {
@@ -102,7 +102,7 @@ void LineEdit::Update(float timeStep)
         lastFontSize_ = text_->GetFontSize();
         lastFontSize_ = text_->GetFontSize();
         UpdateCursor();
         UpdateCursor();
     }
     }
-   
+
     bool cursorVisible = HasFocus() ? cursorBlinkTimer_ < 0.5f : false;
     bool cursorVisible = HasFocus() ? cursorBlinkTimer_ < 0.5f : false;
     cursor_->SetVisible(cursorVisible);
     cursor_->SetVisible(cursorVisible);
 }
 }
@@ -154,7 +154,7 @@ bool LineEdit::OnDragDropTest(UIElement* source)
         ShortStringHash sourceType = source->GetType();
         ShortStringHash sourceType = source->GetType();
         return sourceType == LineEdit::GetTypeStatic() || sourceType == Text::GetTypeStatic();
         return sourceType == LineEdit::GetTypeStatic() || sourceType == Text::GetTypeStatic();
     }
     }
-    
+
     return false;
     return false;
 }
 }
 
 
@@ -176,7 +176,7 @@ bool LineEdit::OnDragDropFinish(UIElement* source)
             return true;
             return true;
         }
         }
     }
     }
-    
+
     return false;
     return false;
 }
 }
 
 
@@ -184,7 +184,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
 {
 {
     bool changed = false;
     bool changed = false;
     bool cursorMoved = false;
     bool cursorMoved = false;
-    
+
     switch (key)
     switch (key)
     {
     {
     case 'X':
     case 'X':
@@ -193,10 +193,10 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         {
         {
             unsigned start = text_->GetSelectionStart();
             unsigned start = text_->GetSelectionStart();
             unsigned length = text_->GetSelectionLength();
             unsigned length = text_->GetSelectionLength();
-            
+
             if (text_->GetSelectionLength())
             if (text_->GetSelectionLength())
                 GetSubsystem<UI>()->SetClipBoardText(line_.SubstringUTF8(start, length));
                 GetSubsystem<UI>()->SetClipBoardText(line_.SubstringUTF8(start, length));
-            
+
             if (key == 'X')
             if (key == 'X')
             {
             {
                 if (start + length < line_.LengthUTF8())
                 if (start + length < line_.LengthUTF8())
@@ -209,7 +209,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             }
             }
         }
         }
         break;
         break;
-        
+
     case 'V':
     case 'V':
         if (textCopyable_ && qualifiers & QUAL_CTRL)
         if (textCopyable_ && qualifiers & QUAL_CTRL)
         {
         {
@@ -237,11 +237,11 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             }
             }
         }
         }
         break;
         break;
-        
+
     case KEY_HOME:
     case KEY_HOME:
         qualifiers |= QUAL_CTRL;
         qualifiers |= QUAL_CTRL;
         // Fallthru
         // Fallthru
-            
+
     case KEY_LEFT:
     case KEY_LEFT:
         if (!(qualifiers & QUAL_SHIFT))
         if (!(qualifiers & QUAL_SHIFT))
             text_->ClearSelection();
             text_->ClearSelection();
@@ -249,13 +249,13 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         {
         {
             if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
             if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
                 dragBeginCursor_ = cursorPosition_;
                 dragBeginCursor_ = cursorPosition_;
-            
+
             if (qualifiers & QUAL_CTRL)
             if (qualifiers & QUAL_CTRL)
                 cursorPosition_ = 0;
                 cursorPosition_ = 0;
             else
             else
                 --cursorPosition_;
                 --cursorPosition_;
             cursorMoved = true;
             cursorMoved = true;
-            
+
             if (textSelectable_ && qualifiers & QUAL_SHIFT)
             if (textSelectable_ && qualifiers & QUAL_SHIFT)
             {
             {
                 unsigned start = dragBeginCursor_;
                 unsigned start = dragBeginCursor_;
@@ -267,7 +267,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             }
             }
         }
         }
         break;
         break;
-        
+
     case KEY_END:
     case KEY_END:
         qualifiers |= QUAL_CTRL;
         qualifiers |= QUAL_CTRL;
         // Fallthru
         // Fallthru
@@ -279,13 +279,13 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         {
         {
             if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
             if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
                 dragBeginCursor_ = cursorPosition_;
                 dragBeginCursor_ = cursorPosition_;
-            
+
             if (qualifiers & QUAL_CTRL)
             if (qualifiers & QUAL_CTRL)
                 cursorPosition_ = line_.LengthUTF8();
                 cursorPosition_ = line_.LengthUTF8();
             else
             else
                 ++cursorPosition_;
                 ++cursorPosition_;
             cursorMoved = true;
             cursorMoved = true;
-            
+
             if (textSelectable_ && qualifiers & QUAL_SHIFT)
             if (textSelectable_ && qualifiers & QUAL_SHIFT)
             {
             {
                 unsigned start = dragBeginCursor_;
                 unsigned start = dragBeginCursor_;
@@ -297,7 +297,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             }
             }
         }
         }
         break;
         break;
-        
+
     case KEY_DELETE:
     case KEY_DELETE:
         if (!text_->GetSelectionLength())
         if (!text_->GetSelectionLength())
         {
         {
@@ -321,14 +321,14 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             changed = true;
             changed = true;
         }
         }
         break;
         break;
-        
+
     case KEY_UP:
     case KEY_UP:
     case KEY_DOWN:
     case KEY_DOWN:
     case KEY_PAGEUP:
     case KEY_PAGEUP:
     case KEY_PAGEDOWN:
     case KEY_PAGEDOWN:
         {
         {
             using namespace UnhandledKey;
             using namespace UnhandledKey;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_KEY] = key;
             eventData[P_KEY] = key;
@@ -337,7 +337,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             SendEvent(E_UNHANDLEDKEY, eventData);
             SendEvent(E_UNHANDLEDKEY, eventData);
         }
         }
         return;
         return;
-        
+
     case KEY_BACKSPACE:
     case KEY_BACKSPACE:
         if (!text_->GetSelectionLength())
         if (!text_->GetSelectionLength())
         {
         {
@@ -365,13 +365,13 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             changed = true;
             changed = true;
         }
         }
         break;
         break;
-        
+
     case KEY_RETURN:
     case KEY_RETURN:
     case KEY_RETURN2:
     case KEY_RETURN2:
     case KEY_KP_ENTER:
     case KEY_KP_ENTER:
         {
         {
             using namespace TextFinished;
             using namespace TextFinished;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_TEXT] = line_;
             eventData[P_TEXT] = line_;
@@ -380,7 +380,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         }
         }
         break;
         break;
     }
     }
-    
+
     if (changed)
     if (changed)
     {
     {
         UpdateText();
         UpdateText();
@@ -393,11 +393,11 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
 void LineEdit::OnChar(unsigned c, int buttons, int qualifiers)
 void LineEdit::OnChar(unsigned c, int buttons, int qualifiers)
 {
 {
     bool changed = false;
     bool changed = false;
-    
+
     // If only CTRL is held down, do not edit
     // If only CTRL is held down, do not edit
     if ((qualifiers & (QUAL_CTRL | QUAL_ALT)) == QUAL_CTRL)
     if ((qualifiers & (QUAL_CTRL | QUAL_ALT)) == QUAL_CTRL)
         return;
         return;
-    
+
     if (c >= 0x20 && (!maxLength_ || line_.LengthUTF8() < maxLength_))
     if (c >= 0x20 && (!maxLength_ || line_.LengthUTF8() < maxLength_))
     {
     {
         String charStr;
         String charStr;
@@ -424,7 +424,7 @@ void LineEdit::OnChar(unsigned c, int buttons, int qualifiers)
         }
         }
         changed = true;
         changed = true;
     }
     }
-    
+
     if (changed)
     if (changed)
     {
     {
         text_->ClearSelection();
         text_->ClearSelection();
@@ -448,7 +448,7 @@ void LineEdit::SetCursorPosition(unsigned position)
 {
 {
     if (position > line_.LengthUTF8() || !cursorMovable_)
     if (position > line_.LengthUTF8() || !cursorMovable_)
         position = line_.LengthUTF8();
         position = line_.LengthUTF8();
-    
+
     if (position != cursorPosition_)
     if (position != cursorPosition_)
     {
     {
         cursorPosition_ = position;
         cursorPosition_ = position;
@@ -459,7 +459,7 @@ void LineEdit::SetCursorPosition(unsigned position)
 void LineEdit::SetCursorBlinkRate(float rate)
 void LineEdit::SetCursorBlinkRate(float rate)
 {
 {
     cursorBlinkRate_ = Max(rate, 0.0f);
     cursorBlinkRate_ = Max(rate, 0.0f);
-    
+
     if (cursorBlinkRate_ == 0.0f)
     if (cursorBlinkRate_ == 0.0f)
         cursorBlinkTimer_ = 0.0f;   // Cursor does not blink, i.e. always visible
         cursorBlinkTimer_ = 0.0f;   // Cursor does not blink, i.e. always visible
 }
 }
@@ -503,7 +503,7 @@ float LineEdit::GetDoubleClickInterval() const
 void LineEdit::UpdateText()
 void LineEdit::UpdateText()
 {
 {
     unsigned utf8Length = line_.LengthUTF8();
     unsigned utf8Length = line_.LengthUTF8();
-    
+
     if (!echoCharacter_)
     if (!echoCharacter_)
         text_->SetText(line_);
         text_->SetText(line_);
     else
     else
@@ -518,9 +518,9 @@ void LineEdit::UpdateText()
         cursorPosition_ = utf8Length;
         cursorPosition_ = utf8Length;
         UpdateCursor();
         UpdateCursor();
     }
     }
-    
+
     using namespace TextChanged;
     using namespace TextChanged;
-    
+
     VariantMap eventData;
     VariantMap eventData;
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_TEXT] = line_;
     eventData[P_TEXT] = line_;
@@ -533,11 +533,11 @@ void LineEdit::UpdateCursor()
     const PODVector<IntVector2>& charPositions = text_->GetCharPositions();
     const PODVector<IntVector2>& charPositions = text_->GetCharPositions();
     if (charPositions.Size())
     if (charPositions.Size())
         x = cursorPosition_ < charPositions.Size() ? charPositions[cursorPosition_].x_ : charPositions.Back().x_;
         x = cursorPosition_ < charPositions.Size() ? charPositions[cursorPosition_].x_ : charPositions.Back().x_;
-    
+
     text_->SetPosition(clipBorder_.left_, clipBorder_.top_);
     text_->SetPosition(clipBorder_.left_, clipBorder_.top_);
     cursor_->SetPosition(text_->GetPosition() + IntVector2(x, 0));
     cursor_->SetPosition(text_->GetPosition() + IntVector2(x, 0));
     cursor_->SetSize(cursor_->GetWidth(), text_->GetRowHeight());
     cursor_->SetSize(cursor_->GetWidth(), text_->GetRowHeight());
-    
+
     // Scroll if necessary
     // Scroll if necessary
     int sx = -GetChildOffset().x_;
     int sx = -GetChildOffset().x_;
     int left = clipBorder_.left_;
     int left = clipBorder_.left_;
@@ -549,7 +549,7 @@ void LineEdit::UpdateCursor()
     if (sx < 0)
     if (sx < 0)
         sx = 0;
         sx = 0;
     SetChildOffset(IntVector2(-sx, 0));
     SetChildOffset(IntVector2(-sx, 0));
-    
+
     // Restart blinking
     // Restart blinking
     cursorBlinkTimer_ = 0.0f;
     cursorBlinkTimer_ = 0.0f;
 }
 }
@@ -559,16 +559,16 @@ unsigned LineEdit::GetCharIndex(const IntVector2& position)
     IntVector2 screenPosition = ElementToScreen(position);
     IntVector2 screenPosition = ElementToScreen(position);
     IntVector2 textPosition = text_->ScreenToElement(screenPosition);
     IntVector2 textPosition = text_->ScreenToElement(screenPosition);
     const PODVector<IntVector2>& charPositions = text_->GetCharPositions();
     const PODVector<IntVector2>& charPositions = text_->GetCharPositions();
-    
+
     if (textPosition.x_ < 0)
     if (textPosition.x_ < 0)
         return 0;
         return 0;
-    
+
     for (unsigned i = charPositions.Size() - 1; i < charPositions.Size(); --i)
     for (unsigned i = charPositions.Size() - 1; i < charPositions.Size(); --i)
     {
     {
         if (textPosition.x_ >= charPositions[i].x_)
         if (textPosition.x_ >= charPositions[i].x_)
             return i;
             return i;
     }
     }
-    
+
     return M_MAX_UNSIGNED;
     return M_MAX_UNSIGNED;
 }
 }
 
 

+ 23 - 23
Engine/UI/ListView.cpp

@@ -162,7 +162,7 @@ ListView::ListView(Context* context) :
     ScrollView(context),
     ScrollView(context),
     highlightMode_(HM_FOCUS),
     highlightMode_(HM_FOCUS),
     multiselect_(false),
     multiselect_(false),
-    hierarchyMode_(true),	// Init to true here so that the setter below takes effect
+    hierarchyMode_(true),    // Init to true here so that the setter below takes effect
     baseIndent_(0),
     baseIndent_(0),
     clearSelectionOnDefocus_(false),
     clearSelectionOnDefocus_(false),
     doubleClickInterval_(500),
     doubleClickInterval_(500),
@@ -185,13 +185,13 @@ void ListView::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<ListView>();
     context->RegisterFactory<ListView>();
 
 
+    COPY_BASE_ATTRIBUTES(ListView, ScrollView);
     ENUM_ACCESSOR_ATTRIBUTE(ListView, "Highlight Mode", GetHighlightMode, SetHighlightMode, HighlightMode, highlightModes, HM_FOCUS, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(ListView, "Highlight Mode", GetHighlightMode, SetHighlightMode, HighlightMode, highlightModes, HM_FOCUS, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Multiselect", GetMultiselect, SetMultiselect, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Multiselect", GetMultiselect, SetMultiselect, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Hierarchy Mode", GetHierarchyMode, SetHierarchyMode, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Hierarchy Mode", GetHierarchyMode, SetHierarchyMode, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_INT, "Base Indent", GetBaseIndent, SetBaseIndent, int, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_INT, "Base Indent", GetBaseIndent, SetBaseIndent, int, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Clear Sel. On Defocus", GetClearSelectionOnDefocus, SetClearSelectionOnDefocus, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Clear Sel. On Defocus", GetClearSelectionOnDefocus, SetClearSelectionOnDefocus, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_FLOAT, "Double Click Interval", GetDoubleClickInterval, SetDoubleClickInterval, float, 0.5f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ListView, VAR_FLOAT, "Double Click Interval", GetDoubleClickInterval, SetDoubleClickInterval, float, 0.5f, AM_FILE);
-    COPY_BASE_ATTRIBUTES(ListView, ScrollView);
 }
 }
 
 
 void ListView::OnKey(int key, int buttons, int qualifiers)
 void ListView::OnKey(int key, int buttons, int qualifiers)
@@ -407,10 +407,10 @@ void ListView::RemoveItem(UIElement* item, unsigned index)
                 if (i > 0)
                 if (i > 0)
                 {
                 {
                     int baseIndent = item->GetIndent();
                     int baseIndent = item->GetIndent();
-                    UIElement* prevKin = GetItem(i - 1);		// Could be parent or sibling
+                    UIElement* prevKin = GetItem(i - 1);        // Could be parent or sibling
                     if (prevKin->GetIndent() < baseIndent)
                     if (prevKin->GetIndent() < baseIndent)
                     {
                     {
-                        UIElement* nextKin = GetItem(i + 1);	// Could be sibling or parent-sibling or 0 if index out of bound
+                        UIElement* nextKin = GetItem(i + 1);    // Could be sibling or parent-sibling or 0 if index out of bound
                         if (!nextKin || nextKin->GetIndent() < baseIndent)
                         if (!nextKin || nextKin->GetIndent() < baseIndent)
                         {
                         {
                             // If we reach here then the parent has no other children
                             // If we reach here then the parent has no other children
@@ -471,9 +471,9 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
 {
 {
     // Make a weak pointer to self to check for destruction as a response to events
     // Make a weak pointer to self to check for destruction as a response to events
     WeakPtr<ListView> self(this);
     WeakPtr<ListView> self(this);
-    
+
     unsigned numItems = GetNumItems();
     unsigned numItems = GetNumItems();
-    
+
     // Remove first items that should no longer be selected
     // Remove first items that should no longer be selected
     for (PODVector<unsigned>::Iterator i = selections_.Begin(); i != selections_.End();)
     for (PODVector<unsigned>::Iterator i = selections_.Begin(); i != selections_.End();)
     {
     {
@@ -481,23 +481,23 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
         if (!indices.Contains(index))
         if (!indices.Contains(index))
         {
         {
             i = selections_.Erase(i);
             i = selections_.Erase(i);
-            
+
             using namespace ItemSelected;
             using namespace ItemSelected;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_SELECTION] = index;
             eventData[P_SELECTION] = index;
             SendEvent(E_ITEMDESELECTED, eventData);
             SendEvent(E_ITEMDESELECTED, eventData);
-            
+
             if (self.Expired())
             if (self.Expired())
                 return;
                 return;
         }
         }
         else
         else
             ++i;
             ++i;
     }
     }
-    
+
     bool added = false;
     bool added = false;
-    
+
     // Then add missing items
     // Then add missing items
     for (PODVector<unsigned>::ConstIterator i = indices.Begin(); i != indices.End(); ++i)
     for (PODVector<unsigned>::ConstIterator i = indices.Begin(); i != indices.End(); ++i)
     {
     {
@@ -513,14 +513,14 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
                     selections_.Push(index);
                     selections_.Push(index);
                     added = true;
                     added = true;
                 }
                 }
-                
+
                 using namespace ItemSelected;
                 using namespace ItemSelected;
-                
+
                 VariantMap eventData;
                 VariantMap eventData;
                 eventData[P_ELEMENT] = (void*)this;
                 eventData[P_ELEMENT] = (void*)this;
                 eventData[P_SELECTION] = *i;
                 eventData[P_SELECTION] = *i;
                 SendEvent(E_ITEMSELECTED, eventData);
                 SendEvent(E_ITEMSELECTED, eventData);
-                
+
                 if (self.Expired())
                 if (self.Expired())
                     return;
                     return;
             }
             }
@@ -529,11 +529,11 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
         if (!multiselect_)
         if (!multiselect_)
             break;
             break;
     }
     }
-    
+
     // Re-sort selections if necessary
     // Re-sort selections if necessary
     if (added)
     if (added)
         Sort(selections_.Begin(), selections_.End());
         Sort(selections_.Begin(), selections_.End());
-    
+
     UpdateSelectionEffect();
     UpdateSelectionEffect();
     SendEvent(E_SELECTIONCHANGED);
     SendEvent(E_SELECTIONCHANGED);
 }
 }
@@ -542,31 +542,31 @@ void ListView::AddSelection(unsigned index)
 {
 {
     // Make a weak pointer to self to check for destruction as a response to events
     // Make a weak pointer to self to check for destruction as a response to events
     WeakPtr<ListView> self(this);
     WeakPtr<ListView> self(this);
-    
+
     if (!multiselect_)
     if (!multiselect_)
         SetSelection(index);
         SetSelection(index);
     else
     else
     {
     {
         if (index >= GetNumItems())
         if (index >= GetNumItems())
             return;
             return;
-        
+
         if (!selections_.Contains(index))
         if (!selections_.Contains(index))
         {
         {
             selections_.Push(index);
             selections_.Push(index);
-            
+
             using namespace ItemSelected;
             using namespace ItemSelected;
-            
+
             VariantMap eventData;
             VariantMap eventData;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_SELECTION] = index;
             eventData[P_SELECTION] = index;
             SendEvent(E_ITEMSELECTED, eventData);
             SendEvent(E_ITEMSELECTED, eventData);
-            
+
             if (self.Expired())
             if (self.Expired())
                 return;
                 return;
-            
+
             Sort(selections_.Begin(), selections_.End());
             Sort(selections_.Begin(), selections_.End());
         }
         }
-        
+
         EnsureItemVisibility(index);
         EnsureItemVisibility(index);
         UpdateSelectionEffect();
         UpdateSelectionEffect();
         SendEvent(E_SELECTIONCHANGED);
         SendEvent(E_SELECTIONCHANGED);

+ 37 - 37
Engine/UI/Menu.cpp

@@ -59,9 +59,9 @@ Menu::~Menu()
 void Menu::RegisterObject(Context* context)
 void Menu::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Menu>();
     context->RegisterFactory<Menu>();
-    
-    REF_ACCESSOR_ATTRIBUTE(Menu, VAR_INTVECTOR2, "Popup Offset", GetPopupOffset, SetPopupOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+
     COPY_BASE_ATTRIBUTES(Menu, Button);
     COPY_BASE_ATTRIBUTES(Menu, Button);
+    REF_ACCESSOR_ATTRIBUTE(Menu, VAR_INTVECTOR2, "Popup Offset", GetPopupOffset, SetPopupOffset, IntVector2, IntVector2::ZERO, AM_FILE);
 }
 }
 
 
 void Menu::OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
 void Menu::OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
@@ -87,7 +87,7 @@ void Menu::OnHover(const IntVector2& position, const IntVector2& screenPosition,
         }
         }
     }
     }
 }
 }
-    
+
 void Menu::OnShowPopup()
 void Menu::OnShowPopup()
 {
 {
 }
 }
@@ -101,16 +101,16 @@ bool Menu::LoadXML(const XMLElement& source, XMLFile* styleFile)
         String styleName = source.GetAttribute("style");
         String styleName = source.GetAttribute("style");
         if (styleName.Empty())
         if (styleName.Empty())
             styleName = GetTypeName();
             styleName = GetTypeName();
-        
+
         SetStyle(styleFile, styleName);
         SetStyle(styleFile, styleName);
     }
     }
-    
+
     // Then load rest of the attributes from the source
     // Then load rest of the attributes from the source
     if (!Serializable::LoadXML(source))
     if (!Serializable::LoadXML(source))
         return false;
         return false;
-    
+
     unsigned nextInternalChild = 0;
     unsigned nextInternalChild = 0;
-    
+
     // Load child elements. Internal elements are not to be created as they already exist
     // Load child elements. Internal elements are not to be created as they already exist
     XMLElement childElem = source.GetChild("element");
     XMLElement childElem = source.GetChild("element");
     while (childElem)
     while (childElem)
@@ -121,7 +121,7 @@ bool Menu::LoadXML(const XMLElement& source, XMLFile* styleFile)
         if (typeName.Empty())
         if (typeName.Empty())
             typeName = "UIElement";
             typeName = "UIElement";
         UIElement* child = 0;
         UIElement* child = 0;
-        
+
         if (!internalElem)
         if (!internalElem)
         {
         {
             if (!popupElem)
             if (!popupElem)
@@ -155,23 +155,23 @@ bool Menu::LoadXML(const XMLElement& source, XMLFile* styleFile)
                         break;
                         break;
                     }
                     }
                 }
                 }
-                
+
                 if (!child)
                 if (!child)
                     LOGWARNING("Could not find matching internal child element of type " + typeName + " in " + GetTypeName());
                     LOGWARNING("Could not find matching internal child element of type " + typeName + " in " + GetTypeName());
             }
             }
         }
         }
-        
+
         if (child)
         if (child)
         {
         {
             if (!child->LoadXML(childElem, styleFile))
             if (!child->LoadXML(childElem, styleFile))
                 return false;
                 return false;
         }
         }
-        
+
         childElem = childElem.GetNext("element");
         childElem = childElem.GetNext("element");
     }
     }
-    
+
     ApplyAttributes();
     ApplyAttributes();
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -185,11 +185,11 @@ bool Menu::SaveXML(XMLElement& dest)
         if (!dest.SetBool("internal", internal_))
         if (!dest.SetBool("internal", internal_))
             return false;
             return false;
     }
     }
-    
+
     // Write attributes
     // Write attributes
     if (!Serializable::SaveXML(dest))
     if (!Serializable::SaveXML(dest))
         return false;
         return false;
-    
+
     // Write child elements
     // Write child elements
     for (unsigned i = 0; i < children_.Size(); ++i)
     for (unsigned i = 0; i < children_.Size(); ++i)
     {
     {
@@ -198,7 +198,7 @@ bool Menu::SaveXML(XMLElement& dest)
         if (!element->SaveXML(childElem))
         if (!element->SaveXML(childElem))
             return false;
             return false;
     }
     }
-    
+
     // Save the popup element as a "virtual" child element
     // Save the popup element as a "virtual" child element
     if (popup_)
     if (popup_)
     {
     {
@@ -207,7 +207,7 @@ bool Menu::SaveXML(XMLElement& dest)
         if (!popup_->SaveXML(childElem))
         if (!popup_->SaveXML(childElem))
             return false;
             return false;
     }
     }
-    
+
     return true;
     return true;
 }
 }
 
 
@@ -215,12 +215,12 @@ void Menu::SetPopup(UIElement* popup)
 {
 {
     if (popup == this)
     if (popup == this)
         return;
         return;
-    
+
     if (popup_ && !popup)
     if (popup_ && !popup)
         ShowPopup(false);
         ShowPopup(false);
-    
+
     popup_ = popup;
     popup_ = popup;
-    
+
     // Detach from current parent (if any) to only show when it is time
     // Detach from current parent (if any) to only show when it is time
     if (popup_)
     if (popup_)
         popup_->Remove();
         popup_->Remove();
@@ -240,16 +240,16 @@ void Menu::ShowPopup(bool enable)
 {
 {
     if (!popup_)
     if (!popup_)
         return;
         return;
-    
+
     if (enable)
     if (enable)
     {
     {
         // Find the UI root element for showing the popup
         // Find the UI root element for showing the popup
         UIElement* root = GetRoot();
         UIElement* root = GetRoot();
         if (!root)
         if (!root)
             return;
             return;
-        
+
         OnShowPopup();
         OnShowPopup();
-        
+
         if (popup_->GetParent() != root)
         if (popup_->GetParent() != root)
             root->AddChild(popup_);
             root->AddChild(popup_);
         popup_->SetPosition(GetScreenPosition() + popupOffset_);
         popup_->SetPosition(GetScreenPosition() + popupOffset_);
@@ -268,12 +268,12 @@ void Menu::ShowPopup(bool enable)
             if (menu)
             if (menu)
                 menu->ShowPopup(false);
                 menu->ShowPopup(false);
         }
         }
-        
+
         popup_->SetVar(originHash, Variant::EMPTY);
         popup_->SetVar(originHash, Variant::EMPTY);
         popup_->SetVisible(false);
         popup_->SetVisible(false);
         popup_->Remove();
         popup_->Remove();
     }
     }
-    
+
     showPopup_ = enable;
     showPopup_ = enable;
     selected_ = enable;
     selected_ = enable;
 }
 }
@@ -282,7 +282,7 @@ void Menu::SetAccelerator(int key, int qualifiers)
 {
 {
     acceleratorKey_ = key;
     acceleratorKey_ = key;
     acceleratorQualifiers_ = qualifiers;
     acceleratorQualifiers_ = qualifiers;
-    
+
     if (key)
     if (key)
         SubscribeToEvent(E_KEYDOWN, HANDLER(Menu, HandleKeyDown));
         SubscribeToEvent(E_KEYDOWN, HANDLER(Menu, HandleKeyDown));
     else
     else
@@ -302,15 +302,15 @@ void Menu::HandlePressedReleased(StringHash eventType, VariantMap& eventData)
         if (popup_)
         if (popup_)
             return;
             return;
     }
     }
-    
+
     // Toggle popup visibility if exists
     // Toggle popup visibility if exists
     ShowPopup(!showPopup_);
     ShowPopup(!showPopup_);
-    
+
     // Send event on each click if no popup, or whenever the popup is opened
     // Send event on each click if no popup, or whenever the popup is opened
     if (!popup_ || showPopup_)
     if (!popup_ || showPopup_)
     {
     {
         using namespace MenuSelected;
         using namespace MenuSelected;
-        
+
         VariantMap newEventData;
         VariantMap newEventData;
         newEventData[P_ELEMENT] = (void*)this;
         newEventData[P_ELEMENT] = (void*)this;
         SendEvent(E_MENUSELECTED, newEventData);
         SendEvent(E_MENUSELECTED, newEventData);
@@ -321,23 +321,23 @@ void Menu::HandleFocusChanged(StringHash eventType, VariantMap& eventData)
 {
 {
     if (!showPopup_)
     if (!showPopup_)
         return;
         return;
-    
+
     using namespace FocusChanged;
     using namespace FocusChanged;
-    
+
     UIElement* element = static_cast<UIElement*>(eventData[P_ELEMENT].GetPtr());
     UIElement* element = static_cast<UIElement*>(eventData[P_ELEMENT].GetPtr());
     UIElement* root = GetRoot();
     UIElement* root = GetRoot();
-    
+
     // If another element was focused due to the menu button being clicked, do not hide the popup
     // If another element was focused due to the menu button being clicked, do not hide the popup
     if (eventType == E_FOCUSCHANGED && static_cast<UIElement*>(eventData[P_CLICKEDELEMENT].GetPtr()))
     if (eventType == E_FOCUSCHANGED && static_cast<UIElement*>(eventData[P_CLICKEDELEMENT].GetPtr()))
         return;
         return;
-    
+
     // If clicked emptiness or defocused, hide the popup
     // If clicked emptiness or defocused, hide the popup
     if (!element)
     if (!element)
     {
     {
         ShowPopup(false);
         ShowPopup(false);
         return;
         return;
     }
     }
-    
+
     // Otherwise see if the clicked element has either the menu item or the popup in its parent chain.
     // Otherwise see if the clicked element has either the menu item or the popup in its parent chain.
     // In that case, do not hide
     // In that case, do not hide
     while (element)
     while (element)
@@ -349,7 +349,7 @@ void Menu::HandleFocusChanged(StringHash eventType, VariantMap& eventData)
         else
         else
             element = element->GetParent();
             element = element->GetParent();
     }
     }
-    
+
     ShowPopup(false);
     ShowPopup(false);
 }
 }
 
 
@@ -357,9 +357,9 @@ void Menu::HandleKeyDown(StringHash eventType, VariantMap& eventData)
 {
 {
     if (!enabled_)
     if (!enabled_)
         return;
         return;
-    
+
     using namespace KeyDown;
     using namespace KeyDown;
-    
+
     // Activate if accelerator key pressed
     // Activate if accelerator key pressed
     if (eventData[P_KEY].GetInt() == acceleratorKey_ && (acceleratorQualifiers_ == QUAL_ANY || eventData[P_QUALIFIERS].GetInt() ==
     if (eventData[P_KEY].GetInt() == acceleratorKey_ && (acceleratorQualifiers_ == QUAL_ANY || eventData[P_QUALIFIERS].GetInt() ==
         acceleratorQualifiers_) && eventData[P_REPEAT].GetBool() == false)
         acceleratorQualifiers_) && eventData[P_REPEAT].GetBool() == false)

+ 12 - 12
Engine/UI/ScrollBar.cpp

@@ -49,7 +49,7 @@ ScrollBar::ScrollBar(Context* context) :
     downRect_(IntRect::ZERO)
     downRect_(IntRect::ZERO)
 {
 {
     enabled_ = true;
     enabled_ = true;
-    
+
     backButton_ = CreateChild<Button>();
     backButton_ = CreateChild<Button>();
     backButton_->SetInternal(true);
     backButton_->SetInternal(true);
     backButton_->SetRepeat(DEFAULT_REPEAT_DELAY, DEFAULT_REPEAT_RATE);
     backButton_->SetRepeat(DEFAULT_REPEAT_DELAY, DEFAULT_REPEAT_RATE);
@@ -59,12 +59,12 @@ ScrollBar::ScrollBar(Context* context) :
     forwardButton_ = CreateChild<Button>();
     forwardButton_ = CreateChild<Button>();
     forwardButton_->SetInternal(true);
     forwardButton_->SetInternal(true);
     forwardButton_->SetRepeat(DEFAULT_REPEAT_DELAY, DEFAULT_REPEAT_RATE);
     forwardButton_->SetRepeat(DEFAULT_REPEAT_DELAY, DEFAULT_REPEAT_RATE);
-    
+
     SubscribeToEvent(backButton_, E_PRESSED, HANDLER(ScrollBar, HandleBackButtonPressed));
     SubscribeToEvent(backButton_, E_PRESSED, HANDLER(ScrollBar, HandleBackButtonPressed));
     SubscribeToEvent(forwardButton_, E_PRESSED, HANDLER(ScrollBar, HandleForwardButtonPressed));
     SubscribeToEvent(forwardButton_, E_PRESSED, HANDLER(ScrollBar, HandleForwardButtonPressed));
     SubscribeToEvent(slider_, E_SLIDERCHANGED, HANDLER(ScrollBar, HandleSliderChanged));
     SubscribeToEvent(slider_, E_SLIDERCHANGED, HANDLER(ScrollBar, HandleSliderChanged));
     SubscribeToEvent(slider_, E_SLIDERPAGED, HANDLER(ScrollBar, HandleSliderPaged));
     SubscribeToEvent(slider_, E_SLIDERPAGED, HANDLER(ScrollBar, HandleSliderPaged));
-    
+
     // Set default orientation/layout
     // Set default orientation/layout
     SetOrientation(O_HORIZONTAL);
     SetOrientation(O_HORIZONTAL);
 }
 }
@@ -76,7 +76,8 @@ ScrollBar::~ScrollBar()
 void ScrollBar::RegisterObject(Context* context)
 void ScrollBar::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<ScrollBar>();
     context->RegisterFactory<ScrollBar>();
-    
+
+    COPY_BASE_ATTRIBUTES(ScrollBar, UIElement);
     ENUM_ACCESSOR_ATTRIBUTE(ScrollBar, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(ScrollBar, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
@@ -86,13 +87,12 @@ void ScrollBar::RegisterObject(Context* context)
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Right Image Rect", rightRect_, IntRect::ZERO, AM_FILE);
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Right Image Rect", rightRect_, IntRect::ZERO, AM_FILE);
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Up Image Rect", upRect_, IntRect::ZERO, AM_FILE);
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Up Image Rect", upRect_, IntRect::ZERO, AM_FILE);
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Down Image Rect", downRect_, IntRect::ZERO, AM_FILE);
     ATTRIBUTE(ScrollBar, VAR_INTRECT, "Down Image Rect", downRect_, IntRect::ZERO, AM_FILE);
-    COPY_BASE_ATTRIBUTES(ScrollBar, UIElement);
 }
 }
 
 
 void ScrollBar::ApplyAttributes()
 void ScrollBar::ApplyAttributes()
 {
 {
     UIElement::ApplyAttributes();
     UIElement::ApplyAttributes();
-    
+
     // Reapply orientation to the button images
     // Reapply orientation to the button images
     if (slider_->GetOrientation() == O_HORIZONTAL)
     if (slider_->GetOrientation() == O_HORIZONTAL)
     {
     {
@@ -110,7 +110,7 @@ void ScrollBar::OnResize()
 {
 {
     // Disable layout operations while setting the button sizes is incomplete
     // Disable layout operations while setting the button sizes is incomplete
     DisableLayoutUpdate();
     DisableLayoutUpdate();
-    
+
     if (slider_->GetOrientation() == O_HORIZONTAL)
     if (slider_->GetOrientation() == O_HORIZONTAL)
     {
     {
         int height = GetHeight();
         int height = GetHeight();
@@ -123,14 +123,14 @@ void ScrollBar::OnResize()
         backButton_->SetFixedSize(width, width);
         backButton_->SetFixedSize(width, width);
         forwardButton_->SetFixedSize(width, width);
         forwardButton_->SetFixedSize(width, width);
     }
     }
-    
+
     EnableLayoutUpdate();
     EnableLayoutUpdate();
 }
 }
 
 
 void ScrollBar::SetOrientation(Orientation orientation)
 void ScrollBar::SetOrientation(Orientation orientation)
 {
 {
     slider_->SetOrientation(orientation);
     slider_->SetOrientation(orientation);
-    
+
     if (orientation == O_HORIZONTAL)
     if (orientation == O_HORIZONTAL)
     {
     {
         backButton_->SetImageRect(leftRect_);
         backButton_->SetImageRect(leftRect_);
@@ -141,7 +141,7 @@ void ScrollBar::SetOrientation(Orientation orientation)
         backButton_->SetImageRect(upRect_);
         backButton_->SetImageRect(upRect_);
         forwardButton_->SetImageRect(downRect_);
         forwardButton_->SetImageRect(downRect_);
     }
     }
-    
+
     OnResize();
     OnResize();
     if (orientation == O_HORIZONTAL)
     if (orientation == O_HORIZONTAL)
         SetLayout(LM_HORIZONTAL);
         SetLayout(LM_HORIZONTAL);
@@ -218,7 +218,7 @@ void ScrollBar::HandleSliderChanged(StringHash eventType, VariantMap& eventData)
 {
 {
     // Send the event forward
     // Send the event forward
     VariantMap newEventData;
     VariantMap newEventData;
-    
+
     newEventData[ScrollBarChanged::P_ELEMENT] = (void*)this;
     newEventData[ScrollBarChanged::P_ELEMENT] = (void*)this;
     newEventData[ScrollBarChanged::P_VALUE] = slider_->GetValue();
     newEventData[ScrollBarChanged::P_VALUE] = slider_->GetValue();
     SendEvent(E_SCROLLBARCHANGED, newEventData);
     SendEvent(E_SCROLLBARCHANGED, newEventData);
@@ -227,7 +227,7 @@ void ScrollBar::HandleSliderChanged(StringHash eventType, VariantMap& eventData)
 void ScrollBar::HandleSliderPaged(StringHash eventType, VariantMap& eventData)
 void ScrollBar::HandleSliderPaged(StringHash eventType, VariantMap& eventData)
 {
 {
     using namespace SliderPaged;
     using namespace SliderPaged;
- 
+
     if (eventData[P_BUTTONS].GetInt() & MOUSEB_LEFT)
     if (eventData[P_BUTTONS].GetInt() & MOUSEB_LEFT)
     {
     {
         if (eventData[P_OFFSET].GetInt() < 0)
         if (eventData[P_OFFSET].GetInt() < 0)

+ 32 - 32
Engine/UI/ScrollView.cpp

@@ -50,7 +50,7 @@ ScrollView::ScrollView(Context* context) :
     clipChildren_ = true;
     clipChildren_ = true;
     enabled_ = true;
     enabled_ = true;
     focusMode_ = FM_FOCUSABLE_DEFOCUSABLE;
     focusMode_ = FM_FOCUSABLE_DEFOCUSABLE;
-    
+
     horizontalScrollBar_ = CreateChild<ScrollBar>();
     horizontalScrollBar_ = CreateChild<ScrollBar>();
     horizontalScrollBar_->SetInternal(true);
     horizontalScrollBar_->SetInternal(true);
     horizontalScrollBar_->SetAlignment(HA_LEFT, VA_BOTTOM);
     horizontalScrollBar_->SetAlignment(HA_LEFT, VA_BOTTOM);
@@ -63,7 +63,7 @@ ScrollView::ScrollView(Context* context) :
     scrollPanel_->SetInternal(true);
     scrollPanel_->SetInternal(true);
     scrollPanel_->SetEnabled(true);
     scrollPanel_->SetEnabled(true);
     scrollPanel_->SetClipChildren(true);
     scrollPanel_->SetClipChildren(true);
-    
+
     SubscribeToEvent(horizontalScrollBar_, E_SCROLLBARCHANGED, HANDLER(ScrollView, HandleScrollBarChanged));
     SubscribeToEvent(horizontalScrollBar_, E_SCROLLBARCHANGED, HANDLER(ScrollView, HandleScrollBarChanged));
     SubscribeToEvent(horizontalScrollBar_, E_VISIBLECHANGED, HANDLER(ScrollView, HandleScrollBarVisibleChanged));
     SubscribeToEvent(horizontalScrollBar_, E_VISIBLECHANGED, HANDLER(ScrollView, HandleScrollBarVisibleChanged));
     SubscribeToEvent(verticalScrollBar_, E_SCROLLBARCHANGED, HANDLER(ScrollView, HandleScrollBarChanged));
     SubscribeToEvent(verticalScrollBar_, E_SCROLLBARCHANGED, HANDLER(ScrollView, HandleScrollBarChanged));
@@ -77,28 +77,28 @@ ScrollView::~ScrollView()
 void ScrollView::RegisterObject(Context* context)
 void ScrollView::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<ScrollView>();
     context->RegisterFactory<ScrollView>();
-    
+
+    COPY_BASE_ATTRIBUTES(ScrollView, UIElement);
     REF_ACCESSOR_ATTRIBUTE(ScrollView, VAR_INTVECTOR2, "View Position", GetViewPosition, SetViewPositionAttr, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(ScrollView, VAR_INTVECTOR2, "View Position", GetViewPosition, SetViewPositionAttr, IntVector2, IntVector2::ZERO, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Step", GetScrollStep, SetScrollStep, float, 0.1f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Step", GetScrollStep, SetScrollStep, float, 0.1f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Page Step", GetPageStep, SetPageStep, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Page Step", GetPageStep, SetPageStep, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Show/Hide Scrollbars", GetScrollBarsAutoVisible, SetScrollBarsAutoVisible, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Show/Hide Scrollbars", GetScrollBarsAutoVisible, SetScrollBarsAutoVisible, bool, true, AM_FILE);
-    COPY_BASE_ATTRIBUTES(ScrollView, UIElement);
 }
 }
 
 
 void ScrollView::ApplyAttributes()
 void ScrollView::ApplyAttributes()
 {
 {
     UIElement::ApplyAttributes();
     UIElement::ApplyAttributes();
-    
+
     // Set the scrollbar orientations again and perform size update now that the style is known
     // Set the scrollbar orientations again and perform size update now that the style is known
     horizontalScrollBar_->SetOrientation(O_HORIZONTAL);
     horizontalScrollBar_->SetOrientation(O_HORIZONTAL);
     verticalScrollBar_->SetOrientation(O_VERTICAL);
     verticalScrollBar_->SetOrientation(O_VERTICAL);
-    
+
     // If the scroll panel has a child, it should be the content element, which has some special handling
     // If the scroll panel has a child, it should be the content element, which has some special handling
     if (scrollPanel_->GetNumChildren())
     if (scrollPanel_->GetNumChildren())
         SetContentElement(scrollPanel_->GetChild(0));
         SetContentElement(scrollPanel_->GetChild(0));
-    
+
     OnResize();
     OnResize();
-    
+
     // Reapply view position with proper content element and size
     // Reapply view position with proper content element and size
     SetViewPosition(viewPositionAttr_);
     SetViewPosition(viewPositionAttr_);
 }
 }
@@ -124,7 +124,7 @@ void ScrollView::OnKey(int key, int buttons, int qualifiers)
                 horizontalScrollBar_->StepBack();
                 horizontalScrollBar_->StepBack();
         }
         }
         break;
         break;
-        
+
     case KEY_RIGHT:
     case KEY_RIGHT:
         if (horizontalScrollBar_->IsVisible())
         if (horizontalScrollBar_->IsVisible())
         {
         {
@@ -134,11 +134,11 @@ void ScrollView::OnKey(int key, int buttons, int qualifiers)
                 horizontalScrollBar_->StepForward();
                 horizontalScrollBar_->StepForward();
         }
         }
         break;
         break;
-        
+
     case KEY_HOME:
     case KEY_HOME:
         qualifiers |= QUAL_CTRL;
         qualifiers |= QUAL_CTRL;
         // Fallthru
         // Fallthru
-        
+
     case KEY_UP:
     case KEY_UP:
         if (verticalScrollBar_->IsVisible())
         if (verticalScrollBar_->IsVisible())
         {
         {
@@ -148,11 +148,11 @@ void ScrollView::OnKey(int key, int buttons, int qualifiers)
                 verticalScrollBar_->StepBack();
                 verticalScrollBar_->StepBack();
         }
         }
         break;
         break;
-        
+
     case KEY_END:
     case KEY_END:
         qualifiers |= QUAL_CTRL;
         qualifiers |= QUAL_CTRL;
         // Fallthru
         // Fallthru
-        
+
     case KEY_DOWN:
     case KEY_DOWN:
         if (verticalScrollBar_->IsVisible())
         if (verticalScrollBar_->IsVisible())
         {
         {
@@ -162,12 +162,12 @@ void ScrollView::OnKey(int key, int buttons, int qualifiers)
                 verticalScrollBar_->StepForward();
                 verticalScrollBar_->StepForward();
         }
         }
         break;
         break;
-        
+
     case KEY_PAGEUP:
     case KEY_PAGEUP:
         if (verticalScrollBar_->IsVisible())
         if (verticalScrollBar_->IsVisible())
             verticalScrollBar_->ChangeValue(-pageStep_);
             verticalScrollBar_->ChangeValue(-pageStep_);
         break;
         break;
-        
+
     case KEY_PAGEDOWN:
     case KEY_PAGEDOWN:
         if (verticalScrollBar_->IsVisible())
         if (verticalScrollBar_->IsVisible())
             verticalScrollBar_->ChangeValue(pageStep_);
             verticalScrollBar_->ChangeValue(pageStep_);
@@ -179,7 +179,7 @@ void ScrollView::OnResize()
 {
 {
     UpdatePanelSize();
     UpdatePanelSize();
     UpdateViewSize();
     UpdateViewSize();
-    
+
     // If scrollbar autovisibility is enabled, check whether scrollbars should be visible.
     // If scrollbar autovisibility is enabled, check whether scrollbars should be visible.
     // This may force another update of the panel size
     // This may force another update of the panel size
     if (scrollBarsAutoVisible_)
     if (scrollBarsAutoVisible_)
@@ -188,7 +188,7 @@ void ScrollView::OnResize()
         horizontalScrollBar_->SetVisible(horizontalScrollBar_->GetRange() > M_EPSILON);
         horizontalScrollBar_->SetVisible(horizontalScrollBar_->GetRange() > M_EPSILON);
         verticalScrollBar_->SetVisible(verticalScrollBar_->GetRange() > M_EPSILON);
         verticalScrollBar_->SetVisible(verticalScrollBar_->GetRange() > M_EPSILON);
         ignoreEvents_ = false;
         ignoreEvents_ = false;
-        
+
         UpdatePanelSize();
         UpdatePanelSize();
     }
     }
 }
 }
@@ -197,7 +197,7 @@ void ScrollView::SetContentElement(UIElement* element)
 {
 {
     if (element == contentElement_)
     if (element == contentElement_)
         return;
         return;
-    
+
     if (contentElement_)
     if (contentElement_)
     {
     {
         scrollPanel_->RemoveChild(contentElement_);
         scrollPanel_->RemoveChild(contentElement_);
@@ -209,7 +209,7 @@ void ScrollView::SetContentElement(UIElement* element)
         scrollPanel_->AddChild(contentElement_);
         scrollPanel_->AddChild(contentElement_);
         SubscribeToEvent(contentElement_, E_RESIZED, HANDLER(ScrollView, HandleElementResized));
         SubscribeToEvent(contentElement_, E_RESIZED, HANDLER(ScrollView, HandleElementResized));
     }
     }
-    
+
     OnResize();
     OnResize();
 }
 }
 
 
@@ -269,24 +269,24 @@ void ScrollView::UpdatePanelSize()
     // Ignore events in case content element resizes itself along with the panel
     // Ignore events in case content element resizes itself along with the panel
     // (content element resize triggers our OnResize(), so it could lead to infinite recursion)
     // (content element resize triggers our OnResize(), so it could lead to infinite recursion)
     ignoreEvents_ = true;
     ignoreEvents_ = true;
-    
+
     IntVector2 panelSize = GetSize();
     IntVector2 panelSize = GetSize();
     if (verticalScrollBar_->IsVisible())
     if (verticalScrollBar_->IsVisible())
         panelSize.x_ -= verticalScrollBar_->GetWidth();
         panelSize.x_ -= verticalScrollBar_->GetWidth();
     if (horizontalScrollBar_->IsVisible())
     if (horizontalScrollBar_->IsVisible())
         panelSize.y_ -= horizontalScrollBar_->GetHeight();
         panelSize.y_ -= horizontalScrollBar_->GetHeight();
-    
+
     scrollPanel_->SetSize(panelSize);
     scrollPanel_->SetSize(panelSize);
     horizontalScrollBar_->SetWidth(scrollPanel_->GetWidth());
     horizontalScrollBar_->SetWidth(scrollPanel_->GetWidth());
     verticalScrollBar_->SetHeight(scrollPanel_->GetHeight());
     verticalScrollBar_->SetHeight(scrollPanel_->GetHeight());
-    
+
     if (resizeContentWidth_ && contentElement_)
     if (resizeContentWidth_ && contentElement_)
     {
     {
         IntRect panelBorder = scrollPanel_->GetClipBorder();
         IntRect panelBorder = scrollPanel_->GetClipBorder();
         contentElement_->SetWidth(scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_);
         contentElement_->SetWidth(scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_);
         UpdateViewSize();
         UpdateViewSize();
     }
     }
-    
+
     ignoreEvents_ = false;
     ignoreEvents_ = false;
 }
 }
 
 
@@ -296,10 +296,10 @@ void ScrollView::UpdateViewSize()
     if (contentElement_)
     if (contentElement_)
         size = contentElement_->GetSize();
         size = contentElement_->GetSize();
     IntRect panelBorder = scrollPanel_->GetClipBorder();
     IntRect panelBorder = scrollPanel_->GetClipBorder();
-    
+
     viewSize_.x_ = Max(size.x_, scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_);
     viewSize_.x_ = Max(size.x_, scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_);
     viewSize_.y_ = Max(size.y_, scrollPanel_->GetHeight() - panelBorder.top_ - panelBorder.bottom_);
     viewSize_.y_ = Max(size.y_, scrollPanel_->GetHeight() - panelBorder.top_ - panelBorder.bottom_);
-    
+
     UpdateView(viewPosition_);
     UpdateView(viewPosition_);
     UpdateScrollBars();
     UpdateScrollBars();
 }
 }
@@ -307,12 +307,12 @@ void ScrollView::UpdateViewSize()
 void ScrollView::UpdateScrollBars()
 void ScrollView::UpdateScrollBars()
 {
 {
     ignoreEvents_ = true;
     ignoreEvents_ = true;
-    
+
     IntVector2 size = scrollPanel_->GetSize();
     IntVector2 size = scrollPanel_->GetSize();
     IntRect panelBorder = scrollPanel_->GetClipBorder();
     IntRect panelBorder = scrollPanel_->GetClipBorder();
     size.x_ -= panelBorder.left_ + panelBorder.right_;
     size.x_ -= panelBorder.left_ + panelBorder.right_;
     size.y_ -= panelBorder.top_ + panelBorder.bottom_;
     size.y_ -= panelBorder.top_ + panelBorder.bottom_;
-    
+
     if (size.x_ > 0 && viewSize_.x_ > 0)
     if (size.x_ > 0 && viewSize_.x_ > 0)
     {
     {
         float range = (float)viewSize_.x_ / (float)size.x_ - 1.0f;
         float range = (float)viewSize_.x_ / (float)size.x_ - 1.0f;
@@ -327,7 +327,7 @@ void ScrollView::UpdateScrollBars()
         verticalScrollBar_->SetValue((float)viewPosition_.y_ / (float)size.y_);
         verticalScrollBar_->SetValue((float)viewPosition_.y_ / (float)size.y_);
         verticalScrollBar_->SetStepFactor(STEP_FACTOR / (float)size.y_);
         verticalScrollBar_->SetStepFactor(STEP_FACTOR / (float)size.y_);
     }
     }
-    
+
     ignoreEvents_ = false;
     ignoreEvents_ = false;
 }
 }
 
 
@@ -337,15 +337,15 @@ void ScrollView::UpdateView(const IntVector2& position)
     IntRect panelBorder = scrollPanel_->GetClipBorder();
     IntRect panelBorder = scrollPanel_->GetClipBorder();
     IntVector2 panelSize(scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_, scrollPanel_->GetHeight() -
     IntVector2 panelSize(scrollPanel_->GetWidth() - panelBorder.left_ - panelBorder.right_, scrollPanel_->GetHeight() -
         panelBorder.top_ - panelBorder.bottom_);
         panelBorder.top_ - panelBorder.bottom_);
-    
+
     viewPosition_.x_ = Clamp(position.x_, 0, viewSize_.x_ - panelSize.x_);
     viewPosition_.x_ = Clamp(position.x_, 0, viewSize_.x_ - panelSize.x_);
     viewPosition_.y_ = Clamp(position.y_, 0, viewSize_.y_ - panelSize.y_);
     viewPosition_.y_ = Clamp(position.y_, 0, viewSize_.y_ - panelSize.y_);
     scrollPanel_->SetChildOffset(IntVector2(-viewPosition_.x_ + panelBorder.left_, -viewPosition_.y_ + panelBorder.top_));
     scrollPanel_->SetChildOffset(IntVector2(-viewPosition_.x_ + panelBorder.left_, -viewPosition_.y_ + panelBorder.top_));
-    
+
     if (viewPosition_ != oldPosition)
     if (viewPosition_ != oldPosition)
     {
     {
         using namespace ViewChanged;
         using namespace ViewChanged;
-        
+
         VariantMap eventData;
         VariantMap eventData;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_X] = viewPosition_.x_;
         eventData[P_X] = viewPosition_.x_;
@@ -362,7 +362,7 @@ void ScrollView::HandleScrollBarChanged(StringHash eventType, VariantMap& eventD
         IntRect panelBorder = scrollPanel_->GetClipBorder();
         IntRect panelBorder = scrollPanel_->GetClipBorder();
         size.x_ -= panelBorder.left_ + panelBorder.right_;
         size.x_ -= panelBorder.left_ + panelBorder.right_;
         size.y_ -= panelBorder.top_ + panelBorder.bottom_;
         size.y_ -= panelBorder.top_ + panelBorder.bottom_;
-        
+
         UpdateView(IntVector2(
         UpdateView(IntVector2(
             (int)(horizontalScrollBar_->GetValue() * (float)size.x_),
             (int)(horizontalScrollBar_->GetValue() * (float)size.x_),
             (int)(verticalScrollBar_->GetValue() * (float)size.y_)
             (int)(verticalScrollBar_->GetValue() * (float)size.y_)

+ 13 - 13
Engine/UI/Slider.cpp

@@ -57,7 +57,7 @@ Slider::Slider(Context* context) :
     enabled_ = true;
     enabled_ = true;
     knob_ = CreateChild<BorderImage>();
     knob_ = CreateChild<BorderImage>();
     knob_->SetInternal(true);
     knob_->SetInternal(true);
-    
+
     UpdateSlider();
     UpdateSlider();
 }
 }
 
 
@@ -68,19 +68,19 @@ Slider::~Slider()
 void Slider::RegisterObject(Context* context)
 void Slider::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Slider>();
     context->RegisterFactory<Slider>();
-    
+
+    COPY_BASE_ATTRIBUTES(Slider, BorderImage);
     ENUM_ACCESSOR_ATTRIBUTE(Slider, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(Slider, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
-    COPY_BASE_ATTRIBUTES(Slider, BorderImage);
 }
 }
 
 
 void Slider::Update(float timeStep)
 void Slider::Update(float timeStep)
 {
 {
     if (dragSlider_)
     if (dragSlider_)
         hovering_ = true;
         hovering_ = true;
-    
+
     // Propagate hover effect to the slider knob
     // Propagate hover effect to the slider knob
     knob_->SetHovering(hovering_);
     knob_->SetHovering(hovering_);
     knob_->SetSelected(hovering_);
     knob_->SetSelected(hovering_);
@@ -89,10 +89,10 @@ void Slider::Update(float timeStep)
 void Slider::OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
 void Slider::OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
 {
 {
     BorderImage::OnHover(position, screenPosition, buttons, qualifiers, cursor);
     BorderImage::OnHover(position, screenPosition, buttons, qualifiers, cursor);
-    
+
     // Show hover effect if inside the slider knob
     // Show hover effect if inside the slider knob
     hovering_ = knob_->IsInside(screenPosition, true);
     hovering_ = knob_->IsInside(screenPosition, true);
-    
+
     // If not hovering on the knob, send it as page event
     // If not hovering on the knob, send it as page event
     if (!hovering_)
     if (!hovering_)
         Page(position, buttons, qualifiers);
         Page(position, buttons, qualifiers);
@@ -118,10 +118,10 @@ void Slider::OnDragMove(const IntVector2& position, const IntVector2& screenPosi
 {
 {
     if (!dragSlider_ || GetSize() == knob_->GetSize())
     if (!dragSlider_ || GetSize() == knob_->GetSize())
         return;
         return;
-    
+
     float newValue = value_;
     float newValue = value_;
     IntVector2 delta = position - dragBeginCursor_;
     IntVector2 delta = position - dragBeginCursor_;
-    
+
     if (orientation_ == O_HORIZONTAL)
     if (orientation_ == O_HORIZONTAL)
     {
     {
         int newX = Clamp(dragBeginPosition_.x_ + delta.x_, 0, GetWidth() - knob_->GetWidth());
         int newX = Clamp(dragBeginPosition_.x_ + delta.x_, 0, GetWidth() - knob_->GetWidth());
@@ -134,7 +134,7 @@ void Slider::OnDragMove(const IntVector2& position, const IntVector2& screenPosi
         knob_->SetPosition(0, newY);
         knob_->SetPosition(0, newY);
         newValue = (float)newY * range_ / (float)(GetHeight() - knob_->GetHeight());
         newValue = (float)newY * range_ / (float)(GetHeight() - knob_->GetHeight());
     }
     }
-    
+
     SetValue(newValue);
     SetValue(newValue);
 }
 }
 
 
@@ -172,9 +172,9 @@ void Slider::SetValue(float value)
     {
     {
         value_ = value;
         value_ = value;
         UpdateSlider();
         UpdateSlider();
-        
+
         using namespace SliderChanged;
         using namespace SliderChanged;
-        
+
         VariantMap eventData;
         VariantMap eventData;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_VALUE] = value_;
         eventData[P_VALUE] = value_;
@@ -195,7 +195,7 @@ void Slider::SetRepeatRate(float rate)
 void Slider::UpdateSlider()
 void Slider::UpdateSlider()
 {
 {
     const IntRect& border = knob_->GetBorder();
     const IntRect& border = knob_->GetBorder();
-    
+
     if (range_ > 0.0f)
     if (range_ > 0.0f)
     {
     {
         if (orientation_ == O_HORIZONTAL)
         if (orientation_ == O_HORIZONTAL)
@@ -227,7 +227,7 @@ void Slider::Page(const IntVector2& position, int buttons, int qualifiers)
     float length = (float)(orientation_ == O_HORIZONTAL ? GetWidth() : GetHeight());
     float length = (float)(orientation_ == O_HORIZONTAL ? GetWidth() : GetHeight());
 
 
     using namespace SliderPaged;
     using namespace SliderPaged;
-    
+
     VariantMap eventData;
     VariantMap eventData;
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_OFFSET] = offset;
     eventData[P_OFFSET] = offset;

+ 3 - 2
Engine/UI/Sprite.cpp

@@ -56,14 +56,15 @@ void Sprite::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Sprite>();
     context->RegisterFactory<Sprite>();
     
     
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Position", GetPosition, SetPosition, Vector2, Vector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Position", GetPosition, SetPosition, Vector2, Vector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Scale", GetScale, SetScale, Vector2, Vector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Scale", GetScale, SetScale, Vector2, Vector2::ZERO, AM_FILE);
     ACCESSOR_ATTRIBUTE(Sprite, VAR_FLOAT, "Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(Sprite, VAR_FLOAT, "Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE(Sprite, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTRECT, "Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
     ACCESSOR_ATTRIBUTE(Sprite, VAR_INT, "Priority", GetPriority, SetPriority, int, 0, AM_FILE);
     ACCESSOR_ATTRIBUTE(Sprite, VAR_INT, "Priority", GetPriority, SetPriority, int, 0, AM_FILE);

+ 49 - 49
Engine/UI/Text.cpp

@@ -84,7 +84,8 @@ Text::~Text()
 void Text::RegisterObject(Context* context)
 void Text::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Text>();
     context->RegisterFactory<Text>();
-    
+
+    COPY_BASE_ATTRIBUTES(Text, UIElement);
     ACCESSOR_ATTRIBUTE(Text, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_FILE);
     ACCESSOR_ATTRIBUTE(Text, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_FILE);
     ATTRIBUTE(Text, VAR_INT, "Font Size", fontSize_, DEFAULT_FONT_SIZE, AM_FILE);
     ATTRIBUTE(Text, VAR_INT, "Font Size", fontSize_, DEFAULT_FONT_SIZE, AM_FILE);
     ATTRIBUTE(Text, VAR_STRING, "Text", text_, String::EMPTY, AM_FILE);
     ATTRIBUTE(Text, VAR_STRING, "Text", text_, String::EMPTY, AM_FILE);
@@ -93,8 +94,7 @@ void Text::RegisterObject(Context* context)
     ATTRIBUTE(Text, VAR_BOOL, "Word Wrap", wordWrap_, false, AM_FILE);
     ATTRIBUTE(Text, VAR_BOOL, "Word Wrap", wordWrap_, false, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Selection Color", GetSelectionColor, SetSelectionColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Selection Color", GetSelectionColor, SetSelectionColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Hover Color", GetHoverColor, SetHoverColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Hover Color", GetHoverColor, SetHoverColor, Color, Color::TRANSPARENT, AM_FILE);
-    COPY_BASE_ATTRIBUTES(Text, UIElement);
-    
+
     // Change the default value for UseDerivedOpacity
     // Change the default value for UseDerivedOpacity
     context->GetAttribute<Text>("Use Derived Opacity")->defaultValue_ = false;
     context->GetAttribute<Text>("Use Derived Opacity")->defaultValue_ = false;
 }
 }
@@ -102,12 +102,12 @@ void Text::RegisterObject(Context* context)
 void Text::ApplyAttributes()
 void Text::ApplyAttributes()
 {
 {
     UIElement::ApplyAttributes();
     UIElement::ApplyAttributes();
-    
+
     // Decode to Unicode now
     // Decode to Unicode now
     unicodeText_.Clear();
     unicodeText_.Clear();
     for (unsigned i = 0; i < text_.Length();)
     for (unsigned i = 0; i < text_.Length();)
         unicodeText_.Push(text_.NextUTF8Char(i));
         unicodeText_.Push(text_.NextUTF8Char(i));
-    
+
     fontSize_ = Max(fontSize_, 1);
     fontSize_ = Max(fontSize_, 1);
     ValidateSelection();
     ValidateSelection();
     UpdateText();
     UpdateText();
@@ -124,12 +124,12 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
             (selected_ && selectionColor_.a_ > 0.0f ? selectionColor_ : hoverColor_));
             (selected_ && selectionColor_.a_ > 0.0f ? selectionColor_ : hoverColor_));
         UIBatch::AddOrMerge(batch, batches);
         UIBatch::AddOrMerge(batch, batches);
     }
     }
-    
+
     // Partial selection batch
     // Partial selection batch
     if (!selected_ && selectionLength_ && charSizes_.Size() >= selectionStart_ + selectionLength_ && selectionColor_.a_ > 0.0f)
     if (!selected_ && selectionLength_ && charSizes_.Size() >= selectionStart_ + selectionLength_ && selectionColor_.a_ > 0.0f)
     {
     {
         UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
         UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
-        
+
         IntVector2 currentStart = charPositions_[selectionStart_];
         IntVector2 currentStart = charPositions_[selectionStart_];
         IntVector2 currentEnd = currentStart;
         IntVector2 currentEnd = currentStart;
         for (unsigned i = selectionStart_; i < selectionStart_ + selectionLength_; ++i)
         for (unsigned i = selectionStart_; i < selectionStart_ + selectionLength_; ++i)
@@ -156,10 +156,10 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
             batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_, currentEnd.y_ - currentStart.y_,
             batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_, currentEnd.y_ - currentStart.y_,
                 0, 0, 0, 0, selectionColor_);
                 0, 0, 0, 0, selectionColor_);
         }
         }
-        
+
         UIBatch::AddOrMerge(batch, batches);
         UIBatch::AddOrMerge(batch, batches);
     }
     }
-    
+
     // Text batch
     // Text batch
     if (font_)
     if (font_)
     {
     {
@@ -171,23 +171,23 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
         {
         {
             // Only traversing thru the printText once regardless of number of textures/pages in the font
             // Only traversing thru the printText once regardless of number of textures/pages in the font
             Vector<PODVector<GlyphLocation> > pageGlyphLocations(face->textures_.Size());
             Vector<PODVector<GlyphLocation> > pageGlyphLocations(face->textures_.Size());
-            
+
             unsigned rowIndex = 0;
             unsigned rowIndex = 0;
             int x = GetRowStartPosition(rowIndex);
             int x = GetRowStartPosition(rowIndex);
             int y = 0;
             int y = 0;
-            
+
             for (unsigned i = 0; i < printText_.Size(); ++i)
             for (unsigned i = 0; i < printText_.Size(); ++i)
             {
             {
                 unsigned c = printText_[i];
                 unsigned c = printText_[i];
-                
+
                 if (c != '\n')
                 if (c != '\n')
                 {
                 {
                     const FontGlyph* p = face->GetGlyph(c);
                     const FontGlyph* p = face->GetGlyph(c);
                     if (!p)
                     if (!p)
                         continue;
                         continue;
-                    
+
                     pageGlyphLocations[p->page_].Push(GlyphLocation(x, y, p));
                     pageGlyphLocations[p->page_].Push(GlyphLocation(x, y, p));
-                    
+
                     x += p->advanceX_;
                     x += p->advanceX_;
                     if (i < printText_.Size() - 1)
                     if (i < printText_.Size() - 1)
                         x += face->GetKerning(c, printText_[i + 1]);
                         x += face->GetKerning(c, printText_[i + 1]);
@@ -198,12 +198,12 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
                     y += rowHeight_;
                     y += rowHeight_;
                 }
                 }
             }
             }
-            
+
             for (unsigned n = 0; n < face->textures_.Size(); ++n)
             for (unsigned n = 0; n < face->textures_.Size(); ++n)
             {
             {
                 // One batch per texture/page
                 // One batch per texture/page
                 UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, face->textures_[n], &vertexData);
                 UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, face->textures_[n], &vertexData);
-                
+
                 const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations[n];
                 const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations[n];
                 for (unsigned i = 0; i < pageGlyphLocation.Size(); ++i)
                 for (unsigned i = 0; i < pageGlyphLocation.Size(); ++i)
                 {
                 {
@@ -211,7 +211,7 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
                     const FontGlyph& glyph = *glyphLocation.glyph_;
                     const FontGlyph& glyph = *glyphLocation.glyph_;
                     pageBatch.AddQuad(glyphLocation.x_ + glyph.offsetX_, glyphLocation.y_ + glyph.offsetY_, glyph.width_, glyph.height_, glyph.x_, glyph.y_);
                     pageBatch.AddQuad(glyphLocation.x_ + glyph.offsetX_, glyphLocation.y_ + glyph.offsetY_, glyph.width_, glyph.height_, glyph.x_, glyph.y_);
                 }
                 }
-                
+
                 batches.Push(pageBatch);
                 batches.Push(pageBatch);
             }
             }
         }
         }
@@ -221,21 +221,21 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
             unsigned rowIndex = 0;
             unsigned rowIndex = 0;
             int x = GetRowStartPosition(rowIndex);
             int x = GetRowStartPosition(rowIndex);
             int y = 0;
             int y = 0;
-            
+
             UIBatch batch(this, BLEND_ALPHA, currentScissor, face->textures_[0], &vertexData);
             UIBatch batch(this, BLEND_ALPHA, currentScissor, face->textures_[0], &vertexData);
-            
+
             for (unsigned i = 0; i < printText_.Size(); ++i)
             for (unsigned i = 0; i < printText_.Size(); ++i)
             {
             {
                 unsigned c = printText_[i];
                 unsigned c = printText_[i];
-                
+
                 if (c != '\n')
                 if (c != '\n')
                 {
                 {
                     const FontGlyph* p = face->GetGlyph(c);
                     const FontGlyph* p = face->GetGlyph(c);
                     if (!p)
                     if (!p)
                         continue;
                         continue;
-                    
+
                     batch.AddQuad(x + p->offsetX_, y + p->offsetY_, p->width_, p->height_, p->x_, p->y_);
                     batch.AddQuad(x + p->offsetX_, y + p->offsetY_, p->width_, p->height_, p->x_, p->y_);
-                    
+
                     x += p->advanceX_;
                     x += p->advanceX_;
                     if (i < printText_.Size() - 1)
                     if (i < printText_.Size() - 1)
                         x += face->GetKerning(c, printText_[i + 1]);
                         x += face->GetKerning(c, printText_[i + 1]);
@@ -246,11 +246,11 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
                     y += rowHeight_;
                     y += rowHeight_;
                 }
                 }
             }
             }
-            
+
             UIBatch::AddOrMerge(batch, batches);
             UIBatch::AddOrMerge(batch, batches);
         }
         }
     }
     }
-    
+
     // Reset hovering for next frame
     // Reset hovering for next frame
     hovering_ = false;
     hovering_ = false;
 }
 }
@@ -274,26 +274,26 @@ bool Text::SetFont(Font* font, int size)
         LOGERROR("Null font for Text");
         LOGERROR("Null font for Text");
         return false;
         return false;
     }
     }
-    
+
     if (font != font_ || size != fontSize_)
     if (font != font_ || size != fontSize_)
     {
     {
         font_ = font;
         font_ = font;
         fontSize_ = Max(size, 1);
         fontSize_ = Max(size, 1);
         UpdateText();
         UpdateText();
     }
     }
-    
+
     return true;
     return true;
 }
 }
 
 
 void Text::SetText(const String& text)
 void Text::SetText(const String& text)
 {
 {
     text_ = text;
     text_ = text;
-    
+
     // Decode to Unicode now
     // Decode to Unicode now
     unicodeText_.Clear();
     unicodeText_.Clear();
     for (unsigned i = 0; i < text_.Length();)
     for (unsigned i = 0; i < text_.Length();)
         unicodeText_.Push(text_.NextUTF8Char(i));
         unicodeText_.Push(text_.NextUTF8Char(i));
-    
+
     ValidateSelection();
     ValidateSelection();
     UpdateText();
     UpdateText();
 }
 }
@@ -363,22 +363,22 @@ void Text::UpdateText(bool inResize)
 {
 {
     int width = 0;
     int width = 0;
     int height = 0;
     int height = 0;
-    
+
     rowWidths_.Clear();
     rowWidths_.Clear();
     printText_.Clear();
     printText_.Clear();
-    
+
     PODVector<unsigned> printToText;
     PODVector<unsigned> printToText;
-    
+
     if (font_)
     if (font_)
     {
     {
         const FontFace* face = font_->GetFace(fontSize_);
         const FontFace* face = font_->GetFace(fontSize_);
         if (!face)
         if (!face)
             return;
             return;
-        
+
         rowHeight_ = face->rowHeight_;
         rowHeight_ = face->rowHeight_;
         int rowWidth = 0;
         int rowWidth = 0;
         int rowHeight = (int)(rowSpacing_ * rowHeight_);
         int rowHeight = (int)(rowSpacing_ * rowHeight_);
-        
+
         // First see if the text must be split up
         // First see if the text must be split up
         if (!wordWrap_)
         if (!wordWrap_)
         {
         {
@@ -396,11 +396,11 @@ void Text::UpdateText(bool inResize)
             {
             {
                 unsigned j;
                 unsigned j;
                 unsigned c = unicodeText_[i];
                 unsigned c = unicodeText_[i];
-                
+
                 if (c != '\n')
                 if (c != '\n')
                 {
                 {
                     bool ok = true;
                     bool ok = true;
-                    
+
                     if (nextBreak <= i)
                     if (nextBreak <= i)
                     {
                     {
                         int futureRowWidth = rowWidth;
                         int futureRowWidth = rowWidth;
@@ -431,7 +431,7 @@ void Text::UpdateText(bool inResize)
                             }
                             }
                         }
                         }
                     }
                     }
-                    
+
                     if (!ok)
                     if (!ok)
                     {
                     {
                         // If did not find any breaks on the line, copy until j, or at least 1 char, to prevent infinite loop
                         // If did not find any breaks on the line, copy until j, or at least 1 char, to prevent infinite loop
@@ -449,7 +449,7 @@ void Text::UpdateText(bool inResize)
                         rowWidth = 0;
                         rowWidth = 0;
                         nextBreak = lineStart = i;
                         nextBreak = lineStart = i;
                     }
                     }
-                    
+
                     if (i < unicodeText_.Size())
                     if (i < unicodeText_.Size())
                     {
                     {
                         // When copying a space, position is allowed to be over row width
                         // When copying a space, position is allowed to be over row width
@@ -477,13 +477,13 @@ void Text::UpdateText(bool inResize)
                 }
                 }
             }
             }
         }
         }
-        
+
         rowWidth = 0;
         rowWidth = 0;
-        
+
         for (unsigned i = 0; i < printText_.Size(); ++i)
         for (unsigned i = 0; i < printText_.Size(); ++i)
         {
         {
             unsigned c = printText_[i];
             unsigned c = printText_[i];
-            
+
             if (c != '\n')
             if (c != '\n')
             {
             {
                 const FontGlyph* glyph = face->GetGlyph(c);
                 const FontGlyph* glyph = face->GetGlyph(c);
@@ -502,22 +502,22 @@ void Text::UpdateText(bool inResize)
                 rowWidth = 0;
                 rowWidth = 0;
             }
             }
         }
         }
-        
+
         if (rowWidth)
         if (rowWidth)
         {
         {
             width = Max(width, rowWidth);
             width = Max(width, rowWidth);
             height += rowHeight;
             height += rowHeight;
             rowWidths_.Push(rowWidth);
             rowWidths_.Push(rowWidth);
         }
         }
-        
+
         // Set row height even if text is empty
         // Set row height even if text is empty
         if (!height)
         if (!height)
             height = rowHeight;
             height = rowHeight;
-        
+
         // Store position & size of each character
         // Store position & size of each character
         charPositions_.Resize(unicodeText_.Size() + 1);
         charPositions_.Resize(unicodeText_.Size() + 1);
         charSizes_.Resize(unicodeText_.Size());
         charSizes_.Resize(unicodeText_.Size());
-        
+
         unsigned rowIndex = 0;
         unsigned rowIndex = 0;
         int x = GetRowStartPosition(rowIndex);
         int x = GetRowStartPosition(rowIndex);
         int y = 0;
         int y = 0;
@@ -546,7 +546,7 @@ void Text::UpdateText(bool inResize)
         // Store the ending position
         // Store the ending position
         charPositions_[unicodeText_.Size()] = IntVector2(x, y);
         charPositions_[unicodeText_.Size()] = IntVector2(x, y);
     }
     }
-    
+
     // Set minimum and current size according to the text size, but respect fixed width if set
     // Set minimum and current size according to the text size, but respect fixed width if set
     if (GetMinWidth() != GetMaxWidth())
     if (GetMinWidth() != GetMaxWidth())
     {
     {
@@ -559,7 +559,7 @@ void Text::UpdateText(bool inResize)
 void Text::ValidateSelection()
 void Text::ValidateSelection()
 {
 {
     unsigned textLength = unicodeText_.Size();
     unsigned textLength = unicodeText_.Size();
-    
+
     if (textLength)
     if (textLength)
     {
     {
         if (selectionStart_ >= textLength)
         if (selectionStart_ >= textLength)
@@ -577,10 +577,10 @@ void Text::ValidateSelection()
 int Text::GetRowStartPosition(unsigned rowIndex) const
 int Text::GetRowStartPosition(unsigned rowIndex) const
 {
 {
     int rowWidth = 0;
     int rowWidth = 0;
-    
+
     if (rowIndex < rowWidths_.Size())
     if (rowIndex < rowWidths_.Size())
         rowWidth = rowWidths_[rowIndex];
         rowWidth = rowWidths_[rowIndex];
-    
+
     int ret = GetIndentWidth();
     int ret = GetIndentWidth();
 
 
     switch (textAlignment_)
     switch (textAlignment_)
@@ -594,7 +594,7 @@ int Text::GetRowStartPosition(unsigned rowIndex) const
         ret += GetSize().x_ - rowWidth;
         ret += GetSize().x_ - rowWidth;
         break;
         break;
     }
     }
-    
+
     return ret;
     return ret;
 }
 }
 
 

+ 1 - 1
Engine/UI/Window.cpp

@@ -61,6 +61,7 @@ void Window::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Window>();
     context->RegisterFactory<Window>();
 
 
+    COPY_BASE_ATTRIBUTES(Window, BorderImage);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTRECT, "Resize Border", GetResizeBorder, SetResizeBorder, IntRect, IntRect(DEFAULT_RESIZE_BORDER, \
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTRECT, "Resize Border", GetResizeBorder, SetResizeBorder, IntRect, IntRect(DEFAULT_RESIZE_BORDER, \
         DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER), AM_FILE);
         DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER), AM_FILE);
     ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Is Movable", IsMovable, SetMovable, bool, false, AM_FILE);
     ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Is Movable", IsMovable, SetMovable, bool, false, AM_FILE);
@@ -69,7 +70,6 @@ void Window::RegisterObject(Context* context)
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Shade Color", GetModalShadeColor, SetModalShadeColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Shade Color", GetModalShadeColor, SetModalShadeColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Frame Color", GetModalFrameColor, SetModalFrameColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Frame Color", GetModalFrameColor, SetModalFrameColor, Color, Color::TRANSPARENT, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTVECTOR2, "Modal Frame Size", GetModalFrameSize, SetModalFrameSize, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTVECTOR2, "Modal Frame Size", GetModalFrameSize, SetModalFrameSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    COPY_BASE_ATTRIBUTES(Window, BorderImage);
 }
 }
 
 
 void Window::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
 void Window::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)