@@ -15,27 +15,25 @@ use libremarkable::ui_extensions::element::UIConstraintRefresh;
1515use libremarkable:: ui_extensions:: element:: UIElement ;
1616use libremarkable:: ui_extensions:: element:: UIElementWrapper ;
1717use log:: { debug, error, info} ;
18+ use marauder:: drawings;
1819use marauder:: modes:: draw:: DrawMode ;
20+ use marauder:: proto:: whiteboard:: whiteboard_client:: WhiteboardClient ;
21+ use marauder:: proto:: whiteboard:: { drawing, event} ;
22+ use marauder:: proto:: whiteboard:: { Drawing , Event } ;
23+ use marauder:: proto:: whiteboard:: { RecvEventsReq , SendEventReq } ;
1924use serde:: Deserialize ;
2025use std:: collections:: VecDeque ;
26+ use std:: convert:: TryInto ;
2127use std:: process:: Command ;
22- use std:: sync:: atomic:: AtomicBool ;
2328use std:: sync:: atomic:: Ordering ;
29+ use std:: sync:: atomic:: { AtomicBool , AtomicU32 } ;
2430use std:: sync:: Mutex ;
2531use std:: time:: Duration ;
2632use tokio:: time:: delay_for;
2733use tonic:: transport:: Channel ;
2834use tonic:: transport:: Endpoint ;
2935use tonic:: Request ;
3036use uuid:: Uuid ;
31- use whiteboard:: whiteboard_client:: WhiteboardClient ;
32- use whiteboard:: { drawing, event} ;
33- use whiteboard:: { Drawing , Event } ;
34- use whiteboard:: { RecvEventsReq , SendEventReq } ;
35-
36- pub mod whiteboard {
37- tonic:: include_proto!( "hypercard.whiteboard" ) ;
38- }
3937
4038const USAGE : & str = "
4139reMarkable whiteboard HyperCard.
@@ -65,13 +63,14 @@ struct Ctx {
6563}
6664
6765const CANVAS_REGION : mxcfb_rect = mxcfb_rect {
68- top : 720 ,
66+ top : 2 + 70 ,
6967 left : 0 ,
70- height : 1080 + 50 , //1850? 1900? !1872
68+ height : 1900 ,
7169 width : 1404 ,
7270} ;
7371
7472lazy_static ! {
73+ static ref PEOPLE_COUNT : AtomicU32 = AtomicU32 :: new( 0 ) ;
7574 static ref UNPRESS_OBSERVED : AtomicBool = AtomicBool :: new( false ) ;
7675 static ref WACOM_IN_RANGE : AtomicBool = AtomicBool :: new( false ) ;
7776 static ref WACOM_HISTORY : Mutex <VecDeque <( cgmath:: Point2 <f32 >, i32 ) >> =
@@ -80,6 +79,9 @@ lazy_static! {
8079 static ref TX : Mutex <Option <std:: sync:: mpsc:: Sender <Drawing >>> = Mutex :: new( None ) ;
8180}
8281
82+ const DRAWING_PACE : Duration = Duration :: from_millis ( 2 ) ;
83+ const INTER_DRAWING_PACE : Duration = Duration :: from_millis ( 8 ) ;
84+
8385#[ tokio:: main]
8486async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
8587 env_logger:: init ( ) ;
@@ -112,14 +114,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
112114 inner : UIElement :: Region {
113115 size : CANVAS_REGION . size ( ) . cast ( ) . unwrap ( ) + cgmath:: vec2 ( 1 , 3 ) ,
114116 border_px : 2 ,
115- border_color : color:: BLACK ,
117+ border_color : color:: WHITE ,
116118 } ,
117119 ..Default :: default ( )
118120 } ,
119121 ) ;
120122
121123 app. draw_elements ( ) ;
122124
125+ let appref0 = app. upgrade_ref ( ) ;
126+ tokio:: spawn ( async move {
127+ paint_mouldings ( appref0) . await ;
128+ } ) ;
129+
123130 let host = args. clone ( ) . flag_host ;
124131 info ! ( "[main] connecting to {:?}..." , host) ;
125132 let ch = Endpoint :: from_shared ( host) . unwrap ( ) . connect ( ) . await ?;
@@ -356,6 +363,15 @@ fn on_btn(app: &mut ApplicationContext, input: gpio::GPIOEvent) {
356363 gpio:: PhysicalButton :: MIDDLE | gpio:: PhysicalButton :: LEFT => {
357364 app. clear ( btn == gpio:: PhysicalButton :: MIDDLE ) ;
358365 app. draw_elements ( ) ;
366+
367+ let appref = app. upgrade_ref ( ) ;
368+ // TODO: make libremarkable async
369+ tokio:: task:: spawn_blocking ( move || {
370+ let rt_handle = tokio:: runtime:: Handle :: current ( ) ;
371+ rt_handle. block_on ( async move {
372+ paint_mouldings ( appref) . await ;
373+ } ) ;
374+ } ) ;
359375 }
360376 gpio:: PhysicalButton :: POWER => {
361377 Command :: new ( "systemctl" )
@@ -403,17 +419,20 @@ async fn loop_recv(app: &mut ApplicationContext<'_>, ch: Channel, ctx: Ctx) {
403419 paint ( app, drawing) . await ;
404420 info ! ( "[loop_recv] painted" ) ;
405421 }
422+ Some ( event:: Event :: UsersInTheRoom ( c) ) => {
423+ let old = PEOPLE_COUNT . swap ( c, Ordering :: Relaxed ) ;
424+ repaint_people_counter ( app, old, c) . await ;
425+ info ! ( "[loop_recv] room {:?} has {:?} users" , event. in_room_id, c) ;
426+ }
406427 Some ( event:: Event :: UserJoinedTheRoom ( _) ) => {
407- info ! (
408- "[loop_recv] user {:?} joined room {:?}" ,
409- event. by_user_id, event. in_room_id
410- ) ;
428+ info ! ( "[loop_recv] user {:?} joined room" , event. by_user_id) ;
429+ let c = PEOPLE_COUNT . fetch_add ( 1 , Ordering :: Relaxed ) ;
430+ repaint_people_counter ( app, c, c + 1 ) . await ;
411431 }
412432 Some ( event:: Event :: UserLeftTheRoom ( _) ) => {
413- info ! (
414- "[loop_recv] user {:?} left room {:?}" ,
415- event. by_user_id, event. in_room_id
416- ) ;
433+ info ! ( "[loop_recv] user {:?} left room" , event. by_user_id) ;
434+ let c = PEOPLE_COUNT . fetch_sub ( 1 , Ordering :: Relaxed ) ;
435+ repaint_people_counter ( app, c, c - 1 ) . await ;
417436 }
418437 } ,
419438 } ;
@@ -428,7 +447,7 @@ async fn paint(app: &mut ApplicationContext<'_>, drawing: Drawing) {
428447 let ( xs, ys, ps, ws) = ( drawing. xs , drawing. ys , drawing. pressures , drawing. widths ) ;
429448 for i in 0 ..( xs. len ( ) - 2 ) {
430449 if i != 0 {
431- delay_for ( Duration :: from_millis ( 2 ) ) . await ;
450+ delay_for ( DRAWING_PACE ) . await ;
432451 }
433452 let points: Vec < ( cgmath:: Point2 < f32 > , i32 , u32 ) > = vec ! [
434453 // start
@@ -511,3 +530,90 @@ async fn send_drawing(client: &mut WhiteboardClient<Channel>, drawing: Drawing,
511530 . map_err ( |e| error ! ( "!Send: {:?}" , e) ) ;
512531 info ! ( "REP = {:?}" , rep) ;
513532}
533+
534+ fn drawing_for_people_counter ( c : u32 , color : drawing:: Color ) -> Vec < Drawing > {
535+ match c {
536+ 0 => drawings:: top_right_0:: f ( color) ,
537+ 1 => drawings:: top_right_1:: f ( color) ,
538+ 2 => drawings:: top_right_2:: f ( color) ,
539+ 3 => drawings:: top_right_3:: f ( color) ,
540+ 4 => drawings:: top_right_4:: f ( color) ,
541+ 5 => drawings:: top_right_5:: f ( color) ,
542+ 6 => drawings:: top_right_6:: f ( color) ,
543+ 7 => drawings:: top_right_7:: f ( color) ,
544+ 8 => drawings:: top_right_8:: f ( color) ,
545+ 9 => drawings:: top_right_9:: f ( color) ,
546+ _ => {
547+ info ! ( "drawing PEOPLE_COUNT of 9 even though it's at {:?}" , c) ;
548+ drawings:: top_right_9:: f ( color)
549+ }
550+ }
551+ }
552+
553+ async fn paint_vec ( app : & mut ApplicationContext < ' _ > , xs : Vec < Drawing > ) {
554+ let mut i = 0 ;
555+ let len = xs. len ( ) ;
556+ for x in xs {
557+ if i != 0 && i != len {
558+ delay_for ( INTER_DRAWING_PACE ) . await ;
559+ }
560+ paint ( app, x) . await ;
561+ i += 1 ;
562+ }
563+ }
564+
565+ async fn repaint_people_counter ( app : & mut ApplicationContext < ' _ > , o : u32 , n : u32 ) {
566+ paint_vec ( app, drawing_for_people_counter ( o, drawing:: Color :: White ) ) . await ;
567+ paint_vec ( app, drawing_for_people_counter ( n, drawing:: Color :: Black ) ) . await ;
568+ }
569+
570+ async fn paint_mouldings ( app : & mut ApplicationContext < ' _ > ) {
571+ let c = drawing:: Color :: Black ;
572+ let appref0 = app. upgrade_ref ( ) ;
573+ debug ! ( "[paint_mouldings] drawing UI..." ) ;
574+ tokio:: spawn ( async move {
575+ let appref1 = appref0. upgrade_ref ( ) ;
576+ tokio:: spawn ( async move {
577+ paint ( appref1, top_bar ( c) ) . await ;
578+
579+ delay_for ( INTER_DRAWING_PACE ) . await ;
580+ // TODO: tools
581+ // let appref2 = appref1.upgrade_ref();
582+ // tokio::spawn(async move {
583+ // paint_vec(appref2, drawings::top_left_help::f(c)).await;
584+ // });
585+ // let appref3 = appref1.upgrade_ref();
586+ // tokio::spawn(async move {
587+ // paint_vec(appref3, drawings::top_left_white_empty_square::f(c)).await;
588+ // });
589+ // let appref4 = appref1.upgrade_ref();
590+ // tokio::spawn(async move {
591+ // paint_vec(appref4, drawings::top_left_x3::f(c)).await;
592+ // });
593+ let count = PEOPLE_COUNT . load ( Ordering :: Relaxed ) ;
594+ let appref5 = appref1. upgrade_ref ( ) ;
595+ tokio:: spawn ( async move {
596+ paint_vec ( appref5, drawing_for_people_counter ( count, c) ) . await ;
597+ } ) ;
598+ } ) ;
599+ delay_for ( INTER_DRAWING_PACE ) . await ;
600+ paint_vec ( appref0, drawings:: title_whiteboard:: f ( c) ) . await ;
601+ } ) ;
602+ debug ! ( "[paint_mouldings] drawing UI... Done." ) ;
603+ }
604+
605+ fn top_bar ( c : drawing:: Color ) -> Drawing {
606+ let ( start, end) : ( usize , usize ) = ( 1 , CANVAS_REGION . width . try_into ( ) . unwrap ( ) ) ;
607+ let count = ( end - start + 1 ) / 2 ;
608+ Drawing {
609+ xs : ( start..end)
610+ . into_iter ( )
611+ . step_by ( 2 )
612+ . map ( |x| x as f32 )
613+ . collect ( ) ,
614+ ys : vec ! [ 70.444 ; count] ,
615+ pressures : vec ! [ 3992 ; count] ,
616+ widths : vec ! [ 2 ; count] ,
617+ color : c as i32 ,
618+ }
619+ }
0 commit comments