@@ -8,6 +8,7 @@ use caw_window_utils::{
88} ;
99use clap:: { Parser , Subcommand , ValueEnum } ;
1010use line_2d:: Coord ;
11+ use rgb_int:: Rgb24 ;
1112use sdl2:: {
1213 EventPump ,
1314 event:: { Event , WindowEvent } ,
@@ -27,10 +28,6 @@ pub enum OscilloscopeStyle {
2728 TimeDomainStereo ,
2829}
2930
30- impl PersistentData for OscilloscopeStyle {
31- const NAME : & ' static str = "oscilloscope_style" ;
32- }
33-
3431#[ derive( Parser ) ]
3532struct OscilloscopeCommand {
3633 #[ arg( long, default_value_t = 640 ) ]
@@ -108,6 +105,18 @@ struct Cli {
108105 title : String ,
109106}
110107
108+ #[ derive( Serialize , Deserialize , Clone , Copy , Debug ) ]
109+ struct OscilloscopeUiState {
110+ style : OscilloscopeStyle ,
111+ scale : f32 ,
112+ line_width : u32 ,
113+ alpha_scale : u8 ,
114+ }
115+
116+ impl PersistentData for OscilloscopeUiState {
117+ const NAME : & ' static str = "oscilloscope_ui" ;
118+ }
119+
111120#[ derive( Default ) ]
112121struct ScopeState {
113122 samples : VecDeque < ( f32 , f32 ) > ,
@@ -136,25 +145,42 @@ impl App {
136145
137146 fn run_oscilloscope (
138147 mut self ,
139- mut args : OscilloscopeCommand ,
148+ args : OscilloscopeCommand ,
140149 ) -> anyhow:: Result < ( ) > {
141150 self . canvas . window_mut ( ) . set_resizable ( true ) ;
142151 let mut viz_udp_client = oscilloscope:: Client :: new ( self . server ) ?;
143152 let mut scope_state = ScopeState :: default ( ) ;
144- if let Some ( style) = OscilloscopeStyle :: load_ ( & self . title ) {
145- args. style = style;
146- }
153+ let rgb = Rgb24 :: new ( args. red , args. green , args. blue ) ;
154+ let mut window_size = WindowSize {
155+ width : args. width ,
156+ height : args. height ,
157+ } ;
158+ let max_num_samples = args. max_num_samples ;
159+ let mut ui_state = {
160+ let args = args;
161+ if let Some ( ui_state) = OscilloscopeUiState :: load_ ( & self . title ) {
162+ ui_state
163+ } else {
164+ OscilloscopeUiState {
165+ style : args. style ,
166+ scale : args. scale ,
167+ line_width : args. line_width ,
168+ alpha_scale : args. alpha_scale ,
169+ }
170+ }
171+ } ;
147172 loop {
148173 for event in self . event_pump . poll_iter ( ) {
149174 Self :: handle_event_common ( event. clone ( ) , self . title . as_str ( ) ) ;
150175 match event {
151176 Event :: MouseWheel { y, .. } => {
152177 let ratio = 1.1 ;
153178 if y > 0 {
154- args . scale *= ratio;
179+ ui_state . scale *= ratio;
155180 } else if y < 0 {
156- args . scale /= ratio;
181+ ui_state . scale /= ratio;
157182 }
183+ ui_state. save_ ( & self . title ) ;
158184 }
159185 Event :: KeyDown {
160186 scancode : Some ( scancode) ,
@@ -167,43 +193,41 @@ impl App {
167193 Scancode :: Left => ( -1 , 0 ) ,
168194 Scancode :: Right => ( 1 , 0 ) ,
169195 Scancode :: Num1 => {
170- args. style = OscilloscopeStyle :: TimeDomain ;
171- args. style . save_ ( & self . title ) ;
196+ ui_state. style =
197+ OscilloscopeStyle :: TimeDomain ;
198+ ui_state. save_ ( & self . title ) ;
172199 continue ;
173200 }
174201 Scancode :: Num2 => {
175- args . style =
202+ ui_state . style =
176203 OscilloscopeStyle :: TimeDomainStereo ;
177- args . style . save_ ( & self . title ) ;
204+ ui_state . save_ ( & self . title ) ;
178205 continue ;
179206 }
180207 Scancode :: Num3 => {
181- args . style = OscilloscopeStyle :: Xy ;
182- args . style . save_ ( & self . title ) ;
208+ ui_state . style = OscilloscopeStyle :: Xy ;
209+ ui_state . save_ ( & self . title ) ;
183210 continue ;
184211 }
185212 _ => ( 0 , 0 ) ,
186213 } ;
187- args . line_width = ( ( args . line_width as i32 )
214+ ui_state . line_width = ( ( ui_state . line_width as i32 )
188215 + line_width_delta)
189216 . clamp ( 1 , 20 )
190217 as u32 ;
191- args . alpha_scale = ( args . alpha_scale as i32
218+ ui_state . alpha_scale = ( ui_state . alpha_scale as i32
192219 + alpha_scale_delta)
193220 . clamp ( 1 , 255 )
194221 as u8 ;
222+ ui_state. save_ ( & self . title ) ;
195223 }
196224 Event :: Window {
197- win_event : WindowEvent :: Resized ( width , height ) ,
225+ win_event : WindowEvent :: Resized ( new_width , new_height ) ,
198226 ..
199227 } => {
200- args. width = width as u32 ;
201- args. height = height as u32 ;
202- ( WindowSize {
203- width : args. width ,
204- height : args. height ,
205- } )
206- . save_ ( & self . title ) ;
228+ window_size. width = new_width as u32 ;
229+ window_size. height = new_height as u32 ;
230+ window_size. save_ ( & self . title ) ;
207231 }
208232 _ => ( ) ,
209233 }
@@ -212,17 +236,17 @@ impl App {
212236 for sample_pair in viz_udp_client. pairs ( ) {
213237 scope_state. samples . push_back ( sample_pair) ;
214238 }
215- while scope_state. samples . len ( ) > args . max_num_samples {
239+ while scope_state. samples . len ( ) > max_num_samples {
216240 scope_state. samples . pop_front ( ) ;
217241 }
218242 }
219243 self . canvas . set_draw_color ( Color :: RGB ( 0 , 0 , 0 ) ) ;
220244 self . canvas . clear ( ) ;
221245 let screen_size = Coord {
222- x : args . width as i32 ,
223- y : args . height as i32 ,
246+ x : window_size . width as i32 ,
247+ y : window_size . height as i32 ,
224248 } ;
225- match args . style {
249+ match ui_state . style {
226250 OscilloscopeStyle :: TimeDomain => {
227251 let num_samples_to_draw = screen_size. x as usize ;
228252 let sample_mean_iter = scope_state
@@ -232,14 +256,13 @@ impl App {
232256 . take ( num_samples_to_draw)
233257 . rev ( )
234258 . map ( |( left, right) | ( left + right) / 2.0 ) ;
235- self . canvas . set_draw_color ( Color :: RGBA (
236- args. red , args. green , args. blue , 255 ,
237- ) ) ;
259+ self . canvas
260+ . set_draw_color ( Color :: RGBA ( rgb. r , rgb. g , rgb. b , 255 ) ) ;
238261 let mut prev = None ;
239262 for ( x, sample) in sample_mean_iter. enumerate ( ) {
240263 let x = x as i32 ;
241264 let y = screen_size. y
242- - ( ( sample * args . scale ) as i32
265+ - ( ( sample * ui_state . scale ) as i32
243266 + ( screen_size. y / 2 ) ) ;
244267 let coord = Coord { x, y } ;
245268 if let Some ( prev) = prev {
@@ -249,8 +272,8 @@ impl App {
249272 let rect = Rect :: new (
250273 x,
251274 y,
252- args . line_width ,
253- args . line_width ,
275+ ui_state . line_width ,
276+ ui_state . line_width ,
254277 ) ;
255278 let _ = self . canvas . fill_rect ( rect) ;
256279 }
@@ -272,14 +295,13 @@ impl App {
272295 make_sample_pair_iter ( ) . map ( |( x, _) | x) ;
273296 let sample_right_iter =
274297 make_sample_pair_iter ( ) . map ( |( _, x) | x) ;
275- self . canvas . set_draw_color ( Color :: RGBA (
276- args. red , args. green , args. blue , 255 ,
277- ) ) ;
298+ self . canvas
299+ . set_draw_color ( Color :: RGBA ( rgb. r , rgb. g , rgb. b , 255 ) ) ;
278300 let mut prev = None ;
279301 for ( x, sample) in sample_left_iter. enumerate ( ) {
280302 let x = x as i32 ;
281303 let y = screen_size. y
282- - ( ( sample * args . scale ) as i32
304+ - ( ( sample * ui_state . scale ) as i32
283305 + ( screen_size. y / 3 ) ) ;
284306 let coord = Coord { x, y } ;
285307 if let Some ( prev) = prev {
@@ -289,8 +311,8 @@ impl App {
289311 let rect = Rect :: new (
290312 x,
291313 y,
292- args . line_width ,
293- args . line_width ,
314+ ui_state . line_width ,
315+ ui_state . line_width ,
294316 ) ;
295317 let _ = self . canvas . fill_rect ( rect) ;
296318 }
@@ -301,7 +323,7 @@ impl App {
301323 for ( x, sample) in sample_right_iter. enumerate ( ) {
302324 let x = x as i32 ;
303325 let y = screen_size. y
304- - ( ( sample * args . scale ) as i32
326+ - ( ( sample * ui_state . scale ) as i32
305327 + ( ( 2 * screen_size. y ) / 3 ) ) ;
306328 let coord = Coord { x, y } ;
307329 if let Some ( prev) = prev {
@@ -311,8 +333,8 @@ impl App {
311333 let rect = Rect :: new (
312334 x,
313335 y,
314- args . line_width ,
315- args . line_width ,
336+ ui_state . line_width ,
337+ ui_state . line_width ,
316338 ) ;
317339 let _ = self . canvas . fill_rect ( rect) ;
318340 }
@@ -324,8 +346,8 @@ impl App {
324346 let mut coord_iter =
325347 scope_state. samples . iter ( ) . map ( |( left, right) | {
326348 Coord {
327- x : ( left * args . scale ) as i32 ,
328- y : ( right * args . scale ) as i32 ,
349+ x : ( left * ui_state . scale ) as i32 ,
350+ y : ( right * ui_state . scale ) as i32 ,
329351 } + screen_size / 2
330352 } ) ;
331353 let mut prev = if let Some ( first) = coord_iter. next ( ) {
@@ -334,20 +356,20 @@ impl App {
334356 Coord :: new ( 0 , 0 )
335357 } ;
336358 for ( i, coord) in coord_iter. enumerate ( ) {
337- let alpha = ( ( args . alpha_scale as usize * i)
338- / args . max_num_samples )
359+ let alpha = ( ( ui_state . alpha_scale as usize * i)
360+ / max_num_samples)
339361 . min ( 255 ) as u8 ;
340362 self . canvas . set_draw_color ( Color :: RGBA (
341- args . red , args . green , args . blue , alpha,
363+ rgb . r , rgb . g , rgb . b , alpha,
342364 ) ) ;
343365 for Coord { x, y } in
344366 line_2d:: coords_between ( prev, coord)
345367 {
346368 let rect = Rect :: new (
347369 x,
348370 y,
349- args . line_width ,
350- args . line_width ,
371+ ui_state . line_width ,
372+ ui_state . line_width ,
351373 ) ;
352374 let _ = self . canvas . fill_rect ( rect) ;
353375 }
@@ -440,18 +462,13 @@ fn main() -> anyhow::Result<()> {
440462 Err ( _) => None ,
441463 Ok ( window_position) => Some ( window_position) ,
442464 } ;
443-
444465 let mut window_builder = match command {
445466 Command :: Oscilloscope ( _) => {
446- let wb = video_subsystem. window ( title. as_str ( ) , width, height) ;
447- wb
448- }
449- Command :: Blink ( _) => {
450- let mut wb = video_subsystem. window ( "" , width, height) ;
451- wb. always_on_top ( ) ;
452- wb
467+ video_subsystem. window ( title. as_str ( ) , width, height)
453468 }
469+ Command :: Blink ( _) => video_subsystem. window ( "" , width, height) ,
454470 } ;
471+ window_builder. always_on_top ( ) ;
455472 if let Some ( WindowPosition { x, y } ) = window_position {
456473 window_builder. position ( x, y) ;
457474 }
0 commit comments