Commit dd21bfed authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

positioning: Calculate sizes instead of storing, move position out of widgets

Sizes of widgets can be derived, so storing them was only for C compatibility. Similar with storing position inside of widgets.

Some layout margin and scaling changes could be introduced, meaning a possibility of visual differences.
parent 1f69787f
Pipeline #49281 passed with stages
in 9 minutes and 32 seconds
......@@ -498,53 +498,6 @@ eek_renderer_get_icon_surface (const gchar *icon_name,
return surface;
}
static gboolean
sign (EekPoint *p1, EekPoint *p2, EekPoint *p3)
{
// FIXME: what is this actually checking?
return (p1->x - p3->x) * (p2->y - p3->y) -
(p2->x - p3->x) * (p1->y - p3->y);
}
uint32_t
eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_t angle)
{
EekPoint points[4];
gboolean b1, b2, b3;
points[0].x = bounds.x;
points[0].y = bounds.y;
points[1].x = points[0].x + bounds.width;
points[1].y = points[0].y;
points[2].x = points[1].x;
points[2].y = points[1].y + bounds.height;
points[3].x = points[0].x;
points[3].y = points[2].y;
for (unsigned i = 0; i < G_N_ELEMENTS(points); i++) {
eek_point_rotate (&points[i], angle);
points[i].x += origin.x;
points[i].y += origin.y;
}
b1 = sign (&point, &points[0], &points[1]) < 0.0;
b2 = sign (&point, &points[1], &points[2]) < 0.0;
b3 = sign (&point, &points[2], &points[0]) < 0.0;
if (b1 == b2 && b2 == b3) {
return 1;
}
b1 = sign (&point, &points[2], &points[3]) < 0.0;
b2 = sign (&point, &points[3], &points[0]) < 0.0;
b3 = sign (&point, &points[0], &points[2]) < 0.0;
if (b1 == b2 && b2 == b3) {
return 1;
}
return 0;
}
struct transformation
eek_renderer_get_transformation (EekRenderer *renderer) {
struct transformation failed = {0};
......
......@@ -34,6 +34,5 @@ eek_xml_layout_real_create_keyboard (const char *keyboard_type,
enum squeek_arrangement_kind t)
{
struct squeek_layout *layout = squeek_load_layout(keyboard_type, t);
squeek_layout_place_contents(layout);
return level_keyboard_new(manager, layout);
}
......@@ -17,6 +17,7 @@ use ::keyboard::{
KeyState, PressType,
generate_keymap, generate_keycodes, FormattingError
};
use ::layout;
use ::layout::ArrangementKind;
use ::resources;
use ::util::c::as_str;
......@@ -215,6 +216,7 @@ 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,
views: HashMap<String, Vec<ButtonIds>>,
#[serde(default)]
......@@ -269,6 +271,7 @@ enum Action {
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
struct Outline {
/// FIXME: replace with Size
bounds: Bounds,
}
......@@ -303,6 +306,20 @@ impl From<io::Error> for Error {
}
}
pub fn add_offsets<'a, I: 'a, T, F: 'a>(iterator: I, get_size: F)
-> impl Iterator<Item=(f64, T)> + 'a
where I: Iterator<Item=T>,
F: Fn(&T) -> f64,
{
let mut offset = 0.0;
iterator.map(move |item| {
let size = get_size(&item);
let value = (offset, item);
offset += size;
value
})
}
impl Layout {
pub fn from_resource(name: &str) -> Result<Layout, LoadError> {
let data = resources::get_keyboard(name)
......@@ -403,34 +420,35 @@ impl Layout {
);
let views = HashMap::from_iter(
self.views.iter().map(|(name, view)| {(
name.clone(),
::layout::View {
bounds: ::layout::c::Bounds {
x: self.bounds.x,
y: self.bounds.y,
width: self.bounds.width,
height: self.bounds.height,
},
rows: view.iter().map(|row| {
::layout::Row {
angle: 0,
bounds: None,
buttons: row.split_ascii_whitespace().map(|name| {
Box::new(create_button(
&self.buttons,
&self.outlines,
name,
button_states_cache.get(name.into())
.expect("Button state not created")
.clone(),
&mut warning_handler,
))
}).collect(),
}
}).collect(),
}
)})
self.views.iter().map(|(name, view)| {
let rows = view.iter().map(|row| {
let buttons = row.split_ascii_whitespace()
.map(|name| {
Box::new(create_button(
&self.buttons,
&self.outlines,
name,
button_states_cache.get(name.into())
.expect("Button state not created")
.clone(),
&mut warning_handler,
))
});
::layout::Row {
angle: 0,
buttons: add_offsets(
buttons,
|button| button.size.width,
).collect()
}
});
let rows = add_offsets(rows, |row| row.get_height())
.collect();
(
name.clone(),
layout::View::new(rows)
)
})
);
(
......@@ -440,6 +458,13 @@ impl Layout {
CString::new(keymap_str)
.expect("Invalid keymap string generated")
},
// FIXME: use a dedicated field
margins: layout::Margins {
top: self.bounds.x,
left: self.bounds.y,
bottom: 0.0,
right: self.bounds.y,
},
}),
warning_handler,
)
......@@ -629,13 +654,11 @@ fn create_button<H: WarningHandler>(
}
});
::layout::Button {
layout::Button {
name: cname,
outline_name: CString::new(outline_name).expect("Bad outline"),
// TODO: do layout before creating buttons
bounds: ::layout::c::Bounds {
x: outline.bounds.x,
y: outline.bounds.y,
size: layout::Size {
width: outline.bounds.width,
height: outline.bounds.height,
},
......@@ -734,8 +757,8 @@ mod tests {
.unwrap();
assert_eq!(
out.views["base"]
.rows[0]
.buttons[0]
.get_rows()[0].1
.buttons[0].1
.label,
::layout::Label::Text(CString::new("test").unwrap())
);
......@@ -749,8 +772,8 @@ mod tests {
.unwrap();
assert_eq!(
out.views["base"]
.rows[0]
.buttons[0]
.get_rows()[0].1
.buttons[0].1
.label,
::layout::Label::Text(CString::new("test").unwrap())
);
......@@ -765,8 +788,8 @@ mod tests {
.unwrap();
assert_eq!(
out.views["base"]
.rows[0]
.buttons[0]
.get_rows()[0].1
.buttons[0].1
.state.borrow()
.keycodes.len(),
2
......
......@@ -48,17 +48,14 @@ mod c {
let cr = unsafe { cairo::Context::from_raw_none(cr) };
let view = layout.get_current_view();
let view_position = view.bounds.get_position();
for row in &view.rows {
for button in &row.buttons {
for (row_offset, row) in &view.get_rows() {
for (x_offset, button) in &row.buttons {
let state = RefCell::borrow(&button.state).clone();
if state.pressed == keyboard::PressType::Pressed || state.locked {
let position = &view_position
+ row.bounds.clone().unwrap().get_position()
+ button.bounds.get_position();
render_button_at_position(
renderer, &cr,
position, button.as_ref(),
row_offset + Point { x: *x_offset, y: 0.0 },
button.as_ref(),
state.pressed, state.locked,
);
}
......@@ -76,15 +73,12 @@ mod c {
let layout = unsafe { &mut *layout };
let cr = unsafe { cairo::Context::from_raw_none(cr) };
let view = layout.get_current_view();
let view_position = view.bounds.get_position();
for row in &view.rows {
for button in &row.buttons {
let position = &view_position
+ row.bounds.clone().unwrap().get_position()
+ button.bounds.get_position();
for (row_offset, row) in &view.get_rows() {
for (x_offset, button) in &row.buttons {
render_button_at_position(
renderer, &cr,
position, button.as_ref(),
row_offset + Point { x: *x_offset, y: 0.0 },
button.as_ref(),
keyboard::PressType::Released, false,
);
}
......@@ -105,7 +99,7 @@ pub fn render_button_at_position(
cr.translate(position.x, position.y);
cr.rectangle(
0.0, 0.0,
button.bounds.width, button.bounds.height
button.size.width, button.size.height
);
cr.clip();
unsafe {
......
......@@ -28,9 +28,6 @@ struct transformation squeek_layout_calculate_transformation(
const struct squeek_layout *layout,
double allocation_width, double allocation_size);
void
squeek_layout_place_contents(struct squeek_layout*);
struct squeek_layout *squeek_load_layout(const char *name, uint32_t type);
const char *squeek_layout_get_keymap(const struct squeek_layout*);
enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *);
......
This diff is collapsed.
......@@ -56,8 +56,8 @@ fn check_layout(layout: Layout) {
// "Press" each button with keysyms
for view in layout.views.values() {
for row in &view.rows {
for button in &row.buttons {
for (_y, row) in &view.get_rows() {
for (_x, button) in &row.buttons {
let keystate = button.state.borrow();
for keycode in &keystate.keycodes {
match state.key_get_one_sym(*keycode) {
......
......@@ -2,6 +2,8 @@
use std::collections::HashMap;
use std::rc::Rc;
use ::float_ord::FloatOrd;
use std::borrow::Borrow;
use std::hash::{ Hash, Hasher };
use std::iter::FromIterator;
......@@ -142,6 +144,16 @@ pub fn hash_map_map<K, V, F, K1, V1>(map: HashMap<K, V>, mut f: F)
)
}
pub fn find_max_double<T, I, F>(iterator: I, get: F)
-> f64
where I: Iterator<Item=T>,
F: Fn(&T) -> f64
{
iterator.map(|value| FloatOrd(get(&value)))
.max().unwrap_or(FloatOrd(0f64))
.0
}
/// Compares pointers but not internal values of Rc
pub struct Pointer<T>(pub Rc<T>);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment