11/// Main compositor orchestrating the GPU-accelerated desktop environment
2- use std:: sync:: Arc ;
2+ use std:: sync:: { Arc , Mutex } ;
33use std:: time:: { Duration , Instant } ;
4+ use std:: collections:: VecDeque ;
45use winit:: {
56 dpi:: PhysicalSize ,
67 event_loop:: EventLoop ,
@@ -12,13 +13,25 @@ use crate::{
1213 core:: Context ,
1314 renderer:: Renderer ,
1415 window:: { WindowManager , WindowId } ,
15- ui:: { UITree , Container , Button , Text , Rectangle , LayoutDirection , UIElement , LayoutConstraints } ,
16+ ui:: { UITree , Container , Button , Text , LayoutDirection , UIElement , LayoutConstraints , Dock , Wallpaper } ,
1617 events:: { EventDispatcher , Event , InputEvent , MouseButton , ButtonState , Modifiers } ,
1718 text:: TextRenderer ,
1819 assets:: AssetManager ,
1920 geometry:: { Rect , Size , Color } ,
2021} ;
2122
23+ /// Global app launch queue for communication between dock and compositor
24+ static APP_LAUNCH_QUEUE : std:: sync:: LazyLock < Arc < Mutex < VecDeque < String > > > > = std:: sync:: LazyLock :: new ( || {
25+ Arc :: new ( Mutex :: new ( VecDeque :: new ( ) ) )
26+ } ) ;
27+
28+ /// Queue an app to be launched
29+ pub fn queue_app_launch ( app_id : String ) {
30+ if let Ok ( mut queue) = APP_LAUNCH_QUEUE . lock ( ) {
31+ queue. push_back ( app_id) ;
32+ }
33+ }
34+
2235/// Configuration for the compositor
2336#[ derive( Debug , Clone ) ]
2437pub struct CompositorConfig {
@@ -311,95 +324,24 @@ impl Compositor {
311324 Ok ( ( ) )
312325 }
313326
314- /// Create macOS-style desktop UI with dock and proper layout
327+ /// Create macOS-style desktop UI with beautiful glassy dock and wallpaper
315328 fn create_desktop_ui ( & mut self ) {
316- // Create macOS-style dock at the bottom
317- let mut dock = Container :: new ( "dock" . to_string ( ) )
318- . with_direction ( LayoutDirection :: Horizontal ) ;
319-
320- // Dock constraints - centered, glass effect, proper macOS sizing
321- dock. layout_mut ( ) . constraints = LayoutConstraints {
322- preferred_size : Some ( Size :: new ( 400.0 , 68.0 ) ) , // macOS dock height
323- min_size : Size :: new ( 300.0 , 68.0 ) ,
324- max_size : Size :: new ( 600.0 , 68.0 ) ,
325- flex_grow : 0.0 ,
329+ // Create beautiful wallpaper with floating effects
330+ let mut wallpaper = Wallpaper :: new ( "wallpaper" . to_string ( ) ) ;
331+ wallpaper. layout_mut ( ) . constraints = LayoutConstraints {
332+ preferred_size : Some ( Size :: new ( self . context . size . width as f32 , self . context . size . height as f32 ) ) ,
333+ min_size : Size :: new ( 0.0 , 0.0 ) ,
334+ max_size : Size :: new ( f32:: INFINITY , f32:: INFINITY ) ,
335+ flex_grow : 1.0 ,
326336 flex_shrink : 0.0 ,
327337 aspect_ratio : None ,
328338 } ;
329339
330- // macOS-style dock background (translucent glass effect)
331- let mut dock_background = Rectangle :: new ( "dock_background" . to_string ( ) )
332- . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 0.8 ) ) // Dark translucent
333- . with_corner_radius ( 16.0 ) ; // Rounded corners like macOS
340+ // Create beautiful glassy dock with default apps
341+ let mut dock = Dock :: new ( "dock" . to_string ( ) ) ;
342+ dock. add_default_apps ( ) ;
334343
335- // Create dock app icons with proper macOS styling
336- let mut finder_icon = Button :: new ( "finder" . to_string ( ) , "📁" . to_string ( ) )
337- . with_colors (
338- Color :: new ( 0.2 , 0.2 , 0.2 , 0.9 ) , // Subtle background
339- Color :: new ( 0.3 , 0.3 , 0.3 , 0.9 ) , // Hover
340- Color :: new ( 0.4 , 0.4 , 0.4 , 0.9 ) , // Active
341- ) ;
342- finder_icon. layout_mut ( ) . constraints = LayoutConstraints {
343- preferred_size : Some ( Size :: new ( 52.0 , 52.0 ) ) , // macOS dock icon size
344- min_size : Size :: new ( 48.0 , 48.0 ) ,
345- max_size : Size :: new ( 64.0 , 64.0 ) ,
346- flex_grow : 0.0 ,
347- flex_shrink : 0.0 ,
348- aspect_ratio : Some ( 1.0 ) , // Square icons
349- } ;
350-
351- let mut safari_icon = Button :: new ( "safari" . to_string ( ) , "🌐" . to_string ( ) )
352- . with_colors (
353- Color :: new ( 0.2 , 0.2 , 0.2 , 0.9 ) ,
354- Color :: new ( 0.3 , 0.3 , 0.3 , 0.9 ) ,
355- Color :: new ( 0.4 , 0.4 , 0.4 , 0.9 ) ,
356- ) ;
357- safari_icon. layout_mut ( ) . constraints = LayoutConstraints {
358- preferred_size : Some ( Size :: new ( 52.0 , 52.0 ) ) ,
359- min_size : Size :: new ( 48.0 , 48.0 ) ,
360- max_size : Size :: new ( 64.0 , 64.0 ) ,
361- flex_grow : 0.0 ,
362- flex_shrink : 0.0 ,
363- aspect_ratio : Some ( 1.0 ) ,
364- } ;
365-
366- let mut terminal_icon = Button :: new ( "terminal" . to_string ( ) , "⚫" . to_string ( ) )
367- . with_colors (
368- Color :: new ( 0.2 , 0.2 , 0.2 , 0.9 ) ,
369- Color :: new ( 0.3 , 0.3 , 0.3 , 0.9 ) ,
370- Color :: new ( 0.4 , 0.4 , 0.4 , 0.9 ) ,
371- ) ;
372- terminal_icon. layout_mut ( ) . constraints = LayoutConstraints {
373- preferred_size : Some ( Size :: new ( 52.0 , 52.0 ) ) ,
374- min_size : Size :: new ( 48.0 , 48.0 ) ,
375- max_size : Size :: new ( 64.0 , 64.0 ) ,
376- flex_grow : 0.0 ,
377- flex_shrink : 0.0 ,
378- aspect_ratio : Some ( 1.0 ) ,
379- } ;
380-
381- let mut settings_icon = Button :: new ( "settings" . to_string ( ) , "⚙️" . to_string ( ) )
382- . with_colors (
383- Color :: new ( 0.2 , 0.2 , 0.2 , 0.9 ) ,
384- Color :: new ( 0.3 , 0.3 , 0.3 , 0.9 ) ,
385- Color :: new ( 0.4 , 0.4 , 0.4 , 0.9 ) ,
386- ) ;
387- settings_icon. layout_mut ( ) . constraints = LayoutConstraints {
388- preferred_size : Some ( Size :: new ( 52.0 , 52.0 ) ) ,
389- min_size : Size :: new ( 48.0 , 48.0 ) ,
390- max_size : Size :: new ( 64.0 , 64.0 ) ,
391- flex_grow : 0.0 ,
392- flex_shrink : 0.0 ,
393- aspect_ratio : Some ( 1.0 ) ,
394- } ;
395-
396- // Add icons to dock with proper spacing
397- dock. add_child ( Box :: new ( finder_icon) ) ;
398- dock. add_child ( Box :: new ( safari_icon) ) ;
399- dock. add_child ( Box :: new ( terminal_icon) ) ;
400- dock. add_child ( Box :: new ( settings_icon) ) ;
401-
402- // Create desktop container with stack layout
344+ // Create desktop container with stack layout for proper layering
403345 let mut desktop = Container :: new ( "desktop" . to_string ( ) )
404346 . with_direction ( LayoutDirection :: Stack ) ;
405347
@@ -412,22 +354,13 @@ impl Compositor {
412354 aspect_ratio : None ,
413355 } ;
414356
415- // macOS-style gradient wallpaper
416- let mut wallpaper = Rectangle :: new ( "wallpaper" . to_string ( ) )
417- . with_color ( Color :: from_hex ( "#4c1d95" ) . unwrap_or ( Color :: new ( 0.3 , 0.11 , 0.58 , 1.0 ) ) ) ; // macOS purple gradient
418- wallpaper. layout_mut ( ) . constraints = LayoutConstraints {
419- preferred_size : Some ( Size :: new ( self . context . size . width as f32 , self . context . size . height as f32 ) ) ,
420- min_size : Size :: new ( 0.0 , 0.0 ) ,
421- max_size : Size :: new ( f32:: INFINITY , f32:: INFINITY ) ,
422- flex_grow : 1.0 ,
423- flex_shrink : 0.0 ,
424- aspect_ratio : None ,
425- } ;
426-
357+ // Add wallpaper and dock - order matters for layering
427358 desktop. add_child ( Box :: new ( wallpaper) ) ;
428359 desktop. add_child ( Box :: new ( dock) ) ;
429360
430361 self . desktop_ui . set_root ( Box :: new ( desktop) ) ;
362+
363+ println ! ( "🖥️ Beautiful macOS-style desktop created with glassy dock!" ) ;
431364 }
432365
433366 /// Create a demo window with macOS-style design
@@ -455,7 +388,10 @@ impl Compositor {
455388 Color :: new ( 0.0 , 0.48 , 1.0 , 1.0 ) , // macOS blue
456389 Color :: new ( 0.0 , 0.42 , 0.9 , 1.0 ) , // Hover
457390 Color :: new ( 0.0 , 0.36 , 0.8 , 1.0 ) , // Active
458- ) ;
391+ )
392+ . on_click ( || {
393+ println ! ( "🚀 Demo: Launching Finder..." ) ;
394+ } ) ;
459395 button1. layout_mut ( ) . constraints = LayoutConstraints {
460396 preferred_size : Some ( Size :: new ( 140.0 , 32.0 ) ) ,
461397 min_size : Size :: new ( 100.0 , 28.0 ) ,
@@ -470,7 +406,10 @@ impl Compositor {
470406 Color :: new ( 0.55 , 0.55 , 0.55 , 1.0 ) , // macOS gray
471407 Color :: new ( 0.65 , 0.65 , 0.65 , 1.0 ) , // Hover
472408 Color :: new ( 0.45 , 0.45 , 0.45 , 1.0 ) , // Active
473- ) ;
409+ )
410+ . on_click ( || {
411+ println ! ( "🚀 Demo: Launching Terminal..." ) ;
412+ } ) ;
474413 button2. layout_mut ( ) . constraints = LayoutConstraints {
475414 preferred_size : Some ( Size :: new ( 140.0 , 32.0 ) ) ,
476415 min_size : Size :: new ( 100.0 , 28.0 ) ,
@@ -500,6 +439,173 @@ impl Compositor {
500439 self . demo_window_id = Some ( window_id) ;
501440 }
502441
442+ /// Create a new app window based on app ID
443+ fn create_app_window ( & mut self , app_id : & str ) {
444+ let ( title, content) = match app_id {
445+ "finder" => self . create_finder_window ( ) ,
446+ "terminal" => self . create_terminal_window ( ) ,
447+ "code" => self . create_code_editor_window ( ) ,
448+ "browser" => self . create_browser_window ( ) ,
449+ "calculator" => self . create_calculator_window ( ) ,
450+ "settings" => self . create_settings_window ( ) ,
451+ "music" => self . create_music_window ( ) ,
452+ "photos" => self . create_photos_window ( ) ,
453+ _ => ( "Unknown App" . to_string ( ) , Box :: new ( Text :: new ( "unknown" . to_string ( ) , "Unknown Application" . to_string ( ) ) ) as Box < dyn UIElement > ) ,
454+ } ;
455+
456+ let window_id = self . window_manager . create_window ( title, content) ;
457+ println ! ( "🚀 Launched {} (Window ID: {:?})" , app_id, window_id) ;
458+ }
459+
460+ /// Create Finder file manager window
461+ fn create_finder_window ( & self ) -> ( String , Box < dyn UIElement > ) {
462+ let mut content = Container :: new ( "finder_content" . to_string ( ) )
463+ . with_direction ( LayoutDirection :: Vertical ) ;
464+
465+ let title = Text :: new ( "finder_title" . to_string ( ) , "Finder" . to_string ( ) )
466+ . with_font_size ( 18.0 )
467+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
468+
469+ let file_list = Container :: new ( "file_list" . to_string ( ) )
470+ . with_direction ( LayoutDirection :: Vertical ) ;
471+
472+ content. add_child ( Box :: new ( title) ) ;
473+ content. add_child ( Box :: new ( file_list) ) ;
474+
475+ ( "Finder" . to_string ( ) , Box :: new ( content) )
476+ }
477+
478+ /// Create Terminal window
479+ fn create_terminal_window ( & self ) -> ( String , Box < dyn UIElement > ) {
480+ let mut content = Container :: new ( "terminal_content" . to_string ( ) )
481+ . with_direction ( LayoutDirection :: Vertical ) ;
482+
483+ let prompt = Text :: new ( "terminal_prompt" . to_string ( ) , "user@prisma:~$ " . to_string ( ) )
484+ . with_font_size ( 14.0 )
485+ . with_color ( Color :: new ( 0.0 , 1.0 , 0.0 , 1.0 ) ) ; // Green terminal text
486+
487+ content. add_child ( Box :: new ( prompt) ) ;
488+
489+ ( "Terminal" . to_string ( ) , Box :: new ( content) )
490+ }
491+
492+ /// Create Code Editor window
493+ fn create_code_editor_window ( & self ) -> ( String , Box < dyn UIElement > ) {
494+ let mut content = Container :: new ( "code_content" . to_string ( ) )
495+ . with_direction ( LayoutDirection :: Vertical ) ;
496+
497+ let code_text = Text :: new ( "code_text" . to_string ( ) , "// Welcome to PrismaUI Code Editor\n fn main() {\n println!(\" Hello, World!\" );\n }" . to_string ( ) )
498+ . with_font_size ( 12.0 )
499+ . with_color ( Color :: new ( 0.9 , 0.9 , 0.9 , 1.0 ) ) ;
500+
501+ content. add_child ( Box :: new ( code_text) ) ;
502+
503+ ( "Code Editor" . to_string ( ) , Box :: new ( content) )
504+ }
505+
506+ /// Create Browser window
507+ fn create_browser_window ( & self ) -> ( String , Box < dyn UIElement > ) {
508+ let mut content = Container :: new ( "browser_content" . to_string ( ) )
509+ . with_direction ( LayoutDirection :: Vertical ) ;
510+
511+ let address_bar = Text :: new ( "address_bar" . to_string ( ) , "https://prismaui.dev" . to_string ( ) )
512+ . with_font_size ( 14.0 )
513+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
514+
515+ let page_content = Text :: new ( "page_content" . to_string ( ) , "Welcome to PrismaUI Browser\n \n A GPU-accelerated web browser built with Rust." . to_string ( ) )
516+ . with_font_size ( 14.0 )
517+ . with_color ( Color :: new ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
518+
519+ content. add_child ( Box :: new ( address_bar) ) ;
520+ content. add_child ( Box :: new ( page_content) ) ;
521+
522+ ( "Safari" . to_string ( ) , Box :: new ( content) )
523+ }
524+
525+ /// Create Calculator window
526+ fn create_calculator_window ( & self ) -> ( String , Box < dyn UIElement > ) {
527+ let mut content = Container :: new ( "calculator_content" . to_string ( ) )
528+ . with_direction ( LayoutDirection :: Vertical ) ;
529+
530+ let display = Text :: new ( "calc_display" . to_string ( ) , "0" . to_string ( ) )
531+ . with_font_size ( 24.0 )
532+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
533+
534+ let buttons = Container :: new ( "calc_buttons" . to_string ( ) )
535+ . with_direction ( LayoutDirection :: Horizontal ) ;
536+
537+ content. add_child ( Box :: new ( display) ) ;
538+ content. add_child ( Box :: new ( buttons) ) ;
539+
540+ ( "Calculator" . to_string ( ) , Box :: new ( content) )
541+ }
542+
543+ /// Create Settings window
544+ fn create_settings_window ( & self ) -> ( String , Box < dyn UIElement > ) {
545+ let mut content = Container :: new ( "settings_content" . to_string ( ) )
546+ . with_direction ( LayoutDirection :: Vertical ) ;
547+
548+ let title = Text :: new ( "settings_title" . to_string ( ) , "System Preferences" . to_string ( ) )
549+ . with_font_size ( 18.0 )
550+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
551+
552+ let options = Text :: new ( "settings_options" . to_string ( ) , "• Display Settings\n • Audio Settings\n • Network Settings\n • Privacy Settings" . to_string ( ) )
553+ . with_font_size ( 14.0 )
554+ . with_color ( Color :: new ( 0.3 , 0.3 , 0.3 , 1.0 ) ) ;
555+
556+ content. add_child ( Box :: new ( title) ) ;
557+ content. add_child ( Box :: new ( options) ) ;
558+
559+ ( "System Preferences" . to_string ( ) , Box :: new ( content) )
560+ }
561+
562+ /// Create Music window
563+ fn create_music_window ( & self ) -> ( String , Box < dyn UIElement > ) {
564+ let mut content = Container :: new ( "music_content" . to_string ( ) )
565+ . with_direction ( LayoutDirection :: Vertical ) ;
566+
567+ let title = Text :: new ( "music_title" . to_string ( ) , "Music" . to_string ( ) )
568+ . with_font_size ( 18.0 )
569+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
570+
571+ let playlist = Text :: new ( "music_playlist" . to_string ( ) , "♪ Now Playing: Ambient Desktop Sounds\n ♪ Next: Coding Beats\n ♪ Queue: Lo-Fi Study Mix" . to_string ( ) )
572+ . with_font_size ( 14.0 )
573+ . with_color ( Color :: new ( 0.3 , 0.3 , 0.3 , 1.0 ) ) ;
574+
575+ content. add_child ( Box :: new ( title) ) ;
576+ content. add_child ( Box :: new ( playlist) ) ;
577+
578+ ( "Music" . to_string ( ) , Box :: new ( content) )
579+ }
580+
581+ /// Create Photos window
582+ fn create_photos_window ( & self ) -> ( String , Box < dyn UIElement > ) {
583+ let mut content = Container :: new ( "photos_content" . to_string ( ) )
584+ . with_direction ( LayoutDirection :: Vertical ) ;
585+
586+ let title = Text :: new ( "photos_title" . to_string ( ) , "Photos" . to_string ( ) )
587+ . with_font_size ( 18.0 )
588+ . with_color ( Color :: new ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
589+
590+ let gallery = Text :: new ( "photos_gallery" . to_string ( ) , "📷 My Photos (42 items)\n 📁 Screenshots\n 📁 Desktop Wallpapers\n 📁 GPU Renders" . to_string ( ) )
591+ . with_font_size ( 14.0 )
592+ . with_color ( Color :: new ( 0.3 , 0.3 , 0.3 , 1.0 ) ) ;
593+
594+ content. add_child ( Box :: new ( title) ) ;
595+ content. add_child ( Box :: new ( gallery) ) ;
596+
597+ ( "Photos" . to_string ( ) , Box :: new ( content) )
598+ }
599+
600+ /// Process queued app launches
601+ fn process_app_launches ( & mut self ) {
602+ if let Ok ( mut queue) = APP_LAUNCH_QUEUE . lock ( ) {
603+ while let Some ( app_id) = queue. pop_front ( ) {
604+ self . create_app_window ( & app_id) ;
605+ }
606+ }
607+ }
608+
503609 /// Handle window resize
504610 fn resize ( & mut self , new_size : PhysicalSize < u32 > ) {
505611 self . context . resize ( new_size) ;
@@ -526,6 +632,9 @@ impl Compositor {
526632 // Update window manager
527633 self . window_manager . update ( ) ;
528634
635+ // Process app launch queue
636+ self . process_app_launches ( ) ;
637+
529638 // Update text layouts for UI elements that need it
530639 // TODO: This should be more efficient, only updating dirty text
531640 // self.update_text_layouts();
0 commit comments