custom_create_window/
custom_create_window.rs

1extern crate sdl2_mt;
2
3use sdl2_mt::event::Event::*;
4use sdl2_mt::event::WindowEvent;
5use sdl2_mt::keyboard::Keycode;
6use sdl2_mt::pixels::Color;
7
8use std::sync::mpsc;
9use std::thread::sleep;
10use std::time::Duration;
11
12fn main() {
13    //sdlh is "sdl handle"
14    let sdlh = sdl2_mt::init();
15
16    // create_window() allows you to run arbitrary code to create a window
17    // and then return the drawable Canvas from that window.
18    let window = sdlh.create_window(Box::new(|_sdl, video_subsystem| {
19        let canvas = video_subsystem.window("2D plot", 720, 720)
20            .position_centered()
21            .resizable()
22            .build()
23            .unwrap()
24            .into_canvas()
25            .software()
26            .build()
27            .unwrap();
28        
29        Some(canvas)
30    })).unwrap().unwrap();
31
32    sleep(Duration::from_millis(20));
33
34    // example of running arbitrary code on the UI thread
35    sdlh.run_on_ui_thread(Box::new(move |_sdl, windows| {
36        let canvas = windows.get_mut(&window).unwrap();
37        canvas.set_draw_color(Color::RGBA(128, 128, 128, 255));
38        canvas.clear();
39        canvas.present();
40    })).unwrap();
41
42    // create a channel we can use to easily break the loop
43    // from inside the closure.
44    let (tx, rx) = mpsc::channel();
45    while rx.try_recv().is_err() {
46        let tx = tx.clone();
47
48        // handle any new UI events that have happened
49        sdlh.handle_ui_events(Box::new(move |_sdl, windows, event| {
50            match event {
51                &Quit { .. } | &KeyDown { keycode: Some(Keycode::Escape), .. } => {
52                    // send a message to rx to cancel the loop
53                    tx.send(()).unwrap();
54                },
55
56                &KeyDown { keycode: Some(keycode), .. } => {
57                    use sdl2_mt::video::WindowPos::Positioned;
58                    let mut canvas = windows.get_mut(&window).unwrap();
59                    let (mut x, mut y) = canvas.window().position();
60                    match keycode {
61                        Keycode::Up    => y -= 5,
62                        Keycode::Down  => y += 5,
63                        Keycode::Left  => x -= 5,
64                        Keycode::Right => x += 5,
65                        _ => {}
66                    }
67                    canvas.window_mut().set_position(Positioned(x), Positioned(y));
68                },
69
70                &Window { win_event: WindowEvent::Resized(new_w, new_h), .. } => {
71                    let mut canvas = windows.get_mut(&window).unwrap();
72                    canvas.set_draw_color(Color::RGBA(128, (new_h % 256) as u8, (new_w % 256) as u8, 255));
73                    canvas.clear();
74                    canvas.present();
75                },
76                // false means "this event handler function did not handle this event"
77                // in a multithreaded application, you might have an event handler per window.
78                // this makes it easier to juggle events between handlers.
79                _ => return false
80            }
81            // true means we handled this event
82            true
83        })).unwrap();
84
85        // keep the CPU usage down
86        sleep(Duration::from_millis(15));
87    }
88
89    // not strictly necessary, since when the main thread exits in Rust the entire program is killed.
90    // the exit() function has the effect of terminating the SDL2 UI thread.
91    sdlh.exit().unwrap();
92}