Merge branch 'margins' into 'master'
Use margins, remove bounds See merge request Librem5/squeekboard!283
This commit is contained in:
		@ -1,18 +1,11 @@
 | 
			
		||||
# Maintained by: Mark Müller <markmueller86@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 208 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 35.33, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 52.67, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 99.67, height: 52 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 35.33, height: 52 }
 | 
			
		||||
    default: { width: 35.33, height: 52 }
 | 
			
		||||
    altline: { width: 52.67, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    spaceline: { width: 99.67, height: 52 }
 | 
			
		||||
    special: { width: 35.33, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,11 @@
 | 
			
		||||
# Maintained by: Mark Müller <markmueller86@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 540, height: 168 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48, height: 42 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 81, height: 42 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 108, height: 42 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 216, height: 42 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48, height: 42 }
 | 
			
		||||
    default: { width: 48, height: 42 }
 | 
			
		||||
    altline: { width: 81, height: 42 }
 | 
			
		||||
    wide: { width: 108, height: 42 }
 | 
			
		||||
    spaceline: { width: 216, height: 42 }
 | 
			
		||||
    special: { width: 48, height: 42 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -2,19 +2,12 @@
 | 
			
		||||
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
 | 
			
		||||
# Sep 2019
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 0.33, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
    default: { width: 32, height: 52 }
 | 
			
		||||
    altline: { width: 48.39024, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    outline7: { width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline: { width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 35.33, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 52.67, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 99.67, height: 52 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 44, height: 52 }
 | 
			
		||||
    default: { width: 35.33, height: 52 }
 | 
			
		||||
    altline: { width: 52.67, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    spaceline: { width: 99.67, height: 52 }
 | 
			
		||||
    special: { width: 44, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 0.33, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
    default: { width: 32, height: 52 }
 | 
			
		||||
    altline: { width: 48.39024, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    outline7: { width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline: { width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,12 @@
 | 
			
		||||
# Italian layout created by Antonio Pandolfo
 | 
			
		||||
# 03 october 2019
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 35.33, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 52.67, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 99.67, height: 52 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 44, height: 52 }
 | 
			
		||||
    default: { width: 35.33, height: 52 }
 | 
			
		||||
    altline: { width: 52.67, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    spaceline: { width: 99.67, height: 52 }
 | 
			
		||||
    special: { width: 44, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,11 @@
 | 
			
		||||
# Maintained by: Mark Müller <markmueller86@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 208 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    default-wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    default: { width: 62, height: 52 }
 | 
			
		||||
    default-wide: { width: 62, height: 52 }
 | 
			
		||||
    altline: { width: 62, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    special: { width: 62, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base: # hiragana
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,11 @@
 | 
			
		||||
# Maintained by: Mark Müller <markmueller86@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 540, height: 168 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 42 }
 | 
			
		||||
    default-wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 42 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 42 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 42 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 42 }
 | 
			
		||||
    default: { width: 62, height: 42 }
 | 
			
		||||
    default-wide: { width: 62, height: 42 }
 | 
			
		||||
    altline: { width: 62, height: 42 }
 | 
			
		||||
    wide: { width: 62, height: 42 }
 | 
			
		||||
    special: { width: 62, height: 42 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base: # hiragana
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 0.33, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
    default: { width: 32, height: 52 }
 | 
			
		||||
    altline: { width: 48.39024, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    outline7: { width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline: { width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 0.33, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 37.46341, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 120.5853, height: 52 }
 | 
			
		||||
    default: { width: 37.46341, height: 52 }
 | 
			
		||||
    altline: { width: 48.39024, height: 52 }
 | 
			
		||||
    outline7: { width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline: { width: 120.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 0.33, width: 360, height: 210 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
    default: { width: 32, height: 52 }
 | 
			
		||||
    altline: { width: 48.39024, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    outline7: { width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline: { width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 208 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 35.33, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 52.67, height: 52 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 62, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 142, height: 52 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 44, height: 52 }
 | 
			
		||||
    default: { width: 35.33, height: 52 }
 | 
			
		||||
    altline: { width: 52.67, height: 52 }
 | 
			
		||||
    wide: { width: 62, height: 52 }
 | 
			
		||||
    spaceline: { width: 142, height: 52 }
 | 
			
		||||
    special: { width: 44, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
bounds: { x: 0, y: 1, width: 540, height: 168 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 54, height: 42 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 81, height: 42 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 108, height: 42 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 216, height: 42 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 54, height: 42 }
 | 
			
		||||
    default: { width: 54, height: 42 }
 | 
			
		||||
    altline: { width: 81, height: 42 }
 | 
			
		||||
    wide: { width: 108, height: 42 }
 | 
			
		||||
    spaceline: { width: 216, height: 42 }
 | 
			
		||||
    special: { width: 54, height: 42 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/data.rs
									
									
									
									
									
								
							@ -1,5 +1,7 @@
 | 
			
		||||
/**! The parsing of the data files for layouts */
 | 
			
		||||
 | 
			
		||||
// TODO: find a nice way to make sure non-positive sizes don't break layouts
 | 
			
		||||
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::collections::{ HashMap, HashSet };
 | 
			
		||||
use std::env;
 | 
			
		||||
@ -216,21 +218,20 @@ fn load_layout_data_with_fallback(
 | 
			
		||||
#[derive(Debug, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
pub struct Layout {
 | 
			
		||||
    /// FIXME: deprecate in favor of margins
 | 
			
		||||
    bounds: Bounds,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    margins: Margins,
 | 
			
		||||
    views: HashMap<String, Vec<ButtonIds>>,
 | 
			
		||||
    #[serde(default)] 
 | 
			
		||||
    buttons: HashMap<String, ButtonMeta>,
 | 
			
		||||
    outlines: HashMap<String, Outline>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq, Default)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
struct Bounds {
 | 
			
		||||
    x: f64,
 | 
			
		||||
    y: f64,
 | 
			
		||||
    width: f64,
 | 
			
		||||
    height: f64,
 | 
			
		||||
struct Margins {
 | 
			
		||||
    top: f64,
 | 
			
		||||
    bottom: f64,
 | 
			
		||||
    side: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Buttons are embedded in a single string
 | 
			
		||||
@ -271,8 +272,8 @@ enum Action {
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
struct Outline {
 | 
			
		||||
    /// FIXME: replace with Size
 | 
			
		||||
    bounds: Bounds,
 | 
			
		||||
    width: f64,
 | 
			
		||||
    height: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Errors encountered loading the layout into yaml
 | 
			
		||||
@ -460,10 +461,10 @@ impl Layout {
 | 
			
		||||
                },
 | 
			
		||||
                // FIXME: use a dedicated field
 | 
			
		||||
                margins: layout::Margins {
 | 
			
		||||
                    top: self.bounds.x,
 | 
			
		||||
                    left: self.bounds.y,
 | 
			
		||||
                    bottom: 0.0,
 | 
			
		||||
                    right: self.bounds.y,
 | 
			
		||||
                    top: self.margins.top,
 | 
			
		||||
                    left: self.margins.side,
 | 
			
		||||
                    bottom: self.margins.bottom,
 | 
			
		||||
                    right: self.margins.side,
 | 
			
		||||
                },
 | 
			
		||||
            }),
 | 
			
		||||
            warning_handler,
 | 
			
		||||
@ -649,9 +650,7 @@ fn create_button<H: WarningHandler>(
 | 
			
		||||
            warning_handler.handle(
 | 
			
		||||
                &format!("No default outline defined! Using 1x1!")
 | 
			
		||||
            );
 | 
			
		||||
            Outline {
 | 
			
		||||
                bounds: Bounds { x: 0f64, y: 0f64, width: 1f64, height: 1f64 },
 | 
			
		||||
            }
 | 
			
		||||
            Outline { width: 1f64, height: 1f64 }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    layout::Button {
 | 
			
		||||
@ -659,8 +658,8 @@ fn create_button<H: WarningHandler>(
 | 
			
		||||
        outline_name: CString::new(outline_name).expect("Bad outline"),
 | 
			
		||||
        // TODO: do layout before creating buttons
 | 
			
		||||
        size: layout::Size {
 | 
			
		||||
            width: outline.bounds.width,
 | 
			
		||||
            height: outline.bounds.height,
 | 
			
		||||
            width: outline.width,
 | 
			
		||||
            height: outline.height,
 | 
			
		||||
        },
 | 
			
		||||
        label: label,
 | 
			
		||||
        state: state,
 | 
			
		||||
@ -686,7 +685,7 @@ mod tests {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Layout::from_file(PathBuf::from("tests/layout.yaml")).unwrap(),
 | 
			
		||||
            Layout {
 | 
			
		||||
                bounds: Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 },
 | 
			
		||||
                margins: Margins { top: 0f64, bottom: 0f64, side: 0f64 },
 | 
			
		||||
                views: hashmap!(
 | 
			
		||||
                    "base".into() => vec!("test".into()),
 | 
			
		||||
                ),
 | 
			
		||||
@ -701,11 +700,7 @@ mod tests {
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                outlines: hashmap!{
 | 
			
		||||
                    "default".into() => Outline {
 | 
			
		||||
                        bounds: Bounds {
 | 
			
		||||
                            x: 0f64, y: 0f64, width: 0f64, height: 0f64
 | 
			
		||||
                        }, 
 | 
			
		||||
                    }
 | 
			
		||||
                    "default".into() => Outline { width: 0f64, height: 0f64 }, 
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
@ -855,4 +850,21 @@ mod tests {
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_layout_margins() {
 | 
			
		||||
        let out = Layout::from_file(PathBuf::from("tests/layout_margins.yaml"))
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .build(PanicWarn).0
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            out.margins,
 | 
			
		||||
            layout::Margins {
 | 
			
		||||
                top: 1.0,
 | 
			
		||||
                bottom: 3.0,
 | 
			
		||||
                left: 2.0,
 | 
			
		||||
                right: 2.0,
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								src/layout.rs
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								src/layout.rs
									
									
									
									
									
								
							@ -99,7 +99,7 @@ pub mod c {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Scale + translate
 | 
			
		||||
    /// Translate and then scale
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
    pub struct Transformation {
 | 
			
		||||
        pub origin_x: f64,
 | 
			
		||||
@ -108,6 +108,14 @@ pub mod c {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Transformation {
 | 
			
		||||
        /// Applies the new transformation after this one
 | 
			
		||||
        pub fn chain(self, next: Transformation) -> Transformation {
 | 
			
		||||
            Transformation {
 | 
			
		||||
                origin_x: self.origin_x + self.scale * next.origin_x,
 | 
			
		||||
                origin_y: self.origin_y + self.scale * next.origin_y,
 | 
			
		||||
                scale: self.scale * next.scale,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fn forward(&self, p: Point) -> Point {
 | 
			
		||||
            Point {
 | 
			
		||||
                x: (p.x - self.origin_x) / self.scale,
 | 
			
		||||
@ -195,7 +203,8 @@ pub mod c {
 | 
			
		||||
        println!("{:?}", button);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Positions the layout within the available space
 | 
			
		||||
    /// Positions the layout contents within the available space.
 | 
			
		||||
    /// The origin of the transformation is the point inside the margins.
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_calculate_transformation(
 | 
			
		||||
@ -204,15 +213,10 @@ pub mod c {
 | 
			
		||||
        allocation_height: f64,
 | 
			
		||||
    ) -> Transformation {
 | 
			
		||||
        let layout = unsafe { &*layout };
 | 
			
		||||
        let size = layout.calculate_size();
 | 
			
		||||
        let h_scale = allocation_width / size.width;
 | 
			
		||||
        let v_scale = allocation_height / size.height;
 | 
			
		||||
        let scale = if h_scale < v_scale { h_scale } else { v_scale };
 | 
			
		||||
        Transformation {
 | 
			
		||||
            origin_x: (allocation_width - (scale * size.width)) / 2.0,
 | 
			
		||||
            origin_y: (allocation_height - (scale * size.height)) / 2.0,
 | 
			
		||||
            scale: scale,
 | 
			
		||||
        }
 | 
			
		||||
        layout.calculate_transformation(Size {
 | 
			
		||||
            width: allocation_width,
 | 
			
		||||
            height: allocation_height,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
@ -427,7 +431,7 @@ pub struct ButtonPlace<'a> {
 | 
			
		||||
    offset: c::Point,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub struct Size {
 | 
			
		||||
    pub width: f64,
 | 
			
		||||
    pub height: f64,
 | 
			
		||||
@ -560,6 +564,7 @@ pub enum ArrangementKind {
 | 
			
		||||
    Wide = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub struct Margins {
 | 
			
		||||
    pub top: f64,
 | 
			
		||||
    pub bottom: f64,
 | 
			
		||||
@ -713,7 +718,8 @@ impl Layout {
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn calculate_size(&self) -> Size {
 | 
			
		||||
    /// Calculates size without margins
 | 
			
		||||
    fn calculate_inner_size(&self) -> Size {
 | 
			
		||||
        Size {
 | 
			
		||||
            height: find_max_double(
 | 
			
		||||
                self.views.iter(),
 | 
			
		||||
@ -725,6 +731,39 @@ impl Layout {
 | 
			
		||||
            ),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Size including margins
 | 
			
		||||
    fn calculate_size(&self) -> Size {
 | 
			
		||||
        let inner_size = self.calculate_inner_size();
 | 
			
		||||
        Size {
 | 
			
		||||
            width: self.margins.left + inner_size.width + self.margins.right,
 | 
			
		||||
            height: (
 | 
			
		||||
                self.margins.top
 | 
			
		||||
                + inner_size.height
 | 
			
		||||
                + self.margins.bottom
 | 
			
		||||
            ),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    pub fn calculate_transformation(
 | 
			
		||||
        &self,
 | 
			
		||||
        available: Size,
 | 
			
		||||
    ) -> c::Transformation {
 | 
			
		||||
        let size = self.calculate_size();
 | 
			
		||||
        let h_scale = available.width / size.width;
 | 
			
		||||
        let v_scale = available.height / size.height;
 | 
			
		||||
        let scale = if h_scale < v_scale { h_scale } else { v_scale };
 | 
			
		||||
        let outside_margins = c::Transformation {
 | 
			
		||||
            origin_x: (available.width - (scale * size.width)) / 2.0,
 | 
			
		||||
            origin_y: (available.height - (scale * size.height)) / 2.0,
 | 
			
		||||
            scale: scale,
 | 
			
		||||
        };
 | 
			
		||||
        outside_margins.chain(c::Transformation {
 | 
			
		||||
            origin_x: self.margins.left,
 | 
			
		||||
            origin_y: self.margins.top,
 | 
			
		||||
            scale: 1.0,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod procedures {
 | 
			
		||||
@ -907,4 +946,58 @@ mod test {
 | 
			
		||||
                .is_none()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn check_bottom_margin() {
 | 
			
		||||
        // just one button
 | 
			
		||||
        let view = View::new(vec![
 | 
			
		||||
            (
 | 
			
		||||
                0.0,
 | 
			
		||||
                Row {
 | 
			
		||||
                    angle: 0,
 | 
			
		||||
                    buttons: vec![(
 | 
			
		||||
                        0.0,
 | 
			
		||||
                        Box::new(Button {
 | 
			
		||||
                            size: Size { width: 1.0, height: 1.0 },
 | 
			
		||||
                            ..*make_button_with_state("foo".into(), make_state())
 | 
			
		||||
                        }),
 | 
			
		||||
                    )]
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
        ]);
 | 
			
		||||
        let layout = Layout {
 | 
			
		||||
            current_view: String::new(),
 | 
			
		||||
            keymap_str: CString::new("").unwrap(),
 | 
			
		||||
            kind: ArrangementKind::Base,
 | 
			
		||||
            locked_keys: HashSet::new(),
 | 
			
		||||
            pressed_keys: HashSet::new(),
 | 
			
		||||
            // Lots of bottom margin
 | 
			
		||||
            margins: Margins {
 | 
			
		||||
                top: 0.0,
 | 
			
		||||
                left: 0.0,
 | 
			
		||||
                right: 0.0,
 | 
			
		||||
                bottom: 1.0,
 | 
			
		||||
            },
 | 
			
		||||
            views: hashmap! {
 | 
			
		||||
                String::new() => view,
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            layout.calculate_inner_size(),
 | 
			
		||||
            Size { width: 1.0, height: 1.0 }
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            layout.calculate_size(),
 | 
			
		||||
            Size { width: 1.0, height: 2.0 }
 | 
			
		||||
        );
 | 
			
		||||
        // Don't change those values randomly!
 | 
			
		||||
        // They take advantage of incidental precise float representation
 | 
			
		||||
        // to even be comparable.
 | 
			
		||||
        let transformation = layout.calculate_transformation(
 | 
			
		||||
            Size { width: 2.0, height: 2.0 }
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(transformation.scale, 1.0);
 | 
			
		||||
        assert_eq!(transformation.origin_x, 0.5);
 | 
			
		||||
        assert_eq!(transformation.origin_y, 0.0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "test"
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    test:
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
# missing views
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
# extra field
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "test"
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
bad_field: false
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
# punctuation
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "."
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    ".":
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
# punctuation
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "å"
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    å:
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,8 @@
 | 
			
		||||
---
 | 
			
		||||
# punctuation
 | 
			
		||||
bounds:
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 0
 | 
			
		||||
    height: 0
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "か゚" # 2 codepoints
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 0, height: 0 }
 | 
			
		||||
    default: { width: 0, height: 0 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								tests/layout_margins.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/layout_margins.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
# Margins present
 | 
			
		||||
margins: { top: 1, side: 2, bottom: 3 }
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "test"
 | 
			
		||||
outlines:
 | 
			
		||||
    default: { width: 1, height: 1 }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								tests/layout_position.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/layout_position.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
# Margins present
 | 
			
		||||
margins: { top: 1, side: 2, bottom: 3 }
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "test"
 | 
			
		||||
outlines:
 | 
			
		||||
    default: { width: 1, height: 1 }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user