#include "Numeric_Axis.h" namespace renderive::detail { Axis_Control::Axis_Control(::Scene_Base& scene, const Axis_Properties& properties) : Axis_State_Strategy(scene, properties) {} void Axis_Control::handle_event(const Event& event) { if (event.type == Event_Type::Wheel && get<&Axis_Properties::wheel>()) { const auto& wheel = static_cast(event); const Range range = get<&Axis_Properties::coordinates>(); const Orientation orientation = get<&Axis_Base_Properties::orientation>(); const double anchor_pixel = orientation == Orientation::Horizontal ? wheel.position.x : wheel.position.y; const double anchor = transform().pixel_to_coord(anchor_pixel); const double factor = wheel.angle_delta_y >= 0.0 ? 0.9 : 1.1; const Range next{anchor + (range.origin - anchor) * factor, anchor + (range.target - anchor) * factor}; set<&Axis_Properties::coordinates>(next); event.accept(); return; } if (!get<&Axis_Properties::drag>()) return; if (event.type == Event_Type::Pointer_Press) { const auto& pointer = static_cast(event); if (pointer.button == Mouse_Button::Left) { interaction_.update([&](Axis_Interaction_State& interaction) { interaction.dragging = true; interaction.last_pointer = pointer.position; }); event.accept(); } } else if (event.type == Event_Type::Pointer_Move) { const auto& pointer = static_cast(event); PointF previous; bool dragging{}; interaction_.update([&](Axis_Interaction_State& interaction) { dragging = interaction.dragging; if (!dragging) return; previous = interaction.last_pointer; interaction.last_pointer = pointer.position; }); if (!dragging) return; const Orientation orientation = get<&Axis_Base_Properties::orientation>(); const double delta = orientation == Orientation::Horizontal ? pointer.position.x - previous.x : pointer.position.y - previous.y; const Range range = get<&Axis_Properties::coordinates>(); const std::size_t pixel_length = get<&Axis_Base_Properties::pixel_length>(); const double shift = pixel_length == 0 ? 0.0 : -delta * range.length() / static_cast(pixel_length); set<&Axis_Properties::coordinates>(Range{range.origin + shift, range.target + shift}); event.accept(); } else if (event.type == Event_Type::Pointer_Release) { bool accepted{}; interaction_.update([&](Axis_Interaction_State& interaction) { accepted = interaction.dragging; interaction.dragging = false; }); if (accepted) event.accept(); } } void Axis_Control::publish() { Axis_State_Strategy::publish(); interaction_.publish(); } std::uint64_t Axis_Control::state_revision() const { return Axis_State_Strategy::state_revision() + interaction_.state_revision(); } Range Axis_Control::coordinate_range(const Axis_Properties& state) const noexcept { return state.coordinates.get(); } } // namespace renderive::detail