@@ -64,7 +64,7 @@ impl GameOfLife {
6464 match message {
6565 Message :: Grid ( message, version) => {
6666 if version == self . version {
67- self . grid . update ( message) ;
67+ return self . grid . update ( message) . discard ( ) ;
6868 }
6969 }
7070 Message :: Tick | Message :: Next => {
@@ -195,6 +195,9 @@ mod grid {
195195 use iced:: widget:: canvas;
196196 use iced:: widget:: canvas:: event:: { self , Event } ;
197197 use iced:: widget:: canvas:: { Cache , Canvas , Frame , Geometry , Path , Text } ;
198+ use iced:: window;
199+ use iced:: window:: CursorGrab ;
200+ use iced:: Task ;
198201 use iced:: {
199202 Color , Element , Fill , Point , Rectangle , Renderer , Size , Theme , Vector ,
200203 } ;
@@ -219,6 +222,7 @@ mod grid {
219222 pub enum Message {
220223 Populate ( Cell ) ,
221224 Unpopulate ( Cell ) ,
225+ Panning ( bool ) ,
222226 Translated ( Vector ) ,
223227 Scaled ( f32 , Option < Vector > ) ,
224228 Ticked {
@@ -282,7 +286,7 @@ mod grid {
282286 } )
283287 }
284288
285- pub fn update ( & mut self , message : Message ) {
289+ pub fn update ( & mut self , message : Message ) -> Task < Message > {
286290 match message {
287291 Message :: Populate ( cell) => {
288292 self . state . populate ( cell) ;
@@ -296,6 +300,22 @@ mod grid {
296300
297301 self . preset = Preset :: Custom ;
298302 }
303+ Message :: Panning ( panning) => {
304+ #[ cfg( any( target_os = "linux" , target_os = "windows" ) ) ]
305+ let cursor_grab = CursorGrab :: Confined ;
306+ #[ cfg( any( target_os = "macos" , target_arch = "wasm32" ) ) ]
307+ let cursor_grab = CursorGrab :: Locked ;
308+ return window:: get_oldest ( ) . then ( move |id| {
309+ window:: cursor_grab (
310+ id. expect ( "there is only a single window so it must be the oldest" ) ,
311+ if panning {
312+ cursor_grab
313+ } else {
314+ CursorGrab :: None
315+ } ,
316+ )
317+ } ) ;
318+ }
299319 Message :: Translated ( translation) => {
300320 self . translation = translation;
301321
@@ -327,6 +347,8 @@ mod grid {
327347 dbg ! ( error) ;
328348 }
329349 }
350+
351+ Task :: none ( )
330352 }
331353
332354 pub fn view ( & self ) -> Element < Message > {
@@ -379,13 +401,17 @@ mod grid {
379401
380402 fn update (
381403 & self ,
382- interaction : & mut Interaction ,
404+ mut interaction : & mut Interaction ,
383405 event : Event ,
384406 bounds : Rectangle ,
385407 cursor : mouse:: Cursor ,
386408 ) -> ( event:: Status , Option < Message > ) {
387409 if let Event :: Mouse ( mouse:: Event :: ButtonReleased ( _) ) = event {
388410 * interaction = Interaction :: None ;
411+ return (
412+ event:: Status :: Captured ,
413+ Some ( Message :: Panning ( false ) ) ,
414+ ) ;
389415 }
390416
391417 let Some ( cursor_position) = cursor. position_in ( bounds) else {
@@ -430,36 +456,35 @@ mod grid {
430456 mouse:: Button :: Right => {
431457 * interaction = Interaction :: Panning {
432458 translation : self . translation ,
433- start : cursor_position,
434459 } ;
435460
436- None
461+ Some ( Message :: Panning ( true ) )
437462 }
438463 _ => None ,
439464 } ;
440465
441466 ( event:: Status :: Captured , message)
442467 }
443- mouse:: Event :: CursorMoved { .. } => {
444- let message = match * interaction {
445- Interaction :: Drawing => populate,
446- Interaction :: Erasing => unpopulate,
447- Interaction :: Panning { translation, start } => {
448- Some ( Message :: Translated (
449- translation
450- + ( cursor_position - start)
451- * ( 1.0 / self . scaling ) ,
452- ) )
468+ mouse:: Event :: CursorMoved { .. } => match * interaction {
469+ Interaction :: Drawing => {
470+ ( event:: Status :: Captured , populate)
471+ }
472+ Interaction :: Erasing => {
473+ ( event:: Status :: Captured , unpopulate)
474+ }
475+ _ => ( event:: Status :: Ignored , None ) ,
476+ } ,
477+ mouse:: Event :: MouseMotion { delta } => {
478+ match & mut interaction {
479+ Interaction :: Panning { translation } => {
480+ * translation += delta / self . scaling ;
481+ (
482+ event:: Status :: Captured ,
483+ Some ( Message :: Translated ( * translation) ) ,
484+ )
453485 }
454- Interaction :: None => None ,
455- } ;
456-
457- let event_status = match interaction {
458- Interaction :: None => event:: Status :: Ignored ,
459- _ => event:: Status :: Captured ,
460- } ;
461-
462- ( event_status, message)
486+ _ => ( event:: Status :: Ignored , None ) ,
487+ }
463488 }
464489 mouse:: Event :: WheelScrolled { delta } => match delta {
465490 mouse:: ScrollDelta :: Lines { y, .. }
@@ -881,7 +906,7 @@ mod grid {
881906 None ,
882907 Drawing ,
883908 Erasing ,
884- Panning { translation : Vector , start : Point } ,
909+ Panning { translation : Vector } ,
885910 }
886911
887912 impl Default for Interaction {
0 commit comments