1#[macro_use]
16extern crate gfx;
17
18extern crate gfx_window_glutin;
19extern crate gfx_device_gl;
20
21extern crate glutin;
22
23pub mod context;
24pub mod color;
25pub mod events;
26mod pipeline;
27
28pub use context::Context;
29
30
31use std::thread;
32use std::sync::mpsc;
33use std::ops::{Deref, DerefMut};
34
35pub struct Canvas {
36 ev_loop_handle: mpsc::Receiver<glutin::Event>,
37 ctx: context::Context,
38 listeners: events::ActiveListeners,
39}
40
41impl Canvas {
42
43 pub fn new() -> Self {
45 let ev_loop = glutin::EventsLoop::new();
46 let ctx = context::Context::new(800, 600, &ev_loop);
47
48 let (tx, ev_loop_handle) = mpsc::channel();
49
50 thread::spawn(move ||{
51 use glutin::ControlFlow;
52 let mut ev_loop = ev_loop;
53
54 ev_loop.run_forever(|e|{
55 match e {
56 _ => {
58 match tx.send(e) {
59 Ok(_) => ControlFlow::Continue,
60 Err(_) => ControlFlow::Break,
61 }
62 }
63 }
64 });
65 });
66
67 Canvas {
68 ev_loop_handle,
69 ctx,
70 listeners: events::ActiveListeners::new(),
71 }
72 }
73
74
75 pub fn on<E: events::Listener>(&mut self, handler: events::Callback<E>)
80 {
81 self.listeners.add::<E>(handler);
82 }
83
84 pub fn off<E: events::Listener>(&mut self) {
85 self.listeners.remove(E::event_id());
86 }
87
88 pub fn context_mut(&mut self) -> &mut context::Context {
90 &mut self.ctx
91 }
92
93 pub fn pause(&mut self) {
95 let mut running = true;
96
97 while running {
98 while let Ok(e) = self.ev_loop_handle.try_recv() {
99 use glutin::Event::WindowEvent;
100 use glutin::VirtualKeyCode;
101 use glutin::WindowEvent::*;
102
103 fn is_break(input: glutin::KeyboardInput) -> bool {
104 input.virtual_keycode == Some(VirtualKeyCode::Escape) ||
105 (input.state == glutin::ElementState::Pressed &&
106 input.virtual_keycode == Some(VirtualKeyCode::Space))
107 }
108
109 if let WindowEvent {window_id: _, event} = e {
110 match event {
111 Closed => running = false,
112 KeyboardInput { device_id: _, input } if is_break(input)
113 => running = false,
114 Resized(width, height) => {
115 self.ctx.window.update_views(gfx_window_glutin::update_views);
116 self.ctx.resize(width, height);
118
119 if let Some(cb) = self.listeners.resize.as_mut() {
120 cb(&mut self.ctx, (width, height));
121 }
122 },
123 MouseMoved { device_id: _, position } => {
124 if let Some(cb) = self.listeners.mouse_move.as_mut() {
125 cb(&mut self.ctx, position);
126 }
127 },
128 MouseInput { device_id: _, state, button } => {
129 if let Some(cb) = self.listeners.mouse_click.as_mut() {
130 cb(&mut self.ctx, (state, button));
131 }
132 },
133 MouseWheel { device_id: _, delta, phase: _ } => {
134 if let Some(cb) = self.listeners.mouse_scroll.as_mut() {
135 println!("delta: {:?}", delta);
136 if let glutin::MouseScrollDelta::LineDelta(_, y) = delta {
137 cb(&mut self.ctx, events::ScrollEvent::new(y));
138 }
139 }
140 },
141 KeyboardInput { device_id: _, input } => {
142 if let Some(cb) = self.listeners.key_press.as_mut() {
143 cb(&mut self.ctx, input);
144 }
145 },
146 _ => (),
147 }
148 }
149 }
150
151 self.ctx.window.draw();
152 ::std::thread::sleep(::std::time::Duration::from_millis(10));
153 }
154 }
155}
156
157impl Deref for Canvas {
158 type Target = context::Context;
159 fn deref(&self) -> &Self::Target {
160 &self.ctx
161 }
162}
163
164impl DerefMut for Canvas {
165 fn deref_mut(&mut self) -> &mut Self::Target {
166 &mut self.ctx
167 }
168}
169
170
171
172#[cfg(test)]
173mod tests {
174 #[test]
175 fn it_works() {
176 }
177}