Browse Source

Auto-resize the UI root when scale is changed. Fix Console to support scaled UI. Add UI scale Lua bindings. Tweak UI scale AngelScript bindings. Fix UI render scissor region to work properly with scaled UI. Added brief documentation on UI scaling.

Lasse Öörni 10 years ago
parent
commit
a4e22db6e5

+ 6 - 0
Docs/Reference.dox

@@ -2063,6 +2063,12 @@ Angelcode:
 	ui.SetCursor(cursor);
 \endcode
 
+\section UI_Scaling Scaling
+
+By default the %UI is pixel perfect: the root element is sized equal to the application window size.
+
+The pixel scaling can be changed with the functions \ref UI::SetScale "SetScale()", \ref UI::SetWidth "SetWidth()" and \ref UI::SetHeight "SetHeight()".
+
 \page Urho2D Urho2D
 In order to make 2D games in Urho3D, the Urho2D sublibrary is provided. Urho2D includes 2D graphics and 2D physics.
 

+ 4 - 3
Source/Urho3D/AngelScript/UIAPI.cpp

@@ -700,6 +700,8 @@ static void RegisterUI(asIScriptEngine* engine)
     engine->RegisterObjectMethod("UI", "bool SaveLayout(File@+, UIElement@+)", asFUNCTION(UISaveLayout), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("UI", "bool SaveLayout(VectorBuffer&, UIElement@+)", asFUNCTION(UISaveLayoutVectorBuffer), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("UI", "void SetFocusElement(UIElement@+, bool byKey = false)", asMETHOD(UI, SetFocusElement), asCALL_THISCALL);
+    engine->RegisterObjectMethod("UI", "void SetWidth(float value)", asMETHOD(UI, SetWidth), asCALL_THISCALL);
+    engine->RegisterObjectMethod("UI", "void SetHeight(float value)", asMETHOD(UI, SetHeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "UIElement@+ GetElementAt(const IntVector2&in, bool activeOnly = true)", asMETHODPR(UI, GetElementAt, (const IntVector2&, bool), UIElement*), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "UIElement@+ GetElementAt(int, int, bool activeOnly = true)", asMETHODPR(UI, GetElementAt, (int, int, bool), UIElement*), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "bool HasModalElement() const", asMETHOD(UI, HasModalElement), asCALL_THISCALL);
@@ -735,9 +737,8 @@ static void RegisterUI(asIScriptEngine* engine)
     engine->RegisterObjectMethod("UI", "bool get_useMutableGlyphs() const", asMETHOD(UI, GetUseMutableGlyphs), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "void set_forceAutoHint(bool)", asMETHOD(UI, SetForceAutoHint), asCALL_THISCALL);
     engine->RegisterObjectMethod("UI", "bool get_forceAutoHint() const", asMETHOD(UI, GetForceAutoHint), asCALL_THISCALL);
-    engine->RegisterObjectMethod("UI", "void SetWidth(float value)", asMETHOD(UI, SetWidth), asCALL_THISCALL);
-    engine->RegisterObjectMethod("UI", "void SetHeight(float value)", asMETHOD(UI, SetHeight), asCALL_THISCALL);
-    engine->RegisterObjectMethod("UI", "void SetScale(float value)", asMETHOD(UI, SetScale), asCALL_THISCALL);
+    engine->RegisterObjectMethod("UI", "void set_scale(float value)", asMETHOD(UI, SetScale), asCALL_THISCALL);
+    engine->RegisterObjectMethod("UI", "float get_scale() const", asMETHOD(UI, GetScale), asCALL_THISCALL);
     engine->RegisterGlobalFunction("UI@+ get_ui()", asFUNCTION(GetUI), asCALL_CDECL);
 }
 

+ 3 - 4
Source/Urho3D/Engine/Console.cpp

@@ -27,7 +27,6 @@
 #include "../Engine/Console.h"
 #include "../Engine/EngineEvents.h"
 #include "../Graphics/Graphics.h"
-#include "../Graphics/GraphicsEvents.h"
 #include "../Input/Input.h"
 #include "../IO/IOEvents.h"
 #include "../IO/Log.h"
@@ -93,7 +92,7 @@ Console::Console(Context* context) :
     SubscribeToEvent(lineEdit_, E_TEXTFINISHED, URHO3D_HANDLER(Console, HandleTextFinished));
     SubscribeToEvent(lineEdit_, E_UNHANDLEDKEY, URHO3D_HANDLER(Console, HandleLineEditKey));
     SubscribeToEvent(closeButton_, E_RELEASED, URHO3D_HANDLER(Console, HandleCloseButtonPressed));
-    SubscribeToEvent(E_SCREENMODE, URHO3D_HANDLER(Console, HandleScreenMode));
+    SubscribeToEvent(uiRoot, E_RESIZED, URHO3D_HANDLER(Console, HandleRootElementResized));
     SubscribeToEvent(E_LOGMESSAGE, URHO3D_HANDLER(Console, HandleLogMessage));
     SubscribeToEvent(E_POSTUPDATE, URHO3D_HANDLER(Console, HandlePostUpdate));
 }
@@ -223,7 +222,7 @@ void Console::SetFocusOnShow(bool enable)
 
 void Console::UpdateElements()
 {
-    int width = GetSubsystem<Graphics>()->GetWidth();
+    int width = GetSubsystem<UI>()->GetRoot()->GetWidth();
     const IntRect& border = background_->GetLayoutBorder();
     const IntRect& panelBorder = rowContainer_->GetScrollPanel()->GetClipBorder();
     rowContainer_->SetFixedWidth(width - border.left_ - border.right_);
@@ -378,7 +377,7 @@ void Console::HandleCloseButtonPressed(StringHash eventType, VariantMap& eventDa
     SetVisible(false);
 }
 
-void Console::HandleScreenMode(StringHash eventType, VariantMap& eventData)
+void Console::HandleRootElementResized(StringHash eventType, VariantMap& eventData)
 {
     UpdateElements();
 }

+ 2 - 2
Source/Urho3D/Engine/Console.h

@@ -126,8 +126,8 @@ private:
     void HandleLineEditKey(StringHash eventType, VariantMap& eventData);
     /// Handle close button being pressed.
     void HandleCloseButtonPressed(StringHash eventType, VariantMap& eventData);
-    /// Handle rendering window resize.
-    void HandleScreenMode(StringHash eventType, VariantMap& eventData);
+    /// Handle UI root resize.
+    void HandleRootElementResized(StringHash eventType, VariantMap& eventData);
     /// Handle a log message.
     void HandleLogMessage(StringHash eventType, VariantMap& eventData);
     /// Handle the application post-update.

+ 5 - 0
Source/Urho3D/LuaScript/pkgs/UI/UI.pkg

@@ -23,6 +23,9 @@ class UI : public Object
     void SetUseScreenKeyboard(bool enable);
     void SetUseMutableGlyphs(bool enable);
     void SetForceAutoHint(bool enable);
+    void SetScale(float scale);
+    void SetWidth(float size);
+    void SetHeight(float size);
 
     UIElement* GetRoot() const;
     UIElement* GetRootModalElement() const;
@@ -47,6 +50,7 @@ class UI : public Object
     bool GetForceAutoHint() const;
     bool HasModalElement() const;
     bool IsDragging() const;
+    float GetScale() const;
 
     tolua_readonly tolua_property__get_set UIElement* root;
     tolua_readonly tolua_property__get_set UIElement* rootModalElement;
@@ -67,6 +71,7 @@ class UI : public Object
     tolua_property__get_set bool useMutableGlyphs;
     tolua_property__get_set bool forceAutoHint;
     tolua_readonly tolua_property__has_set bool modalElement;
+    tolua_property__get_set float scale;
 };
 
 UI* GetUI();

+ 23 - 14
Source/Urho3D/UI/UI.cpp

@@ -408,7 +408,8 @@ void UI::RenderUpdate()
     batches_.Clear();
     vertexData_.Clear();
     const IntVector2& rootSize = rootElement_->GetSize();
-    IntRect currentScissor = IntRect(0, 0, (int)(rootSize.x_ / uiScale_), (int)(rootSize.y_ / uiScale_));
+    // Note: the scissors operate on unscaled coordinates. Scissor scaling is only performed during render
+    IntRect currentScissor = IntRect(0, 0, rootSize.x_, rootSize.y_);
     if (rootElement_->IsVisible())
         GetBatches(rootElement_, currentScissor);
 
@@ -702,8 +703,8 @@ void UI::Initialize()
     graphics_ = graphics;
     UIBatch::posAdjust = Vector3(Graphics::GetPixelUVOffset(), 0.0f);
 
-    rootElement_->SetSize(graphics->GetWidth(), graphics->GetHeight());
-    rootModalElement_->SetSize(rootElement_->GetSize());
+    // Apply initial UI scale to set the root elements size
+    SetScale(uiScale_);
 
     vertexBuffer_ = new VertexBuffer(context_);
     debugVertexBuffer_ = new VertexBuffer(context_);
@@ -1380,8 +1381,8 @@ void UI::HandleScreenMode(StringHash eventType, VariantMap& eventData)
         Initialize();
     else
     {
-        rootElement_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
-        rootModalElement_->SetSize(rootElement_->GetSize());
+        // Reapply UI scale to resize the root elements
+        SetScale(uiScale_);
     }
 }
 
