Files
Renderive/render_2D/render_2D/axis/Numeric_Axis.cpp
T
2026-08-13 16:48:35 +08:00

84 lines
3.4 KiB
C++

#include "Numeric_Axis.h"
namespace renderive::detail {
Axis_Control::Axis_Control(const Axis_Properties& properties)
: Axis_State_Strategy(properties) {}
void Axis_Control::handle_event(const Event& event) {
if (event.type == Event_Type::Wheel && get<&Axis_Properties::wheel>()) {
const auto& wheel = static_cast<const Wheel_Event&>(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<const Pointer_Event&>(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<const Pointer_Event&>(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<double>(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