11// Copyright 2025 System76 <info@system76.com>
22// SPDX-License-Identifier: GPL-3.0-only
33
4- use cosmic:: { Apply , widget} ;
4+ use super :: model;
5+ use cosmic:: iced:: futures;
6+ use cosmic:: { Apply , iced, widget} ;
7+ use cosmic_settings_audio_client:: { self as audio_client, CosmicAudioProxy } ;
58use cosmic_settings_page:: { self as page, Section , section} ;
6- use cosmic_settings_sound_subscription :: { self as subscription } ;
9+ use futures :: executor :: block_on ;
710use slotmap:: SlotMap ;
11+ use std:: cell:: RefCell ;
12+ use std:: rc:: Rc ;
13+ use std:: sync:: Arc ;
814
915#[ derive( Clone , Debug ) ]
10- pub enum Message { }
16+ pub enum Message {
17+ /// Update for the model.
18+ Model ( cosmic_settings_sound:: Message ) ,
19+ /// Set the profile of a sound device.
20+ SetProfile ( u32 , u32 ) ,
21+ /// Surface Action
22+ Surface ( cosmic:: surface:: Action ) ,
23+ }
1124
1225impl From < Message > for crate :: pages:: Message {
1326 fn from ( message : Message ) -> Self {
@@ -24,6 +37,8 @@ impl From<Message> for crate::Message {
2437#[ derive( Default ) ]
2538pub struct Page {
2639 entity : page:: Entity ,
40+ model : model:: Model ,
41+ client : Option < Rc < RefCell < audio_client:: Client > > > ,
2742}
2843
2944impl page:: AutoBind < crate :: pages:: Message > for Page { }
@@ -41,55 +56,83 @@ impl page::Page<crate::pages::Message> for Page {
4156 Some ( vec ! [ sections. insert( view( ) ) ] )
4257 }
4358
44- fn on_leave ( & mut self ) -> cosmic:: Task < crate :: pages:: Message > {
45- cosmic:: Task :: done ( crate :: pages:: Message :: Sound ( super :: Message :: Reload ) )
46- }
47-
4859 fn set_id ( & mut self , entity : cosmic_settings_page:: Entity ) {
4960 self . entity = entity;
5061 }
5162
52- fn subscription (
53- & self ,
54- _core : & cosmic:: Core ,
55- ) -> cosmic:: iced:: Subscription < crate :: pages:: Message > {
56- cosmic:: iced:: Subscription :: run ( subscription:: watch)
57- . map ( |message| super :: Message :: Subscription ( message) . into ( ) )
63+ fn on_leave ( & mut self ) -> cosmic:: Task < crate :: pages:: Message > {
64+ * self = Page {
65+ entity : self . entity ,
66+ ..Page :: default ( )
67+ } ;
68+ cosmic:: Task :: none ( )
69+ }
70+
71+ fn subscription ( & self , _core : & cosmic:: Core ) -> iced:: Subscription < crate :: pages:: Message > {
72+ iced:: Subscription :: run ( || {
73+ iced:: stream:: channel (
74+ 1 ,
75+ move |emitter : futures:: channel:: mpsc:: Sender < crate :: pages:: Message > | async move {
76+ cosmic_settings_sound:: subscribe ( emitter, |m| Message :: Model ( m) . into ( ) ) . await
77+ } ,
78+ )
79+ } )
5880 }
5981}
6082
6183impl Page {
62- pub fn update ( & mut self , _message : Message ) -> cosmic:: Task < crate :: app:: Message > {
84+ pub fn update ( & mut self , message : Message ) -> cosmic:: Task < crate :: app:: Message > {
85+ match message {
86+ Message :: Model ( cosmic_settings_sound:: Message :: Subscription ( message) ) => {
87+ self . model . update ( message) ;
88+ }
89+
90+ Message :: Model ( cosmic_settings_sound:: Message :: Client ( client) ) => {
91+ if let Some ( client) = Arc :: into_inner ( client) {
92+ self . client = Some ( Rc :: new ( RefCell :: new ( client) ) ) ;
93+ self . model = model:: Model {
94+ text : model:: Text {
95+ hd_audio : fl ! ( "sound-hd-audio" ) ,
96+ usb_audio : fl ! ( "sound-usb-audio" ) ,
97+ } ,
98+ ..model:: Model :: default ( )
99+ } ;
100+ }
101+ }
102+
103+ Message :: Surface ( a) => return cosmic:: task:: message ( crate :: app:: Message :: Surface ( a) ) ,
104+
105+ Message :: SetProfile ( id, index) => {
106+ if let Some ( client) = self . client . clone ( ) {
107+ block_on ( async move {
108+ _ = client. borrow_mut ( ) . conn . set_profile ( id, index, true ) . await ;
109+ } ) ;
110+ }
111+ }
112+ }
113+
63114 cosmic:: Task :: none ( )
64115 }
65116}
66117
67118pub fn view ( ) -> Section < crate :: pages:: Message > {
68- Section :: default ( ) . view :: < Page > ( move |binder, _page, _section| {
69- let sound_page_id = binder. find_page_by_id ( "sound" ) . unwrap ( ) . 0 ;
70- let sound_page = binder. page [ sound_page_id]
71- . downcast_ref :: < super :: Page > ( )
72- . unwrap ( ) ;
73-
74- let devices = sound_page
75- . model
76- . device_profile_dropdowns
77- . iter ( )
78- . cloned ( )
79- . map ( |( device_id, name, active_profile, indexes, descriptions) | {
119+ Section :: default ( ) . view :: < Page > ( move |_, page, _section| {
120+ let devices = page. model . device_profile_dropdowns . iter ( ) . cloned ( ) . map (
121+ |( device_id, name, active_profile, indexes, descriptions) | {
80122 let dropdown = widget:: dropdown:: popup_dropdown (
81123 descriptions,
82124 active_profile,
83- move |id| super :: Message :: SetProfile ( device_id, indexes[ id] ) ,
125+ move |id| Message :: SetProfile ( device_id, indexes[ id] ) ,
84126 cosmic:: iced:: window:: Id :: RESERVED ,
85- super :: Message :: Surface ,
127+ Message :: Surface ,
86128 crate :: Message :: from,
87129 )
88130 . apply ( cosmic:: Element :: from)
89131 . map ( crate :: pages:: Message :: from) ;
90132
91133 widget:: settings:: item:: builder ( name) . control ( dropdown)
92- } ) ;
134+ } ,
135+ ) ;
93136
94137 widget:: settings:: section ( ) . extend ( devices) . into ( )
95138 } )
0 commit comments