fission_core/input/
slider.rs1use super::{ControllerContext, InputController};
2use crate::event::{InputEvent, PointerEvent};
3use crate::{ActionEnvelope, ActionId};
4use fission_ir::{op::Op, semantics::Role, NodeId};
5use serde_json;
6
7pub struct SliderController;
8
9impl InputController for SliderController {
10 fn handle_event(&mut self, ctx: &mut ControllerContext, event: &InputEvent) -> bool {
11 match event {
12 InputEvent::Pointer(PointerEvent::Down { point, .. }) => {
13 if let Some(hit_id) = crate::hit_test::hit_test_with_scroll(ctx.ir, ctx.layout, ctx.scroll, *point) {
14 let mut current_id = Some(hit_id);
15 while let Some(node_id) = current_id {
16 if let Some(node) = ctx.ir.nodes.get(&node_id) {
17 if let Op::Semantics(sem) = &node.op {
18 if sem.role == Role::Slider {
19 ctx.interaction.set_focused(Some(node_id));
20 ctx.interaction.set_pressed(node_id, true);
21
22 self.update_value(ctx, node_id, point.x);
23 return true;
24 }
25 }
26 current_id = node.parent;
27 } else { break; }
28 }
29 }
30 }
31 InputEvent::Pointer(PointerEvent::Move { point }) => {
32 if let Some(focused_id) = ctx.interaction.focused {
33 if ctx.interaction.is_pressed(focused_id) {
34 if let Some(node) = ctx.ir.nodes.get(&focused_id) {
35 if let Op::Semantics(sem) = &node.op {
36 if sem.role == Role::Slider {
37 self.update_value(ctx, focused_id, point.x);
38 return true;
39 }
40 }
41 }
42 }
43 }
44 }
45 _ => {}
46 }
47 false
48 }
49}
50
51impl SliderController {
52 fn update_value(&self, ctx: &mut ControllerContext, node_id: NodeId, point_x: f32) {
53 if let Some(geom) = ctx.layout.get_node_geometry(node_id) {
54 if let Some(node) = ctx.ir.nodes.get(&node_id) {
55 if let Op::Semantics(sem) = &node.op {
56 let min = sem.min_value.unwrap_or(0.0);
57 let max = sem.max_value.unwrap_or(1.0);
58
59 let width = geom.rect.width();
64 if width > 0.0 {
65 let local_x = point_x - geom.rect.x();
66 let t = (local_x / width).clamp(0.0, 1.0);
67 let new_val = min + t * (max - min);
68
69 if let Some(entry) = sem.actions.entries.first() {
70 let payload = serde_json::to_vec(&new_val).unwrap();
71 let envelope = ActionEnvelope {
72 id: ActionId::from_u128(entry.action_id),
73 payload,
74 };
75 ctx.dispatched_actions.push((node_id, envelope, crate::ActionInput::None));
76 }
77 }
78 }
79 }
80 }
81 }
82}