Browse Source

New UI Work

Josh Engebretson 10 years ago
parent
commit
4f60555490

+ 2 - 3
Source/Atomic/Engine/Engine.cpp

@@ -48,7 +48,6 @@
 #include "../Resource/ResourceCache.h"
 #include "../Resource/ResourceCache.h"
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 #include "../Scene/SceneEvents.h"
 #include "../Scene/SceneEvents.h"
-#include "../UI/UI.h"
 #ifdef ATOMIC_ATOMIC2D
 #ifdef ATOMIC_ATOMIC2D
 #include "../Atomic2D/Atomic2D.h"
 #include "../Atomic2D/Atomic2D.h"
 #endif
 #endif
@@ -135,7 +134,7 @@ Engine::Engine(Context* context) :
     context_->RegisterSubsystem(new TBUI(context_));
     context_->RegisterSubsystem(new TBUI(context_));
     #endif
     #endif
 
 
-    context_->RegisterSubsystem(new UI(context_));
+    //context_->RegisterSubsystem(new UI(context_));
 
 
     // Register object factories for libraries which are not automatically registered along with subsystem creation
     // Register object factories for libraries which are not automatically registered along with subsystem creation
     RegisterSceneLibrary(context_);
     RegisterSceneLibrary(context_);
@@ -687,7 +686,7 @@ void Engine::Render()
     GetSubsystem<TBUI>()->Render();
     GetSubsystem<TBUI>()->Render();
 #endif
 #endif
 
 
-    GetSubsystem<UI>()->Render();
+    //GetSubsystem<UI>()->Render();
     graphics->EndFrame();
     graphics->EndFrame();
 }
 }
 
 

+ 2 - 3
Source/Atomic/Graphics/View.cpp

@@ -46,7 +46,6 @@
 #include "../Graphics/TextureCube.h"
 #include "../Graphics/TextureCube.h"
 #include "../Graphics/VertexBuffer.h"
 #include "../Graphics/VertexBuffer.h"
 #include "../Graphics/View.h"
 #include "../Graphics/View.h"
-#include "../UI/UI.h"
 #include "../Core/WorkQueue.h"
 #include "../Core/WorkQueue.h"
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
@@ -1611,8 +1610,8 @@ void View::ExecuteRenderPathCommands()
             
             
             case CMD_RENDERUI:
             case CMD_RENDERUI:
                 {
                 {
-                    SetRenderTargets(command);
-                    GetSubsystem<UI>()->Render(false);
+                    //SetRenderTargets(command);
+                    //GetSubsystem<UI>()->Render(false);
                 }
                 }
                 break;
                 break;
 
 

+ 1 - 170
Source/Atomic/Input/Input.cpp

@@ -34,7 +34,6 @@
 #include "../Resource/ResourceCache.h"
 #include "../Resource/ResourceCache.h"
 #include "../IO/RWOpsWrapper.h"
 #include "../IO/RWOpsWrapper.h"
 #include "../Core/StringUtils.h"
 #include "../Core/StringUtils.h"
-#include "../UI/UI.h"
 
 
 #include <cstring>
 #include <cstring>
 
 
@@ -852,34 +851,11 @@ int Input::AddScreenJoystick(XMLFile* layoutFile, XMLFile* styleFile)
 
 
 bool Input::RemoveScreenJoystick(SDL_JoystickID id)
 bool Input::RemoveScreenJoystick(SDL_JoystickID id)
 {
 {
-    if (!joysticks_.Contains(id))
-    {
-        LOGERRORF("Failed to remove non-existing screen joystick ID #%d", id);
-        return false;
-    }
-
-    JoystickState& state = joysticks_[id];
-    if (!state.screenJoystick_)
-    {
-        LOGERRORF("Failed to remove joystick with ID #%d which is not a screen joystick", id);
-        return false;
-    }
-
-    state.screenJoystick_->Remove();
-    joysticks_.Erase(id);
-
     return true;
     return true;
 }
 }
 
 
 void Input::SetScreenJoystickVisible(SDL_JoystickID id, bool enable)
 void Input::SetScreenJoystickVisible(SDL_JoystickID id, bool enable)
 {
 {
-    if (joysticks_.Contains(id))
-    {
-        JoystickState& state = joysticks_[id];
-
-        if (state.screenJoystick_)
-            state.screenJoystick_->SetVisible(enable);
-    }
 }
 }
 
 
 void Input::SetScreenKeyboardVisible(bool enable)
 void Input::SetScreenKeyboardVisible(bool enable)
@@ -1150,8 +1126,7 @@ JoystickState* Input::GetJoystick(SDL_JoystickID id)
 
 
 bool Input::IsScreenJoystickVisible(SDL_JoystickID id) const
 bool Input::IsScreenJoystickVisible(SDL_JoystickID id) const
 {
 {
-    HashMap<SDL_JoystickID, JoystickState>::ConstIterator i = joysticks_.Find(id);
-    return i != joysticks_.End() && i->second_.screenJoystick_ && i->second_.screenJoystick_->IsVisible();
+    return false;
 }
 }
 
 
 bool Input::GetScreenKeyboardSupport() const
 bool Input::GetScreenKeyboardSupport() const
@@ -2006,14 +1981,6 @@ void Input::HandleScreenMode(StringHash eventType, VariantMap& eventData)
         SetMousePosition(center);
         SetMousePosition(center);
         lastMousePosition_ = center;
         lastMousePosition_ = center;
     }
     }
-
-    // Resize screen joysticks to new screen size
-    for (HashMap<SDL_JoystickID, JoystickState>::Iterator i = joysticks_.Begin(); i != joysticks_.End(); ++i)
-    {
-        UIElement* screenjoystick = i->second_.screenJoystick_;
-        if (screenjoystick)
-            screenjoystick->SetSize(graphics_->GetWidth(), graphics_->GetHeight());
-    }
     
     
     focusedThisFrame_ = true;
     focusedThisFrame_ = true;
 
 
