Mon, 17 May 2021 23:52:19 +0300
#188 Widgets now set their own cursors:
- MarkdownLabel
- Window
- Inputbox
--- 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 ®ions = 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++) {