@@ -1793,22 +1794,30 @@ IntVector2 UI::SumTouchPositions(UI::DragData* dragData, const IntVector2& oldSe
     return sendPos;
 }
 
-void UI::SetWidth(float size)
+void UI::SetScale(float scale)
 {
-    Graphics* g = GetSubsystem<Graphics>();
-    if (g)
+    uiScale_ = Max(scale, M_EPSILON);
+    Graphics* graphics = GetSubsystem<Graphics>();
+    if (graphics)
     {
-        uiScale_ = g->GetWidth() / size;
+        rootElement_->SetSize((int)((float)graphics->GetWidth() / uiScale_ + 0.5f), (int)((float)graphics_->GetHeight() /
+            uiScale_ + 0.5));
+        rootModalElement_->SetSize(rootElement_->GetSize());
     }
 }
 
+void UI::SetWidth(float size)
+{
+    Graphics* graphics = GetSubsystem<Graphics>();
+    if (graphics)
+        SetScale((float)graphics->GetWidth() / size);
+}
+
 void UI::SetHeight(float size)
 {
-    Graphics* g = GetSubsystem<Graphics>();
-    if (g)
-    {
-        uiScale_ = g->GetHeight() / size;
-    }
+    Graphics* graphics = GetSubsystem<Graphics>();
+    if (graphics)
+        SetScale((float)graphics->GetHeight() / size);
 }
 
 void RegisterUILibrary(Context* context)

+ 6 - 9
Source/Urho3D/UI/UI.h

@@ -95,6 +95,12 @@ public:
     void SetUseMutableGlyphs(bool enable);
     /// Set whether to force font autohinting instead of using FreeType's TTF bytecode interpreter.
     void SetForceAutoHint(bool enable);
+    /// Set %UI scale. 1.0 is default (pixel perfect). Resize the root element to match.
+    void SetScale(float scale);
+    /// Scale %UI to the specified width in pixels.
+    void SetWidth(float size);
+    /// Scale %UI to the specified height in pixels.
+    void SetHeight(float size);
 
     /// Return root UI element.
     UIElement* GetRoot() const { return rootElement_; }
@@ -184,15 +190,6 @@ public:
     /// Return current UI scale.
     float GetScale() const { return uiScale_; }
 
-    /// Set current UI scale.
-    void SetScale(float scale) { uiScale_ = scale; }
-
-    /// Set UI width.
-    void SetWidth(float size);
-
-    /// Set UI height.
-    void SetHeight(float size);
-
 private:
     /// Initialize when screen mode initially set.
     void Initialize();