@@ -2029,143 +1996,7 @@ void Input::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
 
 
 void Input::HandleScreenJoystickTouch(StringHash eventType, VariantMap& eventData)
 void Input::HandleScreenJoystickTouch(StringHash eventType, VariantMap& eventData)
 {
 {
-    using namespace TouchBegin;
-
-    // Only interested in events from screen joystick(s)
-    TouchState& state = touches_[eventData[P_TOUCHID].GetInt()];
-    IntVector2 position(state.position_.x_, state.position_.y_);
-    UIElement* element = eventType == E_TOUCHBEGIN ? GetSubsystem<UI>()->GetElementAt(position) : state.touchedElement_;
-    if (!element)
-        return;
-    Variant variant = element->GetVar(VAR_SCREEN_JOYSTICK_ID);
-    if (variant.IsEmpty())
-        return;
-    SDL_JoystickID joystickID = variant.GetInt();
-
-    if (eventType == E_TOUCHEND)
-        state.touchedElement_.Reset();
-    else
-        state.touchedElement_ = element;
-
-    // Prepare a fake SDL event
-    SDL_Event evt;
-
-    const String& name = element->GetName();
-    if (name.StartsWith("Button"))
-    {
-        if (eventType == E_TOUCHMOVE)
-            return;
-
-        // Determine whether to inject a joystick event or keyboard/mouse event
-        Variant keyBindingVar = element->GetVar(VAR_BUTTON_KEY_BINDING);
-        Variant mouseButtonBindingVar = element->GetVar(VAR_BUTTON_MOUSE_BUTTON_BINDING);
-        if (keyBindingVar.IsEmpty() && mouseButtonBindingVar.IsEmpty())
-        {
-            evt.type = eventType == E_TOUCHBEGIN ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
-            evt.jbutton.which = joystickID;
-            evt.jbutton.button = ToUInt(name.Substring(6));
-        }
-        else
-        {
-            if (!keyBindingVar.IsEmpty())
-            {
-                evt.type = eventType == E_TOUCHBEGIN ? SDL_KEYDOWN : SDL_KEYUP;
-                evt.key.keysym.sym = keyBindingVar.GetInt();
-                evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
-            }
-            if (!mouseButtonBindingVar.IsEmpty())
-            {
-                // Mouse button are sent as extra events besides key events
-                // Disable touch emulation handling during this to prevent endless loop
-                bool oldTouchEmulation = touchEmulation_;
-                touchEmulation_ = false;
-
-                SDL_Event evt;
-                evt.type = eventType == E_TOUCHBEGIN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
-                evt.button.button = mouseButtonBindingVar.GetInt();
-                HandleSDLEvent(&evt);
-
-                touchEmulation_ = oldTouchEmulation;
-            }
-        }
-    }
-    else if (name.StartsWith("Hat"))
-    {
-        Variant keyBindingVar = element->GetVar(VAR_BUTTON_KEY_BINDING);
-        if (keyBindingVar.IsEmpty())
-        {
-            evt.type = SDL_JOYHATMOTION;
-            evt.jaxis.which = joystickID;
-            evt.jhat.hat = ToUInt(name.Substring(3));
-            evt.jhat.value = HAT_CENTER;
-            if (eventType != E_TOUCHEND)
-            {
-                IntVector2 relPosition = position - element->GetScreenPosition() - element->GetSize() / 2;
-                if (relPosition.y_ < 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
-                    evt.jhat.value |= HAT_UP;
-                if (relPosition.y_ > 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
-                    evt.jhat.value |= HAT_DOWN;
-                if (relPosition.x_ < 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
-                    evt.jhat.value |= HAT_LEFT;
-                if (relPosition.x_ > 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
-                    evt.jhat.value |= HAT_RIGHT;
-            }
-        }
-        else
-        {
-            // Hat is binded by 4 keys, like 'WASD'
-            String keyBinding = keyBindingVar.GetString();
-
-            if (eventType == E_TOUCHEND)
-            {
-                evt.type = SDL_KEYUP;
-                evt.key.keysym.sym = element->GetVar(VAR_LAST_KEYSYM).GetInt();
-                if (!evt.key.keysym.sym)
-                    return;
-
-                element->SetVar(VAR_LAST_KEYSYM, 0);
-            }
-            else
-            {
-                evt.type = SDL_KEYDOWN;
-                IntVector2 relPosition = position - element->GetScreenPosition() - element->GetSize() / 2;
-                if (relPosition.y_ < 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
-                    evt.key.keysym.sym = keyBinding[0];
-                else if (relPosition.y_ > 0 && Abs(relPosition.x_ * 3 / 2) < Abs(relPosition.y_))
-                    evt.key.keysym.sym = keyBinding[1];
-                else if (relPosition.x_ < 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
-                    evt.key.keysym.sym = keyBinding[2];
-                else if (relPosition.x_ > 0 && Abs(relPosition.y_ * 3 / 2) < Abs(relPosition.x_))
-                    evt.key.keysym.sym = keyBinding[3];
-                else
-                    return;
-
-                if (eventType == E_TOUCHMOVE && evt.key.keysym.sym != element->GetVar(VAR_LAST_KEYSYM).GetInt())
-                {
-                    // Dragging past the directional boundary will cause an additional key up event for previous key symbol
-                    SDL_Event evt;
-                    evt.type = SDL_KEYUP;
-                    evt.key.keysym.sym = element->GetVar(VAR_LAST_KEYSYM).GetInt();
-                    if (evt.key.keysym.sym)
-                    {
-                        evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
-                        HandleSDLEvent(&evt);
-                    }
-
-                    element->SetVar(VAR_LAST_KEYSYM, 0);
-                }
-
-                evt.key.keysym.scancode = SDL_SCANCODE_UNKNOWN;
-
-                element->SetVar(VAR_LAST_KEYSYM, evt.key.keysym.sym);
-            }
-        }
-    }
-    else
-        return;
 
 
-    // Handle the fake SDL event to turn it into Atomic genuine event
-    HandleSDLEvent(&evt);
 }
 }
 
 
 }
 }

+ 2 - 4
Source/Atomic/Input/Input.h

@@ -28,8 +28,6 @@
 #include "../Core/Object.h"
 #include "../Core/Object.h"
 #include "../Container/List.h"
 #include "../Container/List.h"
 
 
-#include "../UI/Cursor.h"
-
 namespace Atomic
 namespace Atomic
 {
 {
 
 
@@ -74,7 +72,7 @@ struct JoystickState
 {
 {
     /// Construct with defaults.
     /// Construct with defaults.
     JoystickState() :
     JoystickState() :
-        joystick_(0), controller_(0), screenJoystick_(0)
+        joystick_(0), controller_(0)
     {
     {
     }
     }
 
 
@@ -107,7 +105,7 @@ struct JoystickState
     /// SDL game controller.
     /// SDL game controller.
     SDL_GameController* controller_;
     SDL_GameController* controller_;
     /// UI element containing the screen joystick.
     /// UI element containing the screen joystick.
-    UIElement* screenJoystick_;
+    // UIElement* screenJoystick_;
     /// Joystick name.
     /// Joystick name.
     String name_;
     String name_;
     /// Button up/down state.
     /// Button up/down state.

+ 0 - 207
Source/Atomic/UI/BorderImage.cpp

@@ -1,207 +0,0 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "Precompiled.h"
-#include "../UI/BorderImage.h"
-#include "../Core/Context.h"
-#include "../Resource/ResourceCache.h"
-#include "../Graphics/Texture2D.h"
-
-#include "../DebugNew.h"
-
-namespace Atomic
-{
-
-extern const char* blendModeNames[];
-extern const char* UI_CATEGORY;
-
-BorderImage::BorderImage(Context* context) :
-    UIElement(context),
-    imageRect_(IntRect::ZERO),
-    border_(IntRect::ZERO),
-    imageBorder_(IntRect::ZERO),
-    hoverOffset_(IntVector2::ZERO),
-    blendMode_(BLEND_REPLACE),
-    tiled_(false)
-{
-}
-
-BorderImage::~BorderImage()
-{
-}
-
-void BorderImage::RegisterObject(Context* context)
-{
-    context->RegisterFactory<BorderImage>(UI_CATEGORY);
-
-    COPY_BASE_ATTRIBUTES(UIElement);
-    MIXED_ACCESSOR_ATTRIBUTE("Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
-    ACCESSOR_ATTRIBUTE("Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Border", GetBorder, SetBorder, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Image Border", GetImageBorder, SetImageBorder, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Hover Image Offset", GetHoverOffset, SetHoverOffset, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Tiled", IsTiled, SetTiled, bool, false, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
-}
-
-void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
-{
-    GetBatches(batches, vertexData, currentScissor, hovering_ || selected_ || HasFocus() ? hoverOffset_ : IntVector2::ZERO);
-}
-
-void BorderImage::SetTexture(Texture* texture)
-{
-    texture_ = texture;
-    if (imageRect_ == IntRect::ZERO)
-        SetFullImageRect();
-}
-
-void BorderImage::SetImageRect(const IntRect& rect)
-{
-    if (rect != IntRect::ZERO)
-        imageRect_ = rect;
-}
-
-void BorderImage::SetFullImageRect()
-{
-    if (texture_)
-        SetImageRect(IntRect(0, 0, texture_->GetWidth(), texture_->GetHeight()));
-}
-
-void BorderImage::SetBorder(const IntRect& rect)
-{
-    border_.left_ = Max(rect.left_, 0);
-    border_.top_ = Max(rect.top_, 0);
-    border_.right_ = Max(rect.right_, 0);
-    border_.bottom_ = Max(rect.bottom_, 0);
-}
-
-void BorderImage::SetImageBorder(const IntRect& rect)
-{
-    imageBorder_.left_ = Max(rect.left_, 0);
-    imageBorder_.top_ = Max(rect.top_, 0);
-    imageBorder_.right_ = Max(rect.right_, 0);
-    imageBorder_.bottom_ = Max(rect.bottom_, 0);
-}
-
-void BorderImage::SetHoverOffset(const IntVector2& offset)
-{
-    hoverOffset_ = offset;
-}
-
-void BorderImage::SetHoverOffset(int x, int y)
-{
-    hoverOffset_ = IntVector2(x, y);
-}
-
-void BorderImage::SetBlendMode(BlendMode mode)
-{
-    blendMode_ = mode;
-}
-
-void BorderImage::SetTiled(bool enable)
-{
-    tiled_ = enable;
-}
-
-void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor, const IntVector2& offset)
-{
-    bool allOpaque = true;
-    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)
-        allOpaque = false;
-
-    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
-    const IntRect& uvBorder = (imageBorder_ == IntRect::ZERO) ? border_ : imageBorder_;
-    int x = GetIndentWidth();
-    IntVector2 size = GetSize();
-    size.x_ -= x;
-    IntVector2 innerSize(
-        Max(size.x_ - border_.left_ - border_.right_, 0),
-        Max(size.y_ - border_.top_ - border_.bottom_, 0));
-    IntVector2 innerUvSize(
-        Max(imageRect_.right_ - imageRect_.left_ - uvBorder.left_ - uvBorder.right_, 0),
-        Max(imageRect_.bottom_ - imageRect_.top_ - uvBorder.top_ - uvBorder.bottom_, 0));
-
-    IntVector2 uvTopLeft(imageRect_.left_, imageRect_.top_);
-    uvTopLeft += offset;
-
-    // Top
-    if (border_.top_)
-    {
-        if (border_.left_)
-            batch.AddQuad(x, 0, border_.left_, border_.top_, uvTopLeft.x_, uvTopLeft.y_, uvBorder.left_, uvBorder.top_);
-        if (innerSize.x_)
-            batch.AddQuad(x + border_.left_, 0, innerSize.x_, border_.top_, uvTopLeft.x_ + uvBorder.left_, uvTopLeft.y_,
-                innerUvSize.x_, uvBorder.top_, tiled_);
-        if (border_.right_)
-            batch.AddQuad(x + border_.left_ + innerSize.x_, 0, border_.right_, border_.top_, uvTopLeft.x_ + uvBorder.left_ +
-                innerUvSize.x_, uvTopLeft.y_, uvBorder.right_, uvBorder.top_);
-    }
-    // Middle
-    if (innerSize.y_)
-    {
-        if (border_.left_)
-            batch.AddQuad(x, border_.top_, border_.left_, innerSize.y_, uvTopLeft.x_, uvTopLeft.y_ + uvBorder.top_,
-                uvBorder.left_, innerUvSize.y_, tiled_);
-        if (innerSize.x_)
-            batch.AddQuad(x + border_.left_, border_.top_, innerSize.x_, innerSize.y_, uvTopLeft.x_ + uvBorder.left_,
-                uvTopLeft.y_ + uvBorder.top_, innerUvSize.x_, innerUvSize.y_, tiled_);
-        if (border_.right_)
-            batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_, border_.right_, innerSize.y_, uvTopLeft.x_ +
-                uvBorder.left_ + innerUvSize.x_, uvTopLeft.y_ + uvBorder.top_, uvBorder.right_, innerUvSize.y_, tiled_);
-    }
-    // Bottom
-    if (border_.bottom_)
-    {
-        if (border_.left_)
-            batch.AddQuad(x, border_.top_ + innerSize.y_, border_.left_, border_.bottom_, uvTopLeft.x_, uvTopLeft.y_ +
-                uvBorder.top_ + innerUvSize.y_, uvBorder.left_, uvBorder.bottom_);
-        if (innerSize.x_)
-            batch.AddQuad(x + border_.left_, border_.top_ + innerSize.y_, innerSize.x_, border_.bottom_, uvTopLeft.x_ +
-                uvBorder.left_, uvTopLeft.y_ + uvBorder.top_ + innerUvSize.y_, innerUvSize.x_, uvBorder.bottom_, tiled_);
-        if (border_.right_)
-            batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_ + innerSize.y_, border_.right_, border_.bottom_,
-                uvTopLeft.x_ + uvBorder.left_ + innerUvSize.x_, uvTopLeft.y_ + uvBorder.top_ + innerUvSize.y_,
-                uvBorder.right_, uvBorder.bottom_);
-    }
-
-    UIBatch::AddOrMerge(batch, batches);
-
-    // Reset hovering for next frame
-    hovering_ = false;
-}
-
-void BorderImage::SetTextureAttr(const ResourceRef& value)
-{
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    SetTexture(cache->GetResource<Texture2D>(value.name_));
-}
-
-ResourceRef BorderImage::GetTextureAttr() const
-{
-    return GetResourceRef(texture_, Texture2D::GetTypeStatic());
-}
-
-}

+ 0 - 109
Source/Atomic/UI/BorderImage.h

@@ -1,109 +0,0 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../Graphics/GraphicsDefs.h"
-#include "../UI/UIElement.h"
-
-namespace Atomic
-{
-
-class Texture;
-class Texture2D;
-
-/// %Image %UI element with optional border.
-class ATOMIC_API BorderImage : public UIElement
-{
-    OBJECT(BorderImage);
-
-public:
-    /// Construct.
-    BorderImage(Context* context);
-    /// Destruct.
-    virtual ~BorderImage();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Return UI rendering batches.
-    virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-
-    /// Set texture.
-    void SetTexture(Texture* texture);
-    /// Set part of texture to use as the image.
-    void SetImageRect(const IntRect& rect);
-    /// Use whole texture as the image.
-    void SetFullImageRect();
-    /// Set border dimensions on the screen.
-    void SetBorder(const IntRect& rect);
-    /// Set border dimensions on the image. If zero (default) uses the screen dimensions, resulting in pixel-perfect borders.
-    void SetImageBorder(const IntRect& rect);
-    /// Set offset to image rectangle used on hover.
-    void SetHoverOffset(const IntVector2& offset);
-    /// Set offset to image rectangle used on hover.
-    void SetHoverOffset(int x, int y);
-    /// Set blend mode.
-    void SetBlendMode(BlendMode mode);
-    /// Set tiled mode.
-    void SetTiled(bool enable);
-
-    /// Return texture.
-    Texture* GetTexture() const { return texture_; }
-    /// Return image rectangle.
-    const IntRect& GetImageRect() const { return imageRect_; }
-    /// Return border screen dimensions.
-    const IntRect& GetBorder() const { return border_; }
-    /// Return border image dimensions. Zero rect uses border screen dimensions.
-    const IntRect& GetImageBorder() const { return imageBorder_; }
-    /// Return offset to image rectangle used on hover.
-    const IntVector2& GetHoverOffset() const { return hoverOffset_; }
-    /// Return blend mode.
-    BlendMode GetBlendMode() const { return blendMode_; }
-    /// Return whether is tiled.
-    bool IsTiled() const { return tiled_; }
-
-    /// Set texture attribute.
-    void SetTextureAttr(const ResourceRef& value);
-    /// Return texture attribute.
-    ResourceRef GetTextureAttr() const;
-
-protected:
-    /// Return UI rendering batches with offset to image rectangle.
-    void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor, const IntVector2& offset);
-
-    /// Texture.
-    SharedPtr<Texture> texture_;
-    /// Image rectangle.
-    IntRect imageRect_;
-    /// Border dimensions on screen.
-    IntRect border_;
-    /// Border dimensions on the image.
-    IntRect imageBorder_;
-    /// Offset to image rectangle on hover.
-    IntVector2 hoverOffset_;
-    /// Blend mode flag.
-    BlendMode blendMode_;
-    /// Tiled flag.
-    bool tiled_;
-};
-
-}

+ 0 - 309
Source/Atomic/UI/Cursor.cpp

@@ -1,309 +0,0 @@
-//
-// Copyright (c) 2008-2015 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "../Core/Context.h"
-#include "../UI/Cursor.h"
-#include "../Input/Input.h"
-#include "../Input/InputEvents.h"
-#include "../IO/Log.h"
-#include "../Container/Ptr.h"
-#include "../Resource/ResourceCache.h"
-#include "../Graphics/Texture2D.h"
-#include "../UI/UI.h"
-
-#include "../DebugNew.h"
-
-namespace Atomic
-{
-
-static const char* shapeNames[] =
-{
-    "Normal",
-    "IBeam",
-    "Cross",
-    "ResizeVertical",
-    "ResizeDiagonalTopRight",
-    "ResizeHorizontal",
-    "ResizeDiagonalTopLeft",
-    "ResizeAll",
-    "AcceptDrop",
-    "RejectDrop",
-    "Busy",
-    "BusyArrow"
-};
-
-/// OS cursor shape lookup table matching cursor shape enumeration
-static const int osCursorLookup[CS_MAX_SHAPES] =
-{
-    SDL_SYSTEM_CURSOR_ARROW,    // CS_NORMAL
-    SDL_SYSTEM_CURSOR_IBEAM,     // CS_IBEAM
-    SDL_SYSTEM_CURSOR_CROSSHAIR, // CS_CROSS
-    SDL_SYSTEM_CURSOR_SIZENS,   // CS_RESIZEVERTICAL
-    SDL_SYSTEM_CURSOR_SIZENESW, // CS_RESIZEDIAGONAL_TOPRIGHT
-    SDL_SYSTEM_CURSOR_SIZEWE,   // CS_RESIZEHORIZONTAL
-    SDL_SYSTEM_CURSOR_SIZENWSE, // CS_RESIZEDIAGONAL_TOPLEFT
-    SDL_SYSTEM_CURSOR_SIZEALL,   // CS_RESIZE_ALL
-    SDL_SYSTEM_CURSOR_HAND,     // CS_ACCEPTDROP
-    SDL_SYSTEM_CURSOR_NO,       // CS_REJECTDROP
-    SDL_SYSTEM_CURSOR_WAIT,   // CS_BUSY
-    SDL_SYSTEM_CURSOR_WAITARROW // CS_BUSY_ARROW
-};
-
-extern const char* UI_CATEGORY;
-
-Cursor::Cursor(Context* context) :
-    BorderImage(context),
-    shape_(shapeNames[CS_NORMAL]),
-    useSystemShapes_(false),
-    osShapeDirty_(false)
-{
-    // Define the defaults for system cursor usage.
-    for (unsigned i = 0; i < CS_MAX_SHAPES; i++)
-        shapeInfos_[shapeNames[i]] = CursorShapeInfo(i);
-
-    // Subscribe to OS mouse cursor visibility changes to be able to reapply the cursor shape
-    SubscribeToEvent(E_MOUSEVISIBLECHANGED, HANDLER(Cursor, HandleMouseVisibleChanged));
-}
-
-Cursor::~Cursor()
-{
-    for (HashMap<String, CursorShapeInfo>::Iterator i = shapeInfos_.Begin(); i != shapeInfos_.End(); ++i)
-    {
-        if (i->second_.osCursor_)
-        {
-            SDL_FreeCursor(i->second_.osCursor_);
-            i->second_.osCursor_ = 0;
-        }
-    }
-}
-
-void Cursor::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Cursor>(UI_CATEGORY);
-
-    COPY_BASE_ATTRIBUTES(BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Priority", M_MAX_INT);
-    ACCESSOR_ATTRIBUTE("Use System Shapes", GetUseSystemShapes, SetUseSystemShapes, bool, false, AM_FILE);
-    MIXED_ACCESSOR_ATTRIBUTE("Shapes", GetShapesAttr, SetShapesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
-}
-
-void Cursor::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
-{
-    unsigned initialSize = vertexData.Size();
-    const IntVector2& offset = shapeInfos_[shape_].hotSpot_;
-    Vector2 floatOffset(-(float)offset.x_, -(float)offset.y_);
-
-    BorderImage::GetBatches(batches, vertexData, currentScissor);
-    for (unsigned i = initialSize; i < vertexData.Size(); i += 6)
-    {
-        vertexData[i] += floatOffset.x_;
-        vertexData[i + 1] += floatOffset.y_;
-    }
-}
-
-void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot)
-{
-    if (shape < CS_NORMAL || shape >= CS_MAX_SHAPES)
-    {
-        LOGERROR("Shape index out of bounds, can not define cursor shape");
-        return;
-    }
-
-    DefineShape(shapeNames[shape], image, imageRect, hotSpot);
-}
-
-void Cursor::DefineShape(const String& shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot)
-{
-    if (!image)
-        return;
-
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    
-    if (!shapeInfos_.Contains(shape))
-        shapeInfos_[shape] = CursorShapeInfo();
-
-    CursorShapeInfo& info = shapeInfos_[shape];
-
-    // Prefer to get the texture with same name from cache to prevent creating several copies of the texture
-    info.texture_ = cache->GetResource<Texture2D>(image->GetName(), false);
-    if (!info.texture_)
-    {
-        Texture2D* texture = new Texture2D(context_);
-        texture->SetData(SharedPtr<Image>(image));
-        info.texture_ = texture;
-    }
-
-    info.image_ = image;
-    info.imageRect_ = imageRect;
-    info.hotSpot_ = hotSpot;
-
-    // Remove existing SDL cursor
-    if (info.osCursor_)
-    {
-        SDL_FreeCursor(info.osCursor_);
-        info.osCursor_ = 0;
-    }
-
-    // Reset current shape if it was edited
-    if (shape_ == shape)
-    {
-        shape_ = String::EMPTY;
-        SetShape(shape);
-    }
-}
-
-
-void Cursor::SetShape(const String& shape)
-{
-    if (shape == String::EMPTY || shape.Empty() || shape_ == shape || !shapeInfos_.Contains(shape))
-        return;
-
-    shape_ = shape;
-
-    CursorShapeInfo& info = shapeInfos_[shape_];
-    texture_ = info.texture_;
-    imageRect_ = info.imageRect_;
-    SetSize(info.imageRect_.Size());
-
-    // To avoid flicker, the UI subsystem will apply the OS shape once per frame. Exception: if we are using the
-    // busy shape, set it immediately as we may block before that
-    osShapeDirty_ = true;
-    if (shape_ == shapeNames[CS_BUSY])
-        ApplyOSCursorShape();
-}
-
-void Cursor::SetShape(CursorShape shape)
-{
-    if (shape < CS_NORMAL || shape >= CS_MAX_SHAPES || shape_ == shapeNames[shape])
-        return;
-
-    SetShape(shapeNames[shape]);
-}
-
-void Cursor::SetUseSystemShapes(bool enable)
-{
-    if (enable != useSystemShapes_)
-    {
-        useSystemShapes_ = enable;
-        // Reapply current shape
-        osShapeDirty_ = true;
-    }
-}
-
-void Cursor::SetShapesAttr(const VariantVector& value)
-{
-    unsigned index = 0;
-    if (!value.Size())
-        return;
-
-    for (VariantVector::ConstIterator i = value.Begin(); i != value.End(); ++i)
-    {
-        VariantVector shapeVector = i->GetVariantVector();
-        if (shapeVector.Size() >= 4)
-        {
-            String shape = shapeVector[0].GetString();
-            ResourceRef ref = shapeVector[1].GetResourceRef();
-            IntRect imageRect = shapeVector[2].GetIntRect();
-            IntVector2 hotSpot = shapeVector[3].GetIntVector2();
-
-            DefineShape(shape, GetSubsystem<ResourceCache>()->GetResource<Image>(ref.name_), imageRect, hotSpot);
-        }
-    }
-}
-
-VariantVector Cursor::GetShapesAttr() const
-{
-    VariantVector ret;
-
-    for (HashMap<String, CursorShapeInfo>::ConstIterator i = shapeInfos_.Begin(); i != shapeInfos_.End(); ++i)
-    {
-        if (i->second_.imageRect_ != IntRect::ZERO)
-        {
-            // Could use a map but this simplifies the UI xml.
-            VariantVector shape;
-            shape.Push(i->first_);
-            shape.Push(GetResourceRef(i->second_.texture_, Texture2D::GetTypeStatic()));
-            shape.Push(i->second_.imageRect_);
-            shape.Push(i->second_.hotSpot_);
-            ret.Push(shape);
-        }
-    }
-
-    return ret;
-}
-
-void Cursor::ApplyOSCursorShape()
-{
-    // Mobile platforms do not support applying OS cursor shapes: comment out to avoid log error messages
-#if !defined(ANDROID) && !defined(IOS)
-    if (!osShapeDirty_ || !GetSubsystem<Input>()->IsMouseVisible() || GetSubsystem<UI>()->GetCursor() != this)
-        return;
-
-    CursorShapeInfo& info = shapeInfos_[shape_];
-
-    // Remove existing SDL cursor if is not a system shape while we should be using those, or vice versa
-    if (info.osCursor_ && info.systemDefined_ != useSystemShapes_)
-    {
-        SDL_FreeCursor(info.osCursor_);
-        info.osCursor_ = 0;
-    }
-
-    // Create SDL cursor now if necessary
-    if (!info.osCursor_)
-    {
-        // Create a system default shape
-        if (useSystemShapes_ && info.systemCursor_ >= 0 && info.systemCursor_ < CS_MAX_SHAPES)
-        {
-            info.osCursor_ = SDL_CreateSystemCursor((SDL_SystemCursor)osCursorLookup[info.systemCursor_]);
-            info.systemDefined_ = true;
-            if (!info.osCursor_)
-                LOGERROR("Could not create system cursor");
-        }
-        // Create from image
-        else if (info.image_)
-        {
-            SDL_Surface* surface = info.image_->GetSDLSurface(info.imageRect_);
-
-            if (surface)
-            {
-                info.osCursor_ = SDL_CreateColorCursor(surface, info.hotSpot_.x_, info.hotSpot_.y_);
-                info.systemDefined_ = false;
-                if (!info.osCursor_)
-                    LOGERROR("Could not create cursor from image " + info.image_->GetName());
-                SDL_FreeSurface(surface);
-            }
-        }
-    }
-
-    if (info.osCursor_)
-        SDL_SetCursor(info.osCursor_);
-
-    osShapeDirty_ = false;
-#endif
-}
-
-void Cursor::HandleMouseVisibleChanged(StringHash eventType, VariantMap& eventData)
-{
-    ApplyOSCursorShape();
-}
-
-}

+ 0 - 143
Source/Atomic/UI/Cursor.h

@@ -1,143 +0,0 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../UI/BorderImage.h"
-#include "../Resource/Image.h"
-#include "../Graphics/Texture.h"
-
-#include <SDL/include/SDL_mouse.h>
-
-namespace Atomic
-{
-
-/// %Cursor shapes recognized by the UI subsystem.
-enum CursorShape
-{
-    CS_NORMAL = 0,
-    CS_IBEAM,
-    CS_CROSS,
-    CS_RESIZEVERTICAL,
-    CS_RESIZEDIAGONAL_TOPRIGHT,
-    CS_RESIZEHORIZONTAL,
-    CS_RESIZEDIAGONAL_TOPLEFT,
-    CS_RESIZE_ALL,
-    CS_ACCEPTDROP,
-    CS_REJECTDROP,
-    CS_BUSY,
-    CS_BUSY_ARROW,
-    CS_MAX_SHAPES
-};
-
-/// %Cursor image and hotspot information.
-struct ATOMIC_API CursorShapeInfo
-{
-    /// Construct with defaults.
-    CursorShapeInfo() :
-        imageRect_(IntRect::ZERO),
-        hotSpot_(IntVector2::ZERO),
-        osCursor_(0),
-        systemDefined_(false),
-        systemCursor_(-1)
-    {
-    }
-
-    /// Construct with system cursor.
-    CursorShapeInfo(int systemCursor) :
-        imageRect_(IntRect::ZERO),
-        hotSpot_(IntVector2::ZERO),
-        osCursor_(0),
-        systemDefined_(false),
-        systemCursor_(systemCursor)
-    {
-    }
-
-    /// Image.
-    SharedPtr<Image> image_;
-    /// Texture.
-    SharedPtr<Texture> texture_;
-    /// Image rectangle.
-    IntRect imageRect_;
-    /// Hotspot coordinates.
-    IntVector2 hotSpot_;
-    /// System cursor index.
-    int systemCursor_;
-    /// OS cursor.
-    SDL_Cursor* osCursor_;
-    /// Whether the OS cursor is system defined.
-    bool systemDefined_;
-};
-
-/// Mouse cursor %UI element.
-class ATOMIC_API Cursor : public BorderImage
-{
-    OBJECT(Cursor);
-
-public:
-    /// Construct.
-    Cursor(Context* context);
-    /// Destruct.
-    virtual ~Cursor();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Return UI rendering batches.
-    virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-
-    /// Define a shape.
-    void DefineShape(const String& shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
-    /// Define a shape.
-    void DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
-    /// Set current shape.
-    void SetShape(const String& shape);
-    /// Set current shape.
-    void SetShape(CursorShape shape);
-    /// Set whether to use system default shapes. Is only possible when the OS mouse cursor has been set visible from the Input subsystem.
-    void SetUseSystemShapes(bool enable);
-    /// Get current shape.
-    const String& GetShape() const { return shape_; }
-    /// Return whether is using system default shapes.
-    bool GetUseSystemShapes() const { return useSystemShapes_; }
-
-    /// Set shapes attribute.
-    void SetShapesAttr(const VariantVector& value);
-    /// Return shapes attribute.
-    VariantVector GetShapesAttr() const;
-    /// Apply pending OS cursor shape. Called by UI. No-op when the OS mouse pointer is not used.
-    void ApplyOSCursorShape();
-
-protected:
-    /// Handle operating system mouse cursor visibility change event.
-    void HandleMouseVisibleChanged(StringHash eventType, VariantMap& eventData);
-
-    /// Current shape definition.
-    String shape_;
-    /// Shape definitions.
-    HashMap<String, CursorShapeInfo> shapeInfos_;
-    /// Use system default shapes flag.
-    bool useSystemShapes_;
-    /// OS cursor shape needs update flag.
-    bool osShapeDirty_;
-};
-
-}

+ 11 - 10
Source/Atomic/UI/TBUI.cpp

@@ -14,7 +14,6 @@
 #include "../Graphics/VertexBuffer.h"
 #include "../Graphics/VertexBuffer.h"
 #include "../Input/Input.h"
 #include "../Input/Input.h"
 #include "../Input/InputEvents.h"
 #include "../Input/InputEvents.h"
-#include "../UI/UI.h"
 #include "../UI/TBUI.h"
 #include "../UI/TBUI.h"
 
 
 #include <TurboBadger/tb_core.h>
 #include <TurboBadger/tb_core.h>
@@ -153,7 +152,7 @@ public:
             texture = tbuibitmap->texture_;
             texture = tbuibitmap->texture_;
         }
         }
 
 
-        UIBatch b(tbui_, BLEND_ALPHA , currentScissor_, texture, vertexData_);
+        UIBatch b(BLEND_ALPHA , currentScissor_, texture, vertexData_);
 
 
         float fadeAlpha = tbui_->GetFadeAlpha();
         float fadeAlpha = tbui_->GetFadeAlpha();
 
 
@@ -238,7 +237,7 @@ public:
 WeakPtr<Context> TBUI::readerContext_;
 WeakPtr<Context> TBUI::readerContext_;
 
 
 TBUI::TBUI(Context* context) :
 TBUI::TBUI(Context* context) :
-    UIElement(context),
+    Object(context),
     rootWidget_(0),
     rootWidget_(0),
     initialized_(false),
     initialized_(false),
     inputDisabled_(false),
     inputDisabled_(false),
@@ -312,7 +311,7 @@ void TBUI::Initialize()
     int width = graphics->GetWidth();
     int width = graphics->GetWidth();
     int height = graphics->GetHeight();
     int height = graphics->GetHeight();
     rootWidget_->SetSize(width, height);
     rootWidget_->SetSize(width, height);
-    SetSize(width, height);
+    //SetSize(width, height);
 
 
     rootWidget_->SetVisibilility(tb::WIDGET_VISIBILITY_VISIBLE);
     rootWidget_->SetVisibilility(tb::WIDGET_VISIBILITY_VISIBLE);
 
 
@@ -362,7 +361,7 @@ void TBUI::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
 
 
 void TBUI::SubmitBatchVertexData(Texture* texture, const PODVector<float>& vertexData)
 void TBUI::SubmitBatchVertexData(Texture* texture, const PODVector<float>& vertexData)
 {
 {
-    UIBatch b(this, BLEND_ALPHA , TBUIRenderer::renderer_->currentScissor_, texture, &vertexData_);
+    UIBatch b(BLEND_ALPHA , TBUIRenderer::renderer_->currentScissor_, texture, &vertexData_);
 
 
     unsigned begin = b.vertexData_->Size();
     unsigned begin = b.vertexData_->Size();
     b.vertexData_->Resize(begin + vertexData.Size());
     b.vertexData_->Resize(begin + vertexData.Size());
@@ -385,7 +384,7 @@ void TBUI::HandleScreenMode(StringHash eventType, VariantMap& eventData)
 
 
     using namespace ScreenMode;
     using namespace ScreenMode;
     rootWidget_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
     rootWidget_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
-    SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
+    //SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
 }
 }
 
 
 void TBUI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
 void TBUI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
@@ -397,7 +396,7 @@ void TBUI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
     unsigned button = eventData[P_BUTTON].GetUInt();
     unsigned button = eventData[P_BUTTON].GetUInt();
 
 
     IntVector2 pos;
     IntVector2 pos;
-    pos = GetSubsystem<UI>()->GetCursorPosition();
+    pos = GetSubsystem<Input>()->GetMousePosition();
 
 
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
     int qualifiers = input->GetQualifiers();
     int qualifiers = input->GetQualifiers();
@@ -441,8 +440,9 @@ void TBUI::HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
     unsigned button = eventData[P_BUTTON].GetUInt();
     unsigned button = eventData[P_BUTTON].GetUInt();
 
 
     IntVector2 pos;
     IntVector2 pos;
-    pos = GetSubsystem<UI>()->GetCursorPosition();
+
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
+    pos = input->GetMousePosition();
     int qualifiers = input->GetQualifiers();
     int qualifiers = input->GetQualifiers();
 
 
 #ifdef ATOMIC_PLATFORM_WINDOWS
 #ifdef ATOMIC_PLATFORM_WINDOWS
@@ -894,8 +894,9 @@ void TBUI::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
     batches_.Clear();
     batches_.Clear();
     vertexData_.Clear();
     vertexData_.Clear();
 
 
-    const IntVector2& rootSize = GetSize();
-    IntRect currentScissor = IntRect(0, 0, rootSize.x_, rootSize.y_);
+    TBRect rect = rootWidget_->GetRect();
+
+    IntRect currentScissor = IntRect(0, 0, rect.w, rect.h);
     GetBatches(batches_, vertexData_, currentScissor);
     GetBatches(batches_, vertexData_, currentScissor);
 
 
 }
 }

+ 3 - 2
Source/Atomic/UI/TBUI.h

@@ -2,7 +2,8 @@
 
 
 #ifdef ATOMIC_TBUI
 #ifdef ATOMIC_TBUI
 
 
-#include "UIElement.h"
+#include "../Core/Object.h"
+#include "../UI/UIBatch.h"
 
 
 namespace tb
 namespace tb
 {
 {
@@ -17,7 +18,7 @@ namespace Atomic
 class VertexBuffer;
 class VertexBuffer;
 
 
 /// %UI element which renders a 3D scene.
 /// %UI element which renders a 3D scene.
-class ATOMIC_API TBUI : public UIElement
+class ATOMIC_API TBUI : public Object
 {
 {
     OBJECT(TBUI);
     OBJECT(TBUI);
 
 

+ 0 - 1462
Source/Atomic/UI/UI.cpp

@@ -1,1462 +0,0 @@
-//
-// Copyright (c) 2008-2015 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "Precompiled.h"
-#include "../Core/Context.h"
-#include "../Core/CoreEvents.h"
-#include "../UI/Cursor.h"
-#include "../Graphics/Graphics.h"
-#include "../Graphics/GraphicsEvents.h"
-#include "../Input/Input.h"
-#include "../Input/InputEvents.h"
-#include "../IO/Log.h"
-#include "../Math/Matrix3x4.h"
-#include "../Core/Profiler.h"
-#include "../Resource/ResourceCache.h"
-#include "../Graphics/Shader.h"
-#include "../Graphics/ShaderVariation.h"
-#include "../Container/Sort.h"
-#include "../Graphics/Texture2D.h"
-#include "../UI/UI.h"
-#include "../UI/UIEvents.h"
-#include "../Graphics/VertexBuffer.h"
-
-#include <SDL/include/SDL.h>
-
-#include "../DebugNew.h"
-
-#define TOUCHID_MASK(id) (1 << id)
-
-namespace Atomic
-{
-
-StringHash VAR_ORIGIN("Origin");
-const StringHash VAR_ORIGINAL_PARENT("OriginalParent");
-const StringHash VAR_ORIGINAL_CHILD_INDEX("OriginalChildIndex");
-const StringHash VAR_PARENT_CHANGED("ParentChanged");
-
-const float DEFAULT_DOUBLECLICK_INTERVAL = 0.5f;
-const float DEFAULT_DRAGBEGIN_INTERVAL = 0.5f;
-const float DEFAULT_TOOLTIP_DELAY = 0.5f;
-const int DEFAULT_DRAGBEGIN_DISTANCE = 5;
-const int DEFAULT_FONT_TEXTURE_MAX_SIZE = 2048;
-
-const char* UI_CATEGORY = "UI";
-
-UI::UI(Context* context) :
-    Object(context),
-    rootElement_(new UIElement(context)),
-    rootModalElement_(new UIElement(context)),
-    doubleClickInterval_(DEFAULT_DOUBLECLICK_INTERVAL),
-    dragBeginInterval_(DEFAULT_DRAGBEGIN_INTERVAL),
-    defaultToolTipDelay_(DEFAULT_TOOLTIP_DELAY),
-    dragBeginDistance_(DEFAULT_DRAGBEGIN_DISTANCE),
-    mouseButtons_(0),
-    lastMouseButtons_(0),
-    qualifiers_(0),
-    maxFontTextureSize_(DEFAULT_FONT_TEXTURE_MAX_SIZE),
-    dragElementsCount_(0),
-    dragConfirmedCount_(0),
-    initialized_(false),
-    usingTouchInput_(false),
-    #ifdef WIN32
-    nonFocusedMouseWheel_(false),    // Default MS Windows behaviour
-    #else
-    nonFocusedMouseWheel_(true),     // Default Mac OS X and Linux behaviour
-    #endif
-    useSystemClipboard_(false),
-    #if defined(ANDROID) || defined(IOS)
-    useScreenKeyboard_(true),
-    #else
-    useScreenKeyboard_(false),
-    #endif
-    useMutableGlyphs_(false),
-    forceAutoHint_(false),
-    nonModalBatchSize_(0)
-{
-    rootElement_->SetTraversalMode(TM_DEPTH_FIRST);
-    rootModalElement_->SetTraversalMode(TM_DEPTH_FIRST);
-
-    // Register UI library object factories
-    RegisterUILibrary(context_);
-
-    SubscribeToEvent(E_SCREENMODE, HANDLER(UI, HandleScreenMode));
-    SubscribeToEvent(E_MOUSEBUTTONDOWN, HANDLER(UI, HandleMouseButtonDown));
-    SubscribeToEvent(E_MOUSEBUTTONUP, HANDLER(UI, HandleMouseButtonUp));
-    SubscribeToEvent(E_MOUSEMOVE, HANDLER(UI, HandleMouseMove));
-    SubscribeToEvent(E_MOUSEWHEEL, HANDLER(UI, HandleMouseWheel));
-    SubscribeToEvent(E_TOUCHBEGIN, HANDLER(UI, HandleTouchBegin));
-    SubscribeToEvent(E_TOUCHEND, HANDLER(UI, HandleTouchEnd));
-    SubscribeToEvent(E_TOUCHMOVE, HANDLER(UI, HandleTouchMove));
-    SubscribeToEvent(E_KEYDOWN, HANDLER(UI, HandleKeyDown));
-    SubscribeToEvent(E_TEXTINPUT, HANDLER(UI, HandleTextInput));
-    SubscribeToEvent(E_DROPFILE, HANDLER(UI, HandleDropFile));
-
-    // Try to initialize right now, but skip if screen mode is not yet set
-    Initialize();
-}
-
-UI::~UI()
-{
-}
-
-void UI::SetCursor(Cursor* cursor)
-{
-    // Remove old cursor (if any) and set new
-    if (cursor_)
-    {
-        rootElement_->RemoveChild(cursor_);
-        cursor_.Reset();
-    }
-    if (cursor)
-    {
-        rootElement_->AddChild(cursor);
-        cursor_ = cursor;
-
-        IntVector2 pos = cursor_->GetPosition();
-        const IntVector2& rootSize = rootElement_->GetSize();
-        pos.x_ = Clamp(pos.x_, 0, rootSize.x_ - 1);
-        pos.y_ = Clamp(pos.y_, 0, rootSize.y_ - 1);
-        cursor_->SetPosition(pos);
-    }
-}
-
-void UI::SetFocusElement(UIElement* element, bool byKey)
-{
-    using namespace FocusChanged;
-
-    UIElement* originalElement = element;
-
-    if (element)
-    {
-        // Return if already has focus
-        if (focusElement_ == element)
-            return;
-
-        // Only allow child elements of the modal element to receive focus
-        if (HasModalElement())
-        {
-            UIElement* topLevel = element->GetParent();
-            while (topLevel && topLevel->GetParent() != rootElement_)
-                topLevel = topLevel->GetParent();
-            if (topLevel)   // If parented to non-modal root then ignore
-                return;
-        }
-
-        // Search for an element in the hierarchy that can alter focus. If none found, exit
-        element = GetFocusableElement(element);
-        if (!element)
-            return;
-    }
-
-    // Remove focus from the old element
-    if (focusElement_)
-    {
-        UIElement* oldFocusElement = focusElement_;
-        focusElement_.Reset();
-
-        VariantMap& focusEventData = GetEventDataMap();
-        focusEventData[Defocused::P_ELEMENT] = oldFocusElement;
-        oldFocusElement->SendEvent(E_DEFOCUSED, focusEventData);
-    }
-
-    // Then set focus to the new
-    if (element && element->GetFocusMode() >= FM_FOCUSABLE)
-    {
-        focusElement_ = element;
-
-        VariantMap& focusEventData = GetEventDataMap();
-        focusEventData[Focused::P_ELEMENT] = element;
-        focusEventData[Focused::P_BYKEY] = byKey;
-        element->SendEvent(E_FOCUSED, focusEventData);
-    }
-
-    VariantMap& eventData = GetEventDataMap();
-    eventData[P_CLICKEDELEMENT] = originalElement;
-    eventData[P_ELEMENT] = element;
-    SendEvent(E_FOCUSCHANGED, eventData);
-}
-
-void UI::Clear()
-{
-    rootElement_->RemoveAllChildren();
-    rootModalElement_->RemoveAllChildren();
-    if (cursor_)
-        rootElement_->AddChild(cursor_);
-}
-
-void UI::Update(float timeStep)
-{
-    assert(rootElement_ && rootModalElement_);
-
-    PROFILE(UpdateUI);
-
-    // Expire hovers
-    for (HashMap<WeakPtr<UIElement>, bool>::Iterator i = hoveredElements_.Begin(); i != hoveredElements_.End(); ++i)
-        i->second_ = false;
-
-    Input* input = GetSubsystem<Input>();
-    bool mouseGrabbed = input->IsMouseGrabbed();
-
-    IntVector2 cursorPos;
-    bool cursorVisible;
-    GetCursorPositionAndVisible(cursorPos, cursorVisible);
-
-    // Drag begin based on time
-    if (dragElementsCount_ > 0 && !mouseGrabbed)
-    {
-        for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End(); )
-        {
-            WeakPtr<UIElement> dragElement = i->first_;
-            UI::DragData* dragData = i->second_;
-
-            if (!dragElement)
-            {
-                i = DragElementErase(i);
-                continue;
-            }
-
-            if (!dragData->dragBeginPending)
-            {
-                ++i;
-                continue;
-            }
-
-            if (dragData->dragBeginTimer.GetMSec(false) >= (unsigned)(dragBeginInterval_ * 1000))
-            {
-                dragData->dragBeginPending = false;
-                IntVector2 beginSendPos = dragData->dragBeginSumPos / dragData->numDragButtons;
-                dragConfirmedCount_ ++;
-                if (!usingTouchInput_)
-                    dragElement->OnDragBegin(dragElement->ScreenToElement(beginSendPos), beginSendPos, dragData->dragButtons, qualifiers_,cursor_);
-                else
-                    dragElement->OnDragBegin(dragElement->ScreenToElement(beginSendPos), beginSendPos, dragData->dragButtons, 0, 0);
-
-                SendDragOrHoverEvent(E_DRAGBEGIN, dragElement, beginSendPos, IntVector2::ZERO, dragData);
-            }
-
-            ++i;
-        }
-    }
-
-    // Mouse hover
-    if (!mouseGrabbed && !input->GetTouchEmulation())
-    {
-        if (!usingTouchInput_ && cursorVisible)
-            ProcessHover(cursorPos, mouseButtons_, qualifiers_, cursor_);
-    }
-
-    // Touch hover
-    unsigned numTouches = input->GetNumTouches();
-    for (unsigned i = 0; i < numTouches; ++i)
-    {
-        TouchState* touch = input->GetTouch(i);
-        ProcessHover(touch->position_, TOUCHID_MASK(touch->touchID_), 0, 0);
-    }
-
-    // End hovers that expired without refreshing
-    for (HashMap<WeakPtr<UIElement>, bool>::Iterator i = hoveredElements_.Begin(); i != hoveredElements_.End();)
-    {
-        if (i->first_.Expired() || !i->second_)
-        {
-            UIElement* element = i->first_;
-            if (element)
-            {
-                using namespace HoverEnd;
-
-                VariantMap& eventData = GetEventDataMap();
-                eventData[P_ELEMENT] = element;
-                element->SendEvent(E_HOVEREND, eventData);
-            }
-            i = hoveredElements_.Erase(i);
-        }
-        else
-            ++i;
-    }
-
-    Update(timeStep, rootElement_);
-    Update(timeStep, rootModalElement_);
-}
-
-void UI::RenderUpdate()
-{
-    assert(rootElement_ && rootModalElement_ && graphics_);
-
-    PROFILE(GetUIBatches);
-
-    uiRendered_ = false;
-
-    // If the OS cursor is visible, do not render the UI's own cursor
-    bool osCursorVisible = GetSubsystem<Input>()->IsMouseVisible();
-
-    // Get rendering batches from the non-modal UI elements
-    batches_.Clear();
-    vertexData_.Clear();
-    const IntVector2& rootSize = rootElement_->GetSize();
-    const IntVector2& rootPosition = rootElement_->GetPosition();
-    IntRect currentScissor = IntRect(rootPosition.x_, rootPosition.y_, rootPosition.x_ + rootSize.x_, rootPosition.y_ + rootSize.y_);
-    GetBatches(rootElement_, currentScissor);
-
-    // Save the batch size of the non-modal batches for later use
-    nonModalBatchSize_ = batches_.Size();
-
-    // Get rendering batches from the modal UI elements
-    GetBatches(rootModalElement_, currentScissor);
-
-    // Get batches from the cursor (and its possible children) last to draw it on top of everything
-    if (cursor_ && cursor_->IsVisible() && !osCursorVisible)
-    {
-        currentScissor = IntRect(0, 0, rootSize.x_, rootSize.y_);
-        cursor_->GetBatches(batches_, vertexData_, currentScissor);
-        GetBatches(cursor_, currentScissor);
-    }
-}
-
-void UI::Render(bool resetRenderTargets)
-{
-    // Perform the default render only if not rendered yet
-    if (resetRenderTargets && uiRendered_)
-        return;
-
-    PROFILE(RenderUI);
-
-    // If the OS cursor is visible, apply its shape now if changed
-    bool osCursorVisible = GetSubsystem<Input>()->IsMouseVisible();
-    if (cursor_ && osCursorVisible)
-        cursor_->ApplyOSCursorShape();
-
-    SetVertexData(vertexBuffer_, vertexData_);
-    SetVertexData(debugVertexBuffer_, debugVertexData_);
-
-    // Render non-modal batches
-    Render(resetRenderTargets, vertexBuffer_, batches_, 0, nonModalBatchSize_);
-    // Render debug draw
-    Render(resetRenderTargets, debugVertexBuffer_, debugDrawBatches_, 0, debugDrawBatches_.Size());
-    // Render modal batches
-    Render(resetRenderTargets, vertexBuffer_, batches_, nonModalBatchSize_, batches_.Size());
-
-    // Clear the debug draw batches and data
-    debugDrawBatches_.Clear();
-    debugVertexData_.Clear();
-
-    uiRendered_ = true;
-}
-
-void UI::DebugDraw(UIElement* element)
-{
-    if (element)
-    {
-        const IntVector2& rootSize = rootElement_->GetSize();
-        element->GetDebugDrawBatches(debugDrawBatches_, debugVertexData_, IntRect(0, 0, rootSize.x_, rootSize.y_));
-    }
-}
-
-SharedPtr<UIElement> UI::LoadLayout(Deserializer& source, XMLFile* styleFile)
-{
-    SharedPtr<XMLFile> xml(new XMLFile(context_));
-    if (!xml->Load(source))
-        return SharedPtr<UIElement>();
-    else
-        return LoadLayout(xml, styleFile);
-}
-
-SharedPtr<UIElement> UI::LoadLayout(XMLFile* file, XMLFile* styleFile)
-{
-    PROFILE(LoadUILayout);
-
-    SharedPtr<UIElement> root;
-
-    if (!file)
-    {
-        LOGERROR("Null UI layout XML file");
-        return root;
-    }
-
-    LOGDEBUG("Loading UI layout " + file->GetName());
-
-    XMLElement rootElem = file->GetRoot("element");
-    if (!rootElem)
-    {
-        LOGERROR("No root UI element in " + file->GetName());
-        return root;
-    }
-
-    String typeName = rootElem.GetAttribute("type");
-    if (typeName.Empty())
-        typeName = "UIElement";
-
-    root = DynamicCast<UIElement>(context_->CreateObject(typeName));
-    if (!root)
-    {
-        LOGERROR("Could not create unknown UI element " + typeName);
-        return root;
-    }
-
-    // Use default style file of the root element if it has one
-    if (!styleFile)
-        styleFile = rootElement_->GetDefaultStyle(false);
-    // Set it as default for later use by children elements
-    if (styleFile)
-        root->SetDefaultStyle(styleFile);
-
-    root->LoadXML(rootElem, styleFile);
-    return root;
-}
-
-bool UI::SaveLayout(Serializer& dest, UIElement* element)
-{
-    PROFILE(SaveUILayout);
-
-    return element && element->SaveXML(dest);
-}
-
-void UI::SetClipboardText(const String& text)
-{
-    clipBoard_ = text;
-    if (useSystemClipboard_)
-        SDL_SetClipboardText(text.CString());
-}
-
-void UI::SetDoubleClickInterval(float interval)
-{
-    doubleClickInterval_ = Max(interval, 0.0f);
-}
-
-void UI::SetDragBeginInterval(float interval)
-{
-    dragBeginInterval_ = Max(interval, 0.0f);
-}
-
-void UI::SetDragBeginDistance(int pixels)
-{
-    dragBeginDistance_ = Max(pixels, 0);
-}
-
-void UI::SetDefaultToolTipDelay(float delay)
-{
-    defaultToolTipDelay_ = Max(delay, 0.0f);
-}
-
-void UI::SetNonFocusedMouseWheel(bool nonFocusedMouseWheel)
-{
-    nonFocusedMouseWheel_ = nonFocusedMouseWheel;
-}
-
-void UI::SetUseSystemClipboard(bool enable)
-{
-    useSystemClipboard_ = enable;
-}
-
-void UI::SetUseScreenKeyboard(bool enable)
-{
-    useScreenKeyboard_ = enable;
-}
-
-IntVector2 UI::GetCursorPosition() const
-{
-    return cursor_ ? cursor_->GetPosition() : GetSubsystem<Input>()->GetMousePosition();
-}
-
-UIElement* UI::GetElementAt(const IntVector2& position, bool enabledOnly)
-{
-    UIElement* result = 0;
-    GetElementAt(result, HasModalElement() ? rootModalElement_ : rootElement_, position, enabledOnly);
-    return result;
-}
-
-UIElement* UI::GetElementAt(int x, int y, bool enabledOnly)
-{
-    return GetElementAt(IntVector2(x, y), enabledOnly);
-}
-
-UIElement* UI::GetFrontElement() const
-{
-    const Vector<SharedPtr<UIElement> >& rootChildren = rootElement_->GetChildren();
-    int maxPriority = M_MIN_INT;
-    UIElement* front = 0;
-
-    for (unsigned i = 0; i < rootChildren.Size(); ++i)
-    {
-        // Do not take into account input-disabled elements, hidden elements or those that are always in the front
-        if (!rootChildren[i]->IsEnabled() || !rootChildren[i]->IsVisible() || !rootChildren[i]->GetBringToBack())
-            continue;
-
-        int priority = rootChildren[i]->GetPriority();
-        if (priority > maxPriority)
-        {
-            maxPriority = priority;
-            front = rootChildren[i];
-        }
-    }
-
-    return front;
-}
-
-const Vector<UIElement*> UI::GetDragElements()
-{
-    // Do not return the element until drag begin event has actually been posted
-    if (!dragElementsConfirmed_.Empty())
-        return dragElementsConfirmed_;
-
-    for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End(); )
-    {
-        WeakPtr<UIElement> dragElement = i->first_;
-        UI::DragData* dragData = i->second_;
-
-        if (!dragElement)
-        {
-            i = DragElementErase(i);
-            continue;
-        }
-
-        if (!dragData->dragBeginPending)
-            dragElementsConfirmed_.Push(dragElement);
-
-        ++i;
-    }
-
-    return dragElementsConfirmed_;
-}
-
-UIElement* UI::GetDragElement(unsigned index)
-{
-    GetDragElements();
-    if (index >= dragElementsConfirmed_.Size())
-        return (UIElement*)0;
-
-    return dragElementsConfirmed_[index];
-}
-
-const String& UI::GetClipboardText() const
-{
-    if (useSystemClipboard_)
-    {
-        char* text = SDL_GetClipboardText();
-        clipBoard_ = String(text);
-        if (text)
-            SDL_free(text);
-    }
-
-    return clipBoard_;
-}
-
-bool UI::HasModalElement() const
-{
-    return rootModalElement_->GetNumChildren() > 0;
-}
-
-void UI::Initialize()
-{
-    Graphics* graphics = GetSubsystem<Graphics>();
-
-    if (!graphics || !graphics->IsInitialized())
-        return;
-
-    PROFILE(InitUI);
-
-    graphics_ = graphics;
-
-    rootElement_->SetSize(graphics->GetWidth(), graphics->GetHeight());
-    rootModalElement_->SetSize(rootElement_->GetSize());
-
-    vertexBuffer_ = new VertexBuffer(context_);
-    debugVertexBuffer_ = new VertexBuffer(context_);
-
-    initialized_ = true;
-
-    SubscribeToEvent(E_BEGINFRAME, HANDLER(UI, HandleBeginFrame));
-    SubscribeToEvent(E_POSTUPDATE, HANDLER(UI, HandlePostUpdate));
-    SubscribeToEvent(E_RENDERUPDATE, HANDLER(UI, HandleRenderUpdate));
-
-    LOGINFO("Initialized user interface");
-}
-
-void UI::Update(float timeStep, UIElement* element)
-{
-    // Keep a weak pointer to the element in case it destroys itself on update
-    WeakPtr<UIElement> elementWeak(element);
-
-    element->Update(timeStep);
-    if (elementWeak.Expired())
-        return;
-
-    const Vector<SharedPtr<UIElement> >& children = element->GetChildren();
-    // Update of an element may modify its child vector. Use just index-based iteration to be safe
-    for (unsigned i = 0; i < children.Size(); ++i)
-        Update(timeStep, children[i]);
-}
-
-void UI::SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData)
-{
-    if (vertexData.Empty())
-        return;
-
-    // Update quad geometry into the vertex buffer
-    // Resize the vertex buffer first if too small or much too large
-    unsigned numVertices = vertexData.Size() / UI_VERTEX_SIZE;
-    if (dest->GetVertexCount() < numVertices || dest->GetVertexCount() > numVertices * 2)
-        dest->SetSize(numVertices, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1, true);
-
-    dest->SetData(&vertexData[0]);
-}
-
-void UI::Render(bool resetRenderTargets, VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigned batchStart, unsigned batchEnd)
-{
-    // Engine does not render when window is closed or device is lost
-    assert(graphics_ && graphics_->IsInitialized() && !graphics_->IsDeviceLost());
-
-    if (batches.Empty())
-        return;
-
-    Vector2 invScreenSize(1.0f / (float)graphics_->GetWidth(), 1.0f / (float)graphics_->GetHeight());
-    Vector2 scale(2.0f * invScreenSize.x_, -2.0f * invScreenSize.y_);
-    Vector2 offset(-1.0f, 1.0f);
-
-    Matrix4 projection(Matrix4::IDENTITY);
-    projection.m00_ = scale.x_;
-    projection.m03_ = offset.x_;
-    projection.m11_ = scale.y_;
-    projection.m13_ = offset.y_;
-    projection.m22_ = 1.0f;
-    projection.m23_ = 0.0f;
-    projection.m33_ = 1.0f;
-
-    graphics_->ClearParameterSources();
-    graphics_->SetColorWrite(true);
-    graphics_->SetCullMode(CULL_CCW);
-    graphics_->SetDepthTest(CMP_ALWAYS);
-    graphics_->SetDepthWrite(false);
-    graphics_->SetDrawAntialiased(false);
-    graphics_->SetFillMode(FILL_SOLID);
-    graphics_->SetStencilTest(false);
-    if (resetRenderTargets)
-        graphics_->ResetRenderTargets();
-    graphics_->SetVertexBuffer(buffer);
-
-    ShaderVariation* noTextureVS = graphics_->GetShader(VS, "Basic", "VERTEXCOLOR");
-    ShaderVariation* diffTextureVS = graphics_->GetShader(VS, "Basic", "DIFFMAP VERTEXCOLOR");
-    ShaderVariation* noTexturePS = graphics_->GetShader(PS, "Basic", "VERTEXCOLOR");
-    ShaderVariation* diffTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP VERTEXCOLOR");
-    ShaderVariation* diffMaskTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP ALPHAMASK VERTEXCOLOR");
-    ShaderVariation* alphaTexturePS = graphics_->GetShader(PS, "Basic", "ALPHAMAP VERTEXCOLOR");
-
-    unsigned alphaFormat = Graphics::GetAlphaFormat();
-
-    for (unsigned i = batchStart; i < batchEnd; ++i)
-    {
-        const UIBatch& batch = batches[i];
-        if (batch.vertexStart_ == batch.vertexEnd_)
-            continue;
-
-        ShaderVariation* ps;
-        ShaderVariation* vs;
-
-        if (!batch.texture_)
-        {
-            ps = noTexturePS;
-            vs = noTextureVS;
-        }
-        else
-        {
-            // If texture contains only an alpha channel, use alpha shader (for fonts)
-            vs = diffTextureVS;
-
-            if (batch.texture_->GetFormat() == alphaFormat)
-                ps = alphaTexturePS;
-            else if (batch.blendMode_ != BLEND_ALPHA && batch.blendMode_ != BLEND_ADDALPHA && batch.blendMode_ != BLEND_PREMULALPHA)
-                ps = diffMaskTexturePS;
-            else
-                ps = diffTexturePS;
-        }
-
-        graphics_->SetShaders(vs, ps);
-        if (graphics_->NeedParameterUpdate(SP_OBJECTTRANSFORM, this))
-            graphics_->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
-        if (graphics_->NeedParameterUpdate(SP_CAMERA, this))
-            graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
-        if (graphics_->NeedParameterUpdate(SP_MATERIAL, this))
-            graphics_->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));
-
-        graphics_->SetBlendMode(batch.blendMode_);
-        graphics_->SetScissorTest(true, batch.scissor_);
-        graphics_->SetTexture(0, batch.texture_);
-        graphics_->Draw(TRIANGLE_LIST, batch.vertexStart_ / UI_VERTEX_SIZE, (batch.vertexEnd_ - batch.vertexStart_) /
-            UI_VERTEX_SIZE);
-    }
-}
-
-void UI::GetBatches(UIElement* element, IntRect currentScissor)
-{
-    // Set clipping scissor for child elements. No need to draw if zero size
-    element->AdjustScissor(currentScissor);
-    if (currentScissor.left_ == currentScissor.right_ || currentScissor.top_ == currentScissor.bottom_)
-        return;
-
-    element->SortChildren();
-    const Vector<SharedPtr<UIElement> >& children = element->GetChildren();
-    if (children.Empty())
-        return;
-
-    // For non-root elements draw all children of same priority before recursing into their children: assumption is that they have
-    // same renderstate
-    Vector<SharedPtr<UIElement> >::ConstIterator i = children.Begin();
-    if (element->GetTraversalMode() == TM_BREADTH_FIRST)
-    {
-        Vector<SharedPtr<UIElement> >::ConstIterator j = i;
-        while (i != children.End())
-        {
-            int currentPriority = (*i)->GetPriority();
-            while (j != children.End() && (*j)->GetPriority() == currentPriority)
-            {
-                if ((*j)->IsWithinScissor(currentScissor) && (*j) != cursor_)
-                    (*j)->GetBatches(batches_, vertexData_, currentScissor);
-                ++j;
-            }
-            // Now recurse into the children
-            while (i != j)
-            {
-                if ((*i)->IsVisible() && (*i) != cursor_)
-                    GetBatches(*i, currentScissor);
-                ++i;
-            }
-        }
-    }
-    // On the root level draw each element and its children immediately after to avoid artifacts
-    else
-    {
-        while (i != children.End())
-        {
-            if ((*i) != cursor_)
-            {
-                if ((*i)->IsWithinScissor(currentScissor))
-                    (*i)->GetBatches(batches_, vertexData_, currentScissor);
-                if ((*i)->IsVisible())
-                    GetBatches(*i, currentScissor);
-            }
-            ++i;
-        }
-    }
-}
-
-void UI::GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool enabledOnly)
-{
-    if (!current)
-        return;
-
-    current->SortChildren();
-    const Vector<SharedPtr<UIElement> >& children = current->GetChildren();
-    LayoutMode parentLayoutMode = current->GetLayoutMode();
-
-    for (unsigned i = 0; i < children.Size(); ++i)
-    {
-        UIElement* element = children[i];
-        bool hasChildren = element->GetNumChildren() > 0;
-
-        if (element != cursor_.Get() && element->IsVisible())
-        {
-            if (element->IsInside(position, true))
-            {
-                // Store the current result, then recurse into its children. Because children
-                // are sorted from lowest to highest priority, the topmost match should remain
-                if (element->IsEnabled() || !enabledOnly)
-                    result = element;
-
-                if (hasChildren)
-                    GetElementAt(result, element, position, enabledOnly);
-                // Layout optimization: if the element has no children, can break out after the first match
-                else if (parentLayoutMode != LM_FREE)
-                    break;
-            }
-            else
-            {
-                if (hasChildren)
-                {
-                    if (element->IsInsideCombined(position, true))
-                        GetElementAt(result, element, position, enabledOnly);
-                }
-                // Layout optimization: if position is much beyond the visible screen, check how many elements we can skip,
-                // or if we already passed all visible elements
-                else if (parentLayoutMode != LM_FREE)
-                {
-                    if (!i)
-                    {
-                        int screenPos = (parentLayoutMode == LM_HORIZONTAL) ? element->GetScreenPosition().x_ :
-                            element->GetScreenPosition().y_;
-                        int layoutMaxSize = current->GetLayoutMaxSize();
-
-                        if (screenPos < 0 && layoutMaxSize > 0)
-                        {
-                            unsigned toSkip = -screenPos / layoutMaxSize;
-                            if (toSkip > 0)
-                                i += (toSkip - 1);
-                        }
-                    }
-                    else if (parentLayoutMode == LM_HORIZONTAL)
-                    {
-                        if (element->GetScreenPosition().x_ >= rootElement_->GetSize().x_)
-                            break;
-                    }
-                    else if (parentLayoutMode == LM_VERTICAL)
-                    {
-                        if (element->GetScreenPosition().y_ >= rootElement_->GetSize().y_)
-                            break;
-                    }
-                }
-            }
-        }
-    }
-}
-
-UIElement* UI::GetFocusableElement(UIElement* element)
-{
-    while (element)
-    {
-        if (element->GetFocusMode() != FM_NOTFOCUSABLE)
-            break;
-        element = element->GetParent();
-    }
-    return element;
-}
-
-void UI::GetCursorPositionAndVisible(IntVector2& pos, bool& visible)
-{
-    // Prefer software cursor then OS-specific cursor
-    if (cursor_ && cursor_->IsVisible())
-    {
-        pos = cursor_->GetPosition();
-        visible = true;
-    }
-    else if (GetSubsystem<Input>()->GetMouseMode() == MM_RELATIVE)
-        visible = true;
-    else
-    {
-        Input* input = GetSubsystem<Input>();
-        pos = input->GetMousePosition();
-        visible = input->IsMouseVisible();
-
-        if (!visible && cursor_)
-            pos = cursor_->GetPosition();
-    }
-}
-
-void UI::SetCursorShape(CursorShape shape)
-{
-    if (cursor_)
-        cursor_->SetShape(shape);
-}
-
-void UI::ProcessHover(const IntVector2& cursorPos, int buttons, int qualifiers, Cursor* cursor)
-{
-    WeakPtr<UIElement> element(GetElementAt(cursorPos));
-
-    for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End();)
-    {
-        WeakPtr<UIElement> dragElement = i->first_;
-        UI::DragData* dragData = i->second_;
-
-        if (!dragElement)
-        {
-            i = DragElementErase(i);
-            continue;
-        }
-
-        bool dragSource = dragElement && (dragElement->GetDragDropMode() & DD_SOURCE) != 0;
-        bool dragTarget = element && (element->GetDragDropMode() & DD_TARGET) != 0;
-        bool dragDropTest = dragSource && dragTarget && element != dragElement;
-        // If drag start event has not been posted yet, do not do drag handling here
-        if (dragData->dragBeginPending)
-            dragSource = dragTarget = dragDropTest = false;
-
-        // Hover effect
-        // If a drag is going on, transmit hover only to the element being dragged, unless it's a drop target
-        if (element && element->IsEnabled())
-        {
-            if (dragElement == element || dragDropTest)
-            {
-                element->OnHover(element->ScreenToElement(cursorPos), cursorPos, buttons, qualifiers, cursor);
-
-                // Begin hover event
-                if (!hoveredElements_.Contains(element))
-                {
-                    SendDragOrHoverEvent(E_HOVERBEGIN, element, cursorPos, IntVector2::ZERO, 0);
-                    // Exit if element is destroyed by the event handling
-                    if (!element)
-                        return;
-                }
-                hoveredElements_[element] = true;
-            }
-        }
-
-        // Drag and drop test
-        if (dragDropTest)
-        {
-            bool accept = element->OnDragDropTest(dragElement);
-            if (accept)
-            {
-                using namespace DragDropTest;
-
-                VariantMap& eventData = GetEventDataMap();
-                eventData[P_SOURCE] = dragElement.Get();
-                eventData[P_TARGET] = element.Get();
-                eventData[P_ACCEPT] = accept;
-                SendEvent(E_DRAGDROPTEST, eventData);
-                accept = eventData[P_ACCEPT].GetBool();
-            }
-
-            if (cursor)
-                cursor->SetShape(accept ? CS_ACCEPTDROP : CS_REJECTDROP);
-        }
-        else if (dragSource && cursor)
-            cursor->SetShape(dragElement == element ? CS_ACCEPTDROP : CS_REJECTDROP);
-
-        ++i;
-    }
-
-    // Hover effect
-    // If no drag is going on, transmit hover event.
-    if (element && element->IsEnabled())
-    {
-        if (dragElementsCount_ == 0)
-        {
-            element->OnHover(element->ScreenToElement(cursorPos), cursorPos, buttons, qualifiers, cursor);
-
-            // Begin hover event
-            if (!hoveredElements_.Contains(element))
-            {
-                SendDragOrHoverEvent(E_HOVERBEGIN, element, cursorPos, IntVector2::ZERO, 0);
-                // Exit if element is destroyed by the event handling
-                if (!element)
-                    return;
-            }
-            hoveredElements_[element] = true;
-        }
-    }
-}
-
-void UI::ProcessClickBegin(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible)
-{
-    if (cursorVisible)
-    {
-        WeakPtr<UIElement> element(GetElementAt(cursorPos));
-
-        bool newButton;
-        if (usingTouchInput_)
-            newButton = (button & buttons) == 0;
-        else
-            newButton = true;
-        buttons |= button;
-
-        if (element)
-            SetFocusElement (element);
-
-        // Focus change events may destroy the element, check again.
-        if (element)
-        {
-            // Handle focusing & bringing to front
-            element->BringToFront();
-
-            // Handle click
-            element->OnClickBegin(element->ScreenToElement(cursorPos), cursorPos, button, buttons, qualifiers, cursor);
-            SendClickEvent(E_UIMOUSECLICK, NULL, element, cursorPos, button, buttons, qualifiers);
-
-            // Fire double click event if element matches and is in time
-            if (doubleClickElement_ && element == doubleClickElement_ && clickTimer_.GetMSec(true) <
-                (unsigned)(doubleClickInterval_ * 1000) && lastMouseButtons_ == buttons)
-            {
-                element->OnDoubleClick(element->ScreenToElement(cursorPos), cursorPos, button, buttons, qualifiers, cursor);
-                doubleClickElement_.Reset();
-                SendClickEvent(E_UIMOUSEDOUBLECLICK, NULL, element, cursorPos, button, buttons, qualifiers);
-            }
-            else
-            {
-                doubleClickElement_ = element;
-                clickTimer_.Reset();
-            }
-
-            // Handle start of drag. Click handling may have caused destruction of the element, so check the pointer again
-            bool dragElementsContain = dragElements_.Contains(element);
-            if (element && !dragElementsContain)
-            {
-                DragData* dragData = new DragData();
-                dragElements_[element] = dragData;
-                dragData->dragBeginPending = true;
-                dragData->sumPos = cursorPos;
-                dragData->dragBeginSumPos = cursorPos;
-                dragData->dragBeginTimer.Reset();
-                dragData->dragButtons = button;
-                dragData->numDragButtons = CountSetBits(dragData->dragButtons);
-                dragElementsCount_++;
-
-                dragElementsContain = dragElements_.Contains(element);
-            }
-            else if (element && dragElementsContain && newButton)
-            {
-                DragData* dragData = dragElements_[element];
-                dragData->sumPos += cursorPos;
-                dragData->dragBeginSumPos += cursorPos;
-                dragData->dragButtons |= button;
-                dragData->numDragButtons = CountSetBits(dragData->dragButtons);
-            }
-        }
-        else
-        {
-            // If clicked over no element, or a disabled element, lose focus (but not if there is a modal element)
-            if (!HasModalElement())
-                SetFocusElement(0);
-            SendClickEvent(E_UIMOUSECLICK, NULL, element, cursorPos, button, buttons, qualifiers);
-        }
-
-        lastMouseButtons_ = buttons;
-    }
-}
-
-void UI::ProcessClickEnd(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible)
-{
-    if (cursorVisible)
-    {
-        WeakPtr<UIElement> element(GetElementAt(cursorPos));
-
-        // Handle end of drag
-        for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End();)
-        {
-            WeakPtr<UIElement> dragElement = i->first_;
-            UI::DragData* dragData = i->second_;
-
-            if (!dragElement)
-            {
-                i = DragElementErase(i);
-                continue;
-            }
-
-            if (dragData->dragButtons & button)
-            {
-                // Handle end of click
-                if (element)
-                    element->OnClickEnd(element->ScreenToElement(cursorPos), cursorPos, button, buttons, qualifiers, cursor, dragElement);
-
-                SendClickEvent(E_UIMOUSECLICKEND, dragElement, element, cursorPos, button, buttons, qualifiers);
-
-                if (dragElement && dragElement->IsEnabled() && dragElement->IsVisible() && !dragData->dragBeginPending)
-                {
-                    dragElement->OnDragEnd(dragElement->ScreenToElement(cursorPos), cursorPos, dragData->dragButtons, buttons, cursor);
-                    SendDragOrHoverEvent(E_DRAGEND, dragElement, cursorPos, IntVector2::ZERO, dragData);
-
-                    bool dragSource = dragElement && (dragElement->GetDragDropMode() & DD_SOURCE) != 0;
-                    if (dragSource)
-                    {
-                        bool dragTarget = element && (element->GetDragDropMode() & DD_TARGET) != 0;
-                        bool dragDropFinish = dragSource && dragTarget && element != dragElement;
-
-                        if (dragDropFinish)
-                        {
-                            bool accept = element->OnDragDropFinish(dragElement);
-
-                            // OnDragDropFinish() may have caused destruction of the elements, so check the pointers again
-                            if (accept && dragElement && element)
-                            {
-                                using namespace DragDropFinish;
-
-                                VariantMap& eventData = GetEventDataMap();
-                                eventData[P_SOURCE] = dragElement.Get();
-                                eventData[P_TARGET] = element.Get();
-                                eventData[P_ACCEPT] = accept;
-                                SendEvent(E_DRAGDROPFINISH, eventData);
-                            }
-                        }
-                    }
-                }
-
-                i = DragElementErase(i);
-            }
-            else
-                ++i;
-        }
-    }
-}
-
-void UI::ProcessMove(const IntVector2& cursorPos, const IntVector2& cursorDeltaPos, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible)
-{
-    if (cursorVisible && dragElementsCount_ > 0 && buttons)
-    {
-        Input* input = GetSubsystem<Input>();
-        bool mouseGrabbed = input->IsMouseGrabbed();
-        for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End();)
-        {
-            WeakPtr<UIElement> dragElement = i->first_;
-            UI::DragData* dragData = i->second_;
-
-            if (!dragElement)
-            {
-                i = DragElementErase(i);
-                continue;
-            }
-
-            if (!(dragData->dragButtons & buttons))
-            {
-                ++i;
-                continue;
-            }
-
-            // Calculate the position that we should send for this drag event.
-            IntVector2 sendPos;
-            if (usingTouchInput_)
-            {
-                dragData->sumPos += cursorDeltaPos;
-                sendPos.x_ = dragData->sumPos.x_ / dragData->numDragButtons;
-                sendPos.y_ = dragData->sumPos.y_ / dragData->numDragButtons;
-            }
-            else
-            {
-                dragData->sumPos = cursorPos;
-                sendPos = cursorPos;
-            }
-
-            if (dragElement->IsEnabled() && dragElement->IsVisible())
-            {
-                // Signal drag begin if distance threshold was exceeded
-
-                if (dragData->dragBeginPending && !mouseGrabbed)
-                {
-                    IntVector2 beginSendPos;
-                    beginSendPos.x_ = dragData->dragBeginSumPos.x_ / dragData->numDragButtons;
-                    beginSendPos.y_ = dragData->dragBeginSumPos.y_ / dragData->numDragButtons;
-
-                    IntVector2 offset = cursorPos - beginSendPos;
-                    if (Abs(offset.x_) >= dragBeginDistance_ || Abs(offset.y_) >= dragBeginDistance_)
-                    {
-                        dragData->dragBeginPending = false;
-                        dragConfirmedCount_ ++;
-                        dragElement->OnDragBegin(dragElement->ScreenToElement(beginSendPos), beginSendPos, buttons, qualifiers, cursor);
-                        SendDragOrHoverEvent(E_DRAGBEGIN, dragElement, beginSendPos, IntVector2::ZERO, dragData);
-                    }
-                }
-
-                if (!dragData->dragBeginPending)
-                {
-                    dragElement->OnDragMove(dragElement->ScreenToElement(sendPos), sendPos, cursorDeltaPos, buttons, qualifiers, cursor);
-                    SendDragOrHoverEvent(E_DRAGMOVE, dragElement, sendPos, cursorDeltaPos, dragData);
-                }
-            }
-            else
-            {
-                dragElement->OnDragEnd(dragElement->ScreenToElement(sendPos), sendPos, dragData->dragButtons, buttons, cursor);
-                SendDragOrHoverEvent(E_DRAGEND, dragElement, sendPos, IntVector2::ZERO, dragData);
-                dragElement.Reset();
-            }
-
-            ++i;
-        }
-    }
-}
-
-void UI::SendDragOrHoverEvent(StringHash eventType, UIElement* element, const IntVector2& screenPos, const IntVector2& deltaPos, UI::DragData* dragData)
-{
-    if (!element)
-        return;
-
-    IntVector2 relativePos = element->ScreenToElement(screenPos);
-
-    using namespace DragMove;
-
-    VariantMap& eventData = GetEventDataMap();
-    eventData[P_ELEMENT] = element;
-    eventData[P_X] = screenPos.x_;
-    eventData[P_Y] = screenPos.y_;
-    eventData[P_ELEMENTX] = relativePos.x_;
-    eventData[P_ELEMENTY] = relativePos.y_;
-
-    if (eventType == E_DRAGMOVE)
-    {
-        eventData[P_DX] = deltaPos.x_;
-        eventData[P_DY] = deltaPos.y_;
-    }
-
-    if (dragData)
-    {
-        eventData[P_BUTTONS] = dragData->dragButtons;
-        eventData[P_NUMBUTTONS] = dragData->numDragButtons;
-    }
-
-    element->SendEvent(eventType, eventData);
-}
-
-void UI::SendClickEvent(StringHash eventType, UIElement* beginElement, UIElement* endElement, const IntVector2& pos, int button, int buttons, int qualifiers)
-{
-    VariantMap& eventData = GetEventDataMap();
-    eventData[UIMouseClick::P_ELEMENT] = endElement;
-    eventData[UIMouseClick::P_X] = pos.x_;
-    eventData[UIMouseClick::P_Y] = pos.y_;
-    eventData[UIMouseClick::P_BUTTON] = button;
-    eventData[UIMouseClick::P_BUTTONS] = buttons;
-    eventData[UIMouseClick::P_QUALIFIERS] = qualifiers;
-
-    // For click end events, send also the element the click began on
-    if (eventType == E_UIMOUSECLICKEND)
-        eventData[UIMouseClickEnd::P_BEGINELEMENT] = beginElement;
-
-    SendEvent(eventType, eventData);
-}
-
-void UI::HandleScreenMode(StringHash eventType, VariantMap& eventData)
-{
-    using namespace ScreenMode;
-
-    if (!initialized_)
-        Initialize();
-    else
-    {
-        rootElement_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
-        rootModalElement_->SetSize(rootElement_->GetSize());
-    }
-}
-
-void UI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
-{
-    using namespace MouseButtonDown;
-
-    mouseButtons_ = eventData[P_BUTTONS].GetInt();
-    qualifiers_ = eventData[P_QUALIFIERS].GetInt();
-    usingTouchInput_ = false;
-
-    IntVector2 cursorPos;
-    bool cursorVisible;
-    GetCursorPositionAndVisible(cursorPos, cursorVisible);
-
-    // Handle drag cancelling
-    ProcessDragCancel();
-
-    Input* input = GetSubsystem<Input>();
-
-    if (!input->IsMouseGrabbed())
-        ProcessClickBegin(cursorPos, eventData[P_BUTTON].GetInt(), mouseButtons_, qualifiers_, cursor_, cursorVisible);
-}
-
-void UI::HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
-{
-    using namespace MouseButtonUp;
-
-    mouseButtons_ = eventData[P_BUTTONS].GetInt();
-    qualifiers_ = eventData[P_QUALIFIERS].GetInt();
-
-    IntVector2 cursorPos;
-    bool cursorVisible;
-    GetCursorPositionAndVisible(cursorPos, cursorVisible);
-
-    ProcessClickEnd(cursorPos, eventData[P_BUTTON].GetInt(), mouseButtons_, qualifiers_, cursor_, cursorVisible);
-}
-
-void UI::HandleMouseMove(StringHash eventType, VariantMap& eventData)
-{
-    using namespace MouseMove;
-
-    mouseButtons_ = eventData[P_BUTTONS].GetInt();
-    qualifiers_ = eventData[P_QUALIFIERS].GetInt();
-    usingTouchInput_ = false;
-
-    Input* input = GetSubsystem<Input>();
-    const IntVector2& rootSize = rootElement_->GetSize();
-
-    IntVector2 DeltaP = IntVector2(eventData[P_DX].GetInt(), eventData[P_DY].GetInt());
-
-    if (cursor_)
-    {
-        if (!input->IsMouseVisible())
-        {
-            // Relative mouse motion: move cursor only when visible
-            if (cursor_->IsVisible())
-            {
-                IntVector2 pos = cursor_->GetPosition();
-                pos.x_ += eventData[P_DX].GetInt();
-                pos.y_ += eventData[P_DY].GetInt();
-                pos.x_ = Clamp(pos.x_, 0, rootSize.x_ - 1);
-                pos.y_ = Clamp(pos.y_, 0, rootSize.y_ - 1);
-                cursor_->SetPosition(pos);
-            }
-        }
-        else
-        {
-            // Absolute mouse motion: move always
-            cursor_->SetPosition(IntVector2(eventData[P_X].GetInt(), eventData[P_Y].GetInt()));
-        }
-    }
-
-    IntVector2 cursorPos;
-    bool cursorVisible;
-    GetCursorPositionAndVisible(cursorPos, cursorVisible);
-
-    ProcessMove(cursorPos, DeltaP, mouseButtons_, qualifiers_, cursor_, cursorVisible);
-}
-
-void UI::HandleMouseWheel(StringHash eventType, VariantMap& eventData)
-{
-}
-
-void UI::HandleTouchBegin(StringHash eventType, VariantMap& eventData)
-{
-}
-
-void UI::HandleTouchEnd(StringHash eventType, VariantMap& eventData)
-{
-}
-
-void UI::HandleTouchMove(StringHash eventType, VariantMap& eventData)
-{
-}
-
-void UI::HandleKeyDown(StringHash eventType, VariantMap& eventData)
-{
-
-}
-
-void UI::HandleTextInput(StringHash eventType, VariantMap& eventData)
-{
-}
-
-void UI::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
-{
-    // If have a cursor, and a drag is not going on, reset the cursor shape. Application logic that wants to apply
-    // custom shapes can do it after this, but needs to do it each frame
-    if (cursor_ && dragElementsCount_ == 0)
-        cursor_->SetShape(CS_NORMAL);
-}
-
-void UI::HandlePostUpdate(StringHash eventType, VariantMap& eventData)
-{
-    using namespace PostUpdate;
-
-    Update(eventData[P_TIMESTEP].GetFloat());
-}
-
-void UI::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
-{
-    RenderUpdate();
-}
-
-void UI::HandleDropFile(StringHash eventType, VariantMap& eventData)
-{
-    Input* input = GetSubsystem<Input>();
-
-    // Sending the UI variant of the event only makes sense if the OS cursor is visible (not locked to window center)
-    if (input->IsMouseVisible())
-    {
-        IntVector2 screenPos = input->GetMousePosition();
-        UIElement* element = GetElementAt(screenPos);
-
-        using namespace UIDropFile;
-
-        VariantMap uiEventData;
-        uiEventData[P_FILENAME] = eventData[P_FILENAME];
-        uiEventData[P_X] = screenPos.x_;
-        uiEventData[P_Y] = screenPos.y_;
-        uiEventData[P_ELEMENT] = element;
-
-        if (element)
-        {
-            IntVector2 relativePos = element->ScreenToElement(screenPos);
-            uiEventData[P_ELEMENTX] = relativePos.x_;
-            uiEventData[P_ELEMENTY] = relativePos.y_;
-        }
-
-        SendEvent(E_UIDROPFILE, uiEventData);
-    }
-}
-
-HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator UI::DragElementErase(HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i)
-{
-    // If running the engine frame in response to an event (re-entering UI frame logic) the dragElements_ may already be empty
-    if (dragElements_.Empty())
-        return dragElements_.End();
-
-    dragElementsConfirmed_.Clear();
-
-    WeakPtr<UIElement> dragElement = i->first_;
-    DragData* dragData = i->second_;
-
-    if (!dragData->dragBeginPending)
-        --dragConfirmedCount_;
-    i = dragElements_.Erase(i);
-    --dragElementsCount_;
-
-    delete dragData;
-    return i;
-}
-
-void UI::ProcessDragCancel()
-{
-    // How to tell difference between drag cancel and new selection on multi-touch?
-    if (usingTouchInput_)
-        return;
-
-    IntVector2 cursorPos;
-    bool cursorVisible;
-    GetCursorPositionAndVisible(cursorPos, cursorVisible);
-
-    for (HashMap<WeakPtr<UIElement>, UI::DragData*>::Iterator i = dragElements_.Begin(); i != dragElements_.End();)
-    {
-        WeakPtr<UIElement> dragElement = i->first_;
-        UI::DragData* dragData = i->second_;
-
-        if (dragElement && dragElement->IsEnabled() && dragElement->IsVisible() && !dragData->dragBeginPending)
-        {
-            dragElement->OnDragCancel(dragElement->ScreenToElement(cursorPos), cursorPos, dragData->dragButtons, mouseButtons_, cursor_);
-            SendDragOrHoverEvent(E_DRAGCANCEL, dragElement, cursorPos, IntVector2::ZERO, dragData);
-            i = DragElementErase(i);
-        }
-        else
-            ++i;
-    }
-}
-
-IntVector2 UI::SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSendPos)
-{
-    IntVector2 sendPos = oldSendPos;
-    if (usingTouchInput_)
-    {
-        int buttons = dragData->dragButtons;
-        dragData->sumPos = IntVector2::ZERO;
-        Input* input = GetSubsystem<Input>();
-        for (int i = 0; (1 << i) <= buttons; i++)
-        {
-            if ((1 << i) & buttons)
-            {
-                TouchState* ts = input->GetTouch(i);
-                if (!ts)
-                    break;
-                IntVector2 pos = ts->position_;
-                dragData->sumPos.x_ += pos.x_;
-                dragData->sumPos.y_ += pos.y_;
-            }
-        }
-        sendPos.x_ = dragData->sumPos.x_ / dragData->numDragButtons;
-        sendPos.y_ = dragData->sumPos.y_ / dragData->numDragButtons;
-    }
-    return sendPos;
-}
-
-void RegisterUILibrary(Context* context)
-{
-    UIElement::RegisterObject(context);
-    BorderImage::RegisterObject(context);
-    Cursor::RegisterObject(context);
-}
-
-}

