diff --git a/libs/ui/include/psemek/ui/key_interceptor.hpp b/libs/ui/include/psemek/ui/key_interceptor.hpp new file mode 100644 index 00000000..8dd06ddc --- /dev/null +++ b/libs/ui/include/psemek/ui/key_interceptor.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include + +namespace psemek::ui +{ + + struct key_interceptor + : element + { + children_range children() const override { return children_; } + + virtual std::shared_ptr set_child(std::shared_ptr c); + + geom::box size_constraints() const override; + + struct shape const & shape() const override; + void reshape(geom::box const & bbox) override; + + void on_key_down(std::function callback); + + bool on_event(key_press const & event) override; + + void draw(painter &) const override {} + + private: + std::shared_ptr child_; + element * children_[1]{nullptr}; + + std::function callback_; + }; + +} diff --git a/libs/ui/source/key_interceptor.cpp b/libs/ui/source/key_interceptor.cpp new file mode 100644 index 00000000..9db47eb8 --- /dev/null +++ b/libs/ui/source/key_interceptor.cpp @@ -0,0 +1,55 @@ +#include +#include + +namespace psemek::ui +{ + + std::shared_ptr key_interceptor::set_child(std::shared_ptr c) + { + auto old = std::move(child_); + if (old) old->set_parent(nullptr); + + child_ = std::move(c); + if (child_) child_->set_parent(this); + children_[0] = child_.get(); + + return old; + } + + geom::box key_interceptor::size_constraints() const + { + if (child_) + return child_->size_constraints(); + return element::size_constraints(); + } + + shape const & key_interceptor::shape() const + { + static const null_shape fallback_shape; + if (child_) + return child_->shape(); + return fallback_shape; + } + + void key_interceptor::reshape(geom::box const & bbox) + { + if (child_) + child_->reshape(bbox); + } + + void key_interceptor::on_key_down(std::function callback) + { + callback_ = std::move(callback); + } + + bool key_interceptor::on_event(key_press const & event) + { + if (callback_ && event.down) + { + return callback_(event.key); + } + + return false; + } + +}