interactive/
interactive.rs

1use hotwire::{WireLine, WireParams, WireRenderer};
2use sdl3::event::Event;
3use sdl3::mouse::MouseButton;
4use sdl3::pixels::Color;
5use std::time::Instant;
6
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8    // Initialize SDL3
9    let sdl = sdl3::init()?;
10    let video = sdl.video()?;
11
12    // Create window
13    let window = video
14        .window("Hotwire - Interactive Example (Click and drag to draw)", 800, 600)
15        .position_centered()
16        .build()
17        .map_err(|e| e.to_string())?;
18
19    let canvas = window.into_canvas();
20    let mut renderer = WireRenderer::new(canvas);
21
22    let mut event_pump = sdl.event_pump()?;
23    let start_time = Instant::now();
24
25    let mut lines: Vec<WireLine> = Vec::new();
26    let mut drawing = false;
27    let mut current_start: Option<(f32, f32)> = None;
28
29    let params = WireParams {
30        sag: 70.0,
31        thickness: 3.5,
32        sway_speed: 1.2,
33        sway_amount: 5.0,
34        segment_density: 2.0,
35        color: Color::RGB(180, 180, 180),
36    };
37
38    'running: loop {
39        // Handle events
40        for event in event_pump.poll_iter() {
41            match event {
42                Event::Quit { .. } => break 'running,
43                Event::MouseButtonDown {
44                    mouse_btn: MouseButton::Left,
45                    x,
46                    y,
47                    ..
48                } => {
49                    drawing = true;
50                    current_start = Some((x as f32, y as f32));
51                }
52                Event::MouseButtonUp {
53                    mouse_btn: MouseButton::Left,
54                    x,
55                    y,
56                    ..
57                } => {
58                    if drawing {
59                        if let Some((start_x, start_y)) = current_start {
60                            // Create a new wire line
61                            let line = WireLine::new(
62                                start_x,
63                                start_y,
64                                x as f32,
65                                y as f32,
66                                params,
67                            );
68                            lines.push(line);
69                        }
70                        drawing = false;
71                        current_start = None;
72                    }
73                }
74                Event::KeyDown { .. } => {
75                    // Clear all lines on any key press
76                    lines.clear();
77                }
78                _ => {}
79            }
80        }
81
82        // Get elapsed time in seconds
83        let time = start_time.elapsed().as_secs_f32();
84
85        // Clear canvas
86        renderer.canvas_mut().set_draw_color(Color::RGB(20, 20, 30));
87        renderer.canvas_mut().clear();
88
89        // Render all completed wire lines
90        for line in &lines {
91            renderer.render(line, time)?;
92        }
93
94        // If currently drawing, show a preview line
95        if drawing {
96            if let Some((start_x, start_y)) = current_start {
97                let mouse_state = event_pump.mouse_state();
98                let preview_line = WireLine::new(
99                    start_x,
100                    start_y,
101                    mouse_state.x() as f32,
102                    mouse_state.y() as f32,
103                    params,
104                );
105                renderer.render(&preview_line, time)?;
106            }
107        }
108
109        // Present
110        renderer.present();
111
112        // Small delay
113        std::thread::sleep(std::time::Duration::from_millis(16));
114    }
115
116    Ok(())
117}