+ 0 - 303
Source/Atomic/UI/UI.h

@@ -1,303 +0,0 @@
-//
-// Copyright (c) 2008-2015 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../Core/Object.h"
-#include "../UI/Cursor.h"
-#include "../UI/UIBatch.h"
-
-namespace Atomic
-{
-
-class Cursor;
-class Graphics;
-class ResourceCache;
-class Timer;
-class UIBatch;
-class UIElement;
-class VertexBuffer;
-class XMLElement;
-class XMLFile;
-
-/// %UI subsystem. Manages the graphical user interface.
-class ATOMIC_API UI : public Object
-{
-    OBJECT(UI);
-
-public:
-    /// Construct.
-    UI(Context* context);
-    /// Destruct.
-    virtual ~UI();
-
-    /// Set cursor UI element.
-    void SetCursor(Cursor* cursor);
-    /// Set focused UI element.
-    void SetFocusElement(UIElement* element, bool byKey = false);
-    /// Clear the UI (excluding the cursor.)
-    void Clear();
-    /// Update the UI logic. Called by HandlePostUpdate().
-    void Update(float timeStep);
-    /// Update the UI for rendering. Called by HandleRenderUpdate().
-    void RenderUpdate();
-    /// Render the UI. If resetRenderTargets is true, is assumed to be the default UI render to backbuffer called by Engine, and will be performed only once. Additional UI renders to a different rendertarget may be triggered from the renderpath.
-    void Render(bool resetRenderTargets = true);
-    /// Debug draw a UI element.
-    void DebugDraw(UIElement* element);
-    /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element.
-    SharedPtr<UIElement> LoadLayout(Deserializer& source, XMLFile* styleFile = 0);
-    /// Load a UI layout from an XML file. Optionally specify another XML file for element style. Return the root element.
-    SharedPtr<UIElement> LoadLayout(XMLFile* file, XMLFile* styleFile = 0);
-    /// Save a UI layout to an XML file. Return true if successful.
-    bool SaveLayout(Serializer& dest, UIElement* element);
-    /// Set clipboard text.
-    void SetClipboardText(const String& text);
-    /// Set UI element double click interval in seconds.
-    void SetDoubleClickInterval(float interval);
-    /// Set UI drag event start interval in seconds.
-    void SetDragBeginInterval(float interval);
-    /// Set UI drag event start distance threshold in pixels.
-    void SetDragBeginDistance(int pixels);
-    /// Set tooltip default display delay in seconds.
-    void SetDefaultToolTipDelay(float delay);    
-    /// Set whether mouse wheel can control also a non-focused element.
-    void SetNonFocusedMouseWheel(bool nonFocusedMouseWheel);
-    /// Set whether to use system clipboard. Default false.
-    void SetUseSystemClipboard(bool enable);
-    /// Set whether to show the on-screen keyboard (if supported) when a %LineEdit is focused. Default true on mobile devices.
-    void SetUseScreenKeyboard(bool enable);
-
-    /// Return root UI element.
-    UIElement* GetRoot() const { return rootElement_; }
-    /// Return root modal element.
-    UIElement* GetRootModalElement() const { return rootModalElement_; }
-    /// Return cursor.
-    Cursor* GetCursor() const { return cursor_; }
-    /// Return cursor position.
-    IntVector2 GetCursorPosition() const;
-    /// Return UI element at screen coordinates. By default returns only input-enabled elements.
-    UIElement* GetElementAt(const IntVector2& position, bool enabledOnly = true);
-    /// Return UI element at screen coordinates. By default returns only input-enabled elements.
-    UIElement* GetElementAt(int x, int y, bool enabledOnly = true);
-    /// Return focused element.
-    UIElement* GetFocusElement() const { return focusElement_; }
-    /// Return topmost enabled root-level non-modal element.
-    UIElement* GetFrontElement() const;
-    /// Return currently dragged elements.
-    const Vector<UIElement*> GetDragElements();
-    /// Return the number of currently dragged elements.
-    unsigned GetNumDragElements() const { return dragConfirmedCount_; }
-    /// Return the drag element at index.
-    UIElement* GetDragElement(unsigned index);
-    /// Return clipboard text.
-    const String& GetClipboardText() const;
-    /// Return UI element double click interval in seconds.
-    float GetDoubleClickInterval() const { return doubleClickInterval_; }
-    /// Return UI drag start event interval in seconds.
-    float GetDragBeginInterval() const { return dragBeginInterval_; }
-    /// Return UI drag start event distance threshold in pixels.
-    int GetDragBeginDistance() const { return dragBeginDistance_; }
-    /// Return tooltip default display delay in seconds.
-    float GetDefaultToolTipDelay() const { return defaultToolTipDelay_; }
-    /// Return font texture maximum size.
-    int GetMaxFontTextureSize() const { return maxFontTextureSize_; }
-    /// Return whether mouse wheel can control also a non-focused element.
-    bool IsNonFocusedMouseWheel() const { return nonFocusedMouseWheel_; }
-    /// Return whether is using the system clipboard.
-    bool GetUseSystemClipboard() const { return useSystemClipboard_; }
-    /// Return whether focusing a %LineEdit will show the on-screen keyboard.
-    bool GetUseScreenKeyboard() const { return useScreenKeyboard_; }
-    /// Return whether is using mutable (eraseable) glyphs for fonts.
-    bool GetUseMutableGlyphs() const { return useMutableGlyphs_; }
-    /// Return whether is using forced autohinting.
-    bool GetForceAutoHint() const { return forceAutoHint_; }
-    /// Return true when UI has modal element(s).
-    bool HasModalElement() const;
-    /// Return whether a drag is in progress.
-    bool IsDragging() const { return dragConfirmedCount_ > 0; };
-
-    /// Data structure used to represent the drag data associated to a UIElement.
-    struct DragData
-    {
-        /// Which button combo initiated the drag.
-        int dragButtons;
-        /// How many buttons initiated the drag.
-        int numDragButtons;
-        /// Sum of all touch locations
-        IntVector2 sumPos;
-        /// Flag for a drag start event pending.
-        bool dragBeginPending;
-        /// Timer used to trigger drag begin event.
-        Timer dragBeginTimer;
-        /// Drag start position.
-        IntVector2 dragBeginSumPos;
-    };
-
-private:
-    /// Initialize when screen mode initially set.
-    void Initialize();
-    /// Update UI element logic recursively.
-    void Update(float timeStep, UIElement* element);
-    /// Upload UI geometry into a vertex buffer.
-    void SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData);
-    /// Render UI batches. Geometry must have been uploaded first.
-    void Render(bool resetRenderTargets, VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigned batchStart, unsigned batchEnd);
-    /// Generate batches from an UI element recursively. Skip the cursor element.
-    void GetBatches(UIElement* element, IntRect currentScissor);
-    /// Return UI element at screen position recursively.
-    void GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool enabledOnly);
-    /// Return the first element in hierarchy that can alter focus.
-    UIElement* GetFocusableElement(UIElement* element);
-    /// Return cursor position and visibility either from the cursor element, or the Input subsystem.
-    void GetCursorPositionAndVisible(IntVector2& pos, bool& visible);
-    /// Set active cursor's shape.
-    void SetCursorShape(CursorShape shape);
-    /// Handle button or touch hover
-    void ProcessHover(const IntVector2& cursorPos, int buttons, int qualifiers, Cursor* cursor);
-    /// Handle button or touch begin.
-    void ProcessClickBegin(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible);
-    /// Handle button or touch end.
-    void ProcessClickEnd(const IntVector2& cursorPos, int button, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible);
-    /// Handle mouse or touch move.
-    void ProcessMove(const IntVector2& cursorPos, const IntVector2& cursorDeltaPos, int buttons, int qualifiers, Cursor* cursor, bool cursorVisible);
-    /// Send a UI element drag or hover begin event.
-    void SendDragOrHoverEvent(StringHash eventType, UIElement* element, const IntVector2& screenPos, const IntVector2& deltaPos, UI::DragData* dragData);
-    /// Send a UI click or double click event.
-    void SendClickEvent(StringHash eventType, UIElement* beginElement, UIElement* endElement, const IntVector2& pos, int button, int buttons, int qualifiers);
-    /// Handle screen mode event.
-    void HandleScreenMode(StringHash eventType, VariantMap& eventData);
-    /// Handle mouse button down event.
-    void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData);
-    /// Handle mouse button up event.
-    void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData);
-    /// Handle mouse move event.
-    void HandleMouseMove(StringHash eventType, VariantMap& eventData);
-    /// Handle mouse wheel event.
-    void HandleMouseWheel(StringHash eventType, VariantMap& eventData);
-    /// Handle touch begin event.
-    void HandleTouchBegin(StringHash eventType, VariantMap& eventData);
-    /// Handle touch end event.
-    void HandleTouchEnd(StringHash eventType, VariantMap& eventData);
-    /// Handle touch move event.
-    void HandleTouchMove(StringHash eventType, VariantMap& eventData);
-    /// Handle keypress event.
-    void HandleKeyDown(StringHash eventType, VariantMap& eventData);
-    /// Handle text input event.
-    void HandleTextInput(StringHash eventType, VariantMap& eventData);
-    /// Handle frame begin event.
-    void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
-    /// Handle logic post-update event.
-    void HandlePostUpdate(StringHash eventType, VariantMap& eventData);
-    /// Handle render update event.
-    void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
-    /// Handle a file being drag-dropped into the application window.
-    void HandleDropFile(StringHash eventType, VariantMap& eventData);
-    /// Remove drag data and return next iterator.
-    HashMap<WeakPtr<UIElement>, DragData*>::Iterator DragElementErase(HashMap<WeakPtr<UIElement>, DragData*>::Iterator dragElement);
-    /// Handle clean up on a drag cancel.
-    void ProcessDragCancel();
-    /// Sum touch positions and return the begin position ready to send.
-    IntVector2 SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSendPos);
-
-    /// Graphics subsystem.
-    WeakPtr<Graphics> graphics_;
-    /// UI root element.
-    SharedPtr<UIElement> rootElement_;
-    /// UI root modal element.
-    SharedPtr<UIElement> rootModalElement_;
-    /// Cursor.
-    SharedPtr<Cursor> cursor_;
-    /// Currently focused element.
-    WeakPtr<UIElement> focusElement_;
-    /// UI rendering batches.
-    PODVector<UIBatch> batches_;
-    /// UI rendering vertex data.
-    PODVector<float> vertexData_;
-    /// UI rendering batches for debug draw.
-    PODVector<UIBatch> debugDrawBatches_;
-    /// UI rendering vertex data for debug draw.
-    PODVector<float> debugVertexData_;
-    /// UI vertex buffer.
-    SharedPtr<VertexBuffer> vertexBuffer_;
-    /// UI debug geometry vertex buffer.
-    SharedPtr<VertexBuffer> debugVertexBuffer_;
-    /// UI element query vector.
-    PODVector<UIElement*> tempElements_;
-    /// Clipboard text.
-    mutable String clipBoard_;
-    /// Seconds between clicks to register a double click.
-    float doubleClickInterval_;
-    /// Seconds from mouse button down to begin a drag if there has been no movement exceeding pixel threshold.
-    float dragBeginInterval_;
-    /// Tooltip default display delay in seconds.
-    float defaultToolTipDelay_;
-    /// Drag begin event distance threshold in pixels.
-    int dragBeginDistance_;
-    /// Mouse buttons held down.
-    int mouseButtons_;
-    /// Last mouse button pressed.
-    int lastMouseButtons_;
-    /// Qualifier keys held down.
-    int qualifiers_;
-    /// Font texture maximum size.
-    int maxFontTextureSize_;
-    /// Initialized flag.
-    bool initialized_;
-    /// Touch used flag.
-    bool usingTouchInput_;
-    /// Flag to switch mouse wheel event to be sent to non-focused element at cursor.
-    bool nonFocusedMouseWheel_;
-    /// Flag for using operating system clipboard instead of internal.
-    bool useSystemClipboard_;
-    /// Flag for showing the on-screen keyboard on focusing a %LineEdit.
-    bool useScreenKeyboard_;
-    /// Flag for using mutable (eraseable) font glyphs.
-    bool useMutableGlyphs_;
-    /// Flag for forcing FreeType autohinting.
-    bool forceAutoHint_;
-    /// Flag for UI already being rendered this frame.
-    bool uiRendered_;
-    /// Non-modal batch size (used internally for rendering).
-    unsigned nonModalBatchSize_;
-    /// Timer used to trigger double click.
-    Timer clickTimer_;
-    /// UI element last clicked for tracking double clicks.
-    WeakPtr<UIElement> doubleClickElement_;
-    /// Currently hovered elements.
-    HashMap<WeakPtr<UIElement>, bool> hoveredElements_;
-    /// Currently dragged elements.
-    HashMap<WeakPtr<UIElement>, DragData*> dragElements_;
-    /// Number of elements in dragElements_.
-    int dragElementsCount_;
-    /// Number of elements in dragElements_ with dragPending = false.
-    int dragConfirmedCount_;
-    /// UI elements that are being touched with touch input.
-    HashMap<WeakPtr<UIElement>, int> touchDragElements_;
-    /// Confirmed drag elements cache.
-    Vector<UIElement*> dragElementsConfirmed_;
-};
-
-/// Register UI library objects.
-void ATOMIC_API RegisterUILibrary(Context* context);
-
-}

