84 lines
3.4 KiB
C++
84 lines
3.4 KiB
C++
#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<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
|