diff options
author | 杨宇千 <crupest@outlook.com> | 2019-08-11 22:08:49 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-08-11 22:08:49 +0800 |
commit | 99a322a6badf5b6d95be4944e80d92fc1cb2589e (patch) | |
tree | 4227de0cbb1fd73ef99de4bc57041492a0450208 /include/cru/ui/click_detector.hpp | |
parent | 3a8abe0aed9bb72ed64cbfe9f2f83a0db285e14c (diff) | |
download | cru-99a322a6badf5b6d95be4944e80d92fc1cb2589e.tar.gz cru-99a322a6badf5b6d95be4944e80d92fc1cb2589e.tar.bz2 cru-99a322a6badf5b6d95be4944e80d92fc1cb2589e.zip |
...
Diffstat (limited to 'include/cru/ui/click_detector.hpp')
-rw-r--r-- | include/cru/ui/click_detector.hpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/include/cru/ui/click_detector.hpp b/include/cru/ui/click_detector.hpp new file mode 100644 index 00000000..e7d5e417 --- /dev/null +++ b/include/cru/ui/click_detector.hpp @@ -0,0 +1,87 @@ +#pragma once +#include "control.hpp" + +#include <cstdlib> +#include <forward_list> +#include <optional> + +namespace cru::ui { +class ClickEventArgs : Object { + public: + ClickEventArgs(Control* sender, const Point& down_point, + const Point& up_point, MouseButton button) + : sender_(sender), + down_point_(down_point), + up_point_(up_point), + button_(button) {} + + CRU_DEFAULT_COPY(ClickEventArgs) + CRU_DEFAULT_MOVE(ClickEventArgs) + + ~ClickEventArgs() override = default; + + Control* GetSender() const { return sender_; } + Point GetDownPoint() const { return down_point_; } + Point GetUpPoint() const { return up_point_; } + MouseButton GetButton() const { return button_; } + + private: + Control* sender_; + Point down_point_; + Point up_point_; + MouseButton button_; +}; + +class ClickDetector : public Object { + public: + explicit ClickDetector(Control* control); + + ClickDetector(const ClickDetector& other) = delete; + ClickDetector& operator=(const ClickDetector& other) = delete; + ClickDetector(ClickDetector&& other) = delete; + ClickDetector& operator=(ClickDetector&& other) = delete; + + ~ClickDetector() override = default; + + Control* GetControl() const { return control_; } + + // Return a union of buttons being pressed. Return 0 if no button is being + // pressed. + MouseButton IsPressing() const { + unsigned result = 0; + if (click_map_.left.has_value()) result |= MouseButton::Left; + if (click_map_.middle.has_value()) result |= MouseButton::Middle; + if (click_map_.right.has_value()) result |= MouseButton::Right; + return static_cast<MouseButton>(result); + } + + IEvent<ClickEventArgs>* ClickEvent() { return &event_; } + + private: + std::optional<Point>& FromButton(MouseButton button) { + switch (button) { + case MouseButton::Left: + return click_map_.left; + case MouseButton::Middle: + return click_map_.middle; + case MouseButton::Right: + return click_map_.right; + default: + std::abort(); + } + } + + private: + Control* control_; + + Event<ClickEventArgs> event_; + + std::forward_list<EventRevokerGuard> event_rovoker_guards_; + + struct { + std::optional<Point> left = std::nullopt; + std::optional<Point> middle = std::nullopt; + std::optional<Point> right = std::nullopt; + } click_map_; +}; +} // namespace cru::ui |