Commit 3b0456b5 authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

Merge branch 'margins' into 'master'

Use margins, remove bounds

See merge request Librem5/squeekboard!283
parents 77a6ca19 257b97e9
# 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:
......
# 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:
......
---
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:
......
---
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:
......
# 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:
......
# 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
......
# 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
......
---
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:
......
---
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:
......
---
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:
......
---
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:
......
---
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:
......
/**! 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,
}
);
}
}
......@@ -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