Onion/image: make Image a fill-type tab (None | Solid | Gradient | Image)
Image fill is now a tab in the Fill type row rather than a separate dropdown. When Image is active, an asset-picker combo selects which image; switching to None/Solid/ Gradient clears the image fill (it otherwise overrides them). The Image tab only appears when there are imported image assets.
This commit is contained in:
parent
6fc3a131a6
commit
aad2d5c515
|
|
@ -812,47 +812,67 @@ impl InfopanelPane {
|
||||||
self.shape_section_open = true;
|
self.shape_section_open = true;
|
||||||
ui.add_space(4.0);
|
ui.add_space(4.0);
|
||||||
|
|
||||||
// Fill — determine current fill type
|
// Fill — determine current fill type. `image_fill` takes render priority,
|
||||||
|
// so when set it's the active type (overriding colour/gradient underneath);
|
||||||
|
// switching to None/Solid/Gradient clears it.
|
||||||
|
let has_image = current_image_fill.is_some();
|
||||||
let has_gradient = matches!(&info.fill_gradient, Some(Some(_)));
|
let has_gradient = matches!(&info.fill_gradient, Some(Some(_)));
|
||||||
let has_solid = matches!(&info.fill_color, Some(Some(_)));
|
let has_solid = matches!(&info.fill_color, Some(Some(_)));
|
||||||
let fill_is_none = matches!(&info.fill_color, Some(None))
|
let fill_is_none = matches!(&info.fill_color, Some(None))
|
||||||
&& matches!(&info.fill_gradient, Some(None));
|
&& matches!(&info.fill_gradient, Some(None));
|
||||||
let fill_mixed = info.fill_color.is_none() && info.fill_gradient.is_none();
|
let fill_mixed = info.fill_color.is_none() && info.fill_gradient.is_none();
|
||||||
|
|
||||||
// Fill type toggle row
|
// Fill type toggle row: None | Solid | Gradient | Image
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Fill:");
|
ui.label("Fill:");
|
||||||
if fill_mixed {
|
if fill_mixed {
|
||||||
ui.label("--");
|
ui.label("--");
|
||||||
} else {
|
} else {
|
||||||
if ui.selectable_label(fill_is_none, "None").clicked() && !fill_is_none {
|
if ui.selectable_label(fill_is_none && !has_image, "None").clicked() {
|
||||||
let action = SetFillPaintAction::solid(
|
if has_image {
|
||||||
layer_id, time, face_ids.clone(), None,
|
shared.pending_actions.push(Box::new(
|
||||||
);
|
SetImageFillAction::new(layer_id, time, face_ids.clone(), None)));
|
||||||
shared.pending_actions.push(Box::new(action));
|
}
|
||||||
|
shared.pending_actions.push(Box::new(
|
||||||
|
SetFillPaintAction::solid(layer_id, time, face_ids.clone(), None)));
|
||||||
}
|
}
|
||||||
if ui.selectable_label(has_solid || (!has_gradient && !fill_is_none), "Solid").clicked() && !has_solid {
|
if ui.selectable_label(has_solid && !has_image, "Solid").clicked() {
|
||||||
// Switch to solid: use existing color or default to black
|
if has_image {
|
||||||
let color = info.fill_color.flatten()
|
shared.pending_actions.push(Box::new(
|
||||||
.unwrap_or(ShapeColor::rgba(0, 0, 0, 255));
|
SetImageFillAction::new(layer_id, time, face_ids.clone(), None)));
|
||||||
let action = SetFillPaintAction::solid(
|
}
|
||||||
layer_id, time, face_ids.clone(), Some(color),
|
if !has_solid {
|
||||||
);
|
let color = info.fill_color.flatten()
|
||||||
shared.pending_actions.push(Box::new(action));
|
.unwrap_or(ShapeColor::rgba(0, 0, 0, 255));
|
||||||
|
shared.pending_actions.push(Box::new(
|
||||||
|
SetFillPaintAction::solid(layer_id, time, face_ids.clone(), Some(color))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ui.selectable_label(has_gradient, "Gradient").clicked() && !has_gradient {
|
if ui.selectable_label(has_gradient && !has_image, "Gradient").clicked() {
|
||||||
let grad = info.fill_gradient.clone().flatten()
|
if has_image {
|
||||||
.unwrap_or_default();
|
shared.pending_actions.push(Box::new(
|
||||||
let action = SetFillPaintAction::gradient(
|
SetImageFillAction::new(layer_id, time, face_ids.clone(), None)));
|
||||||
layer_id, time, face_ids.clone(), Some(grad),
|
}
|
||||||
);
|
if !has_gradient {
|
||||||
shared.pending_actions.push(Box::new(action));
|
let grad = info.fill_gradient.clone().flatten().unwrap_or_default();
|
||||||
|
shared.pending_actions.push(Box::new(
|
||||||
|
SetFillPaintAction::gradient(layer_id, time, face_ids.clone(), Some(grad))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Image tab — only offered if there are imported image assets.
|
||||||
|
if !image_assets.is_empty() || has_image {
|
||||||
|
if ui.selectable_label(has_image, "Image").clicked() && !has_image {
|
||||||
|
if let Some((aid, _)) = image_assets.first() {
|
||||||
|
shared.pending_actions.push(Box::new(
|
||||||
|
SetImageFillAction::new(layer_id, time, face_ids.clone(), Some(*aid))));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Solid fill color editor
|
// Solid fill color editor
|
||||||
if !fill_mixed && has_solid {
|
if !fill_mixed && has_solid && !has_image {
|
||||||
if let Some(Some(color)) = info.fill_color {
|
if let Some(Some(color)) = info.fill_color {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let mut rgba = [color.r, color.g, color.b, color.a];
|
let mut rgba = [color.r, color.g, color.b, color.a];
|
||||||
|
|
@ -868,7 +888,7 @@ impl InfopanelPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gradient fill editor
|
// Gradient fill editor
|
||||||
if !fill_mixed && has_gradient {
|
if !fill_mixed && has_gradient && !has_image {
|
||||||
if let Some(Some(mut grad)) = info.fill_gradient.clone() {
|
if let Some(Some(mut grad)) = info.fill_gradient.clone() {
|
||||||
if gradient_stop_editor(ui, &mut grad, &mut self.selected_shape_gradient_stop) {
|
if gradient_stop_editor(ui, &mut grad, &mut self.selected_shape_gradient_stop) {
|
||||||
let action = SetFillPaintAction::gradient(
|
let action = SetFillPaintAction::gradient(
|
||||||
|
|
@ -879,22 +899,17 @@ impl InfopanelPane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image fill picker (assign/clear an imported image asset on the fill).
|
// Image fill editor — pick which asset (active Image type).
|
||||||
if !face_ids.is_empty() {
|
if has_image {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Image:");
|
ui.label("Image:");
|
||||||
let selected_text = current_image_fill
|
let selected_text = current_image_fill
|
||||||
.and_then(|id| image_assets.iter().find(|(aid, _)| *aid == id))
|
.and_then(|id| image_assets.iter().find(|(aid, _)| *aid == id))
|
||||||
.map(|(_, n)| n.clone())
|
.map(|(_, n)| n.clone())
|
||||||
.unwrap_or_else(|| "None".to_string());
|
.unwrap_or_else(|| "(missing)".to_string());
|
||||||
egui::ComboBox::from_id_salt(("image_fill", path))
|
egui::ComboBox::from_id_salt(("image_fill", path))
|
||||||
.selected_text(selected_text)
|
.selected_text(selected_text)
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
if ui.selectable_label(current_image_fill.is_none(), "None").clicked() {
|
|
||||||
shared.pending_actions.push(Box::new(
|
|
||||||
SetImageFillAction::new(layer_id, time, face_ids.clone(), None),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
for (aid, name) in &image_assets {
|
for (aid, name) in &image_assets {
|
||||||
if ui.selectable_label(current_image_fill == Some(*aid), name).clicked() {
|
if ui.selectable_label(current_image_fill == Some(*aid), name).clicked() {
|
||||||
shared.pending_actions.push(Box::new(
|
shared.pending_actions.push(Box::new(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue