diff --git a/libs/ui/include/psemek/ui/rich_image_view.hpp b/libs/ui/include/psemek/ui/rich_image_view.hpp index ae1c02c4..cf96bf3a 100644 --- a/libs/ui/include/psemek/ui/rich_image_view.hpp +++ b/libs/ui/include/psemek/ui/rich_image_view.hpp @@ -36,6 +36,8 @@ namespace psemek::ui struct shape const & shape() const override { return shape_; } void reshape(geom::box const & bbox) override; + void update(float dt) override; + void draw(painter & p) const override; protected: @@ -45,6 +47,7 @@ namespace psemek::ui std::shared_ptr image_; geom::interval zoom_range_ = {0.f, std::numeric_limits::infinity()}; float zoom_ = 1.f; + float zoom_tgt_ = 1.f; geom::point center_{0.f, 0.f}; bool allow_overflow_ = false; gfx::color_rgba color_{0, 0, 0, 0}; diff --git a/libs/ui/source/rich_image_view.cpp b/libs/ui/source/rich_image_view.cpp index 459614ed..541dfd0e 100644 --- a/libs/ui/source/rich_image_view.cpp +++ b/libs/ui/source/rich_image_view.cpp @@ -46,13 +46,8 @@ namespace psemek::ui // (mouse - bbox.center) / zoom0 + center0 = (mouse - bbox.center) / zoom1 + center1 // center1 - center0 = (mouse - bbox.center) * (1 / zoom0 - 1 / zoom1) - auto new_center = center_; - - if (mouse_) - new_center += (geom::cast(*mouse_) - shape_.box.center()) * (1.f / zoom_ - 1.f / zoom); - - zoom_ = zoom; - set_center(new_center); + zoom_tgt_ = zoom; + set_center(center_); } geom::box rich_image_view::region() const @@ -80,7 +75,6 @@ namespace psemek::ui { set_center(center_ + geom::cast(*drag_ - e.position) / zoom_); drag_ = e.position; - return true; } return false; } @@ -107,7 +101,7 @@ namespace psemek::ui { if (mouseover_) { - set_zoom(zoom_ * std::pow(1.25f, e.delta)); + set_zoom(zoom_tgt_ * std::pow(1.25f, e.delta)); return true; } return false; @@ -137,6 +131,20 @@ namespace psemek::ui post_region_changed(); } + void rich_image_view::update(float dt) + { + float new_zoom = zoom_ + (zoom_tgt_ - zoom_) * std::min(1.f, dt * 20.f); + + auto new_center = center_; + + if (mouse_) + new_center += (geom::cast(*mouse_) - shape_.box.center()) * (1.f / zoom_ - 1.f / new_zoom); + + zoom_ = new_zoom; + + set_center(new_center); + } + void rich_image_view::draw(painter & p) const { auto st = merged_style();