#188 Widgets now set their own cursors: 4.x-dev

Mon, 17 May 2021 23:52:19 +0300

author
cemkalyoncu
date
Mon, 17 May 2021 23:52:19 +0300
branch
4.x-dev
changeset 1680
7bf7ffcbda96
parent 1679
ba8492d69168
child 1681
8ab453216da3

#188 Widgets now set their own cursors:
- MarkdownLabel
- Window
- Inputbox

Source/Gorgon/CGI/Polygon.h file | annotate | diff | comparison | revisions
Source/Gorgon/Graphics/Pointer.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Graphics/Pointer.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Inputbox.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Inputbox.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Label.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Label.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Window.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Window.h file | annotate | diff | comparison | revisions
Source/Gorgon/Window.cpp file | annotate | diff | comparison | revisions
Testing/Source/Manual/Window.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/CGI/Polygon.h	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/CGI/Polygon.h	Mon May 17 23:52:19 2021 +0300
@@ -264,8 +264,8 @@
                     int s = (int)ceil(d.From);
                     int e = (int)floor(d.To);
                     
-                    FitInto(s, xmin*S_, xmax*S_+S_-1);
-                    FitInto(e, xmin*S_, xmax*S_+S_-1);
+                    FitInto(s, xmin*S_, xmax*S_+S_);
+                    FitInto(e, xmin*S_, xmax*S_+S_);
                     
                     for(int x=s; x<e; x++) {
                         cnts[x/S_-xmin]++;
--- a/Source/Gorgon/Graphics/Pointer.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Graphics/Pointer.cpp	Mon May 17 23:52:19 2021 +0300
@@ -28,10 +28,8 @@
 
     PointerStack::Token PointerStack::Set(PointerType type) {
         ASSERT((int)type>(int)PointerType::None && (int)type<(int)PointerType::Max, "Invalid pointer type");
-       
-        if(!pointers[(int)type].ptr) return Token();
         
-        stack.Add(lastind, pointers[(int)type].ptr);
+        stack.insert({lastind, {type, pointers[(int)type].ptr}});
         
         PointerChanged();
         
@@ -39,7 +37,7 @@
     }
     
     PointerStack::Token PointerStack::Set(const Pointer &pointer) {
-        stack.Add(lastind, pointer);
+        stack.insert({lastind, {pointer.GetType(), &pointer}});
         
         PointerChanged();
         
@@ -49,15 +47,15 @@
     void PointerStack::Reset(Token &token) {
         if(token.parent != this) return;
         
-        long curid = -1;
+        Graphics::PointerType curid = PointerType::None;
         
-        if(stack.GetSize() > 0) {
-            curid = stack.Last().Current().first;
+        if(!stack.empty()) {
+            curid = stack.rbegin()->second.first;
         }
         
-        stack.Remove(token.ind);
+        stack.erase(token.ind);
         
-        if(stack.GetSize() == 0 || stack.Last().Current().first != curid) {
+        if(stack.empty() || stack.rbegin()->second.first != curid) {
             PointerChanged();
         }
         
@@ -66,8 +64,8 @@
     }
     
     const Pointer &PointerStack::Current() const {
-        if(stack.GetSize() > 0) {
-            return stack.Last().Current().second;
+        if(!stack.empty()) {
+            return *stack.rbegin()->second.second;
         }
         else {
             for(int i=(int)PointerType::Arrow; i<(int)PointerType::Max; i++) {
@@ -80,7 +78,7 @@
     }
     
     bool PointerStack::IsValid() const {
-        if(stack.GetSize() > 0) {
+        if(!stack.empty()) {
             return true;
         }
         else {
@@ -94,8 +92,8 @@
     }
     
     PointerType PointerStack::GetCurrentType() const {
-        if(IsValid()) {
-            return Current().GetType();
+        if(!stack.empty()) {
+            return stack.rbegin()->second.first;
         }
         else {
             return PointerType::None;
--- a/Source/Gorgon/Graphics/Pointer.h	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Graphics/Pointer.h	Mon May 17 23:52:19 2021 +0300
@@ -545,7 +545,7 @@
         
         int lastind = 0;
         
-        Containers::Hashmap<int, const Pointer> stack;
+        std::map<int, std::pair<PointerType, const Pointer*>> stack;
         
         std::array<Wrapper, (int)PointerType::Max> pointers = {};
     };
--- a/Source/Gorgon/Widgets/Inputbox.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Inputbox.cpp	Mon May 17 23:52:19 2021 +0300
@@ -3,6 +3,7 @@
 #include "../Graphics/Font.h"
 #include "../WindowManager.h"
 #include "../UI.h"
+#include "../Window.h"
 
 namespace Gorgon { namespace Widgets { namespace internal {
     
@@ -21,6 +22,15 @@
             mousedown(tag, location, button); 
         });
         
+        stack.SetMouseOverEvent([this](auto) { 
+            Gorgon::Window *toplevel = dynamic_cast<Gorgon::Window*>(&stack.GetTopLevel());
+            if(!toplevel)
+                return;
+            
+            pointertoken = toplevel->Pointers.Set(Graphics::PointerType::Text); 
+        });
+        stack.SetMouseOutEvent([this](auto) { pointertoken.Revert(); });
+        
         repeater.Register(Input::Keyboard::Keycodes::Left);
         repeater.Register(Input::Keyboard::Keycodes::Right);
         repeater.Register(Input::Keyboard::Keycodes::Backspace);
--- a/Source/Gorgon/Widgets/Inputbox.h	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Inputbox.h	Mon May 17 23:52:19 2021 +0300
@@ -10,6 +10,7 @@
 #include "../UI/Helpers.h"
 #include "../Input/KeyRepeater.h"
 #include "Registry.h"
+#include "../Graphics/Pointer.h"
 
 namespace Gorgon { namespace Widgets {
     
@@ -272,6 +273,7 @@
         
             Input::KeyRepeater repeater;
             
+            Graphics::PointerStack::Token pointertoken;
         };
     }
     /// @endcond
--- a/Source/Gorgon/Widgets/Label.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Label.cpp	Mon May 17 23:52:19 2021 +0300
@@ -2,6 +2,7 @@
 #include "../UI/WidgetContainer.h"
 #include "../Graphics/Bitmap.h"
 #include "../UI.h"
+#include "../Window.h"
 
 namespace Gorgon { namespace Widgets {
     
@@ -126,6 +127,27 @@
                 }
             }
         });
+        
+        stack.SetMouseMoveEvent([this](auto, auto point) {
+            Gorgon::Window *toplevel = dynamic_cast<Gorgon::Window*>(&stack.GetTopLevel());
+            if(!toplevel)
+                return;
+            
+            auto &regions = stack.GetRegions();
+            
+            for(auto &r : regions) {
+                if(IsInside(r.Bounds, point)) {
+                    pointertoken = toplevel->Pointers.Set(Graphics::PointerType::Link);
+                    
+                    return;
+                }
+            }
+            
+            if(!pointertoken.IsNull())
+                pointertoken.Revert();
+        });
+        
+        stack.SetMouseOutEvent([this](auto) { pointertoken.Revert(); });
     }
 
 
--- a/Source/Gorgon/Widgets/Label.h	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Label.h	Mon May 17 23:52:19 2021 +0300
@@ -4,6 +4,7 @@
 #include "../Property.h"
 #include "Registry.h"
 #include "../String/Markdown.h"
+#include "../Graphics/Pointer.h"
 
 namespace Gorgon { namespace Graphics { class Bitmap; } }
 
@@ -169,6 +170,7 @@
         std::string original;
         std::vector<String::MarkdownLink> links;
         std::function<bool (std::string)> inpagehandler;
+        Graphics::PointerStack::Token pointertoken;
     };
     
 } }
--- a/Source/Gorgon/Widgets/Window.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Window.cpp	Mon May 17 23:52:19 2021 +0300
@@ -18,6 +18,7 @@
         stack.SetMouseUpEvent([this](auto tag, auto location, auto button) { mouse_up(tag, location, button); });
         stack.SetMouseMoveEvent([this](auto tag, auto location) { mouse_move(tag, location); });
         stack.SetClickEvent([this](auto tag, auto location, auto button) { mouse_click(tag, location, button); });
+        stack.SetMouseOutEvent([this](auto) { pointertoken.Revert(); });
         
         updatescrollvisibility();
         if(autoplace) {
@@ -233,15 +234,128 @@
         }
     }
     
-    void Window::mouse_move(UI::ComponentTemplate::Tag, Geometry::Point location) {
+    void Window::mouse_move(UI::ComponentTemplate::Tag tag, Geometry::Point location) {
+        if(tag == UI::ComponentTemplate::NoTag) {
+            if(stack.IndexOfTag(UI::ComponentTemplate::DragTag) == -1)
+                tag = UI::ComponentTemplate::DragTag;
+            else {
+                int ind = stack.ComponentAt(location);
+                
+                if(ind != -1)
+                    tag = stack.GetTemplate(ind).GetTag();
+            }
+        }
+        
         auto parent = dynamic_cast<Gorgon::Window*>(&stack.GetTopLevel());
+        auto ptrtype = Graphics::PointerType::None;
+        
+        if(moving) {
+            ptrtype = Graphics::PointerType::Drag;
+        }
+        else if(resizing != none) {
+            switch(resizing) {
+            case top:
+                ptrtype = Graphics::PointerType::ScaleTop;
+                break;
+            case left:
+                ptrtype = Graphics::PointerType::ScaleLeft;
+                break;
+            case right:
+                ptrtype = Graphics::PointerType::ScaleRight;
+                break;
+            case bottom:
+                ptrtype = Graphics::PointerType::ScaleBottom;
+                break;
+            case topleft:
+                ptrtype = Graphics::PointerType::ScaleTopLeft;
+                break;
+            case bottomleft:
+                ptrtype = Graphics::PointerType::ScaleBottomLeft;
+                break;
+            case topright:
+                ptrtype = Graphics::PointerType::ScaleTopRight;
+                break;
+            case bottomright:
+                ptrtype = Graphics::PointerType::ScaleBottomRight;
+                break;
+            default:
+                ;
+            }
+        }
+        else if(allowresize && tag == UI::ComponentTemplate::ResizeTag) {
+            auto size = GetSize();
+            int maxdist = stack.GetTemplate().GetResizeHandleSize();
+            
+            int leftdist = location.X, rightdist  = size.Width  - location.X;
+            int topdist  = location.Y, bottomdist = size.Height - location.Y;
+            
+            resizedir r = none;
+            
+            if(leftdist < rightdist) {
+                if(leftdist <= maxdist) {
+                    r = resizedir(r | left);
+                }
+            }
+            else {
+                if(rightdist <= maxdist) {
+                    r = resizedir(r | right);
+                }
+            }
+            
+            if(topdist < bottomdist) {
+                if(topdist <= maxdist) {
+                    r = resizedir(r | top);
+                }
+            }
+            else {
+                if(bottomdist <= maxdist) {
+                    r = resizedir(r | bottom);
+                }
+            }
+            
+            switch(r) {
+            case top:
+                ptrtype = Graphics::PointerType::ScaleTop;
+                break;
+            case left:
+                ptrtype = Graphics::PointerType::ScaleLeft;
+                break;
+            case right:
+                ptrtype = Graphics::PointerType::ScaleRight;
+                break;
+            case bottom:
+                ptrtype = Graphics::PointerType::ScaleBottom;
+                break;
+            case topleft:
+                ptrtype = Graphics::PointerType::ScaleTopLeft;
+                break;
+            case bottomleft:
+                ptrtype = Graphics::PointerType::ScaleBottomLeft;
+                break;
+            case topright:
+                ptrtype = Graphics::PointerType::ScaleTopRight;
+                break;
+            case bottomright:
+                ptrtype = Graphics::PointerType::ScaleBottomRight;
+                break;
+            default:
+                ;
+            }
+        }
+        
+        if(ptrtype == Graphics::PointerType::None) {
+            pointertoken.Revert();
+        }
+        else {
+            pointertoken = parent->Pointers.Set(ptrtype);
+        }
+        
         if(parent)
             location = parent->GetMouseLocation();
         
         if(location == dragoffset) 
             return;
         
-        
         if(moving) {
             auto newlocation = GetLocation() + location-dragoffset;
             if(HasParent()) {
--- a/Source/Gorgon/Widgets/Window.h	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Widgets/Window.h	Mon May 17 23:52:19 2021 +0300
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "Panel.h"
+#include "../Graphics/Pointer.h"
 
 namespace Gorgon { namespace Graphics { class Bitmap; } }
 
@@ -264,6 +265,7 @@
         resizedir resizing = none;
         bool allowresize = false;
         Geometry::Size minsize;
+        Graphics::PointerStack::Token pointertoken;
     };
     
 } }
--- a/Source/Gorgon/Window.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Source/Gorgon/Window.cpp	Mon May 17 23:52:19 2021 +0300
@@ -56,6 +56,11 @@
         swap(glsize, other.glsize);
 
         Pointers.Swap(other.Pointers);
+        Pointers.PointerChanged.Clear();
+        other.Pointers.PointerChanged.Clear();
+        
+        Pointers.PointerChanged.Register(*this, &Window::UpdatePointer);
+        other.Pointers.PointerChanged.Register(other, &Window::UpdatePointer);
 
         if(data) {
             windows.Add(this);
--- a/Testing/Source/Manual/Window.cpp	Mon May 17 20:56:17 2021 +0300
+++ b/Testing/Source/Manual/Window.cpp	Mon May 17 23:52:19 2021 +0300
@@ -136,7 +136,6 @@
     wind.Pointers.Add(Graphics::PointerType::Text, pointer3);
     
 
-	
 	//img = Graphics::Bitmap({200, 200}, Graphics::ColorMode::Alpha);
 	//for(int x = 0; x<200; x++)
 	//	for(int y = 0; y<200; y++) {

mercurial