+ 24 - 99
Source/Atomic/UI/UIBatch.cpp

@@ -25,7 +25,7 @@
 #include "../Math/Matrix3x4.h"
 #include "../Math/Matrix3x4.h"
 #include "../Graphics/ShaderVariation.h"
 #include "../Graphics/ShaderVariation.h"
 #include "../Graphics/Texture.h"
 #include "../Graphics/Texture.h"
-#include "../UI/UIElement.h"
+#include "../UI/UIBatch.h"
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
@@ -41,7 +41,6 @@ static const float posAdjust = 0.5f;
 static const Vector3 posAdjustVec(posAdjust, posAdjust, 0.0f);
 static const Vector3 posAdjustVec(posAdjust, posAdjust, 0.0f);
 
 
 UIBatch::UIBatch() :
 UIBatch::UIBatch() :
-    element_(0),
     blendMode_(BLEND_REPLACE),
     blendMode_(BLEND_REPLACE),
     texture_(0),
     texture_(0),
     invTextureSize_(Vector2::ONE),
     invTextureSize_(Vector2::ONE),
@@ -52,8 +51,7 @@ UIBatch::UIBatch() :
     SetDefaultColor();
     SetDefaultColor();
 }
 }
 
 
-UIBatch::UIBatch(UIElement* element, BlendMode blendMode, const IntRect& scissor, Texture* texture, PODVector<float>* vertexData) :
-    element_(element),
+UIBatch::UIBatch(BlendMode blendMode, const IntRect& scissor, Texture* texture, PODVector<float>* vertexData) :
     blendMode_(blendMode),
     blendMode_(blendMode),
     scissor_(scissor),
     scissor_(scissor),
     texture_(texture),
     texture_(texture),
