#include namespace psemek::ui { element::children_range button::children() const { return children_range{children_}; } bool button::on_event(mouse_move const & e) { bool const over = shape().contains(geom::cast(e.position)); switch (state_) { case state_t::normal: if (over) { state_ = state_t::mouseover; on_state_changed(state_t::normal); } break; case state_t::mouseover: case state_t::mousedown: if (!over) { auto old = state_; state_ = state_t::normal; on_state_changed(old); } break; } return false; } bool button::on_event(mouse_click const & e) { if (e.button != mouse_button::left) return false; switch (state_) { case state_t::normal: break; case state_t::mouseover: if (e.down) { state_ = state_t::mousedown; if (callback_) post(callback_); on_state_changed(state_t::mouseover); return true; } break; case state_t::mousedown: if (!e.down) { state_ = state_t::mouseover; on_state_changed(state_t::mousedown); return true; } break; } return false; } button::~button() { release_children(); } void button::on_state_changed(state_t old) { if (state() == state_t::mousedown || old == state_t::mousedown) { post_reshape(); } } void button::set_label(std::shared_ptr label) { if (icon()) set_icon(nullptr); if (label_) label_->set_parent(nullptr); label_ = std::move(label); children_[0] = label_.get(); if (label_) label_->set_parent(this); } void button::set_icon(std::shared_ptr icon) { if (label()) set_label(nullptr); if (icon_) icon_->set_parent(nullptr); icon_ = std::move(icon); children_[0] = icon_.get(); if (icon_) icon_->set_parent(this); } }