@@ -8,6 +8,7 @@ use caw_window_utils::{
8
8
} ;
9
9
use clap:: { Parser , Subcommand , ValueEnum } ;
10
10
use line_2d:: Coord ;
11
+ use rgb_int:: Rgb24 ;
11
12
use sdl2:: {
12
13
EventPump ,
13
14
event:: { Event , WindowEvent } ,
@@ -27,10 +28,6 @@ pub enum OscilloscopeStyle {
27
28
TimeDomainStereo ,
28
29
}
29
30
30
- impl PersistentData for OscilloscopeStyle {
31
- const NAME : & ' static str = "oscilloscope_style" ;
32
- }
33
-
34
31
#[ derive( Parser ) ]
35
32
struct OscilloscopeCommand {
36
33
#[ arg( long, default_value_t = 640 ) ]
@@ -108,6 +105,18 @@ struct Cli {
108
105
title : String ,
109
106
}
110
107
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
+
111
120
#[ derive( Default ) ]
112
121
struct ScopeState {
113
122
samples : VecDeque < ( f32 , f32 ) > ,
@@ -136,25 +145,42 @@ impl App {
136
145
137
146
fn run_oscilloscope (
138
147
mut self ,
139
- mut args : OscilloscopeCommand ,
148
+ args : OscilloscopeCommand ,
140
149
) -> anyhow:: Result < ( ) > {
141
150
self . canvas . window_mut ( ) . set_resizable ( true ) ;
142
151
let mut viz_udp_client = oscilloscope:: Client :: new ( self . server ) ?;
143
152
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
+ } ;
147
172
loop {
148
173
for event in self . event_pump . poll_iter ( ) {
149
174
Self :: handle_event_common ( event. clone ( ) , self . title . as_str ( ) ) ;
150
175
match event {
151
176
Event :: MouseWheel { y, .. } => {
152
177
let ratio = 1.1 ;
153
178
if y > 0 {
154
- args . scale *= ratio;
179
+ ui_state . scale *= ratio;
155
180
} else if y < 0 {
156
- args . scale /= ratio;
181
+ ui_state . scale /= ratio;
157
182
}
183
+ ui_state. save_ ( & self . title ) ;
158
184
}
159
185
Event :: KeyDown {
160
186
scancode : Some ( scancode) ,
@@ -167,43 +193,41 @@ impl App {
167
193
Scancode :: Left => ( -1 , 0 ) ,
168
194
Scancode :: Right => ( 1 , 0 ) ,
169
195
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 ) ;
172
199
continue ;
173
200
}
174
201
Scancode :: Num2 => {
175
- args . style =
202
+ ui_state . style =
176
203
OscilloscopeStyle :: TimeDomainStereo ;
177
- args . style . save_ ( & self . title ) ;
204
+ ui_state . save_ ( & self . title ) ;
178
205
continue ;
179
206
}
180
207
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 ) ;
183
210
continue ;
184
211
}
185
212
_ => ( 0 , 0 ) ,
186
213
} ;
187
- args . line_width = ( ( args . line_width as i32 )
214
+ ui_state . line_width = ( ( ui_state . line_width as i32 )
188
215
+ line_width_delta)
189
216
. clamp ( 1 , 20 )
190
217
as u32 ;
191
- args . alpha_scale = ( args . alpha_scale as i32
218
+ ui_state . alpha_scale = ( ui_state . alpha_scale as i32
192
219
+ alpha_scale_delta)
193
220
. clamp ( 1 , 255 )
194
221
as u8 ;
222
+ ui_state. save_ ( & self . title ) ;
195
223
}
196
224
Event :: Window {
197
- win_event : WindowEvent :: Resized ( width , height ) ,
225
+ win_event : WindowEvent :: Resized ( new_width , new_height ) ,
198
226
..
199
227
} => {
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 ) ;
207
231
}
208
232
_ => ( ) ,
209
233
}
@@ -212,17 +236,17 @@ impl App {
212
236
for sample_pair in viz_udp_client. pairs ( ) {
213
237
scope_state. samples . push_back ( sample_pair) ;
214
238
}
215
- while scope_state. samples . len ( ) > args . max_num_samples {
239
+ while scope_state. samples . len ( ) > max_num_samples {
216
240
scope_state. samples . pop_front ( ) ;
217
241
}
218
242
}
219
243
self . canvas . set_draw_color ( Color :: RGB ( 0 , 0 , 0 ) ) ;
220
244
self . canvas . clear ( ) ;
221
245
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 ,
224
248
} ;
225
- match args . style {
249
+ match ui_state . style {
226
250
OscilloscopeStyle :: TimeDomain => {
227
251
let num_samples_to_draw = screen_size. x as usize ;
228
252
let sample_mean_iter = scope_state
@@ -232,14 +256,13 @@ impl App {
232
256
. take ( num_samples_to_draw)
233
257
. rev ( )
234
258
. 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 ) ) ;
238
261
let mut prev = None ;
239
262
for ( x, sample) in sample_mean_iter. enumerate ( ) {
240
263
let x = x as i32 ;
241
264
let y = screen_size. y
242
- - ( ( sample * args . scale ) as i32
265
+ - ( ( sample * ui_state . scale ) as i32
243
266
+ ( screen_size. y / 2 ) ) ;
244
267
let coord = Coord { x, y } ;
245
268
if let Some ( prev) = prev {
@@ -249,8 +272,8 @@ impl App {
249
272
let rect = Rect :: new (
250
273
x,
251
274
y,
252
- args . line_width ,
253
- args . line_width ,
275
+ ui_state . line_width ,
276
+ ui_state . line_width ,
254
277
) ;
255
278
let _ = self . canvas . fill_rect ( rect) ;
256
279
}
@@ -272,14 +295,13 @@ impl App {
272
295
make_sample_pair_iter ( ) . map ( |( x, _) | x) ;
273
296
let sample_right_iter =
274
297
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 ) ) ;
278
300
let mut prev = None ;
279
301
for ( x, sample) in sample_left_iter. enumerate ( ) {
280
302
let x = x as i32 ;
281
303
let y = screen_size. y
282
- - ( ( sample * args . scale ) as i32
304
+ - ( ( sample * ui_state . scale ) as i32
283
305
+ ( screen_size. y / 3 ) ) ;
284
306
let coord = Coord { x, y } ;
285
307
if let Some ( prev) = prev {
@@ -289,8 +311,8 @@ impl App {
289
311
let rect = Rect :: new (
290
312
x,
291
313
y,
292
- args . line_width ,
293
- args . line_width ,
314
+ ui_state . line_width ,
315
+ ui_state . line_width ,
294
316
) ;
295
317
let _ = self . canvas . fill_rect ( rect) ;
296
318
}
@@ -301,7 +323,7 @@ impl App {
301
323
for ( x, sample) in sample_right_iter. enumerate ( ) {
302
324
let x = x as i32 ;
303
325
let y = screen_size. y
304
- - ( ( sample * args . scale ) as i32
326
+ - ( ( sample * ui_state . scale ) as i32
305
327
+ ( ( 2 * screen_size. y ) / 3 ) ) ;
306
328
let coord = Coord { x, y } ;
307
329
if let Some ( prev) = prev {
@@ -311,8 +333,8 @@ impl App {
311
333
let rect = Rect :: new (
312
334
x,
313
335
y,
314
- args . line_width ,
315
- args . line_width ,
336
+ ui_state . line_width ,
337
+ ui_state . line_width ,
316
338
) ;
317
339
let _ = self . canvas . fill_rect ( rect) ;
318
340
}
@@ -324,8 +346,8 @@ impl App {
324
346
let mut coord_iter =
325
347
scope_state. samples . iter ( ) . map ( |( left, right) | {
326
348
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 ,
329
351
} + screen_size / 2
330
352
} ) ;
331
353
let mut prev = if let Some ( first) = coord_iter. next ( ) {
@@ -334,20 +356,20 @@ impl App {
334
356
Coord :: new ( 0 , 0 )
335
357
} ;
336
358
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)
339
361
. min ( 255 ) as u8 ;
340
362
self . canvas . set_draw_color ( Color :: RGBA (
341
- args . red , args . green , args . blue , alpha,
363
+ rgb . r , rgb . g , rgb . b , alpha,
342
364
) ) ;
343
365
for Coord { x, y } in
344
366
line_2d:: coords_between ( prev, coord)
345
367
{
346
368
let rect = Rect :: new (
347
369
x,
348
370
y,
349
- args . line_width ,
350
- args . line_width ,
371
+ ui_state . line_width ,
372
+ ui_state . line_width ,
351
373
) ;
352
374
let _ = self . canvas . fill_rect ( rect) ;
353
375
}
@@ -440,18 +462,13 @@ fn main() -> anyhow::Result<()> {
440
462
Err ( _) => None ,
441
463
Ok ( window_position) => Some ( window_position) ,
442
464
} ;
443
-
444
465
let mut window_builder = match command {
445
466
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)
453
468
}
469
+ Command :: Blink ( _) => video_subsystem. window ( "" , width, height) ,
454
470
} ;
471
+ window_builder. always_on_top ( ) ;
455
472
if let Some ( WindowPosition { x, y } ) = window_position {
456
473
window_builder. position ( x, y) ;
457
474
}
0 commit comments