@@ -67,51 +65,24 @@ UIBatch::UIBatch(UIElement* element, BlendMode blendMode, const IntRect& scissor
 
 
 void UIBatch::SetColor(const Color& color, bool overrideAlpha)
 void UIBatch::SetColor(const Color& color, bool overrideAlpha)
 {
 {
-    if (!element_)
-        overrideAlpha = true;
-
     useGradient_ = false;
     useGradient_ = false;
-    color_ = overrideAlpha ? color.ToUInt() : Color(color.r_, color.g_, color.b_, color.a_ * element_->GetDerivedOpacity()).ToUInt();
+    color_ = color.ToUInt();
 }
 }
 
 
 void UIBatch::SetDefaultColor()
 void UIBatch::SetDefaultColor()
 {
 {
-    if (element_)
-    {
-        color_ = element_->GetDerivedColor().ToUInt();
-        useGradient_ = element_->HasColorGradient();
-    }
-    else
-    {
-        color_ = 0xffffffff;
-        useGradient_ = false;
-    }
+    color_ = 0xffffffff;
+    useGradient_ = false;
 }
 }
 
 
 void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight)
 void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight)
 {
 {
-    unsigned topLeftColor, topRightColor, bottomLeftColor, bottomRightColor;
-
-    if (!useGradient_)
-    {
-        // If alpha is 0, nothing will be rendered, so do not add the quad
-        if (!(color_ & 0xff000000))
-            return;
-        
-        topLeftColor = color_;
-        topRightColor = color_;
-        bottomLeftColor = color_;
-        bottomRightColor = color_;
-    }
-    else
-    {
-        topLeftColor = GetInterpolatedColor(x, y);
-        topRightColor = GetInterpolatedColor(x + width, y);
-        bottomLeftColor = GetInterpolatedColor(x, y + height);
-        bottomRightColor = GetInterpolatedColor(x + width, y + height);
-    }
-    
-    const IntVector2& screenPos = element_->GetScreenPosition();
+    // If alpha is 0, nothing will be rendered, so do not add the quad
+    if (!(color_ & 0xff000000))
+        return;
+            
+    //const IntVector2& screenPos = element_->GetScreenPosition();
+   IntVector2 screenPos(0, 0);
     
     
     float left = (float)(x + screenPos.x_) - posAdjust;
     float left = (float)(x + screenPos.x_) - posAdjust;
     float right = left + (float)width;
     float right = left + (float)width;
@@ -129,27 +100,27 @@ void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int t
     vertexEnd_ = vertexData_->Size();
     vertexEnd_ = vertexData_->Size();
     
     
     dest[0] = left; dest[1] = top; dest[2] = 0.0f;
     dest[0] = left; dest[1] = top; dest[2] = 0.0f;
-    ((unsigned&)dest[3]) = topLeftColor;
+    ((unsigned&)dest[3]) = color_;
     dest[4] = leftUV; dest[5] = topUV;
     dest[4] = leftUV; dest[5] = topUV;
     
     
     dest[6] = right; dest[7] = top; dest[8] = 0.0f;
     dest[6] = right; dest[7] = top; dest[8] = 0.0f;
-    ((unsigned&)dest[9]) = topRightColor;
+    ((unsigned&)dest[9]) = color_;
     dest[10] = rightUV; dest[11] = topUV;
     dest[10] = rightUV; dest[11] = topUV;
     
     
     dest[12] = left; dest[13] = bottom; dest[14] = 0.0f;
     dest[12] = left; dest[13] = bottom; dest[14] = 0.0f;
-    ((unsigned&)dest[15]) = bottomLeftColor;
+    ((unsigned&)dest[15]) = color_;
     dest[16] = leftUV; dest[17] = bottomUV;
     dest[16] = leftUV; dest[17] = bottomUV;
     
     
     dest[18] = right; dest[19] = top; dest[20] = 0.0f;
     dest[18] = right; dest[19] = top; dest[20] = 0.0f;
-    ((unsigned&)dest[21]) = topRightColor;
+    ((unsigned&)dest[21]) = color_;
     dest[22] = rightUV; dest[23] = topUV;
     dest[22] = rightUV; dest[23] = topUV;
     
     
     dest[24] = right; dest[25] = bottom; dest[26] = 0.0f;
     dest[24] = right; dest[25] = bottom; dest[26] = 0.0f;
-    ((unsigned&)dest[27]) = bottomRightColor;
+    ((unsigned&)dest[27]) = color_;
     dest[28] = rightUV; dest[29] = bottomUV;
     dest[28] = rightUV; dest[29] = bottomUV;
 
 
     dest[30] = left; dest[31] = bottom; dest[32] = 0.0f;
     dest[30] = left; dest[31] = bottom; dest[32] = 0.0f;
-    ((unsigned&)dest[33]) = bottomLeftColor;
+    ((unsigned&)dest[33]) = color_;
     dest[34] = leftUV; dest[35] = bottomUV;
     dest[34] = leftUV; dest[35] = bottomUV;
 
 
     dest += 36;
     dest += 36;
@@ -158,27 +129,6 @@ void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int t
 void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int height, int texOffsetX, int texOffsetY,
 void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int height, int texOffsetX, int texOffsetY,
     int texWidth, int texHeight)
     int texWidth, int texHeight)
 {
 {
-    unsigned topLeftColor, topRightColor, bottomLeftColor, bottomRightColor;
-    
-    if (!useGradient_)
-    {
-        // If alpha is 0, nothing will be rendered, so do not add the quad
-        if (!(color_ & 0xff000000))
-            return;
-        
-        topLeftColor = color_;
-        topRightColor = color_;
-        bottomLeftColor = color_;
-        bottomRightColor = color_;
-    }
-    else
-    {
-        topLeftColor = GetInterpolatedColor(x, y);
-        topRightColor = GetInterpolatedColor(x + width, y);
-        bottomLeftColor = GetInterpolatedColor(x, y + height);
-        bottomRightColor = GetInterpolatedColor(x + width, y + height);
-    }
-    
     Vector3 v1 = (transform * Vector3((float)x, (float)y, 0.0f)) - posAdjustVec;
     Vector3 v1 = (transform * Vector3((float)x, (float)y, 0.0f)) - posAdjustVec;
     Vector3 v2 = (transform * Vector3((float)x + (float)width, (float)y, 0.0f)) - posAdjustVec;
     Vector3 v2 = (transform * Vector3((float)x + (float)width, (float)y, 0.0f)) - posAdjustVec;
     Vector3 v3 = (transform * Vector3((float)x, (float)y + (float)height, 0.0f)) - posAdjustVec;
     Vector3 v3 = (transform * Vector3((float)x, (float)y + (float)height, 0.0f)) - posAdjustVec;
@@ -195,35 +145,33 @@ void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int h
     vertexEnd_ = vertexData_->Size();
     vertexEnd_ = vertexData_->Size();
 
 
     dest[0] = v1.x_; dest[1] = v1.y_; dest[2] = 0.0f;
     dest[0] = v1.x_; dest[1] = v1.y_; dest[2] = 0.0f;
-    ((unsigned&)dest[3]) = topLeftColor;
+    ((unsigned&)dest[3]) = color_;
     dest[4] = leftUV; dest[5] = topUV;
     dest[4] = leftUV; dest[5] = topUV;
     
     
     dest[6] = v2.x_; dest[7] = v2.y_; dest[8] = 0.0f;
     dest[6] = v2.x_; dest[7] = v2.y_; dest[8] = 0.0f;
-    ((unsigned&)dest[9]) = topRightColor;
+    ((unsigned&)dest[9]) = color_;
     dest[10] = rightUV; dest[11] = topUV;
     dest[10] = rightUV; dest[11] = topUV;
     
     
     dest[12] = v3.x_; dest[13] = v3.y_; dest[14] = 0.0f;
     dest[12] = v3.x_; dest[13] = v3.y_; dest[14] = 0.0f;
-    ((unsigned&)dest[15]) = bottomLeftColor;
+    ((unsigned&)dest[15]) = color_;
     dest[16] = leftUV; dest[17] = bottomUV;
     dest[16] = leftUV; dest[17] = bottomUV;
     
     
     dest[18] = v2.x_; dest[19] = v2.y_; dest[20] = 0.0f;
     dest[18] = v2.x_; dest[19] = v2.y_; dest[20] = 0.0f;
-    ((unsigned&)dest[21]) = topRightColor;
+    ((unsigned&)dest[21]) = color_;
     dest[22] = rightUV; dest[23] = topUV;
     dest[22] = rightUV; dest[23] = topUV;
     
     
     dest[24] = v4.x_; dest[25] = v4.y_; dest[26] = 0.0f;
     dest[24] = v4.x_; dest[25] = v4.y_; dest[26] = 0.0f;
-    ((unsigned&)dest[27]) = bottomRightColor;
+    ((unsigned&)dest[27]) = color_;
     dest[28] = rightUV; dest[29] = bottomUV;
     dest[28] = rightUV; dest[29] = bottomUV;
 
 
     dest[30] = v3.x_; dest[31] = v3.y_; dest[32] = 0.0f;
     dest[30] = v3.x_; dest[31] = v3.y_; dest[32] = 0.0f;
-    ((unsigned&)dest[33]) = bottomLeftColor;
+    ((unsigned&)dest[33]) = color_;
     dest[34] = leftUV; dest[35] = bottomUV;
     dest[34] = leftUV; dest[35] = bottomUV;
 }
 }
 
 
 void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight, bool tiled)
 void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight, bool tiled)
 {
 {
-    if (!(element_->HasColorGradient() || element_->GetDerivedColor().ToUInt() & 0xff000000))
-        return; // No gradient and alpha is 0, so do not add the quad
-    
+
     if (!tiled)
     if (!tiled)
     {
     {
         AddQuad(x, y, width, height, texOffsetX, texOffsetY, texWidth, texHeight);
         AddQuad(x, y, width, height, texOffsetX, texOffsetY, texWidth, texHeight);
@@ -266,29 +214,6 @@ bool UIBatch::Merge(const UIBatch& batch)
     return true;
     return true;
 }
 }
 
 
-unsigned UIBatch::GetInterpolatedColor(int x, int y)
-{
-    const IntVector2& size = element_->GetSize();
-    
-    if (size.x_ && size.y_)
-    {
-        float cLerpX = Clamp((float)x / (float)size.x_, 0.0f, 1.0f);
-        float cLerpY = Clamp((float)y / (float)size.y_, 0.0f, 1.0f);
-        
-        Color topColor = element_->GetColor(C_TOPLEFT).Lerp(element_->GetColor(C_TOPRIGHT), cLerpX);
-        Color bottomColor = element_->GetColor(C_BOTTOMLEFT).Lerp(element_->GetColor(C_BOTTOMRIGHT), cLerpX);
-        Color color = topColor.Lerp(bottomColor, cLerpY);
-        color.a_ *= element_->GetDerivedOpacity();
-        return color.ToUInt();
-    }
-    else
-    {
-        Color color = element_->GetColor(C_TOPLEFT);
-        color.a_ *= element_->GetDerivedOpacity();
-        return color.ToUInt();
-    }
-}
-
 void UIBatch::AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches)
 void UIBatch::AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches)
 {
 {
     if (batch.vertexEnd_ == batch.vertexStart_)
     if (batch.vertexEnd_ == batch.vertexStart_)

+ 1 - 6
Source/Atomic/UI/UIBatch.h

@@ -33,7 +33,6 @@ class PixelShader;
 class Graphics;
 class Graphics;
 class Matrix3x4;
 class Matrix3x4;
 class Texture;
 class Texture;
-class UIElement;
 
 
 static const unsigned UI_VERTEX_SIZE = 6;
 static const unsigned UI_VERTEX_SIZE = 6;
 
 
@@ -44,7 +43,7 @@ public:
     /// Construct with defaults.
     /// Construct with defaults.
     UIBatch();
     UIBatch();
     /// Construct.
     /// Construct.
-    UIBatch(UIElement* element, BlendMode blendMode, const IntRect& scissor, Texture* texture, PODVector<float>* vertexData);
+    UIBatch(BlendMode blendMode, const IntRect& scissor, Texture* texture, PODVector<float>* vertexData);
     
     
     /// Set new color for the batch. Overrides gradient.
     /// Set new color for the batch. Overrides gradient.
     void SetColor(const Color& color, bool overrideAlpha = false);
     void SetColor(const Color& color, bool overrideAlpha = false);
@@ -58,14 +57,10 @@ public:
     void AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight, bool tiled);
     void AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight, bool tiled);
     /// Merge with another batch.
     /// Merge with another batch.
     bool Merge(const UIBatch& batch);
     bool Merge(const UIBatch& batch);
-    /// Return an interpolated color for the UI element.
-    unsigned GetInterpolatedColor(int x, int y);
     
     
     /// Add or merge a batch.
     /// Add or merge a batch.
     static void AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches);
     static void AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches);
     
     
-    /// Element this batch represents.
-    UIElement* element_;
     /// Blending mode.
     /// Blending mode.
     BlendMode blendMode_;
     BlendMode blendMode_;
     /// Scissor rectangle.
     /// Scissor rectangle.

+ 0 - 1995
Source/Atomic/UI/UIElement.cpp

