Fixed panics in grid auto-grow and style instantiation.

This commit is contained in:
Samuel Guerra 2023-10-27 20:52:18 -03:00
parent f7f60cfc25
commit 6f848b0824
5 changed files with 75 additions and 47 deletions

View File

@ -826,15 +826,49 @@ fn form_editor_window(is_open: ArcVar<bool>) -> WindowRoot {
size = (400, 500);
child = Stack! {
padding = 10;
spacing = 5;
direction = StackDirection::top_to_bottom();
children = ui_vec![
form_field("Name:", var(Txt::from_static("my-crate"))),
form_field("Authors:", var(Txt::from_static("Jhon Doe"))),
form_field("Version:", var(Txt::from_static("0.1.0"))),
]
child = Grid! {
columns = ui_vec![grid::Column!(), grid::Column!(1.lft())];
spacing = (5, 10);
padding = 20;
label::extend_style = Style! {
txt_align = Align::END;
};
cells = ui_vec![
Label! {
txt = "Name";
target = "field-name";
},
TextInput! {
grid::cell::column = 1;
id = "field-name";
txt = var_from("my-crate");
},
Label! {
grid::cell::row = 1;
txt = "Authors";
target = "field-authors";
},
TextInput! {
grid::cell::row = 1;
grid::cell::column = 1;
id = "field-authors";
txt = var_from("Jhon Doe");
},
Label! {
grid::cell::row = 2;
txt = "Version";
target = "field-version";
},
TextInput! {
grid::cell::row = 2;
grid::cell::column = 1;
id = "field-version";
txt = var_from("0.1.0");
},
];
};
child_insert_below = {
@ -855,21 +889,3 @@ fn form_editor_window(is_open: ArcVar<bool>) -> WindowRoot {
};
}
}
fn form_field(label: impl IntoVar<Txt>, value: impl IntoVar<Txt>) -> impl UiNode {
let value_id = WidgetId::new_unique();
Stack! {
direction = StackDirection::left_to_right();
spacing = 5;
children = ui_vec![
Label! {
txt = label;
target = value_id;
},
TextInput! {
id = value_id;
txt = value;
}
]
}
}

View File

@ -33,6 +33,19 @@ context_var! {
pub static STYLE_VAR: StyleFn = StyleFn::new(|_| DefaultStyle!());
}
/// Sets the label style in a context, the parent style is fully replaced.
#[property(CONTEXT, default(STYLE_VAR))]
pub fn replace_style(child: impl UiNode, style: impl IntoVar<StyleFn>) -> impl UiNode {
with_context_var(child, STYLE_VAR, style)
}
/// Extends the label style in a context, the parent style is used, properties of the same name set in
/// `style` override the parent style.
#[property(CONTEXT, default(StyleFn::nil()))]
pub fn extend_style(child: impl UiNode, style: impl IntoVar<StyleFn>) -> impl UiNode {
style::with_style_extension(child, STYLE_VAR, style)
}
/// Default label style.
#[widget($crate::widgets::label::DefaultStyle)]
pub struct DefaultStyle(Style);

View File

@ -1165,28 +1165,28 @@ impl GridLayout {
}
let max_auto_placed = max_auto_placed_i / columns_len + 1;
let max_needed = max_auto_placed.max(max_custom).min(max as usize);
let max_needed_len = max_auto_placed.max(max_custom).min(max as usize) + 1;
let rows_len = children[1].len();
#[allow(clippy::comparison_chain)]
if rows_len < max_needed {
if rows_len < max_needed_len {
let auto = downcast_auto(&mut children[1]);
let mut index = rows_len;
let view = auto_grow_fn.get();
if view.is_nil() {
imaginary_rows = max_needed - rows_len;
imaginary_rows = max_needed_len - rows_len;
} else {
while index < max_needed {
while index < max_needed_len {
let mut row = view(AutoGrowFnArgs { mode: auto_mode, index });
row.init();
auto.push(row);
index += 1;
}
}
} else if rows_len > max_needed {
let remove = rows_len - max_needed;
} else if rows_len > max_needed_len {
let remove = rows_len - max_needed_len;
let auto = downcast_auto(&mut children[1]);
for mut auto in auto.drain(auto.len().saturating_sub(remove)..) {
auto.deinit();
@ -1206,28 +1206,28 @@ impl GridLayout {
}
let max_auto_placed = max_auto_placed_i / rows_len + 1;
let max_needed = max_auto_placed.max(max_custom).min(max as usize);
let max_needed_len = max_auto_placed.max(max_custom).min(max as usize) + 1;
let cols_len = children[0].len();
#[allow(clippy::comparison_chain)]
if cols_len < max_needed {
if cols_len < max_needed_len {
let auto = downcast_auto(&mut children[0]);
let mut index = cols_len;
let view = auto_grow_fn.get();
if view.is_nil() {
imaginary_cols = max_needed - cols_len;
imaginary_cols = max_needed_len - cols_len;
} else {
while index < max_needed {
while index < max_needed_len {
let mut column = view(AutoGrowFnArgs { mode: auto_mode, index });
column.init();
auto.push(column);
index += 1;
}
}
} else if cols_len > max_needed {
let remove = cols_len - max_needed;
} else if cols_len > max_needed_len {
let remove = cols_len - max_needed_len;
let auto = downcast_auto(&mut children[0]);
for mut auto in auto.drain(auto.len().saturating_sub(remove)..) {
auto.deinit();

View File

@ -837,15 +837,11 @@ impl SCROLL {
}
/// Scroll the [`WIDGET`] into view.
///
/// This requests [`commands::scroll_to_info`] for the contextual widget.
pub fn scroll_to(&self, mode: impl Into<super::commands::ScrollToMode>) {
commands::scroll_to(WIDGET.info(), mode.into())
}
/// Scroll the [`WIDGET`] into view and adjusts the zoom scale.
///
/// This requests [`commands::scroll_to_info_zoom`] for the contextual widget.
pub fn scroll_to_zoom(&self, mode: impl Into<super::commands::ScrollToMode>, zoom: impl Into<Factor>) {
commands::scroll_to_zoom(WIDGET.info(), mode.into(), zoom.into())
}

View File

@ -365,10 +365,13 @@ impl StyleFn {
} else if other.is_nil() {
self
} else {
StyleFn::new(move |args| {
let mut r = self(args).unwrap();
r.extend(other(args).unwrap());
r
StyleFn::new(move |args| match (self(args), other(args)) {
(Some(mut a), Some(b)) => {
a.extend(b);
a
}
(Some(r), None) | (None, Some(r)) => r,
_ => StyleBuilder::default(),
})
}
}