Merge branch 'fit-layout-to-panel' into 'main'
scaling: Let layouts stretch to fill the panel See merge request World/Phosh/squeekboard!702
This commit is contained in:
@ -106,8 +106,14 @@ You can change the height of the panel for the keyboard with:
|
|||||||
$ gsettings set sm.puri.Squeekboard scale-in-horizontal-screen-orientation 1.0
|
$ gsettings set sm.puri.Squeekboard scale-in-horizontal-screen-orientation 1.0
|
||||||
$ gsettings set sm.puri.Squeekboard scale-in-vertical-screen-orientation 1.0
|
$ gsettings set sm.puri.Squeekboard scale-in-vertical-screen-orientation 1.0
|
||||||
```
|
```
|
||||||
|
and wether or not layouts will stretch to fit the panel with:
|
||||||
|
|
||||||
Note: If the keyboard is open when the settings for the panel-height are changed, the height of the keyboard will not change until it is opened again, or the layout is changed.
|
```sh
|
||||||
|
$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel true
|
||||||
|
$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel false
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: If the keyboard is open when the settings are changed, the changes will not be visible until the keyboard is opened again, or the layout is changed.
|
||||||
While using Phosh, you can long-click/long-tap the home-bar at the bottom, to open and close the keyboard.
|
While using Phosh, you can long-click/long-tap the home-bar at the bottom, to open and close the keyboard.
|
||||||
|
|
||||||
To reset the settings to the default, you can use:
|
To reset the settings to the default, you can use:
|
||||||
|
|||||||
@ -27,6 +27,15 @@
|
|||||||
For square screens, the setting for screens in landscape-orientation is used.
|
For square screens, the setting for screens in landscape-orientation is used.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name='layout-shape-changes-to-fit-panel' type='b'>
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Wether layouts will stretch to fit the panel or not</summary>
|
||||||
|
<description>
|
||||||
|
While this setting is active, the proportions of layouts can change,
|
||||||
|
to fit the available space on the panel.
|
||||||
|
It can be useful to deactivate this while designing layouts.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
|
||||||
|
|||||||
@ -67,9 +67,18 @@ scale = 1.00
|
|||||||
|
|
||||||
### Layout-stretching
|
### Layout-stretching
|
||||||
|
|
||||||
Squeekboard may slightly stretch layouts horizontally (up to 5.5%) before showing them.
|
Layouts will adjust their proportions to fit the available space on a panel.
|
||||||
For creating layouts with precise sizes, it can be useful to disable this.
|
For creating layouts with precise sizes, it can be useful to deactivate this with:
|
||||||
This can be done by changing the value `1.055` in the line `let scale_x = if (h_scale / v_scale) < 1.055 { h_scale } else { v_scale };` of the `calculate_transformation` function in `src/layout.rs` to `1.0`, before building Squeekboard.
|
|
||||||
|
```
|
||||||
|
$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel false
|
||||||
|
```
|
||||||
|
|
||||||
|
It can be activated again with:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel true
|
||||||
|
```
|
||||||
|
|
||||||
Layout syntax
|
Layout syntax
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
114
src/layout.rs
114
src/layout.rs
@ -17,6 +17,8 @@
|
|||||||
* and let the renderer scale and center it within the widget.
|
* and let the renderer scale and center it within the widget.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use gdk::prelude::SettingsExt;
|
||||||
|
use gio::Settings;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
@ -809,17 +811,39 @@ impl LayoutData {
|
|||||||
&self,
|
&self,
|
||||||
available: Size,
|
available: Size,
|
||||||
) -> c::Transformation {
|
) -> c::Transformation {
|
||||||
|
let gsettings = Settings::new("sm.puri.Squeekboard");
|
||||||
|
let stretch_layout_to_fit_panel = gsettings.boolean ("layout-shape-changes-to-fit-panel");
|
||||||
|
|
||||||
|
let layout_stretching_limit: f64;
|
||||||
|
if stretch_layout_to_fit_panel == true {
|
||||||
|
// The "Base"-layout-shape is intended for use on small displays,
|
||||||
|
// and thus should fill the available space.
|
||||||
|
if self.kind == ArrangementKind::Base { layout_stretching_limit = 5.0 }
|
||||||
|
// The "Wide"-layout-shape is also used on monitors,
|
||||||
|
// and thus should not stretch more than necessary.
|
||||||
|
else { layout_stretching_limit = 1.4 }
|
||||||
|
}
|
||||||
|
else { layout_stretching_limit = 1.0 }
|
||||||
|
|
||||||
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;
|
||||||
// Allow up to 5% (and a bit more) horizontal stretching for filling up available space
|
// Stretch layouts to fill available space, up to some reasonable limits.
|
||||||
let scale_x = if (h_scale / v_scale) < 1.055 { h_scale } else { v_scale };
|
// TODO: On screens that are too large to be held during normal use (such as monitors),
|
||||||
let scale_y = cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0;
|
// layouts should probably not stretch to fit the panel.
|
||||||
|
let scale_x = if stretch_layout_to_fit_panel == true {
|
||||||
|
if (h_scale / v_scale) <= layout_stretching_limit { h_scale }
|
||||||
|
else { v_scale }
|
||||||
|
}
|
||||||
|
else if h_scale / v_scale < 1.0 { h_scale }
|
||||||
|
else { v_scale };
|
||||||
|
let scale_y = if stretch_layout_to_fit_panel == true && h_scale / v_scale > 0.49 { v_scale }
|
||||||
|
else { cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0 };
|
||||||
let outside_margins = c::Transformation {
|
let outside_margins = c::Transformation {
|
||||||
origin_x: (available.width - (scale_x * size.width)) / 2.0,
|
origin_x: (available.width - (scale_x * size.width)) / 2.0,
|
||||||
origin_y: (available.height - (scale_y * size.height)) / 2.0,
|
origin_y: (available.height - (scale_y * size.height)) / 2.0,
|
||||||
scale_x: scale_x,
|
scale_x,
|
||||||
scale_y: scale_y,
|
scale_y,
|
||||||
};
|
};
|
||||||
outside_margins.chain(c::Transformation {
|
outside_margins.chain(c::Transformation {
|
||||||
origin_x: self.margins.left,
|
origin_x: self.margins.left,
|
||||||
@ -1559,7 +1583,10 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_bottom_margin() {
|
fn check_bottom_margin() {
|
||||||
// just one button
|
// TODO: This should work correctly independent from the current settings on the system.
|
||||||
|
let gsettings = Settings::new("sm.puri.Squeekboard");
|
||||||
|
let stretch_layout_to_fit_panel = gsettings.boolean("layout-shape-changes-to-fit-panel");
|
||||||
|
// Just one button
|
||||||
let view = View::new(vec![
|
let view = View::new(vec![
|
||||||
(
|
(
|
||||||
0.0,
|
0.0,
|
||||||
@ -1595,21 +1622,25 @@ mod test {
|
|||||||
layout.calculate_size(),
|
layout.calculate_size(),
|
||||||
Size { width: 1.0, height: 2.0 }
|
Size { width: 1.0, height: 2.0 }
|
||||||
);
|
);
|
||||||
// Don't change those values randomly!
|
// Do not change these values randomly,
|
||||||
// They take advantage of incidental precise float representation
|
// because these are comparable due to incidentally precise float-representation.
|
||||||
// to even be comparable.
|
|
||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 2.0, height: 2.0 }
|
Size { width: 2.0, height: 2.0 } // Panel with a size of 2x2 pixels.
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale_x, 1.0);
|
let scale_x_comparison = if stretch_layout_to_fit_panel == true { 2.0 } else { 1.0 };
|
||||||
assert_eq!(transformation.scale_y, 1.0);
|
let origin_x_comparison = if stretch_layout_to_fit_panel == true { 0.0 } else { 0.5 };
|
||||||
assert_eq!(transformation.origin_x, 0.5);
|
assert_eq!(transformation.scale_x, scale_x_comparison, "transformation.scale_x changed.");
|
||||||
assert_eq!(transformation.origin_y, 0.0);
|
assert_eq!(transformation.scale_y, 1.0, "transformation.scale_y changed.");
|
||||||
|
assert_eq!(transformation.origin_x, origin_x_comparison, "transformation.origin_x changed.");
|
||||||
|
assert_eq!(transformation.origin_y, 0.0, "transformation.origin_y changed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_stretching() {
|
fn check_stretching() {
|
||||||
// just one button
|
// TODO: This should work correctly independent from the current settings on the system.
|
||||||
|
let gsettings = Settings::new("sm.puri.Squeekboard");
|
||||||
|
let stretch_layout_to_fit_panel = gsettings.boolean("layout-shape-changes-to-fit-panel");
|
||||||
|
// Just one button
|
||||||
let view = View::new(vec![
|
let view = View::new(vec![
|
||||||
(
|
(
|
||||||
0.0,
|
0.0,
|
||||||
@ -1636,25 +1667,58 @@ mod test {
|
|||||||
},
|
},
|
||||||
purpose: ContentPurpose::Normal,
|
purpose: ContentPurpose::Normal,
|
||||||
};
|
};
|
||||||
|
// Test that layouts will keep their defined proportions,
|
||||||
|
// if those fit the panel precisely.
|
||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 100.0, height: 100.0 }
|
Size { width: 100.0, height: 100.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale_x, 100.0);
|
assert_eq!(transformation.scale_x, 100.0,
|
||||||
assert_eq!(transformation.scale_y, 100.0);
|
"Layout-width changed when it was supposed to not change.");
|
||||||
|
assert_eq!(transformation.scale_y, 100.0,
|
||||||
|
"Layout-height changed when it was supposed to not change.");
|
||||||
|
// Test that layouts will keep their defined proportions when their size decreases,
|
||||||
|
// if layout-stretching is off.
|
||||||
|
if stretch_layout_to_fit_panel == false {
|
||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 95.0, height: 100.0 }
|
Size { width: 95.0, height: 100.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale_x, 95.0);
|
assert_eq!(transformation.scale_x, 95.0,
|
||||||
assert_eq!(transformation.scale_y, 95.0);
|
"Layout-width did not decrease by the expected amount.");
|
||||||
|
assert_eq!(transformation.scale_y, 95.0,
|
||||||
|
"Layout-height did not decrease by the expected amount.");
|
||||||
|
}
|
||||||
|
// Test that layouts adjust to the panel-size, if layout-stretching is on.
|
||||||
|
if stretch_layout_to_fit_panel == true {
|
||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 105.0, height: 100.0 }
|
Size { width: 500.0, height: 100.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale_x, 105.0);
|
assert_eq!(transformation.scale_x, 500.0,
|
||||||
assert_eq!(transformation.scale_y, 100.0);
|
"Layout-width did not increase by the expected amount.");
|
||||||
|
assert_eq!(transformation.scale_y, 100.0,
|
||||||
|
"Layout-height changed when it was supposed to not change.");
|
||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 106.0, height: 100.0 }
|
Size { width: 100.0, height: 204.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale_x, 100.0);
|
assert_eq!(transformation.scale_x, 100.0,
|
||||||
assert_eq!(transformation.scale_y, 100.0);
|
"Layout-width changed when it was supposed to not change.");
|
||||||
|
assert_eq!(transformation.scale_y, 204.0,
|
||||||
|
"Layout-height did not increase by the expected amount.");
|
||||||
|
// Test that layouts will keep their defined proportions,
|
||||||
|
// if those cannot reach the borders of the screen without stretching by more than the limit.
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 501.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0,
|
||||||
|
"Layout-width changed when it was supposed to not change.");
|
||||||
|
assert_eq!(transformation.scale_y, 100.0,
|
||||||
|
"Layout-height changed when it was supposed to not change.");
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 100.0, height: 205.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0,
|
||||||
|
"Layout-width changed when it was supposed to not change.");
|
||||||
|
assert_eq!(transformation.scale_y, 100.0,
|
||||||
|
"Layout-height changed when it was supposed to not change.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user