@@ -1,1995 +0,0 @@
-//
-// Copyright (c) 2008-2015 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "Precompiled.h"
-#include "../Core/Context.h"
-#include "../Core/CoreEvents.h"
-#include "../UI/Cursor.h"
-#include "../Container/HashSet.h"
-#include "../IO/Log.h"
-#include "../Scene/ObjectAnimation.h"
-#include "../Resource/ResourceCache.h"
-#include "../Container/Sort.h"
-#include "../UI/UI.h"
-#include "../UI/UIElement.h"
-#include "../UI/UIEvents.h"
-
-#include "../DebugNew.h"
-
-namespace Atomic
-{
-
-const char* horizontalAlignments[] =
-{
-    "Left",
-    "Center",
-    "Right",
-    0
-};
-
-const char* verticalAlignments[] =
-{
-    "Top",
-    "Center",
-    "Bottom",
-    0
-};
-
-static const char* focusModes[] =
-{
-    "NotFocusable",
-    "ResetFocus",
-    "Focusable",
-    "FocusableDefocusable",
-    0
-};
-
-static const char* dragDropModes[] =
-{
-    "Disabled",
-    "Source",
-    "Target",
-    "SourceAndTarget",
-    0
-};
-
-static const char* layoutModes[] =
-{
-    "Free",
-    "Horizontal",
-    "Vertical",
-    0
-};
-
-extern const char* UI_CATEGORY;
-
-static bool CompareUIElements(const UIElement* lhs, const UIElement* rhs)
-{
-    return lhs->GetPriority() < rhs->GetPriority();
-}
-
-XPathQuery UIElement::styleXPathQuery_("/elements/element[@type=$typeName]", "typeName:String");
-
-UIElement::UIElement(Context* context) :
-    Animatable(context),
-    parent_(0),
-    clipBorder_(IntRect::ZERO),
-    priority_(0),
-    bringToFront_(false),
-    bringToBack_(true),
-    clipChildren_(false),
-    sortChildren_(true),
-    useDerivedOpacity_(true),
-    editable_(true),
-    selected_(false),
-    visible_(true),
-    hovering_(false),
-    internal_(false),
-    focusMode_(FM_NOTFOCUSABLE),
-    dragDropMode_(DD_DISABLED),
-    layoutMode_(LM_FREE),
-    layoutSpacing_(0),
-    layoutBorder_(IntRect::ZERO),
-    layoutFlexScale_(Vector2::ONE),
-    resizeNestingLevel_(0),
-    layoutNestingLevel_(0),
-    layoutMinSize_(0),
-    layoutMaxSize_(0),
-    indent_(0),
-    indentSpacing_(16),
-    position_(IntVector2::ZERO),
-    positionDirty_(true),
-    size_(IntVector2::ZERO),
-    minSize_(IntVector2::ZERO),
-    maxSize_(M_MAX_INT, M_MAX_INT),
-    childOffset_(IntVector2::ZERO),
-    horizontalAlignment_(HA_LEFT),
-    verticalAlignment_(VA_TOP),
-    opacity_(1.0f),
-    opacityDirty_(true),
-    derivedColorDirty_(true),
-    sortOrderDirty_(false),
-    colorGradient_(false),
-    traversalMode_(TM_BREADTH_FIRST),
-    elementEventSender_(false),
-    dragButtonCombo_(0),
-    dragButtonCount_(0)
-{
-    SetEnabled(false);
-}
-
-UIElement::~UIElement()
-{
-    // If child elements have outside references, detach them
-    for (Vector<SharedPtr<UIElement> >::Iterator i = children_.Begin(); i < children_.End(); ++i)
-    {
-        if (i->Refs() > 1)
-            (*i)->Detach();
-    }
-}
-
-void UIElement::RegisterObject(Context* context)
-{
-    context->RegisterFactory<UIElement>(UI_CATEGORY);
-
-    ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Position", GetPosition, SetPosition, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Min Size", GetMinSize, SetMinSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Max Size", GetMaxSize, SetMaxSize, IntVector2, IntVector2(M_MAX_INT, M_MAX_INT), AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Clip Border", GetClipBorder, SetClipBorder, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Priority", GetPriority, SetPriority, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Opacity", GetOpacity, SetOpacity, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_FILE);
-    ATTRIBUTE("Top Left Color", Color, color_[0], Color::WHITE, AM_FILE);
-    ATTRIBUTE("Top Right Color", Color, color_[1], Color::WHITE, AM_FILE);
-    ATTRIBUTE("Bottom Left Color", Color, color_[2], Color::WHITE, AM_FILE);
-    ATTRIBUTE("Bottom Right Color", Color, color_[3], Color::WHITE, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Is Editable", IsEditable, SetEditable, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Is Selected", IsSelected, SetSelected, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Is Visible", IsVisible, SetVisible, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Bring To Front", GetBringToFront, SetBringToFront, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Bring To Back", GetBringToBack, SetBringToBack, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Clip Children", GetClipChildren, SetClipChildren, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Use Derived Opacity", GetUseDerivedOpacity, SetUseDerivedOpacity, bool, true, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Focus Mode", GetFocusMode, SetFocusMode, FocusMode, focusModes, FM_NOTFOCUSABLE, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Drag And Drop Mode", GetDragDropMode, SetDragDropMode, unsigned, dragDropModes, DD_DISABLED, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE("Layout Mode", GetLayoutMode, SetLayoutMode, LayoutMode, layoutModes, LM_FREE, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Layout Spacing", GetLayoutSpacing, SetLayoutSpacing, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Layout Border", GetLayoutBorder, SetLayoutBorder, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Layout Flex Scale", GetLayoutFlexScale, SetLayoutFlexScale, Vector2, Vector2::ONE, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Indent", GetIndent, SetIndent, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE("Indent Spacing", GetIndentSpacing, SetIndentSpacing, int, 16, AM_FILE);
-    ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE);
-}
-
-void UIElement::ApplyAttributes()
-{
-    colorGradient_ = false;
-    derivedColorDirty_ = true;
-
-    for (unsigned i = 1; i < MAX_UIELEMENT_CORNERS; ++i)
-    {
-        if (color_[i] != color_[0])
-            colorGradient_ = true;
-    }
-}
-
-bool UIElement::LoadXML(const XMLElement& source, bool setInstanceDefault)
-{
-    return LoadXML(source, 0, setInstanceDefault);
-}
-
-bool UIElement::LoadXML(const XMLElement& source, XMLFile* styleFile, bool setInstanceDefault)
-{
-    // Get style override if defined
-    String styleName = source.GetAttribute("style");
-
-    // Apply the style first, if the style file is available
-    if (styleFile)
-    {
-        // If not defined, use type name
-        if (styleName.Empty())
-            styleName = GetTypeName();
-
-        SetStyle(styleName, styleFile);
-    }
-    // The 'style' attribute value in the style file cannot be equals to original's applied style to prevent infinite loop
-    else if (!styleName.Empty() && styleName != appliedStyle_)
-    {
-        // Attempt to use the default style file
-        styleFile = GetDefaultStyle();
-
-        if (styleFile)
-        {
-            // Remember the original applied style
-            String appliedStyle(appliedStyle_);
-            SetStyle(styleName, styleFile);
-            appliedStyle_ = appliedStyle;
-        }
-    }
-
-    // Prevent updates while loading attributes
-    DisableLayoutUpdate();
-
-    // Then load rest of the attributes from the source
-    if (!Animatable::LoadXML(source, setInstanceDefault))
-        return false;
-
-    unsigned nextInternalChild = 0;
-
-    // Load child elements. Internal elements are not to be created as they already exist
-    XMLElement childElem = source.GetChild("element");
-    while (childElem)
-    {
-        bool internalElem = childElem.GetBool("internal");
-        String typeName = childElem.GetAttribute("type");
-        if (typeName.Empty())
-            typeName = "UIElement";
-        unsigned index = childElem.HasAttribute("index") ? childElem.GetUInt("index") : M_MAX_UNSIGNED;
-        UIElement* child = 0;
-
-        if (!internalElem)
-            child = CreateChild(typeName, String::EMPTY, index);
-        else
-        {
-            for (unsigned i = nextInternalChild; i < children_.Size(); ++i)
-            {
-                if (children_[i]->IsInternal() && children_[i]->GetTypeName() == typeName)
-                {
-                    child = children_[i];
-                    nextInternalChild = i + 1;
-                    break;
-                }
-            }
-
-            if (!child)
-                LOGWARNING("Could not find matching internal child element of type " + typeName + " in " + GetTypeName());
-        }
-
-        if (child)
-        {
-            if (!styleFile)
-                styleFile = GetDefaultStyle();
-            if (!child->LoadXML(childElem, styleFile, setInstanceDefault))
-                return false;
-        }
-
-        childElem = childElem.GetNext("element");
-    }
-
-    ApplyAttributes();
-
-    EnableLayoutUpdate();
-    UpdateLayout();
-
-    return true;
-}
-
-bool UIElement::LoadChildXML(const XMLElement& childElem, XMLFile* styleFile, bool setInstanceDefault)
-{
-    bool internalElem = childElem.GetBool("internal");
-    if (internalElem)
-    {
-        LOGERROR("Loading internal child element is not supported");
-        return false;
-    }
-
-    String typeName = childElem.GetAttribute("type");
-    if (typeName.Empty())
-        typeName = "UIElement";
-    unsigned index = childElem.HasAttribute("index") ? childElem.GetUInt("index") : M_MAX_UNSIGNED;
-    UIElement* child = CreateChild(typeName, String::EMPTY, index);
-
-    if (child)
-    {
-        if (!styleFile)
-            styleFile = GetDefaultStyle();
-        if (!child->LoadXML(childElem, styleFile, setInstanceDefault))
-            return false;
-    }
-
-    return true;
-}
-
-bool UIElement::SaveXML(XMLElement& dest) const
-{
-    // Write type
-    if (GetTypeName() != "UIElement")
-    {
-        if (!dest.SetString("type", GetTypeName()))
-            return false;
-    }
-
-    // Write internal flag
-    if (internal_)
-    {
-        if (!dest.SetBool("internal", internal_))
-            return false;
-    }
-
-    // Write style
-    if (!appliedStyle_.Empty() && appliedStyle_ != "UIElement")
-    {
-        if (!dest.SetAttribute("style", appliedStyle_))
-            return false;
-    }
-    else if (internal_)
-    {
-        if (!dest.SetAttribute("style", "none"))
-            return false;
-    }
-
-    // Write attributes
-    if (!Animatable::SaveXML(dest))
-        return false;
-
-    // Write child elements
-    for (unsigned i = 0; i < children_.Size(); ++i)
-    {
-        UIElement* element = children_[i];
-        if (element->IsTemporary())
-            continue;
-
-        XMLElement childElem = dest.CreateChild("element");
-        if (!element->SaveXML(childElem))
-            return false;
-    }
-
-    // Filter UI-style and implicit attributes
-    if (!FilterAttributes(dest))
-        return false;
-
-    return true;
-}
-
-void UIElement::Update(float timeStep)
-{
-}
-
-void UIElement::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
-{
-    // Reset hovering for next frame
-    hovering_ = false;
-}
-
-void UIElement::GetDebugDrawBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
-{
-    UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
-
-    int horizontalThickness = 1;
-    int verticalThickness = 1;
-    if (parent_)
-    {
-        switch (parent_->layoutMode_)
-        {
-        case LM_HORIZONTAL:
-            verticalThickness +=2;
-            break;
-
-        case LM_VERTICAL:
-            horizontalThickness += 2;
-            break;
-
-        default:
-            break;
-        }
-    }
-
-    batch.SetColor(DEBUG_DRAW_COLOR, true);
-    // Left
-    batch.AddQuad(0, 0, horizontalThickness, size_.y_, 0, 0);
-    // Top
-    batch.AddQuad(0, 0, size_.x_, verticalThickness, 0, 0);
-    // Right
-    batch.AddQuad(size_.x_ - horizontalThickness, 0, horizontalThickness, size_.y_, 0, 0);
-    // Bottom
-    batch.AddQuad(0, size_.y_ - verticalThickness, size_.x_, verticalThickness, 0, 0);
-
-    UIBatch::AddOrMerge(batch, batches);
-}
-
-bool UIElement::IsWithinScissor(const IntRect& currentScissor)
-{
-    if (!visible_)
-        return false;
-
-    const IntVector2& screenPos = GetScreenPosition();
-    return screenPos.x_ < currentScissor.right_ && screenPos.x_ + GetWidth() > currentScissor.left_ &&
-        screenPos.y_ < currentScissor.bottom_ && screenPos.y_ + GetHeight() > currentScissor.top_;
-}
-
-const IntVector2& UIElement::GetScreenPosition() const
-{
-    if (positionDirty_)
-    {
-        IntVector2 pos = position_;
-        const UIElement* parent = parent_;
-
-        if (parent)
-        {
-            const IntVector2& parentScreenPos = parent->GetScreenPosition();
-
-            switch (horizontalAlignment_)
-            {
-            case HA_LEFT:
-                pos.x_ += parentScreenPos.x_;
-                break;
-
-            case HA_CENTER:
-                pos.x_ += parentScreenPos.x_ + parent_->size_.x_ / 2 - size_.x_ / 2;
-                break;
-
-            case HA_RIGHT:
-                pos.x_ += parentScreenPos.x_ + parent_->size_.x_ - size_.x_;
-                break;
-            }
-            switch (verticalAlignment_)
-            {
-            case VA_TOP:
-                pos.y_ += parentScreenPos.y_;
-                break;
-
-            case VA_CENTER:
-                pos.y_ += parentScreenPos.y_ + parent_->size_.y_ / 2 - size_.y_ / 2;
-                break;
-
-            case VA_BOTTOM:
-                pos.y_ += parentScreenPos.y_ + parent_->size_.y_ - size_.y_;
-                break;
-            }
-
-            pos += parent_->childOffset_;
-        }
-
-        screenPosition_ = pos;
-        positionDirty_ = false;
-    }
-
-    return screenPosition_;
-}
-
-void UIElement::OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
-{
-    hovering_ = true;
-}
-
-void UIElement::OnClickBegin(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor)
-{
-}
-
-void UIElement::OnClickEnd(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor, UIElement* beginElement)
-{
-}
-
-void UIElement::OnDoubleClick(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor)
-{
-}
-
-void UIElement::OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
-{
-    dragButtonCombo_ = buttons;
-    dragButtonCount_ = CountSetBits(dragButtonCombo_);
-}
-
-void UIElement::OnDragMove(const IntVector2& position, const IntVector2& screenPosition, const IntVector2& deltaPos, int buttons, int qualifiers, Cursor* cursor)
-{
-}
-
-void UIElement::OnDragEnd(const IntVector2& position, const IntVector2& screenPosition, int dragButtons, int buttons, Cursor* cursor)
-{
-    dragButtonCombo_ = 0;
-    dragButtonCount_ = 0;
-}
-
-void UIElement::OnDragCancel(const IntVector2& position, const IntVector2& screenPosition, int dragButtons, int buttons, Cursor* cursor)
-{
-    dragButtonCombo_ = 0;
-    dragButtonCount_ = 0;
-}
-
-bool UIElement::OnDragDropTest(UIElement* source)
-{
-    return true;
-}
-
-bool UIElement::OnDragDropFinish(UIElement* source)
-{
-    return true;
-}
-
-void UIElement::OnWheel(int delta, int buttons, int qualifiers)
-{
-}
-
-void UIElement::OnKey(int key, int buttons, int qualifiers)
-{
-}
-
-void UIElement::OnTextInput(const String& text, int buttons, int qualifiers)
-{
-}
-
-bool UIElement::LoadXML(Deserializer& source)
-{
-    SharedPtr<XMLFile> xml(new XMLFile(context_));
-    return xml->Load(source) && LoadXML(xml->GetRoot());
-}
-
-bool UIElement::SaveXML(Serializer& dest, const String& indentation) const
-{
-    SharedPtr<XMLFile> xml(new XMLFile(context_));
-    XMLElement rootElem = xml->CreateRoot("element");
-    return SaveXML(rootElem) && xml->Save(dest, indentation);
-}
-
-bool UIElement::FilterAttributes(XMLElement& dest) const
-{
-    // Filter UI styling attributes
-    XMLFile* styleFile = GetDefaultStyle();
-    if (styleFile)
-    {
-        String style = dest.GetAttribute("style");
-        if (!style.Empty() && style != "none")
-        {
-            if (styleXPathQuery_.SetVariable("typeName", style))
-            {
-                XMLElement styleElem = GetDefaultStyle()->GetRoot().SelectSinglePrepared(styleXPathQuery_);
-                if (styleElem && !FilterUIStyleAttributes(dest, styleElem))
-                    return false;
-            }
-        }
-    }
-
-    // Filter implicit attributes
-    if (!FilterImplicitAttributes(dest))
-    {
-        LOGERROR("Could not remove implicit attributes");
-        return false;
-    }
-
-    return true;
-}
-
-void UIElement::SetName(const String& name)
-{
-    name_ = name;
-
-    using namespace NameChanged;
-
-    VariantMap& eventData = GetEventDataMap();
-    eventData[P_ELEMENT] = this;
-
-    SendEvent(E_NAMECHANGED, eventData);
-}
-
-void UIElement::SetPosition(const IntVector2& position)
-{
-    if (position != position_)
-    {
-        position_ = position;
-        OnPositionSet();
-        MarkDirty();
-
-        using namespace Positioned;
-
-        VariantMap& eventData = GetEventDataMap();
-        eventData[P_ELEMENT] = this;
-        eventData[P_X] = position_.x_;
-        eventData[P_Y] = position_.y_;
-        SendEvent(E_POSITIONED, eventData);
-    }
-}
-
-void UIElement::SetPosition(int x, int y)
-{
-    SetPosition(IntVector2(x, y));
-}
-
-void UIElement::SetSize(const IntVector2& size)
-{
-    ++resizeNestingLevel_;
-
-    IntVector2 validatedSize;
-    validatedSize.x_ = Clamp(size.x_, minSize_.x_, maxSize_.x_);
-    validatedSize.y_ = Clamp(size.y_, minSize_.y_, maxSize_.y_);
-
-    if (validatedSize != size_)
-    {
-        size_ = validatedSize;
-
-        if (resizeNestingLevel_ == 1)
-        {
-            // Check if parent element's layout needs to be updated first
-            if (parent_)
-                parent_->UpdateLayout();
-
-            MarkDirty();
-            OnResize();
-            UpdateLayout();
-
-            using namespace Resized;
-
-            VariantMap& eventData = GetEventDataMap();
-            eventData[P_ELEMENT] = this;
-            eventData[P_WIDTH] = size_.x_;
-            eventData[P_HEIGHT] = size_.y_;
-            SendEvent(E_RESIZED, eventData);
-        }
-    }
-
-    --resizeNestingLevel_;
-}
-
-void UIElement::SetSize(int width, int height)
-{
-    SetSize(IntVector2(width, height));
-}
-
-void UIElement::SetWidth(int width)
-{
-    SetSize(IntVector2(width, size_.y_));
-}
-
-void UIElement::SetHeight(int height)
-{
-    SetSize(IntVector2(size_.x_, height));
-}
-
-void UIElement::SetMinSize(const IntVector2& minSize)
-{
-    minSize_.x_ = Max(minSize.x_, 0);
-    minSize_.y_ = Max(minSize.y_, 0);
-    SetSize(size_);
-}
-
-void UIElement::SetMinSize(int width, int height)
-{
-    SetMinSize(IntVector2(width, height));
-}
-
-void UIElement::SetMinWidth(int width)
-{
-    SetMinSize(IntVector2(width, minSize_.y_));
-}
-
-void UIElement::SetMinHeight(int height)
-{
-    SetMinSize(IntVector2(minSize_.x_, height));
-}
-
-void UIElement::SetMaxSize(const IntVector2& maxSize)
-{
-    maxSize_.x_ = Max(maxSize.x_, 0);
-    maxSize_.y_ = Max(maxSize.y_, 0);
-    SetSize(size_);
-}
-
-void UIElement::SetMaxSize(int width, int height)
-{
-    SetMaxSize(IntVector2(width, height));
-}
-
-void UIElement::SetMaxWidth(int width)
-{
-    SetMaxSize(IntVector2(width, maxSize_.y_));
-}
-
-void UIElement::SetMaxHeight(int height)
-{
-    SetMaxSize(IntVector2(maxSize_.x_, height));
-}
-
-void UIElement::SetFixedSize(const IntVector2& size)
-{
-    minSize_ = maxSize_ = IntVector2(Max(size.x_, 0), Max(size.y_, 0));
-    SetSize(size);
-}
-
-void UIElement::SetFixedSize(int width, int height)
-{
-    SetFixedSize(IntVector2(width, height));
-}
-
-void UIElement::SetFixedWidth(int width)
-{
-    minSize_.x_ = maxSize_.x_ = Max(width, 0);
-    SetWidth(width);
-}
-
-void UIElement::SetFixedHeight(int height)
-{
-    minSize_.y_ = maxSize_.y_ = Max(height, 0);
-    SetHeight(height);
-}
-
-void UIElement::SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign)
-{
-    SetHorizontalAlignment(hAlign);
-    SetVerticalAlignment(vAlign);
-}
-
-void UIElement::SetHorizontalAlignment(HorizontalAlignment align)
-{
-    if (align != HA_LEFT && parent_ && parent_->GetLayoutMode() == LM_HORIZONTAL)
-    {
-        LOGWARNING("Forcing left alignment because parent element has horizontal layout");
-        align = HA_LEFT;
-    }
-
-    if (horizontalAlignment_ != align)
-    {
-        horizontalAlignment_ = align;
-        MarkDirty();
-    }
-}
-
-void UIElement::SetVerticalAlignment(VerticalAlignment align)
-{
-    if (align != VA_TOP && parent_ && parent_->GetLayoutMode() == LM_VERTICAL)
-    {
-        LOGWARNING("Forcing top alignment because parent element has vertical layout");
-        align = VA_TOP;
-    }
-
-    if (verticalAlignment_ != align)
-    {
-        verticalAlignment_ = align;
-        MarkDirty();
-    }
-}
-
-void UIElement::SetClipBorder(const IntRect& rect)
-{
-    clipBorder_.left_ = Max(rect.left_, 0);
-    clipBorder_.top_ = Max(rect.top_, 0);
-    clipBorder_.right_ = Max(rect.right_, 0);
-    clipBorder_.bottom_ = Max(rect.bottom_, 0);
-}
-
-void UIElement::SetColor(const Color& color)
-{
-    for (unsigned i = 0; i < MAX_UIELEMENT_CORNERS; ++i)
-        color_[i] = color;
-    colorGradient_ = false;
-    derivedColorDirty_ = true;
-}
-
-void UIElement::SetColor(Corner corner, const Color& color)
-{
-    color_[corner] = color;
-    colorGradient_ = false;
-    derivedColorDirty_ = true;
-
-    for (unsigned i = 0; i < MAX_UIELEMENT_CORNERS; ++i)
-    {
-        if (i != corner && color_[i] != color_[corner])
-            colorGradient_ = true;
-    }
-}
-
-void UIElement::SetPriority(int priority)
-{
-    priority_ = priority;
-    if (parent_)
-        parent_->sortOrderDirty_ = true;
-}
-
-void UIElement::SetOpacity(float opacity)
-{
-    opacity_ = Clamp(opacity, 0.0f, 1.0f);
-    MarkDirty();
-}
-
-void UIElement::SetBringToFront(bool enable)
-{
-    bringToFront_ = enable;
-}
-
-void UIElement::SetBringToBack(bool enable)
-{
-    bringToBack_ = enable;
-}
-
-void UIElement::SetClipChildren(bool enable)
-{
-    clipChildren_ = enable;
-}
-
-void UIElement::SetSortChildren(bool enable)
-{
-    if (!sortChildren_ && enable)
-        sortOrderDirty_ = true;
-
-    sortChildren_ = enable;
-}
-
-void UIElement::SetUseDerivedOpacity(bool enable)
-{
-    useDerivedOpacity_ = enable;
-}
-
-void UIElement::SetEnabled(bool enable)
-{
-    enabled_ = enable;
-    enabledPrev_ = enable;
-}
-
-void UIElement::SetDeepEnabled(bool enable)
-{
-    enabled_ = enable;
-
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-        (*i)->SetDeepEnabled(enable);
-}
-
-void UIElement::ResetDeepEnabled()
-{
-    enabled_ = enabledPrev_;
-
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-        (*i)->ResetDeepEnabled();
-}
-
-void UIElement::SetEnabledRecursive(bool enable)
-{
-    enabled_ = enable;
-    enabledPrev_ = enable;
-
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-        (*i)->SetEnabledRecursive(enable);
-}
-
-void UIElement::SetEditable(bool enable)
-{
-    editable_ = enable;
-    OnSetEditable();
-}
-
-void UIElement::SetFocusMode(FocusMode mode)
-{
-    focusMode_ = mode;
-}
-
-void UIElement::SetFocus(bool enable)
-{
-    if (focusMode_ < FM_FOCUSABLE)
-        enable = false;
-
-    UI* ui = GetSubsystem<UI>();
-    if (enable)
-    {
-        if (ui->GetFocusElement() != this)
-            ui->SetFocusElement(this);
-    }
-    else
-    {
-        if (ui->GetFocusElement() == this)
-            ui->SetFocusElement(0);
-    }
-}
-
-void UIElement::SetSelected(bool enable)
-{
-    selected_ = enable;
-}
-
-void UIElement::SetVisible(bool enable)
-{
-    if (enable != visible_)
-    {
-        visible_ = enable;
-
-        // Parent's layout may change as a result of visibility change
-        if (parent_)
-            parent_->UpdateLayout();
-
-        using namespace VisibleChanged;
-
-        VariantMap& eventData = GetEventDataMap();
-        eventData[P_ELEMENT] = this;
-        eventData[P_VISIBLE] = visible_;
-        SendEvent(E_VISIBLECHANGED, eventData);
-    }
-}
-
-void UIElement::SetDragDropMode(unsigned mode)
-{
-    dragDropMode_ = mode;
-}
-
-bool UIElement::SetStyle(const String& styleName, XMLFile* file)
-{
-    // If empty style was requested, replace with type name
-    String actualStyleName = !styleName.Empty() ? styleName : GetTypeName();
-
-    appliedStyle_ = actualStyleName;
-    if (styleName == "none")
-        return true;
-
-    if (!file)
-    {
-        file = GetDefaultStyle();
-        if (!file)
-            return false;
-    }
-    else
-    {
-        // If a custom style file specified, remember it
-        defaultStyle_ = file;
-    }
-
-    styleXPathQuery_.SetVariable("typeName", actualStyleName);
-    XMLElement styleElem = file->GetRoot().SelectSinglePrepared(styleXPathQuery_);
-    return styleElem && SetStyle(styleElem);
-}
-
-bool UIElement::SetStyle(const XMLElement& element)
-{
-    appliedStyle_ = element.GetAttribute("type");
-
-    // Consider style attribute values as instance-level attribute default values
-    return LoadXML(element, true);
-}
-
-bool UIElement::SetStyleAuto(XMLFile* file)
-{
-    return SetStyle(String::EMPTY, file);
-}
-
-void UIElement::SetDefaultStyle(XMLFile* style)
-{
-    defaultStyle_ = style;
-}
-
-void UIElement::SetLayout(LayoutMode mode, int spacing, const IntRect& border)
-{
-    layoutMode_ = mode;
-    layoutSpacing_ = Max(spacing, 0);
-    layoutBorder_ = IntRect(Max(border.left_, 0), Max(border.top_, 0), Max(border.right_, 0), Max(border.bottom_, 0));
-    VerifyChildAlignment();
-    UpdateLayout();
-}
-
-void UIElement::SetLayoutMode(LayoutMode mode)
-{
-    layoutMode_ = mode;
-    VerifyChildAlignment();
-    UpdateLayout();
-}
-
-void UIElement::SetLayoutSpacing(int spacing)
-{
-    layoutSpacing_ = Max(spacing, 0);
-    UpdateLayout();
-}
-
-void UIElement::SetLayoutBorder(const IntRect& border)
-{
-    layoutBorder_ = IntRect(Max(border.left_, 0), Max(border.top_, 0), Max(border.right_, 0), Max(border.bottom_, 0));
-    UpdateLayout();
-}
-
-void UIElement::SetLayoutFlexScale(const Vector2& scale)
-{
-    layoutFlexScale_ = Vector2(Max(scale.x_, 0.0f), Max(scale.y_, 0.0f));
-}
-
-void UIElement::SetIndent(int indent)
-{
-    indent_ = indent;
-    if (parent_)
-        parent_->UpdateLayout();
-    UpdateLayout();
-    OnIndentSet();
-}
-
-void UIElement::SetIndentSpacing(int indentSpacing)
-{
-    indentSpacing_ = Max(indentSpacing, 0);
-    if (parent_)
-        parent_->UpdateLayout();
-    UpdateLayout();
-    OnIndentSet();
-}
-
-void UIElement::UpdateLayout()
-{
-    if (layoutMode_ == LM_FREE || layoutNestingLevel_)
-        return;
-
-    // Prevent further updates while this update happens
-    DisableLayoutUpdate();
-
-    PODVector<int> positions;
-    PODVector<int> sizes;
-    PODVector<int> minSizes;
-    PODVector<int> maxSizes;
-    PODVector<float> flexScales;
-
-    int baseIndentWidth = GetIndentWidth();
-
-    if (layoutMode_ == LM_HORIZONTAL)
-    {
-        int minChildHeight = 0;
-
-        for (unsigned i = 0; i < children_.Size(); ++i)
-        {
-            if (!children_[i]->IsVisible())
-                continue;
-            positions.Push(baseIndentWidth);
-            unsigned indent = children_[i]->GetIndentWidth();
-            sizes.Push(children_[i]->GetWidth() + indent);
-            minSizes.Push(children_[i]->GetMinWidth() + indent);
-            maxSizes.Push(children_[i]->GetMaxWidth() + indent);
-            flexScales.Push(children_[i]->GetLayoutFlexScale().x_);
-            minChildHeight = Max(minChildHeight, children_[i]->GetMinHeight());
-        }
-
-        CalculateLayout(positions, sizes, minSizes, maxSizes, flexScales, GetWidth(), layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_);
-
-        int width = CalculateLayoutParentSize(sizes, layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_);
-        int height = Max(GetHeight(), minChildHeight + layoutBorder_.top_ + layoutBorder_.bottom_);
-        int minWidth = Min(CalculateLayoutParentSize(minSizes, layoutBorder_.left_, layoutBorder_.right_, layoutSpacing_), maxSize_.x_);
-        int minHeight = Min(minChildHeight + layoutBorder_.top_ + layoutBorder_.bottom_, maxSize_.y_);
-        // Respect fixed size if already set
-        if (minSize_.x_ != maxSize_.x_)
-            minSize_.x_ = minWidth;
-        if (minSize_.y_ != maxSize_.y_)
-            minSize_.y_ = minHeight;
-        SetSize(width, height);
-        // Validate the size before resizing child elements, in case of min/max limits
-        width = size_.x_;
-        height = size_.y_;
-
-        unsigned j = 0;
-        for (unsigned i = 0; i < children_.Size(); ++i)
-        {
-            if (!children_[i]->IsVisible())
-                continue;
-            children_[i]->SetPosition(positions[j], GetLayoutChildPosition(children_[i]).y_);
-            children_[i]->SetSize(sizes[j], height - layoutBorder_.top_ - layoutBorder_.bottom_);
-            ++j;
-        }
-    }
-    else if (layoutMode_ == LM_VERTICAL)
-    {
-        int minChildWidth = 0;
-
-        for (unsigned i = 0; i < children_.Size(); ++i)
-        {
-            if (!children_[i]->IsVisible())
-                continue;
-            positions.Push(0);
-            sizes.Push(children_[i]->GetHeight());
-            minSizes.Push(children_[i]->GetMinHeight());
-            maxSizes.Push(children_[i]->GetMaxHeight());
-            flexScales.Push(children_[i]->GetLayoutFlexScale().y_);
-            minChildWidth = Max(minChildWidth, children_[i]->GetMinWidth() + children_[i]->GetIndentWidth());
-        }
-
-        CalculateLayout(positions, sizes, minSizes, maxSizes, flexScales, GetHeight(), layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_);
-
-        int height = CalculateLayoutParentSize(sizes, layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_);
-        int width = Max(GetWidth(), minChildWidth + layoutBorder_.left_ + layoutBorder_.right_);
-        int minHeight = Min(CalculateLayoutParentSize(minSizes, layoutBorder_.top_, layoutBorder_.bottom_, layoutSpacing_), maxSize_.y_);
-        int minWidth = Min(minChildWidth + layoutBorder_.left_ + layoutBorder_.right_, maxSize_.x_);
-        if (minSize_.x_ != maxSize_.x_)
-            minSize_.x_ = minWidth;
-        if (minSize_.y_ != maxSize_.y_)
-            minSize_.y_ = minHeight;
-        SetSize(width, height);
-        width = size_.x_;
-        height = size_.y_;
-
-        unsigned j = 0;
-        for (unsigned i = 0; i < children_.Size(); ++i)
-        {
-            if (!children_[i]->IsVisible())
-                continue;
-            children_[i]->SetPosition(GetLayoutChildPosition(children_[i]).x_ + baseIndentWidth, positions[j]);
-            children_[i]->SetSize(width - layoutBorder_.left_ - layoutBorder_.right_, sizes[j]);
-            ++j;
-        }
-    }
-
-    using namespace LayoutUpdated;
-
-    VariantMap& eventData = GetEventDataMap();
-    eventData[P_ELEMENT] = this;
-    SendEvent(E_LAYOUTUPDATED, eventData);
-
-    EnableLayoutUpdate();
-}
-
-void UIElement::DisableLayoutUpdate()
-{
-    ++layoutNestingLevel_;
-}
-
-void UIElement::EnableLayoutUpdate()
-{
-    --layoutNestingLevel_;
-}
-
-void UIElement::BringToFront()
-{
-    // Follow the parent chain to the top level window. If it has BringToFront mode, bring it to front now
-    UIElement* root = GetRoot();
-    // If element is detached from hierarchy, this must be a no-op
-    if (!root)
-        return;
-
-    UIElement* ptr = this;
-    while (ptr && ptr->GetParent() != root)
-        ptr = ptr->GetParent();
-    if (!ptr || !ptr->GetBringToFront())
-        return;
-
-    // Get the highest priority used by all other top level elements, assign that to the new front element
-    // and decrease others' priority where necessary. However, take into account only input-enabled
-    // elements and those which have the BringToBack flag set
-    HashSet<int> usedPriorities;
-
-    int maxPriority = M_MIN_INT;
-    const Vector<SharedPtr<UIElement> >& rootChildren = root->GetChildren();
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = rootChildren.Begin(); i != rootChildren.End(); ++i)
-    {
-        UIElement* other = *i;
-        if (other->IsEnabled() && other->bringToBack_ && other != ptr)
-        {
-            int priority = other->GetPriority();
-            // M_MAX_INT is used by popups and tooltips. Disregard these to avoid an "arms race" with the priorities
-            if (priority == M_MAX_INT)
-                continue;
-            usedPriorities.Insert(priority);
-            maxPriority = Max(priority, maxPriority);
-        }
-    }
-
-    if (maxPriority != M_MIN_INT && maxPriority >= ptr->GetPriority())
-    {
-        ptr->SetPriority(maxPriority);
-
-        int minPriority = maxPriority;
-        while (usedPriorities.Contains(minPriority))
-            --minPriority;
-
-        for (Vector<SharedPtr<UIElement> >::ConstIterator i = rootChildren.Begin(); i != rootChildren.End(); ++i)
-        {
-            UIElement* other = *i;
-            int priority = other->GetPriority();
-
-            if (other->IsEnabled() && other->bringToBack_ && other != ptr && priority >= minPriority && priority <= maxPriority)
-                other->SetPriority(priority - 1);
-        }
-    }
-}
-
-UIElement* UIElement::CreateChild(StringHash type, const String& name, unsigned index)
-{
-    // Check that creation succeeds and that the object in fact is a UI element
-    SharedPtr<UIElement> newElement = DynamicCast<UIElement>(context_->CreateObject(type));
-    if (!newElement)
-    {
-        LOGERROR("Could not create unknown UI element type " + type.ToString());
-        return 0;
-    }
-
-    if (!name.Empty())
-        newElement->SetName(name);
-
-    InsertChild(index, newElement);
-    return newElement;
-}
-
-void UIElement::AddChild(UIElement* element)
-{
-    InsertChild(M_MAX_UNSIGNED, element);
-}
-
-void UIElement::InsertChild(unsigned index, UIElement* element)
-{
-    // Check for illegal or redundant parent assignment
-    if (!element || element == this || element->parent_ == this)
-        return;
-     // Check for possible cyclic parent assignment
-    UIElement* parent = parent_;
-    while (parent)
-    {
-        if (parent == element)
-            return;
-        parent = parent->parent_;
-    }
-
-    // Add first, then remove from old parent, to ensure the element does not get deleted
-    if (index >= children_.Size())
-        children_.Push(SharedPtr<UIElement>(element));
-    else
-        children_.Insert(children_.Begin() + index, SharedPtr<UIElement>(element));
-
-    XMLFile* previousStyleFile = element->GetDefaultStyle();
-
-    element->Remove();
-
-    if (sortChildren_)
-        sortOrderDirty_ = true;
-
-    element->parent_ = this;
-    element->MarkDirty();
-
-    // If child element did not already have a style file, but has specified a style name, apply it now
-    if (!previousStyleFile && !element->appliedStyle_.Empty() && GetDefaultStyle())
-        element->SetStyle(element->appliedStyle_);
-
-    VerifyChildAlignment();
-    UpdateLayout();
-
-    // Send change event
-    UIElement* root = GetRoot();
-    UIElement* sender = GetElementEventSender();
-    if (sender)
-    {
-        using namespace ElementAdded;
-
-        VariantMap& eventData = GetEventDataMap();
-        eventData[P_ROOT] = root;
-        eventData[P_PARENT] = this;
-        eventData[P_ELEMENT] = element;
-
-        sender->SendEvent(E_ELEMENTADDED, eventData);
-    }
-}
-
-void UIElement::RemoveChild(UIElement* element, unsigned index)
-{
-    for (unsigned i = index; i < children_.Size(); ++i)
-    {
-        if (children_[i] == element)
-        {
-            // Send change event if not already being destroyed
-            UIElement* sender = Refs() > 0 ? GetElementEventSender() : 0;
-            if (sender)
-            {
-                using namespace ElementRemoved;
-
-                VariantMap& eventData = GetEventDataMap();
-                eventData[P_ROOT] = GetRoot();
-                eventData[P_PARENT] = this;
-                eventData[P_ELEMENT] = element;
-
-                sender->SendEvent(E_ELEMENTREMOVED, eventData);
-            }
-
-            element->Detach();
-            children_.Erase(i);
-            UpdateLayout();
-            return;
-        }
-    }
-}
-
-void UIElement::RemoveChildAtIndex(unsigned index)
-{
-    if (index >= children_.Size())
-        return;
-
-    // Send change event if not already being destroyed
-    UIElement* sender = Refs() > 0 ? GetElementEventSender() : 0;
-    if (sender)
-    {
-        using namespace ElementRemoved;
-
-        VariantMap& eventData = GetEventDataMap();
-        eventData[P_ROOT] = GetRoot();
-        eventData[P_PARENT] = this;
-        eventData[P_ELEMENT] = children_[index];
-
-        sender->SendEvent(E_ELEMENTREMOVED, eventData);
-    }
-
-    children_[index]->Detach();
-    children_.Erase(index);
-    UpdateLayout();
-}
-
-void UIElement::RemoveAllChildren()
-{
-    UIElement* root = GetRoot();
-    UIElement* sender = Refs() > 0 ? GetElementEventSender() : 0;
-
-    for (Vector<SharedPtr<UIElement> >::Iterator i = children_.Begin(); i < children_.End(); )
-    {
-        // Send change event if not already being destroyed
-        if (sender)
-        {
-            using namespace ElementRemoved;
-
-            VariantMap& eventData = GetEventDataMap();
-            eventData[P_ROOT] = root;
-            eventData[P_PARENT] = this;
-            eventData[P_ELEMENT] = (*i).Get();
-
-            sender->SendEvent(E_ELEMENTREMOVED, eventData);
-        }
-
-        (*i++)->Detach();
-    }
-    children_.Clear();
-    UpdateLayout();
-}
-
-void UIElement::Remove()
-{
-    if (parent_)
-        parent_->RemoveChild(this);
-}
-
-unsigned UIElement::FindChild(UIElement* element) const
-{
-    Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Find(SharedPtr<UIElement>(element));
-    return i != children_.End() ? i - children_.Begin() : M_MAX_UNSIGNED;
-}
-
-void UIElement::SetParent(UIElement* parent, unsigned index)
-{
-    if (parent)
-        parent->InsertChild(index, this);
-}
-
-void UIElement::SetVar(StringHash key, const Variant& value)
-{
-    vars_[key] = value;
-}
-
-void UIElement::SetInternal(bool enable)
-{
-    internal_ = enable;
-}
-
-void UIElement::SetTraversalMode(TraversalMode traversalMode)
-{
-    traversalMode_ = traversalMode;
-}
-
-void UIElement::SetElementEventSender(bool flag)
-{
-    elementEventSender_ = flag;
-}
-
-float UIElement::GetDerivedOpacity() const
-{
-    if (!useDerivedOpacity_)
-        return opacity_;
-
-    if (opacityDirty_)
-    {
-        derivedOpacity_ = opacity_;
-        const UIElement* parent = parent_;
-
-        while (parent)
-        {
-            derivedOpacity_ *= parent->opacity_;
-            parent = parent->parent_;
-        }
-
-        opacityDirty_ = false;
-    }
-
-    return derivedOpacity_;
-}
-
-bool UIElement::HasFocus() const
-{
-    return GetSubsystem<UI>()->GetFocusElement() == this;
-}
-
-const String& UIElement::GetAppliedStyle() const
-{
-    return appliedStyle_ == GetTypeName() ? String::EMPTY : appliedStyle_;
-}
-
-XMLFile* UIElement::GetDefaultStyle(bool recursiveUp) const
-{
-    if (recursiveUp)
-    {
-        const UIElement* element = this;
-        while (element)
-        {
-            if (element->defaultStyle_)
-                return element->defaultStyle_;
-            element = element->parent_;
-        }
-        return 0;
-    }
-    else
-        return defaultStyle_;
-}
-
-void UIElement::GetChildren(PODVector<UIElement*>& dest, bool recursive) const
-{
-    dest.Clear();
-
-    if (!recursive)
-    {
-        dest.Reserve(children_.Size());
-        for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-            dest.Push(*i);
-    }
-    else
-        GetChildrenRecursive(dest);
-}
-
-unsigned UIElement::GetNumChildren(bool recursive) const
-{
-    if (!recursive)
-        return children_.Size();
-    else
-    {
-        unsigned allChildren = children_.Size();
-        for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-            allChildren += (*i)->GetNumChildren(true);
-
-        return allChildren;
-    }
-}
-
-UIElement* UIElement::GetChild(unsigned index) const
-{
-    return index < children_.Size() ? children_[index] : (UIElement*)0;
-}
-
-UIElement* UIElement::GetChild(const String& name, bool recursive) const
-{
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-    {
-        if ((*i)->name_ == name)
-            return *i;
-
-        if (recursive)
-        {
-            UIElement* element = (*i)->GetChild(name, true);
-            if (element)
-                return element;
-        }
-    }
-
-    return 0;
-}
-
-UIElement* UIElement::GetChild(const StringHash& key, const Variant& value, bool recursive) const
-{
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-    {
-        const Variant& varValue = (*i)->GetVar(key);
-        if (value != Variant::EMPTY ? varValue == value : varValue != Variant::EMPTY)
-            return *i;
-
-        if (recursive)
-        {
-            UIElement* element = (*i)->GetChild(key, value, true);
-            if (element)
-                return element;
-        }
-    }
-
-    return 0;
-}
-
-UIElement* UIElement::GetRoot() const
-{
-    UIElement* root = parent_;
-    if (!root)
-        return 0;
-    while (root->GetParent())
-        root = root->GetParent();
-    return root;
-}
-
-const Color& UIElement::GetDerivedColor() const
-{
-    if (derivedColorDirty_)
-    {
-        derivedColor_ = color_[C_TOPLEFT];
-        derivedColor_.a_ *= GetDerivedOpacity();
-        derivedColorDirty_ = false;
-    }
-
-    return derivedColor_;
-}
-
-const Variant& UIElement::GetVar(const StringHash& key) const
-{
-    VariantMap::ConstIterator i = vars_.Find(key);
-    return i != vars_.End() ? i->second_ : Variant::EMPTY;
-}
-
-IntVector2 UIElement::ScreenToElement(const IntVector2& screenPosition)
-{
-    return screenPosition - GetScreenPosition();
-}
-
-IntVector2 UIElement::ElementToScreen(const IntVector2& position)
-{
-    return position + GetScreenPosition();
-}
-
-bool UIElement::IsInside(IntVector2 position, bool isScreen)
-{
-    if (isScreen)
-        position = ScreenToElement(position);
-    return position.x_ >= 0 && position.y_ >= 0 && position.x_ < size_.x_ && position.y_ < size_.y_;
-}
-
-bool UIElement::IsInsideCombined(IntVector2 position, bool isScreen)
-{
-    // If child elements are clipped, no need to expand the rect
-    if (clipChildren_)
-        return IsInside(position, isScreen);
-
-    if (!isScreen)
-        position = ElementToScreen(position);
-
-    IntRect combined = GetCombinedScreenRect();
-    return position.x_ >= combined.left_ && position.y_ >= combined.top_ && position.x_ < combined.right_ &&
-        position.y_ < combined.bottom_;
-}
-
-IntRect UIElement::GetCombinedScreenRect()
-{
-    IntVector2 screenPosition(GetScreenPosition());
-    IntRect combined(screenPosition.x_, screenPosition.y_, screenPosition.x_ + size_.x_, screenPosition.y_ + size_.y_);
-
-    if (!clipChildren_)
-    {
-        for (Vector<SharedPtr<UIElement> >::Iterator i = children_.Begin(); i != children_.End(); ++i)
-        {
-            IntVector2 childPos = (*i)->GetScreenPosition();
-            const IntVector2& childSize = (*i)->GetSize();
-            if (childPos.x_ < combined.left_)
-                combined.left_ = childPos.x_;
-            if (childPos.y_ < combined.top_)
-                combined.top_ = childPos.y_;
-            if (childPos.x_ + childSize.x_ > combined.right_)
-                combined.right_ = childPos.x_ + childSize.x_;
-            if (childPos.y_ + childSize.y_ > combined.bottom_)
-                combined.bottom_ = childPos.y_ + childSize.y_;
-        }
-    }
-
-    return combined;
-}
-
-void UIElement::SortChildren()
-{
-    if (sortChildren_ && sortOrderDirty_)
-    {
-        // Only sort when there is no layout
-        if (layoutMode_ == LM_FREE)
-            Sort(children_.Begin(), children_.End(), CompareUIElements);
-        sortOrderDirty_ = false;
-    }
-}
-
-void UIElement::SetChildOffset(const IntVector2& offset)
-{
-    if (offset != childOffset_)
-    {
-        childOffset_ = offset;
-        for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-            (*i)->MarkDirty();
-    }
-}
-
-void UIElement::SetHovering(bool enable)
-{
-    hovering_ = enable;
-}
-
-void UIElement::AdjustScissor(IntRect& currentScissor)
-{
-    if (clipChildren_)
-    {
-        IntVector2 screenPos = GetScreenPosition();
-        currentScissor.left_ = Max(currentScissor.left_, screenPos.x_ + clipBorder_.left_);
-        currentScissor.top_ = Max(currentScissor.top_, screenPos.y_ + clipBorder_.top_);
-        currentScissor.right_ = Min(currentScissor.right_, screenPos.x_ + size_.x_ - clipBorder_.right_);
-        currentScissor.bottom_ = Min(currentScissor.bottom_, screenPos.y_ + size_.y_ - clipBorder_.bottom_);
-
-        if (currentScissor.right_ < currentScissor.left_)
-            currentScissor.right_ = currentScissor.left_;
-        if (currentScissor.bottom_ < currentScissor.top_)
-            currentScissor.bottom_ = currentScissor.top_;
-    }
-}
-
-void UIElement::GetBatchesWithOffset(IntVector2& offset, PODVector<UIBatch>& batches, PODVector<float>& vertexData, IntRect
-    currentScissor)
-{
-    Vector2 floatOffset((float)offset.x_, (float)offset.y_);
-    unsigned initialSize = vertexData.Size();
-
-    GetBatches(batches, vertexData, currentScissor);
-    for (unsigned i = initialSize; i < vertexData.Size(); i += 6)
-    {
-        vertexData[i] += floatOffset.x_;
-        vertexData[i + 1] += floatOffset.y_;
-    }
-
-    AdjustScissor(currentScissor);
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-    {
-        if ((*i)->IsVisible())
-            (*i)->GetBatchesWithOffset(offset, batches, vertexData, currentScissor);
-    }
-}
-
-UIElement* UIElement::GetElementEventSender() const
-{
-    UIElement* element = const_cast<UIElement*>(this);
-    if (elementEventSender_)
-        return element;
-
-    while (element->parent_)
-    {
-        element = element->parent_;
-        if (element->elementEventSender_)
-            return element;
-    }
-
-    // If no predefined element event sender in the parental chain, return ultimate root element
-    return element;
-}
-
-void UIElement::OnAttributeAnimationAdded()
-{
-    if (attributeAnimationInfos_.Size() == 1)
-        SubscribeToEvent(E_POSTUPDATE, HANDLER(UIElement, HandlePostUpdate));
-}
-
-void UIElement::OnAttributeAnimationRemoved()
-{
-    if (attributeAnimationInfos_.Empty())
-        UnsubscribeFromEvent(E_POSTUPDATE);
-}
-
-void UIElement::SetObjectAttributeAnimation(const String& name, ValueAnimation* attributeAnimation, WrapMode wrapMode, float speed)
-{
-    Vector<String> names = name.Split('/');
-    // Only attribute name
-    if (names.Size() == 1)
-        SetAttributeAnimation(name, attributeAnimation, wrapMode, speed);
-    else
-    {
-        // Name must in following format: "#0/#1/attribute"
-        UIElement* element = this;
-        for (unsigned i = 0; i < names.Size() - 1; ++i)
-        {
-            if (names[i].Front() != '#')
-            {
-                LOGERROR("Invalid name " + name);
-                return;
-            }
-
-            unsigned index = ToInt(names[i].Substring(1, names[i].Length() - 1));
-            element = element->GetChild(index);
-            if (!element)
-            {
-                LOGERROR("Could not find element by name " + name);
-                return;
-            }
-        }
-
-        element->SetAttributeAnimation(names.Back(), attributeAnimation, wrapMode, speed);
-    }
-}
-
-void UIElement::MarkDirty()
-{
-    positionDirty_ = true;
-    opacityDirty_ = true;
-    derivedColorDirty_ = true;
-
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-        (*i)->MarkDirty();
-}
-
-bool UIElement::RemoveChildXML(XMLElement& parent, const String& name) const
-{
-    static XPathQuery matchXPathQuery("./attribute[@name=$attributeName]", "attributeName:String");
-
-    if (!matchXPathQuery.SetVariable("attributeName", name))
-        return false;
-
-    XMLElement removeElem = parent.SelectSinglePrepared(matchXPathQuery);
-    return !removeElem || parent.RemoveChild(removeElem);
-}
-
-bool UIElement::RemoveChildXML(XMLElement& parent, const String& name, const String& value) const
-{
-    static XPathQuery matchXPathQuery("./attribute[@name=$attributeName and @value=$attributeValue]", "attributeName:String, attributeValue:String");
-
-    if (!matchXPathQuery.SetVariable("attributeName", name))
-        return false;
-    if (!matchXPathQuery.SetVariable("attributeValue", value))
-        return false;
-
-    XMLElement removeElem = parent.SelectSinglePrepared(matchXPathQuery);
-    return !removeElem || parent.RemoveChild(removeElem);
-}
-
-bool UIElement::FilterUIStyleAttributes(XMLElement& dest, const XMLElement& styleElem) const
-{
-    // Remove style attribute only when its value is identical to the value stored in style file
-    String style = styleElem.GetAttribute("style");
-    if (!style.Empty())
-    {
-        if (style == dest.GetAttribute("style"))
-        {
-            if (!dest.RemoveAttribute("style"))
-            {
-                LOGWARNING("Could not remove style attribute");
-                return false;
-            }
-        }
-    }
-
-    // Perform the same action recursively for internal child elements stored in style file
-    XMLElement childDest = dest.GetChild("element");
-    XMLElement childElem = styleElem.GetChild("element");
-    while (childDest && childElem)
-    {
-        if (!childElem.GetBool("internal"))
-        {
-            LOGERROR("Invalid style file, style element can only contain internal child elements");
-            return false;
-        }
-        if (!FilterUIStyleAttributes(childDest, childElem))
-            return false;
-
-        childDest = childDest.GetNext("element");
-        childElem = childElem.GetNext("element");
-    }
-
-    // Remove style attribute when it is the same as its type, however, if it is an internal element then replace it to "none" instead
-    if (!dest.GetAttribute("style").Empty() && dest.GetAttribute("style") == dest.GetAttribute("type"))
-    {
-        if (internal_)
-        {
-            if (!dest.SetAttribute("style", "none"))
-                return false;
-        }
-        else
-        {
-            if (!dest.RemoveAttribute("style"))
-                return false;
-        }
-    }
-
-    return true;
-}
-
-bool UIElement::FilterImplicitAttributes(XMLElement& dest) const
-{
-    // Remove positioning and sizing attributes when they are under the influence of layout mode
-    if (layoutMode_ != LM_FREE && !IsFixedWidth() && !IsFixedHeight())
-    {
-        if (!RemoveChildXML(dest, "Min Size"))
-            return false;
-    }
-    if (parent_ && parent_->layoutMode_ != LM_FREE)
-    {
-        if (!RemoveChildXML(dest, "Position"))
-            return false;
-        if (!RemoveChildXML(dest, "Size"))
-            return false;
-    }
-
-    return true;
-}
-
-void UIElement::GetChildrenRecursive(PODVector<UIElement*>& dest) const
-{
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-    {
-        UIElement* element = *i;
-        dest.Push(element);
-        if (!element->children_.Empty())
-            element->GetChildrenRecursive(dest);
-    }
-}
-
-int UIElement::CalculateLayoutParentSize(const PODVector<int>& sizes, int begin, int end, int spacing)
-{
-    int width = begin + end;
-    if (sizes.Empty())
-        return width;
-
-    for (unsigned i = 0; i < sizes.Size(); ++i)
-    {
-        // If calculating maximum size, and the default is specified, do not overflow it
-        if (sizes[i] == M_MAX_INT)
-            return M_MAX_INT;
-        width += sizes[i] + spacing;
-    }
-    // The last spacing is not needed
-    return width - spacing;
-}
-
-void UIElement::CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes,
-        const PODVector<int>& maxSizes, const PODVector<float>& flexScales, int targetSize, int begin, int end, int spacing)
-{
-    int numChildren = sizes.Size();
-    if (!numChildren)
-        return;
-    int targetTotalSize = targetSize - begin - end - (numChildren - 1) * spacing;
-    if (targetTotalSize < 0)
-        targetTotalSize = 0;
-    int targetChildSize = targetTotalSize / numChildren;
-    int remainder = targetTotalSize % numChildren;
-    float add = (float)remainder / numChildren;
-    float acc = 0.0f;
-
-    // Initial pass
-    for (int i = 0; i < numChildren; ++i)
-    {
-        int targetSize = (int)(targetChildSize * flexScales[i]);
-        if (remainder)
-        {
-            acc += add;
-            if (acc >= 0.5f)
-            {
-                acc -= 1.0f;
-                ++targetSize;
-                --remainder;
-            }
-        }
-        sizes[i] = Clamp(targetSize, minSizes[i], maxSizes[i]);
-    }
-
-    // Error correction passes
-    for (;;)
-    {
-        int actualTotalSize = 0;
-        for (int i = 0; i < numChildren; ++i)
-            actualTotalSize += sizes[i];
-        int error = targetTotalSize - actualTotalSize;
-        // Break if no error
-        if (!error)
-            break;
-
-        // Check which of the children can be resized to correct the error. If none, must break
-        PODVector<unsigned> resizable;
-        for (int i = 0; i < numChildren; ++i)
-        {
-            if (error < 0 && sizes[i] > minSizes[i])
-                resizable.Push(i);
-            else if (error > 0 && sizes[i] < maxSizes[i])
-                resizable.Push(i);
-        }
-        if (resizable.Empty())
-            break;
-
-        int numResizable = resizable.Size();
-        int errorPerChild = error / numResizable;
-        remainder = (abs(error)) % numResizable;
-        add = (float)remainder / numResizable;
-        acc = 0.0f;
-
-        for (int i = 0; i < numResizable; ++i)
-        {
-            unsigned index = resizable[i];
-            int targetSize = sizes[index] + errorPerChild;
-            if (remainder)
-            {
-                acc += add;
-                if (acc >= 0.5f)
-                {
-                    acc -= 1.0f;
-                    targetSize = error < 0 ? targetSize - 1 : targetSize + 1;
-                    --remainder;
-                }
-            }
-
-            sizes[index] = Clamp(targetSize, minSizes[index], maxSizes[index]);
-        }
-    }
-
-    // Calculate final positions and store the minimum child element size
-    layoutMinSize_ = M_MAX_INT;
-    layoutMaxSize_ = 0;
-    int position = begin;
-    for (int i = 0; i < numChildren; ++i)
-    {
-        positions[i] = position;
-        position += sizes[i] + spacing;
-        if (sizes[i] < layoutMinSize_)
-            layoutMinSize_ = sizes[i];
-        if (sizes[i] > layoutMaxSize_)
-            layoutMaxSize_ = sizes[i];
-    }
-}
-
-IntVector2 UIElement::GetLayoutChildPosition(UIElement* child)
-{
-    IntVector2 ret(IntVector2::ZERO);
-
-    HorizontalAlignment ha = child->GetHorizontalAlignment();
-    switch (ha)
-    {
-    case HA_LEFT:
-        ret.x_ = layoutBorder_.left_;
-        break;
-
-    case HA_RIGHT:
-        ret.x_ = -layoutBorder_.right_;
-        break;
-
-    default:
-        break;
-    }
-
-    VerticalAlignment va = child->GetVerticalAlignment();
-    switch (va)
-    {
-    case VA_TOP:
-        ret.y_ = layoutBorder_.top_;
-        break;
-
-    case VA_BOTTOM:
-        ret.y_ = -layoutBorder_.bottom_;
-        break;
-
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-void UIElement::Detach()
-{
-    parent_ = 0;
-    MarkDirty();
-}
-
-void UIElement::VerifyChildAlignment()
-{
-    for (Vector<SharedPtr<UIElement> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
-    {
-        // Reapply child alignments. If they are illegal compared to layout, they will be set left/top as neded
-        (*i)->SetHorizontalAlignment((*i)->GetHorizontalAlignment());
-        (*i)->SetVerticalAlignment((*i)->GetVerticalAlignment());
-    }
-}
-
-void UIElement::HandlePostUpdate(StringHash eventType, VariantMap& eventData)
-{
-    using namespace PostUpdate;
-
-    UpdateAttributeAnimations(eventData[P_TIMESTEP].GetFloat());
-}
-
-}

+ 0 - 636
Source/Atomic/UI/UIElement.h

@@ -1,636 +0,0 @@
-//
-// Copyright (c) 2008-2015 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "../Scene/Animatable.h"
-#include "../UI/UIBatch.h"
-#include "../Math/Vector2.h"
-#include "../Resource/XMLFile.h"
-
-namespace Atomic
-{
-
-const Color DEBUG_DRAW_COLOR(Color::BLUE);
-
-/// %UI element horizontal alignment.
-enum HorizontalAlignment
-{
-    HA_LEFT = 0,
-    HA_CENTER,
-    HA_RIGHT
-};
-
-/// %UI element vertical alignment.
-enum VerticalAlignment
-{
-    VA_TOP = 0,
-    VA_CENTER,
-    VA_BOTTOM
-};
-
-/// %UI element corners.
-enum Corner
-{
-    C_TOPLEFT = 0,
-    C_TOPRIGHT,
-    C_BOTTOMLEFT,
-    C_BOTTOMRIGHT,
-    MAX_UIELEMENT_CORNERS
-};
-
-/// %UI element orientation.
-enum Orientation
-{
-    O_HORIZONTAL = 0,
-    O_VERTICAL
-};
-
-/// %UI element focus mode.
-enum FocusMode
-{
-    /// Is not focusable and does not affect existing focus.
-    FM_NOTFOCUSABLE = 0,
-    /// Resets focus when clicked.
-    FM_RESETFOCUS,
-    /// Is focusable.
-    FM_FOCUSABLE,
-    /// Is focusable and also defocusable by pressing ESC.
-    FM_FOCUSABLE_DEFOCUSABLE
-};
-
-/// Layout operation mode.
-enum LayoutMode
-{
-    /// No layout operations will be performed.
-    LM_FREE = 0,
-    /// Layout child elements horizontally and resize them to fit. Resize element if necessary.
-    LM_HORIZONTAL,
-    /// Layout child elements vertically and resize them to fit. Resize element if necessary.
-    LM_VERTICAL
-};
-
-/// Traversal mode for rendering.
-enum TraversalMode
-{
-    /// Traverse thru children having same priority first and recurse into their children before traversing children having higher priority.
-    TM_BREADTH_FIRST = 0,
-    /// Traverse thru each child and its children immediately after in sequence.
-    TM_DEPTH_FIRST
-};
-
-/// Drag and drop disabled.
-static const unsigned DD_DISABLED = 0x0;
-/// Drag and drop source flag.
-static const unsigned DD_SOURCE = 0x1;
-/// Drag and drop target flag.
-static const unsigned DD_TARGET = 0x2;
-/// Drag and drop source and target.
-static const unsigned DD_SOURCE_AND_TARGET = 0x3;
-
-class Cursor;
-class ResourceCache;
-
-/// Base class for %UI elements.
-class ATOMIC_API UIElement : public Animatable
-{
-    OBJECT(UIElement);
-    BASEOBJECT(UIElement);
-
-public:
-    /// Construct.
-    UIElement(Context* context);
-    /// Destruct.
-    virtual ~UIElement();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Apply attribute changes that can not be applied immediately.
-    virtual void ApplyAttributes();
-    /// Load from XML data. Return true if successful.
-    virtual bool LoadXML(const XMLElement& source, bool setInstanceDefault = false);
-    /// Load from XML data with style. Return true if successful.
-    virtual bool LoadXML(const XMLElement& source, XMLFile* styleFile, bool setInstanceDefault = false);
-    /// Create a child by loading from XML data with style. Return true if successful.
-    virtual bool LoadChildXML(const XMLElement& childElem, XMLFile* styleFile = 0, bool setInstanceDefault = false);
-    /// Save as XML data. Return true if successful.
-    virtual bool SaveXML(XMLElement& dest) const;
-
-    /// Perform UI element update.
-    virtual void Update(float timeStep);
-    /// Return whether is visible and inside a scissor rectangle and should be rendered.
-    virtual bool IsWithinScissor(const IntRect& currentScissor);
-    /// Update and return screen position.
-    virtual const IntVector2& GetScreenPosition() const;
-    /// Return UI rendering batches.
-    virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-    /// Return UI rendering batches for debug draw.
-    virtual void GetDebugDrawBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-    /// React to mouse hover.
-    virtual void OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
-    /// React to mouse click begin.
-    virtual void OnClickBegin(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor);
-    /// React to mouse click end.
-    virtual void OnClickEnd(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor, UIElement* beginElement);
-    /// React to double mouse click.
-    virtual void OnDoubleClick(const IntVector2& position, const IntVector2& screenPosition, int button, int buttons, int qualifiers, Cursor* cursor);
-    /// React to mouse drag begin.
-    virtual void OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
-    /// React to mouse drag motion.
-    virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, const IntVector2& deltaPos, int buttons, int qualifiers, Cursor* cursor);
-    /// React to mouse drag end.
-    virtual void OnDragEnd(const IntVector2& position, const IntVector2& screenPosition, int dragButtons, int releaseButton, Cursor* cursor);
-    /// React to a mouse drag cancel event (ie, when an extra button is pressed)
-    virtual void OnDragCancel(const IntVector2& position, const IntVector2& screenPosition, int dragButtons, int cancelButton, Cursor* cursor);
-    /// React to drag and drop test. Return true to signal that the drop is acceptable.
-    virtual bool OnDragDropTest(UIElement* source);
-    /// React to drag and drop finish. Return true to signal that the drop was accepted.
-    virtual bool OnDragDropFinish(UIElement* source);
-    /// React to mouse wheel.
-    virtual void OnWheel(int delta, int buttons, int qualifiers);
-    /// React to a key press.
-    virtual void OnKey(int key, int buttons, int qualifiers);
-    /// React to text input event.
-    virtual void OnTextInput(const String& text, int buttons, int qualifiers);
-    /// React to resize.
-    virtual void OnResize() {}
-    /// React to position change.
-    virtual void OnPositionSet() {}
-    /// React to editable status change.
-    virtual void OnSetEditable() {}
-    /// React to indent change.
-    virtual void OnIndentSet() {}
-
-    /// Load from an XML file. Return true if successful.
-    bool LoadXML(Deserializer& source);
-    /// Save to an XML file. Return true if successful.
-    bool SaveXML(Serializer& dest, const String& indentation = "\t") const;
-    /// Filter attributes in serialization process.
-    bool FilterAttributes(XMLElement& dest) const;
-
-    /// Set name.
-    void SetName(const String& name);
-    /// Set position.
-    void SetPosition(const IntVector2& position);
-    /// Set position.
-    void SetPosition(int x, int y);
-    /// Set size.
-    void SetSize(const IntVector2& size);
-    /// Set size.
-    void SetSize(int width, int height);
-    /// Set width only.
-    void SetWidth(int width);
-    /// Set height only.
-    void SetHeight(int height);
-    /// Set minimum size.
-    void SetMinSize(const IntVector2& minSize);
-    /// Set minimum size.
-    void SetMinSize(int width, int height);
-    /// Set minimum width.
-    void SetMinWidth(int width);
-    /// Set minimum height.
-    void SetMinHeight(int height);
-    /// Set maximum size.
-    void SetMaxSize(const IntVector2& maxSize);
-    /// Set maximum size.
-    void SetMaxSize(int width, int height);
-    /// Set maximum width.
-    void SetMaxWidth(int width);
-    /// Set maximum height.
-    void SetMaxHeight(int height);
-    /// Set fixed size.
-    void SetFixedSize(const IntVector2& size);
-    /// Set fixed size.
-    void SetFixedSize(int width, int height);
-    /// Set fixed width.
-    void SetFixedWidth(int width);
-    /// Set fixed height.
-    void SetFixedHeight(int height);
-    /// Set horizontal and vertical alignment.
-    void SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign);
-    /// Set horizontal alignment.
-    void SetHorizontalAlignment(HorizontalAlignment align);
-    /// Set vertical alignment.
-    void SetVerticalAlignment(VerticalAlignment align);
-    /// Set child element clipping border.
-    void SetClipBorder(const IntRect& rect);
-    /// Set color on all corners.
-    void SetColor(const Color& color);
-    /// Set color on one corner.
-    void SetColor(Corner corner, const Color& color);
-    /// Set priority.
-    void SetPriority(int priority);
-    /// Set opacity.
-    void SetOpacity(float opacity);
-    /// Set whether should be brought to front when focused.
-    void SetBringToFront(bool enable);
-    /// Set whether should be put to background when another element is focused.
-    void SetBringToBack(bool enable);
-    /// Set whether should clip child elements. Default false.
-    void SetClipChildren(bool enable);
-    /// Set whether should sort child elements according to priority. Default true.
-    void SetSortChildren(bool enable);
-    /// Set whether parent elements' opacity affects opacity. Default true.
-    void SetUseDerivedOpacity(bool enable);
-    /// Set whether reacts to input. Default false, but is enabled by subclasses if applicable.
-    void SetEnabled(bool enable);
-    /// Set enabled state on self and child elements. Elements' own enabled state is remembered (IsEnabledSelf) and can be restored.
-    void SetDeepEnabled(bool enable);
-    /// Reset enabled state to the element's remembered state prior to calling SetDeepEnabled.
-    void ResetDeepEnabled();
-    /// Set enabled state on self and child elements. Unlike SetDeepEnabled this does not remember the elements' own enabled state, but overwrites it.
-    void SetEnabledRecursive(bool enable);
-    /// Set whether value is editable through input. Not applicable to all elements. Default true.
-    void SetEditable(bool enable);
-    /// Set whether is focused. Only one element can be focused at a time.
-    void SetFocus(bool enable);
-    /// Set selected mode. Actual meaning is element dependent, for example constant hover or pressed effect.
-    void SetSelected(bool enable);
-    /// Set whether is visible.
-    void SetVisible(bool enable);
-    /// Set focus mode.
-    void SetFocusMode(FocusMode mode);
-    /// Set drag and drop flags.
-    void SetDragDropMode(unsigned mode);
-    /// Set style from an XML file. Find the style element by name. If the style file is not explicitly provided, use the default style from parental chain. Return true if the style is applied successfully.
-    bool SetStyle(const String& styleName, XMLFile* file = 0);
-    /// Set style from an XML element. Return true if the style is applied successfully.
-    bool SetStyle(const XMLElement& element);
-    /// Set style from an XML file. Find the style element automatically. If the style file is not explicitly provided, use the default style from parental chain. Return true if the style is applied successfully.
-    bool SetStyleAuto(XMLFile* file = 0);
-    /// Set default style file for later use by children elements.
-    void SetDefaultStyle(XMLFile* style);
-    /// Set layout.
-    void SetLayout(LayoutMode mode, int spacing = 0, const IntRect& border = IntRect::ZERO);
-    /// Set layout mode only.
-    void SetLayoutMode(LayoutMode mode);
-    /// Set layout spacing.
-    void SetLayoutSpacing(int spacing);
-    /// Set layout border.
-    void SetLayoutBorder(const IntRect& border);
-    /// Set layout flex scale.
-    void SetLayoutFlexScale(const Vector2& scale);
-    /// Set horizontal indentation.
-    void SetIndent(int indent);
-    /// Set indent spacing (number of pixels per indentation level).
-    void SetIndentSpacing(int indentSpacing);
-    /// Manually update layout. Should not be necessary in most cases, but is provided for completeness.
-    void UpdateLayout();
-    /// Disable automatic layout update. Should only be used if there are performance problems.
-    void DisableLayoutUpdate();
-    /// Enable automatic layout update.
-    void EnableLayoutUpdate();
-    /// Bring UI element to front.
-    void BringToFront();
-    /// Create and add a child element and return it.
-    UIElement* CreateChild(StringHash type, const String& name = String::EMPTY, unsigned index = M_MAX_UNSIGNED);
-    /// Add a child element.
-    void AddChild(UIElement* element);
-    /// Insert a child element into a specific position in the child list.
-    void InsertChild(unsigned index, UIElement* element);
-    /// Remove a child element. Starting search at specified index if provided.
-    void RemoveChild(UIElement* element, unsigned index = 0);
-    /// Remove a child element at index.
-    void RemoveChildAtIndex(unsigned index);
-    /// Remove all child elements.
-    void RemoveAllChildren();
-    /// Remove from the parent element. If no other shared pointer references exist, causes immediate deletion.
-    void Remove();
-    /// Find child index. Return M_MAX_UNSIGNED if not found.
-    unsigned FindChild(UIElement* element) const;
-    /// Set parent element. Same as parent->InsertChild(index, this).
-    void SetParent(UIElement* parent, unsigned index = M_MAX_UNSIGNED);
-    /// Set a user variable.
-    void SetVar(StringHash key, const Variant& value);
-    /// Mark as internally (programmatically) created. Used when an element composes itself out of child elements.
-    void SetInternal(bool enable);
-    /// Set traversal mode for rendering. The default traversal mode is TM_BREADTH_FIRST for non-root element. Root element should be set to TM_DEPTH_FIRST to avoid artifacts during rendering.
-    void SetTraversalMode(TraversalMode traversalMode);
-    /// Set element event sender flag. When child element is added or deleted, the event would be sent using UIElement found in the parental chain having this flag set. If not set, the event is sent using UI's root as per normal.
-    void SetElementEventSender(bool flag);
-
-    /// Template version of creating a child element.
-    template <class T> T* CreateChild(const String& name = String::EMPTY, unsigned index = M_MAX_UNSIGNED);
-
-    /// Return name.
-    const String& GetName() const { return name_; }
-    /// Return position.
-    const IntVector2& GetPosition() const { return position_; }
-    /// Return size.
-    const IntVector2& GetSize() const { return size_; }
-    /// Return width.
-    int GetWidth() const { return size_.x_; }
-    /// Return height.
-    int GetHeight() const { return size_.y_; }
-    /// Return minimum size.
-    const IntVector2& GetMinSize() const { return minSize_; }
-    /// Return minimum width.
-    int GetMinWidth() const { return minSize_.x_; }
-    /// Return minimum height.
-    int GetMinHeight() const { return minSize_.y_; }
-    /// Return maximum size.
-    const IntVector2& GetMaxSize() const { return maxSize_; }
-    /// Return minimum width.
-    int GetMaxWidth() const { return maxSize_.x_; }
-    /// Return minimum height.
-    int GetMaxHeight() const { return maxSize_.y_; }
-    /// Return true if size is fixed.
-    bool IsFixedSize() const { return minSize_ == maxSize_; }
-    /// Return true if width is fixed.
-    bool IsFixedWidth() const { return minSize_.x_ == maxSize_.x_; }
-    /// Return true if height is fixed.
-    bool IsFixedHeight() const { return minSize_.y_ == maxSize_.y_; }
-    /// Return child element offset.
-    const IntVector2& GetChildOffset() const { return childOffset_; }
-    /// Return horizontal alignment.
-    HorizontalAlignment GetHorizontalAlignment() const { return horizontalAlignment_; }
-    /// Return vertical alignment.
-    VerticalAlignment GetVerticalAlignment() const { return verticalAlignment_; }
-    /// Return child element clipping border.
-    const IntRect& GetClipBorder() const { return clipBorder_; }
-    /// Return corner color.
-    const Color& GetColor(Corner corner) const { return color_[corner]; }
-    /// Return priority.
-    int GetPriority() const { return priority_; }
-    /// Return opacity.
-    float GetOpacity() const { return opacity_; }
-    /// Return derived opacity (affected by parent elements.) If UseDerivedOpacity is false, returns same as element's own opacity.
-    float GetDerivedOpacity() const;
-    /// Return whether should be brought to front when focused.
-    bool GetBringToFront() const { return bringToFront_; }
-    /// Return whether should be put to background when another element is focused.
-    bool GetBringToBack() const { return bringToBack_; }
-    /// Return whether should clip child elements.
-    bool GetClipChildren() const { return clipChildren_; }
-    /// Return whether should sort child elements according to priority.
-    bool GetSortChildren() const { return sortChildren_; }
-    /// Return whether parent elements' opacity affects opacity.
-    bool GetUseDerivedOpacity() const { return useDerivedOpacity_; }
-    /// Return whether has focus.
-    bool HasFocus() const;
-    /// Return whether reacts to input.
-    bool IsEnabled() const { return enabled_; }
-    /// Returns the element's last own enabled state. May be different than the value returned by IsEnabled when SetDeepEnabled has been used.
-    bool IsEnabledSelf() const { return enabledPrev_; }
-    /// Return whether value is editable through input.
-    bool IsEditable() const { return editable_; }
-    /// Return whether is selected. Actual meaning is element dependent.
-    bool IsSelected() const { return selected_; }
-    /// Return whether is visible.
-    bool IsVisible() const { return visible_; }
-    /// Return whether the cursor is hovering on this element.
-    bool IsHovering() const { return hovering_; }
-    /// Return whether is internally created.
-    bool IsInternal() const { return internal_; }
-    /// Return whether has different color in at least one corner.
-    bool HasColorGradient() const { return colorGradient_; }
-    /// Return focus mode.
-    FocusMode GetFocusMode() const { return focusMode_; }
-    /// Return drag and drop flags.
-    unsigned GetDragDropMode() const { return dragDropMode_; }
-    /// Return applied style name. Return an empty string when the applied style is an 'auto' style (i.e. style derived from instance's type).
-    const String& GetAppliedStyle() const;
-    /// Return default style.
-    XMLFile* GetDefaultStyle(bool recursiveUp = true) const;
-    /// Return layout mode.
-    LayoutMode GetLayoutMode() const { return layoutMode_; }
-    /// Return layout spacing.
-    int GetLayoutSpacing() const { return layoutSpacing_; }
-    /// Return layout border.
-    const IntRect& GetLayoutBorder() const { return layoutBorder_; }
-    /// Return layout flex scale.
-    const Vector2& GetLayoutFlexScale() const { return layoutFlexScale_; }
-    /// Return number of child elements.
-    unsigned GetNumChildren(bool recursive = false) const;
-    /// Return child element by index.
-    UIElement* GetChild(unsigned index) const;
-    /// Return child element by name.
-    UIElement* GetChild(const String& name, bool recursive = false) const;
-    /// Return child element by variable. If only key is provided, return the first child having the matching variable key. If value is also provided then the actual variable value would also be checked against.
-    UIElement* GetChild(const StringHash& key, const Variant& value = Variant::EMPTY, bool recursive = false) const;
-    /// Return immediate child elements.
-    const Vector<SharedPtr<UIElement> >& GetChildren() const { return children_; }
-    /// Return child elements either recursively or non-recursively.
-    void GetChildren(PODVector<UIElement*>& dest, bool recursive = false) const;
-    /// Return parent element.
-    UIElement* GetParent() const { return parent_; }
-    /// Return root element.
-    UIElement* GetRoot() const;
-    /// Return derived color. Only valid when no gradient.
-    const Color& GetDerivedColor() const;
-    /// Return a user variable.
-    const Variant& GetVar(const StringHash& key) const;
-    /// Return all user variables.
-    const VariantMap& GetVars() const { return vars_; }
-    /// Return the drag button combo if this element is being dragged.
-    int GetDragButtonCombo() const { return dragButtonCombo_; }
-    /// Return the number of buttons dragging this element.
-    unsigned GetDragButtonCount() const { return dragButtonCount_; }
-
-    /// Convert screen coordinates to element coordinates.
-    IntVector2 ScreenToElement(const IntVector2& screenPosition);
-    /// Convert element coordinates to screen coordinates.
-    IntVector2 ElementToScreen(const IntVector2& position);
-    /// Return whether a point (either in element or screen coordinates) is inside the element.
-    bool IsInside(IntVector2 position, bool isScreen);
-    /// Return whether a point (either in element or screen coordinates) is inside the combined rect of the element and its children.
-    bool IsInsideCombined(IntVector2 position, bool isScreen);
-    /// Return combined screen coordinate rect of element and its children.
-    IntRect GetCombinedScreenRect();
-    /// Sort child elements if sorting enabled and order dirty. Called by UI.
-    void SortChildren();
-    /// Return minimum layout element size in the layout direction. Only valid after layout has been calculated. Used internally by UI for optimizations.
-    int GetLayoutMinSize() const { return layoutMinSize_; }
-    /// Return maximum layout element size in the layout direction. Only valid after layout has been calculated. Used internally by UI for optimizations.
-    int GetLayoutMaxSize() const { return layoutMaxSize_; }
-    /// Return horizontal indentation.
-    int GetIndent() const { return indent_; }
-    /// Return indent spacing (number of pixels per indentation level).
-    int GetIndentSpacing() const { return indentSpacing_; }
-    /// Return indent width in pixels.
-    int GetIndentWidth() const { return indent_ * indentSpacing_; }
-    /// Set child offset.
-    void SetChildOffset(const IntVector2& offset);
-    /// Set hovering state.
-    void SetHovering(bool enable);
-    /// Adjust scissor for rendering.
-    void AdjustScissor(IntRect& currentScissor);
-    /// Get UI rendering batches with a specified offset. Also recurses to child elements.
-    void GetBatchesWithOffset(IntVector2& offset, PODVector<UIBatch>& batches, PODVector<float>& vertexData, IntRect
-        currentScissor);
-    /// Return color attribute. Uses just the top-left color.
-    const Color& GetColorAttr() const { return color_[0]; }
-    /// Return traversal mode for rendering.
-    TraversalMode GetTraversalMode() const { return traversalMode_; }
-    /// Return whether element should send child added / removed events by itself. If false, defers to parent element.
-    bool IsElementEventSender() const { return elementEventSender_; }
-    /// Get element which should send child added / removed events.
-    UIElement* GetElementEventSender() const;
-
-protected:
-    /// Handle attribute animation added.
-    virtual void OnAttributeAnimationAdded();
-    /// Handle attribute animation removed.
-    virtual void OnAttributeAnimationRemoved();
-    /// Set object attribute animation internal.
-    virtual void SetObjectAttributeAnimation(const String& name, ValueAnimation* attributeAnimation, WrapMode wrapMode, float speed);
-    /// Mark screen position as needing an update.
-    void MarkDirty();
-    /// Remove child XML element by matching attribute name.
-    bool RemoveChildXML(XMLElement& parent, const String& name) const;
-    /// Remove child XML element by matching attribute name and value.
-    bool RemoveChildXML(XMLElement& parent, const String& name, const String& value) const;
-    /// Filter UI-style attributes in serialization process.
-    bool FilterUIStyleAttributes(XMLElement& dest, const XMLElement& styleElem) const;
-    /// Filter implicit attributes in serialization process.
-    virtual bool FilterImplicitAttributes(XMLElement& dest) const;
-
-    /// Name.
-    String name_;
-    /// Child elements.
-    Vector<SharedPtr<UIElement> > children_;
-    /// Parent element.
-    UIElement* parent_;
-    /// Child element clipping border.
-    IntRect clipBorder_;
-    /// Colors.
-    Color color_[MAX_UIELEMENT_CORNERS];
-    /// User variables.
-    VariantMap vars_;
-    /// Priority.
-    int priority_;
-    /// Bring to front when focused flag.
-    bool bringToFront_;
-    /// Bring to back when defocused flag.
-    bool bringToBack_;
-    /// Clip children flag.
-    bool clipChildren_;
-    /// Sort children according to priority flag.
-    bool sortChildren_;
-    /// Use derived opacity flag.
-    bool useDerivedOpacity_;
-    /// Input enabled flag.
-    bool enabled_;
-    /// Last SetEnabled flag before any SetDeepEnabled.
-    bool enabledPrev_;
-    /// Value editable flag.
-    bool editable_;
-    /// Selected flag.
-    bool selected_;
-    /// Visible flag.
-    bool visible_;
-    /// Hovering flag.
-    bool hovering_;
-    /// Internally created flag.
-    bool internal_;
-    /// Focus mode.
-    FocusMode focusMode_;
-    /// Drag and drop flags.
-    unsigned dragDropMode_;
-    /// Layout mode.
-    LayoutMode layoutMode_;
-    /// Layout spacing.
-    int layoutSpacing_;
-    /// Layout borders.
-    IntRect layoutBorder_;
-    /// Layout flex scale.
-    Vector2 layoutFlexScale_;
-    /// Resize nesting level to prevent multiple events and endless loop.
-    unsigned resizeNestingLevel_;
-    /// Layout update nesting level to prevent endless loop.
-    unsigned layoutNestingLevel_;
-    /// Layout element minimum size in layout direction.
-    int layoutMinSize_;
-    /// Layout element maximum size in layout direction.
-    int layoutMaxSize_;
-    /// Horizontal indentation.
-    int indent_;
-    /// Indent spacing (number of pixels per indentation level).
-    int indentSpacing_;
-    /// Position.
-    IntVector2 position_;
-    /// Screen position.
-    mutable IntVector2 screenPosition_;
-    /// Screen position dirty flag.
-    mutable bool positionDirty_;
-    /// Applied style.
-    String appliedStyle_;
-    /// Drag button combo.
-    int dragButtonCombo_;
-    /// Drag button count.
-    unsigned dragButtonCount_;
-
-private:
-    /// Return child elements recursively.
-    void GetChildrenRecursive(PODVector<UIElement*>& dest) const;
-    /// Calculate layout width for resizing the parent element.
-    int CalculateLayoutParentSize(const PODVector<int>& sizes, int begin, int end, int spacing);
-    /// Calculate child widths/positions in the layout.
-    void CalculateLayout(PODVector<int>& positions, PODVector<int>& sizes, const PODVector<int>& minSizes, const PODVector<int>& maxSizes, const PODVector<float>& flexScales, int targetWidth, int begin, int end, int spacing);
-    /// Get child element constant position in a layout.
-    IntVector2 GetLayoutChildPosition(UIElement* child);
-    /// Detach from parent.
-    void Detach();
-    /// Verify that child elements have proper alignment for layout mode.
-    void VerifyChildAlignment();
-    /// Handle logic post-update event.
-    void HandlePostUpdate(StringHash eventType, VariantMap& eventData);
-
-    /// Size.
-    IntVector2 size_;
-    /// Minimum size.
-    IntVector2 minSize_;
-    /// Maximum size.
-    IntVector2 maxSize_;
-    /// Child elements' offset. Used internally.
-    IntVector2 childOffset_;
-    /// Horizontal alignment.
-    HorizontalAlignment horizontalAlignment_;
-    /// Vertical alignment.
-    VerticalAlignment verticalAlignment_;
-    /// Opacity.
-    float opacity_;
-    /// Derived opacity.
-    mutable float derivedOpacity_;
-    /// Derived color. Only valid when no gradient.
-    mutable Color derivedColor_;
-    /// Derived opacity dirty flag.
-    mutable bool opacityDirty_;
-    /// Derived color dirty flag (only used when no gradient.)
-    mutable bool derivedColorDirty_;
-    /// Child priority sorting dirty flag.
-    bool sortOrderDirty_;
-    /// Has color gradient flag.
-    bool colorGradient_;
-    /// Default style file.
-    SharedPtr<XMLFile> defaultStyle_;
-    /// Traversal mode for rendering.
-    TraversalMode traversalMode_;
-    /// Flag whether node should send child added / removed events by itself.
-    bool elementEventSender_;
-    /// XPath query for selecting UI-style.
-    static XPathQuery styleXPathQuery_;
-};
-
-template <class T> T* UIElement::CreateChild(const String& name, unsigned index) { return static_cast<T*>(CreateChild(T::GetTypeStatic(), name, index)); }
-
-}

