Merge branch 'allow-stretching' into 'master'
layout: allow stretching the layout by a small amount See merge request World/Phosh/squeekboard!544
This commit is contained in:
@ -418,7 +418,8 @@ eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
|||||||
.widget_to_layout = {
|
.widget_to_layout = {
|
||||||
.origin_x = 0,
|
.origin_x = 0,
|
||||||
.origin_y = 0,
|
.origin_y = 0,
|
||||||
.scale = 1,
|
.scale_x = 1,
|
||||||
|
.scale_y = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
priv->render_geometry = initial_geometry;
|
priv->render_geometry = initial_geometry;
|
||||||
|
|||||||
@ -219,7 +219,7 @@ eek_renderer_render_keyboard (EekRenderer *self,
|
|||||||
|
|
||||||
cairo_save(cr);
|
cairo_save(cr);
|
||||||
cairo_translate (cr, geometry.widget_to_layout.origin_x, geometry.widget_to_layout.origin_y);
|
cairo_translate (cr, geometry.widget_to_layout.origin_x, geometry.widget_to_layout.origin_y);
|
||||||
cairo_scale (cr, geometry.widget_to_layout.scale, geometry.widget_to_layout.scale);
|
cairo_scale (cr, geometry.widget_to_layout.scale_x, geometry.widget_to_layout.scale_y);
|
||||||
|
|
||||||
squeek_draw_layout_base_view(keyboard->layout, self, cr);
|
squeek_draw_layout_base_view(keyboard->layout, self, cr);
|
||||||
squeek_layout_draw_all_changed(keyboard->layout, self, cr, submission);
|
squeek_layout_draw_all_changed(keyboard->layout, self, cr, submission);
|
||||||
|
|||||||
@ -87,7 +87,8 @@ void eek_bounds_free (EekBounds *bounds);
|
|||||||
struct transformation {
|
struct transformation {
|
||||||
gdouble origin_x;
|
gdouble origin_x;
|
||||||
gdouble origin_y;
|
gdouble origin_y;
|
||||||
gdouble scale;
|
gdouble scale_x;
|
||||||
|
gdouble scale_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::cmp;
|
||||||
use std::collections::{ HashMap, HashSet };
|
use std::collections::{ HashMap, HashSet };
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -26,6 +27,7 @@ use std::vec::Vec;
|
|||||||
|
|
||||||
use ::action::Action;
|
use ::action::Action;
|
||||||
use ::drawing;
|
use ::drawing;
|
||||||
|
use ::float_ord::FloatOrd;
|
||||||
use ::keyboard::KeyState;
|
use ::keyboard::KeyState;
|
||||||
use ::logging;
|
use ::logging;
|
||||||
use ::manager;
|
use ::manager;
|
||||||
@ -117,28 +119,30 @@ pub mod c {
|
|||||||
pub struct Transformation {
|
pub struct Transformation {
|
||||||
pub origin_x: f64,
|
pub origin_x: f64,
|
||||||
pub origin_y: f64,
|
pub origin_y: f64,
|
||||||
pub scale: f64,
|
pub scale_x: f64,
|
||||||
|
pub scale_y: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transformation {
|
impl Transformation {
|
||||||
/// Applies the new transformation after this one
|
/// Applies the new transformation after this one
|
||||||
pub fn chain(self, next: Transformation) -> Transformation {
|
pub fn chain(self, next: Transformation) -> Transformation {
|
||||||
Transformation {
|
Transformation {
|
||||||
origin_x: self.origin_x + self.scale * next.origin_x,
|
origin_x: self.origin_x + self.scale_x * next.origin_x,
|
||||||
origin_y: self.origin_y + self.scale * next.origin_y,
|
origin_y: self.origin_y + self.scale_y * next.origin_y,
|
||||||
scale: self.scale * next.scale,
|
scale_x: self.scale_x * next.scale_x,
|
||||||
|
scale_y: self.scale_y * next.scale_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn forward(&self, p: Point) -> Point {
|
fn forward(&self, p: Point) -> Point {
|
||||||
Point {
|
Point {
|
||||||
x: (p.x - self.origin_x) / self.scale,
|
x: (p.x - self.origin_x) / self.scale_x,
|
||||||
y: (p.y - self.origin_y) / self.scale,
|
y: (p.y - self.origin_y) / self.scale_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn reverse(&self, p: Point) -> Point {
|
fn reverse(&self, p: Point) -> Point {
|
||||||
Point {
|
Point {
|
||||||
x: p.x * self.scale + self.origin_x,
|
x: p.x * self.scale_x + self.origin_x,
|
||||||
y: p.y * self.scale + self.origin_y,
|
y: p.y * self.scale_y + self.origin_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
||||||
@ -394,7 +398,8 @@ pub mod c {
|
|||||||
let transform = Transformation {
|
let transform = Transformation {
|
||||||
origin_x: 10f64,
|
origin_x: 10f64,
|
||||||
origin_y: 11f64,
|
origin_y: 11f64,
|
||||||
scale: 12f64,
|
scale_x: 12f64,
|
||||||
|
scale_y: 13f64,
|
||||||
};
|
};
|
||||||
let point = Point { x: 1f64, y: 1f64 };
|
let point = Point { x: 1f64, y: 1f64 };
|
||||||
let transformed = transform.reverse(transform.forward(point.clone()));
|
let transformed = transform.reverse(transform.forward(point.clone()));
|
||||||
@ -755,16 +760,20 @@ impl Layout {
|
|||||||
let size = self.calculate_size();
|
let size = self.calculate_size();
|
||||||
let h_scale = available.width / size.width;
|
let h_scale = available.width / size.width;
|
||||||
let v_scale = available.height / size.height;
|
let v_scale = available.height / size.height;
|
||||||
let scale = if h_scale < v_scale { h_scale } else { v_scale };
|
// Allow up to 5% (and a bit more) horizontal stretching for filling up available space
|
||||||
|
let scale_x = if (h_scale / v_scale) < 1.06 { h_scale } else { v_scale };
|
||||||
|
let scale_y = cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0;
|
||||||
let outside_margins = c::Transformation {
|
let outside_margins = c::Transformation {
|
||||||
origin_x: (available.width - (scale * size.width)) / 2.0,
|
origin_x: (available.width - (scale_x * size.width)) / 2.0,
|
||||||
origin_y: (available.height - (scale * size.height)) / 2.0,
|
origin_y: (available.height - (scale_y * size.height)) / 2.0,
|
||||||
scale: scale,
|
scale_x: scale_x,
|
||||||
|
scale_y: scale_y,
|
||||||
};
|
};
|
||||||
outside_margins.chain(c::Transformation {
|
outside_margins.chain(c::Transformation {
|
||||||
origin_x: self.margins.left,
|
origin_x: self.margins.left,
|
||||||
origin_y: self.margins.top,
|
origin_y: self.margins.top,
|
||||||
scale: 1.0,
|
scale_x: 1.0,
|
||||||
|
scale_y: 1.0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1471,8 +1480,63 @@ mod test {
|
|||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 2.0, height: 2.0 }
|
Size { width: 2.0, height: 2.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale, 1.0);
|
assert_eq!(transformation.scale_x, 1.0);
|
||||||
|
assert_eq!(transformation.scale_y, 1.0);
|
||||||
assert_eq!(transformation.origin_x, 0.5);
|
assert_eq!(transformation.origin_x, 0.5);
|
||||||
assert_eq!(transformation.origin_y, 0.0);
|
assert_eq!(transformation.origin_y, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_stretching() {
|
||||||
|
// just one button
|
||||||
|
let view = View::new(vec![
|
||||||
|
(
|
||||||
|
0.0,
|
||||||
|
Row::new(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(),
|
||||||
|
view_latched: LatchedState::Not,
|
||||||
|
keymaps: Vec::new(),
|
||||||
|
kind: ArrangementKind::Base,
|
||||||
|
pressed_keys: HashSet::new(),
|
||||||
|
margins: Margins {
|
||||||
|
top: 0.0,
|
||||||
|
left: 0.0,
|
||||||
|
right: 0.0,
|
||||||
|
bottom: 0.0,
|
||||||
|
},
|
||||||
|
views: hashmap! {
|
||||||
|
String::new() => (c::Point { x: 0.0, y: 0.0 }, view),
|
||||||
|
},
|
||||||
|
purpose: ContentPurpose::Normal,
|
||||||
|
};
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 100.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 95.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 95.0);
|
||||||
|
assert_eq!(transformation.scale_y, 95.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 105.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 105.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 106.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user