@@ -61,7 +61,7 @@ struct Button {
6161 image : ButtonImage ,
6262 changed : bool ,
6363 active : bool ,
64- action : Key
64+ action : Key ,
6565}
6666
6767fn try_load_svg ( path : & str ) -> Result < ButtonImage > {
@@ -103,7 +103,7 @@ impl Button {
103103 action,
104104 active : false ,
105105 changed : false ,
106- image : ButtonImage :: Text ( text)
106+ image : ButtonImage :: Text ( text) ,
107107 }
108108 }
109109 fn new_icon ( path : & str , action : Key ) -> Button {
@@ -154,16 +154,29 @@ impl Button {
154154
155155#[ derive( Default ) ]
156156pub struct FunctionLayer {
157- buttons : Vec < Button >
157+ buttons : Vec < ( usize , Button ) > ,
158+ virtual_button_count : usize ,
158159}
159160
160161impl FunctionLayer {
161162 fn with_config ( cfg : Vec < ButtonConfig > ) -> FunctionLayer {
162163 if cfg. is_empty ( ) {
163164 panic ! ( "Invalid configuration, layer has 0 buttons" ) ;
164165 }
166+
167+ let mut virtual_button_count = 0 ;
165168 FunctionLayer {
166- buttons : cfg. into_iter ( ) . map ( Button :: with_config) . collect ( )
169+ buttons : cfg. into_iter ( ) . scan ( & mut virtual_button_count, |state, cfg| {
170+ let i = * * state;
171+ let mut stretch = cfg. stretch . unwrap_or ( 1 ) ;
172+ if stretch < 1 {
173+ println ! ( "Stretch value must be at least 1, setting to 1." ) ;
174+ stretch = 1 ;
175+ }
176+ * * state += stretch;
177+ Some ( ( i, Button :: with_config ( cfg) ) )
178+ } ) . collect ( ) ,
179+ virtual_button_count,
167180 }
168181 }
169182 fn draw ( & mut self , config : & Config , width : i32 , height : i32 , surface : & Surface , pixel_shift : ( f64 , f64 ) , complete_redraw : bool ) -> Vec < ClipRect > {
@@ -176,7 +189,7 @@ impl FunctionLayer {
176189 c. translate ( height as f64 , 0.0 ) ;
177190 c. rotate ( ( 90.0f64 ) . to_radians ( ) ) ;
178191 let pixel_shift_width = if config. enable_pixel_shift { PIXEL_SHIFT_WIDTH_PX } else { 0 } ;
179- let button_width = ( ( width - pixel_shift_width as i32 ) - ( BUTTON_SPACING_PX * ( self . buttons . len ( ) - 1 ) as i32 ) ) as f64 / self . buttons . len ( ) as f64 ;
192+ let virtual_button_width = ( ( width - pixel_shift_width as i32 ) - ( BUTTON_SPACING_PX * ( self . virtual_button_count - 1 ) as i32 ) ) as f64 / self . virtual_button_count as f64 ;
180193 let radius = 8.0f64 ;
181194 let bot = ( height as f64 ) * 0.15 ;
182195 let top = ( height as f64 ) * 0.85 ;
@@ -188,12 +201,24 @@ impl FunctionLayer {
188201 }
189202 c. set_font_face ( & config. font_face ) ;
190203 c. set_font_size ( 32.0 ) ;
191- for ( i, button) in self . buttons . iter_mut ( ) . enumerate ( ) {
204+
205+ for i in 0 ..self . buttons . len ( ) {
206+ let end = if i + 1 < self . buttons . len ( ) {
207+ self . buttons [ i + 1 ] . 0
208+ } else {
209+ self . virtual_button_count
210+ } ;
211+ let ( start, button) = & mut self . buttons [ i] ;
212+ let start = * start;
213+
192214 if !button. changed && !complete_redraw {
193215 continue ;
194216 } ;
195217
196- let left_edge = ( i as f64 * ( button_width + BUTTON_SPACING_PX as f64 ) ) . floor ( ) + pixel_shift_x + ( pixel_shift_width / 2 ) as f64 ;
218+ let left_edge = ( start as f64 * ( virtual_button_width + BUTTON_SPACING_PX as f64 ) ) . floor ( ) + pixel_shift_x + ( pixel_shift_width / 2 ) as f64 ;
219+
220+ let button_width = virtual_button_width + ( ( end - start - 1 ) as f64 * ( virtual_button_width + BUTTON_SPACING_PX as f64 ) ) . floor ( ) ;
221+
197222 let color = if button. active {
198223 BUTTON_COLOR_ACTIVE
199224 } else if config. show_button_outlines {
@@ -259,6 +284,33 @@ impl FunctionLayer {
259284
260285 modified_regions
261286 }
287+
288+ fn hit ( & self , width : u16 , height : u16 , x : f64 , y : f64 , i : Option < usize > ) -> Option < usize > {
289+ let virtual_button_width = ( width as i32 - ( BUTTON_SPACING_PX * ( self . virtual_button_count - 1 ) as i32 ) ) as f64 / self . virtual_button_count as f64 ;
290+
291+ let i = i. unwrap_or_else ( || {
292+ let virtual_i = ( x / ( width as f64 / self . virtual_button_count as f64 ) ) as usize ;
293+ self . buttons . iter ( ) . position ( |( start, _) | * start > virtual_i) . unwrap_or ( self . buttons . len ( ) ) - 1
294+ } ) ;
295+
296+ let start = self . buttons [ i] . 0 ;
297+ let end = if i + 1 < self . buttons . len ( ) {
298+ self . buttons [ i + 1 ] . 0
299+ } else {
300+ self . virtual_button_count
301+ } ;
302+
303+ let left_edge = ( start as f64 * ( virtual_button_width + BUTTON_SPACING_PX as f64 ) ) . floor ( ) ;
304+
305+ let button_width = virtual_button_width + ( ( end - start - 1 ) as f64 * ( virtual_button_width + BUTTON_SPACING_PX as f64 ) ) . floor ( ) ;
306+
307+ if x < left_edge || x > ( left_edge + button_width)
308+ || y < 0.1 * height as f64 || y > 0.9 * height as f64 {
309+ return None ;
310+ }
311+
312+ Some ( i)
313+ }
262314}
263315
264316struct Interface ;
@@ -281,15 +333,6 @@ impl LibinputInterface for Interface {
281333}
282334
283335
284- fn button_hit ( num : u32 , idx : u32 , width : u16 , height : u16 , x : f64 , y : f64 ) -> bool {
285- let button_width = ( width as i32 - ( BUTTON_SPACING_PX * ( num - 1 ) as i32 ) ) as f64 / num as f64 ;
286- let left_edge = idx as f64 * ( button_width + BUTTON_SPACING_PX as f64 ) ;
287- if x < left_edge || x > ( left_edge + button_width) {
288- return false
289- }
290- y > 0.1 * height as f64 && y < 0.9 * height as f64
291- }
292-
293336fn emit < F > ( uinput : & mut UInputHandle < F > , ty : EventKind , code : u16 , value : i32 ) where F : AsRawFd {
294337 uinput. write ( & [ input_event {
295338 value : value,
@@ -368,7 +411,7 @@ fn real_main(drm: &mut DrmBackend) {
368411 uinput. set_evbit ( EventKind :: Key ) . unwrap ( ) ;
369412 for layer in & layers {
370413 for button in & layer. buttons {
371- uinput. set_keybit ( button. action ) . unwrap ( ) ;
414+ uinput. set_keybit ( button. 1 . action ) . unwrap ( ) ;
372415 }
373416 }
374417 let mut dev_name_c = [ 0 as c_char ; 80 ] ;
@@ -405,7 +448,7 @@ fn real_main(drm: &mut DrmBackend) {
405448 next_timeout_ms = min ( next_timeout_ms, pixel_shift_next_timeout_ms) ;
406449 }
407450
408- if needs_complete_redraw || layers[ active_layer] . buttons . iter ( ) . any ( |b| b. changed ) {
451+ if needs_complete_redraw || layers[ active_layer] . buttons . iter ( ) . any ( |b| b. 1 . changed ) {
409452 let shift = if cfg. enable_pixel_shift {
410453 pixel_shift. get ( )
411454 } else {
@@ -453,10 +496,9 @@ fn real_main(drm: &mut DrmBackend) {
453496 TouchEvent :: Down ( dn) => {
454497 let x = dn. x_transformed ( width as u32 ) ;
455498 let y = dn. y_transformed ( height as u32 ) ;
456- let btn = ( x / ( width as f64 / layers[ active_layer] . buttons . len ( ) as f64 ) ) as u32 ;
457- if button_hit ( layers[ active_layer] . buttons . len ( ) as u32 , btn, width, height, x, y) {
499+ if let Some ( btn) = layers[ active_layer] . hit ( width, height, x, y, None ) {
458500 touches. insert ( dn. seat_slot ( ) , ( active_layer, btn) ) ;
459- layers[ active_layer] . buttons [ btn as usize ] . set_active ( & mut uinput, true ) ;
501+ layers[ active_layer] . buttons [ btn] . 1 . set_active ( & mut uinput, true ) ;
460502 }
461503 } ,
462504 TouchEvent :: Motion ( mtn) => {
@@ -467,15 +509,15 @@ fn real_main(drm: &mut DrmBackend) {
467509 let x = mtn. x_transformed ( width as u32 ) ;
468510 let y = mtn. y_transformed ( height as u32 ) ;
469511 let ( layer, btn) = * touches. get ( & mtn. seat_slot ( ) ) . unwrap ( ) ;
470- let hit = button_hit ( layers[ layer ] . buttons . len ( ) as u32 , btn , width, height, x, y) ;
471- layers[ layer] . buttons [ btn as usize ] . set_active ( & mut uinput, hit) ;
512+ let hit = layers[ active_layer ] . hit ( width, height, x, y, Some ( btn ) ) . is_some ( ) ;
513+ layers[ layer] . buttons [ btn] . 1 . set_active ( & mut uinput, hit) ;
472514 } ,
473515 TouchEvent :: Up ( up) => {
474516 if !touches. contains_key ( & up. seat_slot ( ) ) {
475517 continue ;
476518 }
477519 let ( layer, btn) = * touches. get ( & up. seat_slot ( ) ) . unwrap ( ) ;
478- layers[ layer] . buttons [ btn as usize ] . set_active ( & mut uinput, false ) ;
520+ layers[ layer] . buttons [ btn] . 1 . set_active ( & mut uinput, false ) ;
479521 }
480522 _ => { }
481523 }
0 commit comments