+ 1 - 0
Source/AtomicEditor/Source/AEApplication.cpp

@@ -10,6 +10,7 @@
 #include <Atomic/Core/Main.h>
 #include <Atomic/Core/Main.h>
 #include <Atomic/Core/ProcessUtils.h>
 #include <Atomic/Core/ProcessUtils.h>
 #include <Atomic/Graphics/Graphics.h>
 #include <Atomic/Graphics/Graphics.h>
+#include <Atomic/Resource/XMLFile.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceEvents.h>
 #include <Atomic/Resource/ResourceEvents.h>
 #include <Atomic/DebugNew.h>
 #include <Atomic/DebugNew.h>

+ 0 - 1
Source/AtomicEditor/Source/Editors/ModelResourceEditor.cpp

@@ -24,7 +24,6 @@
 #include "ModelResourceEditor.h"
 #include "ModelResourceEditor.h"
 
 
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
-#include <Atomic/UI/UI.h>
 
 
 namespace AtomicEditor
 namespace AtomicEditor
 {
 {

+ 0 - 1
Source/AtomicEditor/Source/Editors/SceneEditor3D/Gizmo3D.cpp

@@ -11,7 +11,6 @@
 #include <Atomic/Graphics/Octree.h>
 #include <Atomic/Graphics/Octree.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 
 
-#include <Atomic/UI/UI.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
 
 
 #include "Gizmo3D.h"
 #include "Gizmo3D.h"

+ 0 - 3
Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneEditor3D.cpp

@@ -21,10 +21,7 @@
 #include "AEEvents.h"
 #include "AEEvents.h"
 
 
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
-
-
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
-#include <Atomic/UI/UI.h>
 
 
 #include "SceneEditor3D.h"
 #include "SceneEditor3D.h"
 
 

+ 5 - 9
Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneView3D.cpp

@@ -28,8 +28,6 @@
 
 
 #include "SceneView3D.h"
 #include "SceneView3D.h"
 #include "SceneEditor3D.h"
 #include "SceneEditor3D.h"
-
-#include <Atomic/UI/UI.h>
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
 
 
 namespace AtomicEditor
 namespace AtomicEditor
@@ -121,8 +119,7 @@ void SceneView3D::Disable()
 
 
 void SceneView3D::MoveCamera(float timeStep)
 void SceneView3D::MoveCamera(float timeStep)
 {
 {
-    // Do not move if the UI has a focused element (the console)
-    if (GetSubsystem<UI>()->GetFocusElement() || !enabled_)
+    if (!enabled_)
         return;
         return;
 
 
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
@@ -178,9 +175,8 @@ Ray SceneView3D::GetCameraRay()
 {
 {
     Ray camRay;
     Ray camRay;
 
 
-    UI* ui = GetSubsystem<UI>();
-
-    IntVector2 cpos = ui->GetCursorPosition();
+    Input* input = GetSubsystem<Input>();
+    IntVector2 cpos = input->GetMousePosition();
 
 
     TBRect rect = GetWidgetDelegate()->GetRect();
     TBRect rect = GetWidgetDelegate()->GetRect();
 
 
@@ -216,8 +212,8 @@ void SceneView3D::DrawNodeDebug(Node* node, DebugRenderer* debug, bool drawNode)
 
 
 bool SceneView3D::MouseInView()
 bool SceneView3D::MouseInView()
 {
 {
-    UI* ui = GetSubsystem<UI>();
-    IntVector2 pos = ui->GetCursorPosition();
+    Input* input = GetSubsystem<Input>();
+    IntVector2 pos = input->GetMousePosition();
 
 
     TBRect rect = GetWidgetDelegate()->GetRect();
     TBRect rect = GetWidgetDelegate()->GetRect();
     GetWidgetDelegate()->ConvertToRoot(rect.x, rect.y);
     GetWidgetDelegate()->ConvertToRoot(rect.x, rect.y);

+ 0 - 3
Source/AtomicEditor/Source/Player/AEPlayer.cpp

@@ -9,8 +9,6 @@
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
-#include <Atomic/UI/UI.h>
-
 #include <AtomicJS/Javascript/Javascript.h>
 #include <AtomicJS/Javascript/Javascript.h>
 #include <AtomicJS/Javascript/JSVM.h>
 #include <AtomicJS/Javascript/JSVM.h>
 #include <AtomicJS/Javascript/JSEvents.h>
 #include <AtomicJS/Javascript/JSEvents.h>
@@ -94,7 +92,6 @@ void AEPlayer::Invalidate()
     UIModalOps* ops = GetSubsystem<UIModalOps>();
     UIModalOps* ops = GetSubsystem<UIModalOps>();
     ops->Hide();
     ops->Hide();
     context_->RemoveSubsystem<AEPlayer>();
     context_->RemoveSubsystem<AEPlayer>();
-    GetSubsystem<UI>()->GetRoot()->RemoveAllChildren();
 
 
 // BEGIN LICENSE MANAGEMENT
 // BEGIN LICENSE MANAGEMENT
     if (uiPlayer_.NotNull() && uiPlayer_->Show3DInfo())
     if (uiPlayer_.NotNull() && uiPlayer_->Show3DInfo())

+ 0 - 5
Source/AtomicEditor/Source/Player/UIPlayer.cpp

@@ -11,7 +11,6 @@
 #include <Atomic/Core/Context.h>
 #include <Atomic/Core/Context.h>
 #include <Atomic/Core/CoreEvents.h>
 #include <Atomic/Core/CoreEvents.h>
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/Log.h>
-#include <Atomic/UI/UI.h>
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
 
 
 #include <Atomic/Graphics/Graphics.h>
 #include <Atomic/Graphics/Graphics.h>
@@ -106,7 +105,6 @@ UIPlayer::~UIPlayer()
 void UIPlayer::HandleUpdate(StringHash eventType, VariantMap& eventData)
 void UIPlayer::HandleUpdate(StringHash eventType, VariantMap& eventData)
 {
 {
     view3D_->QueueUpdate();
     view3D_->QueueUpdate();
-    UI* ui = GetSubsystem<UI>();
 
 
     // BEGIN LICENSE MANAGEMENT
     // BEGIN LICENSE MANAGEMENT
     if (standardLicense_)
     if (standardLicense_)
@@ -122,9 +120,6 @@ void UIPlayer::HandleUpdate(StringHash eventType, VariantMap& eventData)
     TBWidgetDelegate* view3DDelegate = view3D_->GetWidgetDelegate();
     TBWidgetDelegate* view3DDelegate = view3D_->GetWidgetDelegate();
     TBRect rect = view3DDelegate->GetRect();
     TBRect rect = view3DDelegate->GetRect();
     view3DDelegate->ConvertToRoot(rect.x, rect.y);
     view3DDelegate->ConvertToRoot(rect.x, rect.y);
-
-    ui->GetRoot()->SetPosition(rect.x, rect.y);
-    ui->GetRoot()->SetSize(rect.w, rect.h);
 }
 }
 
 
 
 

+ 1 - 8
Source/AtomicJS/JSBind/modules/UI.json

@@ -2,14 +2,7 @@
 	"name" : "UI",
 	"name" : "UI",
 	"sources" : ["UI"],
 	"sources" : ["UI"],
 	"includes" : ["<Atomic/Graphics/Material.h>", "<Atomic/Scene/Node.h>", "<Atomic/Scene/Scene.h>", "<Atomic/Graphics/Texture2D.h>"],
 	"includes" : ["<Atomic/Graphics/Material.h>", "<Atomic/Scene/Node.h>", "<Atomic/Scene/Scene.h>", "<Atomic/Graphics/Texture2D.h>"],
-	"classes" : ["UI", "UIElement", "BorderImage", "Cursor"],
+	"classes" : [],
 	"overloads" : {
 	"overloads" : {
-		"UIElement" : {
-			"SetColor" : ["Color"],
-			"SetPosition" : ["IntVector2"],
-			"SetSize" : ["int", "int"],
-			"SetMinSize" : ["int", "int"]
-		}
-
 	}
 	}
 }
 }

+ 0 - 13
Source/AtomicJS/Javascript/JSAtomic.cpp

@@ -9,9 +9,6 @@
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Graphics/Renderer.h>
 #include <Atomic/Graphics/Renderer.h>
 #include <Atomic/Graphics/Graphics.h>
 #include <Atomic/Graphics/Graphics.h>
-
-#include <Atomic/UI/UI.h>
-
 #include <Atomic/Engine/Engine.h>
 #include <Atomic/Engine/Engine.h>
 
 
 #include "JSEvents.h"
 #include "JSEvents.h"
@@ -113,13 +110,6 @@ static int js_atomic_GetGraphics(duk_context* ctx)
     return 1;
     return 1;
 }
 }
 
 
-static int js_atomic_GetUI(duk_context* ctx)
-{
-    JSVM* vm = JSVM::GetJSVM(ctx);
-    js_push_class_object_instance(ctx, vm->GetSubsystem<UI>());
-    return 1;
-}
-
 static int js_atomic_GetInput(duk_context* ctx)
 static int js_atomic_GetInput(duk_context* ctx)
 {
 {
     JSVM* vm = JSVM::GetJSVM(ctx);
     JSVM* vm = JSVM::GetJSVM(ctx);
@@ -264,9 +254,6 @@ void jsapi_init_atomic(JSVM* vm)
     duk_push_c_function(ctx, js_atomic_GetInput, 0);
     duk_push_c_function(ctx, js_atomic_GetInput, 0);
     duk_put_prop_string(ctx, -2, "getInput");
     duk_put_prop_string(ctx, -2, "getInput");
 
 
-    duk_push_c_function(ctx, js_atomic_GetUI, 0);
-    duk_put_prop_string(ctx, -2, "getUI");
-
     duk_push_c_function(ctx, js_atomic_script, 1);
     duk_push_c_function(ctx, js_atomic_script, 1);
     duk_put_prop_string(ctx, -2, "script");
     duk_put_prop_string(ctx, -2, "script");
 
 

+ 0 - 3
Source/AtomicJS/Javascript/JSAtomicGame.cpp

@@ -8,9 +8,6 @@
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Graphics/Renderer.h>
 #include <Atomic/Graphics/Renderer.h>
 #include <Atomic/Graphics/Graphics.h>
 #include <Atomic/Graphics/Graphics.h>
-
-#include <Atomic/UI/UI.h>
-
 #include <Atomic/Engine/Engine.h>
 #include <Atomic/Engine/Engine.h>
 
 
 #include "JSEvents.h"
 #include "JSEvents.h"

+ 1 - 20
Source/AtomicJS/Javascript/JSComponent.cpp

@@ -20,7 +20,6 @@
 #include <Atomic/Atomic2D/PhysicsWorld2D.h>
 #include <Atomic/Atomic2D/PhysicsWorld2D.h>
 #include <Atomic/Atomic2D/RigidBody2D.h>
 #include <Atomic/Atomic2D/RigidBody2D.h>
 #include <Atomic/UI/UIEvents.h>
 #include <Atomic/UI/UIEvents.h>
-#include <Atomic/UI/UIElement.h>
 
 
 #include "Javascript.h"
 #include "Javascript.h"
 #include "JSEvents.h"
 #include "JSEvents.h"
@@ -419,25 +418,7 @@ void JSComponent::HandleScriptEvent(StringHash eventType, VariantMap& eventData)
         duk_context* ctx = vm_->GetJSContext();
         duk_context* ctx = vm_->GetJSContext();
         JS_HEAP_PTR function = scriptEventFunctions_[eventType];
         JS_HEAP_PTR function = scriptEventFunctions_[eventType];
 
 
-        if (eventType == E_UIMOUSECLICK)
-        {
-            UIElement* clicked = static_cast<UIElement*>(eventData[UIMouseClick::P_ELEMENT].GetPtr());
-            if (clicked)
-            {
-                duk_push_heapptr(ctx, function);
-                js_push_class_object_instance(ctx, clicked);
-
-                if (duk_pcall(ctx, 1) != 0)
-                {
-                    vm_->SendJSErrorEvent();
-                }
-
-                duk_pop(ctx);
-
-            }
-
-        }
-        else if (eventType == E_PHYSICSBEGINCONTACT2D || E_PHYSICSENDCONTACT2D)
+        if (eventType == E_PHYSICSBEGINCONTACT2D || E_PHYSICSENDCONTACT2D)
         {
         {
             using namespace PhysicsBeginContact2D;
             using namespace PhysicsBeginContact2D;
             PhysicsWorld2D* world = static_cast<PhysicsWorld2D*>(eventData[P_WORLD].GetPtr());
             PhysicsWorld2D* world = static_cast<PhysicsWorld2D*>(eventData[P_WORLD].GetPtr());