Mon, 17 May 2021 20:56:17 +0300
#319 OS cursor support
--- a/Source/Gorgon/Graphics/Pointer.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/Graphics/Pointer.cpp Mon May 17 20:56:17 2021 +0300 @@ -20,32 +20,47 @@ void PointerStack::Add(PointerType type, const Drawable &image, Geometry::Point hotspot) { auto ptr = new DrawablePointer(image, hotspot); + ptr->SetType(type); Add(type, *ptr); pointers[(int)type].owned = true; } PointerStack::Token PointerStack::Set(PointerType type) { - ASSERT((int)type>(int)PointerType::None && (int)type<=(int)PointerType::Drag, "Invalid pointer 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); + PointerChanged(); + return Token(this, lastind++); } PointerStack::Token PointerStack::Set(const Pointer &pointer) { stack.Add(lastind, pointer); + PointerChanged(); + return Token(this, lastind++); } void PointerStack::Reset(Token &token) { if(token.parent != this) return; + long curid = -1; + + if(stack.GetSize() > 0) { + curid = stack.Last().Current().first; + } + stack.Remove(token.ind); + if(stack.GetSize() == 0 || stack.Last().Current().first != curid) { + PointerChanged(); + } + token.parent = nullptr; token.ind = 0; } @@ -55,7 +70,7 @@ return stack.Last().Current().second; } else { - for(int i=(int)PointerType::Arrow; i<=(int)PointerType::Drag; i++) { + for(int i=(int)PointerType::Arrow; i<(int)PointerType::Max; i++) { if(pointers[i].ptr) return *pointers[i].ptr; } @@ -69,7 +84,7 @@ return true; } else { - for(int i=(int)PointerType::Arrow; i<=(int)PointerType::Drag; i++) { + for(int i=(int)PointerType::Arrow; i<(int)PointerType::Max; i++) { if(pointers[i].ptr) return true; } @@ -78,4 +93,13 @@ return false; } + PointerType PointerStack::GetCurrentType() const { + if(IsValid()) { + return Current().GetType(); + } + else { + return PointerType::None; + } + } + } }
--- a/Source/Gorgon/Graphics/Pointer.h Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/Graphics/Pointer.h Mon May 17 20:56:17 2021 +0300 @@ -10,249 +10,349 @@ namespace Gorgon { namespace Graphics { + ///Pointer types + enum class PointerType { + ///No pointer is selected or using default. Do not use this value + None, + + ///Arrow / Pointer + Arrow, + + ///Wait / Hourglass + Wait, + + ///Processing, pointer and wait combined + Processing, + + ///No / Not allowed + No, + + ///Text / Beam pointer + Text, + + ///A pointer for links + Link, + + ///Cursor icon that offers to move an item + Move, + + ///Drag / Closed hand pointer + Drag, + + ///Scaling from left side + ScaleLeft, + + ///Scaling from the right side + ScaleRight, + + ///Scaling from top side + ScaleTop, + + ///Scaling from bottom side + ScaleBottom, + + ///Scaling from top left corner + ScaleTopLeft, + + ///Scaling from top right corner + ScaleTopRight, + + ///Scaling from bottom left corner + ScaleBottomLeft, + + ///Scaling from bottom right corner + ScaleBottomRight, + + ///Cross hair to select a point + Cross, + + /// A cursor denotes a help text + Help, + + ///Straight upward pointing arrow, can be used for alternative objects + Straight, + + ///Do not use this value + Max + }; + /** - * Represents a pointer. When drawn, pointer should move the image so that the hotspot - * will be on the given point. If desired, ownership of the image can be transferred - * to the pointer. - */ - class Pointer : virtual public Drawable { - public: + * Represents a pointer. When drawn, pointer should move the image so that the hotspot + * will be on the given point. If desired, ownership of the image can be transferred + * to the pointer. + */ + class Pointer : virtual public Drawable { + public: - virtual ~Pointer() { - } + virtual ~Pointer() { + } + + /// Returns the type of the pointer + PointerType GetType() const { + return type; + } + + /// Sets the type of the pointer. Pointer type can be used to determine the type while + /// adding to the stack. If operating system pointers are used, this value is used determine + /// which pointer to show. + void SetType(PointerType value) { + type = value; + } protected: - }; + PointerType type = PointerType::Arrow; + }; + + /// This class turns a drawable into a pointer + class DrawablePointer : public Pointer { + public: + DrawablePointer() = default; - /// This class turns a drawable into a pointer - class DrawablePointer : public Pointer { - public: - DrawablePointer() = default; - - /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function - /// after invoking default constructor to transfer ownership. - DrawablePointer(const Drawable &image, int x, int y) : DrawablePointer(image, {x, y}) {} + /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function + /// after invoking default constructor to transfer ownership. + DrawablePointer(const Drawable &image, int x, int y, PointerType type = PointerType::Arrow) : + DrawablePointer(image, {x, y}) + { + SetType(type); + } - /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function - /// after invoking default constructor to transfer ownership. - DrawablePointer(const Drawable &image, Geometry::Point hotspot) : - image(&image), hotspot(hotspot) {} + /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function + /// after invoking default constructor to transfer ownership. + DrawablePointer(const Drawable &image, Geometry::Point hotspot, PointerType type = PointerType::Arrow) : + image(&image), hotspot(hotspot) + { + SetType(type); + } - /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function - /// after invoking default constructor to transfer ownership. - DrawablePointer(const AssumeOwnershipTag &tag, const Drawable &image, int x, int y) : DrawablePointer(tag, image, {x, y}) {} - - /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function - /// after invoking default constructor to transfer ownership. - DrawablePointer(const AssumeOwnershipTag &, const Drawable &image, Geometry::Point hotspot) : - image(&image), hotspot(hotspot) { owner = true; } + /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function + /// after invoking default constructor to transfer ownership. + DrawablePointer(const AssumeOwnershipTag &tag, const Drawable &image, int x, int y, PointerType type = PointerType::Arrow) : + DrawablePointer(tag, image, {x, y}) + { + SetType(type); + } - DrawablePointer(const DrawablePointer &other) = delete; + /// Initializes a pointer. Ownership of the drawable is not transferred. Use Assume function + /// after invoking default constructor to transfer ownership. + DrawablePointer(const AssumeOwnershipTag &, const Drawable &image, Geometry::Point hotspot, PointerType type = PointerType::Arrow) : + image(&image), hotspot(hotspot) + { + owner = true; + SetType(type); + } - DrawablePointer(DrawablePointer &&other) : - image(other.image), hotspot(other.hotspot), owner(other.owner) { - other.image = nullptr; - other.owner = false; - } + DrawablePointer(const DrawablePointer &other) = delete; - DrawablePointer &operator =(const DrawablePointer &) = delete; + DrawablePointer(DrawablePointer &&other) : + image(other.image), hotspot(other.hotspot), owner(other.owner) { + other.image = nullptr; + other.owner = false; + } + + DrawablePointer &operator =(const DrawablePointer &) = delete; - DrawablePointer &operator =(DrawablePointer &&other) { - RemoveImage(); - image = other.image; - owner = other.owner; - hotspot = other.hotspot; - - other.image = nullptr; - other.owner = false; + DrawablePointer &operator =(DrawablePointer &&other) { + RemoveImage(); + image = other.image; + owner = other.owner; + hotspot = other.hotspot; + type = other.type; - return *this; - } + other.image = nullptr; + other.owner = false; + + return *this; + } - //Pointer(Resource::Pointer &pointer); + //Pointer(Resource::Pointer &pointer); - ~DrawablePointer() { - RemoveImage(); - } + ~DrawablePointer() { + RemoveImage(); + } - /// Returns if the pointer has an image - bool HasImage() const { - return image != nullptr; - } + /// Returns if the pointer has an image + bool HasImage() const { + return image != nullptr; + } - /// Returns the image contained in this pointer. You should check HasImage - /// before accessing to the image - const Drawable &GetImage() const { - ASSERT(image, "Pointer image is not set"); + /// Returns the image contained in this pointer. You should check HasImage + /// before accessing to the image + const Drawable &GetImage() const { + ASSERT(image, "Pointer image is not set"); - return *image; - } + return *image; + } - /// Changes the image of this pointer - void SetImage(const Drawable &value) { - RemoveImage(); + /// Changes the image of this pointer + void SetImage(const Drawable &value) { + RemoveImage(); - image = &value; - } + image = &value; + } - /// Changes the image of the pointer by assuming the ownership of the given - /// image - void Assume(const Drawable &value) { - RemoveImage(); + /// Changes the image of the pointer by assuming the ownership of the given + /// image + void Assume(const Drawable &value) { + RemoveImage(); - image = &value; - owner = true; - } + image = &value; + owner = true; + } - /// Changes the image of the pointer by assuming the ownership of the given - /// image - void Assume(const Drawable &value, Geometry::Point hotspot) { - RemoveImage(); + /// Changes the image of the pointer by assuming the ownership of the given + /// image + void Assume(const Drawable &value, Geometry::Point hotspot) { + RemoveImage(); - image = &value; - owner = true; - this->hotspot = hotspot; - } + image = &value; + owner = true; + this->hotspot = hotspot; + } - /// Changes the image of the pointer by assuming the ownership of the given - /// image - void Assume(const Drawable &value, int x, int y) { - RemoveImage(); + /// Changes the image of the pointer by assuming the ownership of the given + /// image + void Assume(const Drawable &value, int x, int y) { + RemoveImage(); - image = &value; - owner = true; - this->hotspot = {x, y}; - } + image = &value; + owner = true; + this->hotspot = {x, y}; + } - /// Removes the image from the pointer - void RemoveImage() { - if(owner) { - delete image; - owner = false; - } + /// Removes the image from the pointer + void RemoveImage() { + if(owner) { + delete image; + owner = false; + } - image = nullptr; - } + image = nullptr; + } - /// Releases the ownership of the drawable and removes it from the pointer - const Drawable &Release() { - auto img = image; + /// Releases the ownership of the drawable and removes it from the pointer + const Drawable &Release() { + auto img = image; - owner = false; - image = nullptr; + owner = false; + image = nullptr; - return *img; - } + return *img; + } - protected: - void draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const override { - if(!image) return; + protected: + void draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const override { + if(!image) return; - image->Draw(target, p-hotspot, color); - } + image->Draw(target, p-hotspot, color); + } - private: - const Drawable *image = nullptr; - Geometry::Point hotspot ={0, 0}; + private: + const Drawable *image = nullptr; + Geometry::Point hotspot ={0, 0}; - bool owner = false; - }; + bool owner = false; + }; + + template<class A_> + class basic_PointerProvider; - template<class A_> - class basic_PointerProvider; + /// Represents animated pointer. + template<class A_> + class basic_AnimatedPointer : public virtual Pointer, public virtual A_::AnimationType { + public: + basic_AnimatedPointer(const basic_PointerProvider<A_> &parent, typename A_::AnimationType &anim) : + A_::AnimationType(parent, false), anim(&anim), parent(parent) + { + SetType(parent.GetType()); + } - /// Represents animated pointer. - template<class A_> - class basic_AnimatedPointer : public virtual Pointer, public virtual A_::AnimationType { - public: - basic_AnimatedPointer(const basic_PointerProvider<A_> &parent, typename A_::AnimationType &anim) : - A_::AnimationType(parent, false), anim(&anim), parent(parent) - { } + basic_AnimatedPointer(const basic_AnimatedPointer &) = delete; - basic_AnimatedPointer(const basic_AnimatedPointer &) = delete; - - basic_AnimatedPointer(basic_AnimatedPointer &&other) : A_::AnimationType(other.parent, false), anim(other.anim), parent(other.parent) { - other.anim = nullptr; - } + basic_AnimatedPointer(basic_AnimatedPointer &&other) : A_::AnimationType(other.parent, false), anim(other.anim), parent(other.parent) { + SetType(other.GetType()); + other.anim = nullptr; + } - ~basic_AnimatedPointer() { - if(anim) - anim->DeleteAnimation(); - } + ~basic_AnimatedPointer() { + if(anim) + anim->DeleteAnimation(); + } - void SetController(Gorgon::Animation::ControllerBase &controller) override { - ASSERT(anim, "Trying to use a moved out pointer"); + void SetController(Gorgon::Animation::ControllerBase &controller) override { + ASSERT(anim, "Trying to use a moved out pointer"); - anim->SetController(controller); - } - - bool HasController() const override { - ASSERT(anim, "Trying to use a moved out pointer"); + anim->SetController(controller); + } + + bool HasController() const override { + ASSERT(anim, "Trying to use a moved out pointer"); - return anim->HasController(); - } + return anim->HasController(); + } - Gorgon::Animation::ControllerBase &GetController() const { - ASSERT(anim, "Trying to use a moved out pointer"); + Gorgon::Animation::ControllerBase &GetController() const override { + ASSERT(anim, "Trying to use a moved out pointer"); - return anim->GetController(); - } + return anim->GetController(); + } - void RemoveController() const { - ASSERT(anim, "Trying to use a moved out pointer"); + void RemoveController() override { + ASSERT(anim, "Trying to use a moved out pointer"); - anim->RemoveController(); - } + anim->RemoveController(); + } - protected: - void draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const override; + protected: + using A_::AnimationType::draw; + + void draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const override; - const basic_PointerProvider<A_> &parent; - typename A_::AnimationType *anim; - }; + typename A_::AnimationType *anim; + const basic_PointerProvider<A_> &parent; + }; /// This class stores information that allows an animated pointer to be created. - template<class A_> + template<class A_> class basic_PointerProvider : public A_ { public: - using AnimationType = basic_AnimatedPointer<A_>; + using AnimationType = basic_AnimatedPointer<A_>; - explicit basic_PointerProvider(Geometry::Point hotspot = {0,0}) : + explicit basic_PointerProvider(Geometry::Point hotspot = {0,0}) : hotspot(hotspot) { } /// Move constructor - basic_PointerProvider(basic_PointerProvider &&other) : + basic_PointerProvider(basic_PointerProvider &&other) : hotspot(other.hotspot), owned(other.owned) { other.owned = false; } - basic_PointerProvider(const basic_PointerProvider &) = delete; + basic_PointerProvider(const basic_PointerProvider &) = delete; virtual ~basic_PointerProvider() { } - /// Creates a pointer from this provider - AnimationType CreatePointer(Gorgon::Animation::Timer &timer) const { - return AnimationType(*this, A_::CreateAnimation(timer)); - } + /// Creates a pointer from this provider + AnimationType CreatePointer(Gorgon::Animation::Timer &timer) const { + return AnimationType(*this, A_::CreateAnimation(timer)); + } - /// Creates a pointer from this provider, just a rename for CreateAnimation - AnimationType CreatePointer(bool create = true) const { - return AnimationType(*this, A_::CreateAnimation(create)); - } + /// Creates a pointer from this provider, just a rename for CreateAnimation + AnimationType CreatePointer(bool create = true) const { + return AnimationType(*this, A_::CreateAnimation(create)); + } - /// Creates a pointer from this provider - AnimationType &CreateAnimation(Gorgon::Animation::ControllerBase &timer) const override { - return *new basic_AnimatedPointer<A_>(*this, A_::CreateAnimation(timer)); - } + /// Creates a pointer from this provider + AnimationType &CreateAnimation(Gorgon::Animation::ControllerBase &timer) const override { + return *new basic_AnimatedPointer<A_>(*this, A_::CreateAnimation(timer)); + } - /// Creates a pointer from this provider - AnimationType &CreateAnimation(bool create = true) const override { - return *new basic_AnimatedPointer<A_>(*this, A_::CreateAnimation(create)); - } + /// Creates a pointer from this provider + AnimationType &CreateAnimation(bool create = true) const override { + return *new basic_AnimatedPointer<A_>(*this, A_::CreateAnimation(create)); + } /// Returns the hotspot of the provider Geometry::Point GetHotspot() const { @@ -264,7 +364,21 @@ hotspot = value; } - protected: + /// Returns the type of the pointer + PointerType GetType() const { + return type; + } + + /// Sets the type of the pointer. Pointer type can be used to determine the type while + /// adding to the stack. If operating system pointers are used, this value is used determine + /// which pointer to show. + void SetType(PointerType value) { + type = value; + } + + protected: + PointerType type = PointerType::Arrow; + /// Hotspot will be transferred to newly created pointers Geometry::Point hotspot; @@ -272,40 +386,16 @@ bool owned; }; - using PointerProvider = basic_PointerProvider<AnimationProvider>; - using BitmapPointerProvider = basic_PointerProvider<BitmapAnimationProvider>; - using ConstBitmapPointerProvider = basic_PointerProvider<ConstBitmapAnimationProvider>; + using PointerProvider = basic_PointerProvider<AnimationProvider>; + using BitmapPointerProvider = basic_PointerProvider<BitmapAnimationProvider>; + using ConstBitmapPointerProvider = basic_PointerProvider<ConstBitmapAnimationProvider>; - ///Pointer types - enum class PointerType { - ///No pointer is selected or using default - None=0, - - ///Arrow / Pointer - Arrow=1, - - ///Wait / Hourglass - Wait=2, - - ///No / Not allowed - No=3, - - ///Text / Beam pointer - Text=4, - - ///Hand pointer - Hand=5, - - ///Drag / Closed hand pointer - Drag=6 - }; - /** - * This class manages a pointer stack that allows multiple pointers to be - * registered and switched. These pointers are pushed to the stack and can - * be reset, setting the pointer to the previous state. - */ + * This class manages a pointer stack that allows multiple pointers to be + * registered and switched. These pointers are pushed to the stack and can + * be reset, setting the pointer to the previous state. + */ class PointerStack { public: @@ -324,13 +414,11 @@ } ~Token() { - if(parent) - parent->Reset(*this); + Revert(); } Token &operator =(Token &&tok) { - if(parent) - parent->Reset(*this); + Revert(); parent = tok.parent; ind = tok.ind; @@ -341,6 +429,14 @@ return *this; } + void Revert() { + if(parent) + parent->Reset(*this); + + parent = nullptr; + ind = 0; + } + /// Checks if the token is null bool IsNull() const { return parent == nullptr; } @@ -357,38 +453,41 @@ int ind = 0; }; - PointerStack() = default; + PointerStack() = default; - PointerStack(const PointerStack &) = delete; + PointerStack(const PointerStack &) = delete; - PointerStack(PointerStack &&other) { - Swap(other); - } + PointerStack(PointerStack &&other) { + Swap(other); + } - void Swap(PointerStack &other) { - using std::swap; + void Swap(PointerStack &other) { + using std::swap; - swap(lastind, other.lastind); - swap(stack, other.stack); - swap(pointers, other.pointers); - } + swap(lastind, other.lastind); + swap(stack, other.stack); + swap(pointers, other.pointers); + } - ~PointerStack() { - for(auto &w : pointers) { - if(w.owned) - delete w.ptr; - } - } + ~PointerStack() { + for(auto &w : pointers) { + if(w.owned) + delete w.ptr; + } + } /// Adds the given pointer to the stack. Ownership of the pointer will not /// be transferred. If the given pointer type exists old one will be overridden. /// If the old pointer is managed by this stack then it will be deleted. - void Add(PointerType type, const Pointer &pointer); + void Add(PointerType type, const Pointer &pointer); - /// Move variant that maps to assume - void Add(PointerType type, const Pointer &&pointer) { - Assume(type, pointer); - } + /// Adds the given pointer to the stack. Ownership of the pointer will not + /// be transferred. If the given pointer type exists old one will be overridden. + /// If the old pointer is managed by this stack then it will be deleted. Type that + /// is set in the pointer is used to refer to this pointer. + void Add(const Pointer &pointer) { + Add(pointer.GetType(), pointer); + } /// Adds the given pointer to the stack. Ownership of the pointer will be /// transferred. If the given pointer type exists old one will be overridden. @@ -399,9 +498,9 @@ /// bound to the life time of the stack. If the given pointer type exists /// old one will be overridden. If the old pointer is managed by this stack /// then it will be deleted. - void Add(PointerType type, const Drawable &image, Geometry::Point hotspot); + void Add(PointerType type, const Drawable &image, Geometry::Point hotspot); - void Add(PointerType type, const Drawable &&image, Geometry::Point hotspot) = delete; + void Add(PointerType type, const Drawable &&image, Geometry::Point hotspot) = delete; /// Checks if the given pointer exists bool Exists(PointerType type) { @@ -410,10 +509,12 @@ return pointers[(int)type].ptr != nullptr; } + PointerType GetCurrentType() const; + /// Set the current pointer to the given type. This would return a token to /// be used to reset this operation. The token should be stored in a variable /// otherwise the pointer would be reset immediately. - Token Set(PointerType type); + Token Set(PointerType type); /// Sets the current pointer in the stack to the given pointer. This pointer /// will not be added to the list. The token should be stored in a variable @@ -433,6 +534,9 @@ /// one registered or pushed pointer bool IsValid() const; + /// This event is fired if the pointer at the top is changed. + Event<PointerStack> PointerChanged = Event<PointerStack>{this}; + private: struct Wrapper { const Pointer *ptr = nullptr; @@ -443,15 +547,15 @@ Containers::Hashmap<int, const Pointer> stack; - std::array<Wrapper, (int)PointerType::Drag+1> pointers = {}; + std::array<Wrapper, (int)PointerType::Max> pointers = {}; }; - template<class A_> - void basic_AnimatedPointer<A_>::draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const { - ASSERT(anim, "Try to use a moved out pointer"); + template<class A_> + void basic_AnimatedPointer<A_>::draw(Gorgon::Graphics::TextureTarget &target, const Geometry::Pointf &p, Gorgon::Graphics::RGBAf color) const { + ASSERT(anim, "Try to use a moved out pointer"); - anim->Draw(target, p-parent.GetHotspot(), color); - } + anim->Draw(target, p-parent.GetHotspot(), color); + } } }
--- a/Source/Gorgon/Resource/Pointer.h Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/Resource/Pointer.h Mon May 17 20:56:17 2021 +0300 @@ -25,18 +25,19 @@ class Pointer : public AnimationStorage, public Graphics::BitmapPointerProvider { public: Pointer(Graphics::Bitmap &bmp, Geometry::Point hotspot, Graphics::PointerType type) : - Graphics::BitmapPointerProvider(hotspot), type(type) { + Graphics::BitmapPointerProvider(hotspot) { Add(bmp); + SetType(type); } Pointer(Graphics::BitmapAnimationProvider &&anim, Geometry::Point hotspot, Graphics::PointerType type) : - Graphics::BitmapPointerProvider(hotspot), type(type) { + Graphics::BitmapPointerProvider(hotspot) { dynamic_cast<Graphics::BitmapAnimationProvider&>(*this) = std::move(anim); + SetType(type); } - explicit Pointer(Graphics::PointerType type = Graphics::PointerType::None) : - type(type) { - + explicit Pointer(Graphics::PointerType type = Graphics::PointerType::None) { + SetType(type); } Pointer(const Pointer &) = delete; @@ -45,16 +46,6 @@ GID::Type GetGID() const override { return GID::Pointer; } - /// Returns the type of the pointer - Graphics::PointerType GetType() const { - return type; - } - - /// Sets the type of the pointer - void SetType(Graphics::PointerType value) { - type = value; - } - void Prepare() override; /// Moves the pointer provider out of resource system. Use Prepare and Discard before calling this function to @@ -68,8 +59,6 @@ static Pointer *LoadLegacy(std::weak_ptr<File> file, std::shared_ptr<Reader> reader, unsigned long size) { Utils::NotImplemented(); } protected: - Graphics::PointerType type = Graphics::PointerType::Arrow; - virtual Graphics::RectangularAnimationStorage animmoveout() override; virtual ~Pointer() { }
--- a/Source/Gorgon/Window.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/Window.cpp Mon May 17 20:56:17 2021 +0300 @@ -277,6 +277,8 @@ pointerlayer = new Graphics::Layer; Layer::Add(*pointerlayer); + + Pointers.PointerChanged.Register(*this, &Window::UpdatePointer); } void Window::SetBackground(const Graphics::Bitmap &value) { @@ -356,4 +358,7 @@ over = MouseHandler{}; } + void Window::UpdatePointer() { + WindowManager::SetPointer(*this, Pointers.GetCurrentType()); + } }
--- a/Source/Gorgon/Window.h Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/Window.h Mon May 17 20:56:17 2021 +0300 @@ -376,6 +376,9 @@ using Layer::Remove; virtual void Remove(Layer &layer) override; + /// Updates current mouse pointer if OS pointer is shown. This is called automatically. + void UpdatePointer(); + /// Returns the minimum size required to fit any window inside. static Geometry::Size GetMinimumRequiredSize();
--- a/Source/Gorgon/WindowManager.h Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/WindowManager.h Mon May 17 20:56:17 2021 +0300 @@ -10,6 +10,8 @@ #include "Event.h" #include "Containers/Image.h" #include "Resource/GID.h" +#include "Graphics/Pointer.h" + namespace Gorgon { @@ -228,5 +230,9 @@ /// Changes the clipboard to the given image. Depending on size of the image, this operation might not work /// on X11 for now. void SetClipboardBitmap(Containers::Image img, bool append = false); + + /// Changes the OS pointer to the requested type. If target OS does not supported the requested + /// type, a similar pointer will be displayed. + void SetPointer(Window &wind, Graphics::PointerType type); } }
--- a/Source/Gorgon/WindowManager/DWM/DWM.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/WindowManager/DWM/DWM.cpp Mon May 17 20:56:17 2021 +0300 @@ -142,6 +142,5 @@ delete data; } - } }
--- a/Source/Gorgon/WindowManager/DWM/Window.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/WindowManager/DWM/Window.cpp Mon May 17 20:56:17 2021 +0300 @@ -546,4 +546,75 @@ } } -} +namespace WindowManager { + + void SetPointer(Window &wind, Graphics::PointerType type) { + HINSTANCE instance=GetModuleHandle(NULL); + LPCSTR cursor; + + switch(type) { + case Graphics::PointerType::Wait: + cursor = IDC_WAIT; + break; + case Graphics::PointerType::Processing: + cursor = IDC_APPSTARTING; + break; + case Graphics::PointerType::No: + cursor = IDC_NO; + break; + case Graphics::PointerType::Text: + cursor = IDC_IBEAM; + break; + case Graphics::PointerType::Link: + cursor = IDC_HAND; + break; + case Graphics::PointerType::Move: + cursor = IDC_HAND; + break; + case Graphics::PointerType::Drag: + cursor = IDC_SIZEALL; + break; + case Graphics::PointerType::ScaleLeft: + cursor = IDC_SIZEWE; + break; + case Graphics::PointerType::ScaleTop: + cursor = IDC_SIZENS; + break; + case Graphics::PointerType::ScaleRight: + cursor = IDC_SIZEWE; + break; + case Graphics::PointerType::ScaleBottom: + cursor = IDC_SIZENS; + break; + case Graphics::PointerType::ScaleTopLeft: + cursor = IDC_SIZENWSE; + break; + case Graphics::PointerType::ScaleTopRight: + cursor = IDC_SIZENESW; + break; + case Graphics::PointerType::ScaleBottomLeft: + cursor = IDC_SIZENESW; + break; + case Graphics::PointerType::ScaleBottomRight: + cursor = IDC_SIZENWSE; + break; + case Graphics::PointerType::Cross: + cursor = IDC_CROSS; + break; + case Graphics::PointerType::Help: + cursor = IDC_HELP; + break; + case Graphics::PointerType::Straight: + cursor = IDC_UPARROW; + break; + default: + cursor = IDC_ARROW; + break; + } + + LoadCursorW(instance, cursor); + SetCursor(c); + } + + +} }
--- a/Source/Gorgon/WindowManager/X11/Window.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Source/Gorgon/WindowManager/X11/Window.cpp Mon May 17 20:56:17 2021 +0300 @@ -6,7 +6,7 @@ #include "../../Graphics/Layer.h" #include "../../Encoding/URI.h" #include "X11Keysym.h" - +#include <X11/cursorfont.h> namespace Gorgon { namespace WindowManager { @@ -788,5 +788,80 @@ break; } } - } -} + } + +namespace WindowManager { + void SetPointer(Window &wind, Graphics::PointerType type) { + int cursor; + static std::map<Graphics::PointerType, Cursor> cursors; + + if(!cursors.count(type)) { + switch(type) { + case Graphics::PointerType::Wait: + cursor = XC_watch; + break; + case Graphics::PointerType::Processing: + cursor = XC_watch; + break; + case Graphics::PointerType::No: + cursor = XC_X_cursor; + break; + case Graphics::PointerType::Text: + cursor = XC_xterm; + break; + case Graphics::PointerType::Link: + cursor = XC_hand1; + break; + case Graphics::PointerType::Move: + cursor = XC_plus; + break; + case Graphics::PointerType::Drag: + cursor = XC_fleur; + break; + case Graphics::PointerType::ScaleLeft: + cursor = XC_left_side; + break; + case Graphics::PointerType::ScaleTop: + cursor = XC_top_side; + break; + case Graphics::PointerType::ScaleRight: + cursor = XC_right_side; + break; + case Graphics::PointerType::ScaleBottom: + cursor = XC_bottom_side; + break; + case Graphics::PointerType::ScaleTopLeft: + cursor = XC_top_left_corner; + break; + case Graphics::PointerType::ScaleTopRight: + cursor = XC_top_right_corner; + break; + case Graphics::PointerType::ScaleBottomLeft: + cursor = XC_bottom_left_corner; + break; + case Graphics::PointerType::ScaleBottomRight: + cursor = XC_bottom_right_corner; + break; + case Graphics::PointerType::Cross: + cursor = XC_crosshair; + break; + case Graphics::PointerType::Help: + cursor = XC_question_arrow; + break; + case Graphics::PointerType::Straight: + cursor = XC_center_ptr; + break; + default: + cursor = XC_arrow; + break; + } + + Cursor c; + c = XCreateFontCursor(WindowManager::display, cursor); + cursors[type] = c; + } + + XDefineCursor(WindowManager::display, internal::getdata(wind)->handle, cursors[type]); + } + +} }
--- a/Testing/Source/Manual/Window.cpp Sat May 15 20:18:29 2021 +0200 +++ b/Testing/Source/Manual/Window.cpp Mon May 17 20:56:17 2021 +0300 @@ -112,10 +112,18 @@ Graphics::DrawablePointer pointer1(cursor1, 8,15); cursor2.Prepare(); - Graphics::DrawablePointer pointer2(cursor2, 8,8); + Graphics::DrawablePointer pointer2(cursor2, 8,8, Gorgon::Graphics::PointerType::Wait); cursor3.Prepare(); - Graphics::DrawablePointer pointer3(cursor3, 1,8); + Graphics::DrawablePointer pointer3(cursor3, 1,8, Gorgon::Graphics::PointerType::Text); + + Resource::File fsave; + auto ptrsave = new Resource::Pointer; + + ptrsave->Add(cursor1); + ptrsave->SetType(Graphics::PointerType::Arrow); + fsave.Root().Add(ptrsave); + fsave.Save("ptrtest.gor"); Resource::File f; f.LoadFile("ptrtest.gor"); @@ -127,14 +135,6 @@ wind.Pointers.Add(Graphics::PointerType::Wait, pointer2); wind.Pointers.Add(Graphics::PointerType::Text, pointer3); - /*Resource::File f; - auto ptr = new Resource::Pointer; - - ptr->Add(cursor1); - ptr->SetType(Graphics::PointerType::Arrow); - f.Root().Add(ptr); - f.Save("ptrtest.gor");*/ - //img = Graphics::Bitmap({200, 200}, Graphics::ColorMode::Alpha);