Add and use TwoRowColToplevelLayout
This tries to find a split point in the list of toplevels to maximize the scale factor when calling `RowColToplevelLayout` twice. If it doesn't get a better scale factor, it just uses a single row/column. Some things don't seem quite right, but the existing layout is not perfect, and this can help. Without the added cross axis spacing, there's overlap, so there may be something wrong with the requested sizes...
This commit is contained in:
parent
1fd7a86ecc
commit
7ab1f93acf
3 changed files with 77 additions and 3 deletions
|
|
@ -11,19 +11,19 @@ use cosmic::iced::{
|
|||
use std::marker::PhantomData;
|
||||
|
||||
mod toplevel_layout;
|
||||
use toplevel_layout::{LayoutToplevel, RowColToplevelLayout, ToplevelLayout};
|
||||
use toplevel_layout::{LayoutToplevel, ToplevelLayout, TwoRowColToplevelLayout};
|
||||
|
||||
pub fn toplevels<Msg>(children: Vec<cosmic::Element<Msg>>) -> Toplevels<Msg> {
|
||||
Toplevels {
|
||||
// TODO configurable
|
||||
layout: RowColToplevelLayout::new(Axis::Horizontal, 16),
|
||||
layout: TwoRowColToplevelLayout::new(Axis::Horizontal, 16),
|
||||
children,
|
||||
_msg: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Toplevels<'a, Msg> {
|
||||
layout: RowColToplevelLayout,
|
||||
layout: TwoRowColToplevelLayout,
|
||||
children: Vec<cosmic::Element<'a, Msg>>,
|
||||
_msg: PhantomData<Msg>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ use std::marker::PhantomData;
|
|||
mod axis_toplevel_layout;
|
||||
mod row_col_toplevel_layout;
|
||||
pub(crate) use row_col_toplevel_layout::RowColToplevelLayout;
|
||||
mod two_row_col_toplevel_layout;
|
||||
pub(crate) use two_row_col_toplevel_layout::TwoRowColToplevelLayout;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct LayoutToplevel<'a, S = Size> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
use cosmic::iced::{advanced::layout::flex::Axis, Length};
|
||||
|
||||
use super::{
|
||||
axis_toplevel_layout::{AxisPoint, AxisRectangle, AxisSize, AxisToplevelLayout},
|
||||
row_col_toplevel_layout::RowColToplevelLayout,
|
||||
LayoutToplevel,
|
||||
};
|
||||
|
||||
pub(crate) struct TwoRowColToplevelLayout(RowColToplevelLayout);
|
||||
|
||||
impl TwoRowColToplevelLayout {
|
||||
pub fn new(axis: Axis, spacing: u32) -> Self {
|
||||
Self(RowColToplevelLayout::new(axis, spacing))
|
||||
}
|
||||
}
|
||||
|
||||
impl AxisToplevelLayout for TwoRowColToplevelLayout {
|
||||
fn axis(&self) -> &Axis {
|
||||
&self.0.axis
|
||||
}
|
||||
|
||||
fn size(&self) -> AxisSize<Length> {
|
||||
AxisSize {
|
||||
main: Length::Fill,
|
||||
cross: Length::Shrink,
|
||||
}
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&self,
|
||||
max_limit: AxisSize,
|
||||
toplevels: &[LayoutToplevel<'_, AxisSize>],
|
||||
) -> impl Iterator<Item = AxisRectangle> {
|
||||
let requested_main_total = self.0.requested_main_total(&toplevels);
|
||||
let scale_factor = self.0.scale_factor(max_limit, toplevels);
|
||||
|
||||
let half_max_limit = AxisSize {
|
||||
main: max_limit.main,
|
||||
cross: max_limit.cross / 2. - self.0.spacing as f32,
|
||||
};
|
||||
|
||||
// See if two row layout is better
|
||||
// TODO not a good fix if there is a large window and many smaller ones?
|
||||
if requested_main_total > max_limit.main && toplevels.len() > 1 {
|
||||
// decide best way to partition list
|
||||
let (split_point, two_row_scale_factor) = (1..toplevels.len())
|
||||
.map(|i| {
|
||||
let (top_row, bottom_row) = toplevels.split_at(i);
|
||||
let top_scale_factor = self.0.scale_factor(half_max_limit, top_row);
|
||||
let bottom_scale_factor = self.0.scale_factor(half_max_limit, bottom_row);
|
||||
(i, top_scale_factor.min(bottom_scale_factor))
|
||||
})
|
||||
.max_by(|(_, scale1), (_, scale2)| scale1.total_cmp(scale2))
|
||||
.unwrap();
|
||||
// Better layout
|
||||
if two_row_scale_factor > scale_factor {
|
||||
// TODO padding
|
||||
let row1 = self.0.layout(half_max_limit, &toplevels[..split_point]);
|
||||
let row2 = self
|
||||
.0
|
||||
.layout(half_max_limit, &toplevels[split_point..])
|
||||
.map(move |mut rect| {
|
||||
rect.origin.cross += max_limit.cross / 2. + self.0.spacing as f32;
|
||||
rect
|
||||
});
|
||||
return itertools::Either::Left(row1.chain(row2));
|
||||
}
|
||||
}
|
||||
|
||||
itertools::Either::Right(self.0.layout(max_limit, toplevels))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue