#pragma once #include #include "../event/Pointer_Event.h" #include "../event/Wheel_Event.h" #include "Abs_Axis_p.h" #include "Axis.h" namespace renderive { struct Axis_Render_State : Abs_Axis_Render_State {}; struct Axis_Input_Data : Abs_Axis_Input_Data {}; struct Axis_Private : Typed_Render_Data_Base, Hit_Testable, Pointer_Interactive, Wheel_Interactive { bool use_wheel = false; bool use_drag = false; bool select_test(const PointF& pos) override { return true; } void wheel_event(const Wheel_Event& event) override { if (use_wheel) { Render_Edit_Lease edit(this); const double delta = event.angle_delta_y; double wheel_steps = delta / 120.0; double factor = std::pow(0.8, wheel_steps); double cursor_pixel = edit->orientation == Orientation::Horizontal ? event.position.x : event.position.y; double cursor_coord = edit_pixel_to_coord(cursor_pixel); double new_coord_length = edit->coord_length * factor; double new_coord_start = cursor_coord - new_coord_length * (cursor_coord - edit->coord_start) / edit->coord_length; edit->coord_start = new_coord_start; edit->coord_length = new_coord_length; event.accept(); } } bool dragging = false; PointF start_global_pos; double start_coord_value; double pixel_pre_coord; void mouse_press_event(const Pointer_Event& event) override { if (!use_drag) return; if (event.button != Mouse_Button::Left) return; if (dragging) return; dragging = true; start_global_pos = event.global_position; Render_State_Lease state(this); start_coord_value = state->coord_start; pixel_pre_coord = state->coord_length / static_cast(state->pixel_length); event.accept(); } void mouse_move_event(const Pointer_Event& event) override { if (!use_drag) return; if (!(event.buttons & static_cast(Mouse_Button::Left))) return; if (!dragging) return; Render_Edit_Lease edit(this); PointF delta{start_global_pos.x - event.global_position.x, start_global_pos.y - event.global_position.y}; auto coord_delta = pixel_pre_coord * (edit->orientation == Orientation::Horizontal ? delta.x : delta.y); edit->coord_start = start_coord_value + coord_delta; event.accept(); } void mouse_release_event(const Pointer_Event& event) override { if (!use_drag) return; if (event.button != Mouse_Button::Left) return; if (!dragging) return; dragging = false; event.accept(); } }; template void Axis::Builder_T::set(Axis* ret) { Abs_Axis::Builder_T::set(ret); Axis_Private* pd = ret->d(); Render_Edit_Lease edit(pd); Axis_Render_State* sc = edit.operator->(); PROP_RT(int, label_precision) PROP_RT(double, coord_start) PROP_RT(double, coord_length) if (sc->coord_length == 0.0) sc->coord_length = 1.0; pd->use_wheel = use_wheel; pd->use_drag = use_drag; } } // namespace renderive