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