feat: per-viewport layer freeze columns in Layer Manager
Add VP freeze/thaw toggle columns to the layer panel when in a paper space layout. Each viewport gets its own column (VP 1, VP 2, …) showing a freeze icon per layer. Clicking toggles frozen_layers on the Viewport entity and syncs back to the panel. - scene: viewport_list() → [(handle, label, frozen_handles)] - LayerPanel: VpCol + vp_frozen per layer, sync_with_viewports() - Message::LayerToggleVpFreeze(layer_idx, vp_col_idx) - Sync VP columns on layout switch, VPLAYER cmd, undo/redo, layer ops Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c2f1c9078f
commit
efc259fdbe
6 changed files with 187 additions and 43 deletions
|
|
@ -348,6 +348,10 @@ impl H7CAD {
|
||||||
if thawed_count > 0 {
|
if thawed_count > 0 {
|
||||||
self.command_line.push_info(&format!("VPLAYER: {thawed_count} layer(s) thawed in viewport."));
|
self.command_line.push_info(&format!("VPLAYER: {thawed_count} layer(s) thawed in viewport."));
|
||||||
}
|
}
|
||||||
|
// Sync layer panel so VP freeze columns update immediately.
|
||||||
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show updated prompt (command stays active for more operations).
|
// Show updated prompt (command stays active for more operations).
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ impl H7CAD {
|
||||||
self.tabs[i].active_grip = None;
|
self.tabs[i].active_grip = None;
|
||||||
self.tabs[i].dirty = snapshot.dirty;
|
self.tabs[i].dirty = snapshot.dirty;
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,8 @@ pub enum Message {
|
||||||
LayerToggleVisible(usize),
|
LayerToggleVisible(usize),
|
||||||
LayerToggleLock(usize),
|
LayerToggleLock(usize),
|
||||||
LayerToggleFreeze(usize),
|
LayerToggleFreeze(usize),
|
||||||
|
/// Toggle per-viewport freeze: (layer_index, vp_col_index)
|
||||||
|
LayerToggleVpFreeze(usize, usize),
|
||||||
LayerNew,
|
LayerNew,
|
||||||
LayerDelete,
|
LayerDelete,
|
||||||
LayerSetCurrent,
|
LayerSetCurrent,
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@ impl H7CAD {
|
||||||
crate::linetypes::populate_document(&mut self.tabs[i].scene.document);
|
crate::linetypes::populate_document(&mut self.tabs[i].scene.document);
|
||||||
self.tabs[i].properties = PropertiesPanel::empty();
|
self.tabs[i].properties = PropertiesPanel::empty();
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
self.tabs[i].scene.fit_all();
|
self.tabs[i].scene.fit_all();
|
||||||
self.tabs[i].dirty = false;
|
self.tabs[i].dirty = false;
|
||||||
|
|
@ -144,7 +145,8 @@ impl H7CAD {
|
||||||
crate::linetypes::populate_document(&mut self.tabs[i].scene.document);
|
crate::linetypes::populate_document(&mut self.tabs[i].scene.document);
|
||||||
self.tabs[i].properties = PropertiesPanel::empty();
|
self.tabs[i].properties = PropertiesPanel::empty();
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output("Scene cleared. Standard linetypes loaded.");
|
.push_output("Scene cleared. Standard linetypes loaded.");
|
||||||
self.tabs[i].current_path = None;
|
self.tabs[i].current_path = None;
|
||||||
|
|
@ -438,6 +440,43 @@ impl H7CAD {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::LayerToggleVpFreeze(layer_idx, vp_col_idx) => {
|
||||||
|
let i = self.active_tab;
|
||||||
|
let vp_handle = self.tabs[i].layers.vp_cols.get(vp_col_idx)
|
||||||
|
.map(|c| c.handle);
|
||||||
|
let layer_name = self.tabs[i].layers.layers.get(layer_idx)
|
||||||
|
.map(|l| l.name.clone());
|
||||||
|
|
||||||
|
if let (Some(vp_handle), Some(layer_name)) = (vp_handle, layer_name) {
|
||||||
|
// Get the layer handle from the document
|
||||||
|
if let Some(doc_layer) = self.tabs[i].scene.document.layers.get(&layer_name) {
|
||||||
|
let layer_handle = doc_layer.handle;
|
||||||
|
self.push_undo_snapshot(i, "VPLAYER");
|
||||||
|
|
||||||
|
// Toggle frozen_layers on the viewport entity
|
||||||
|
for e in self.tabs[i].scene.document.entities_mut() {
|
||||||
|
if let acadrust::EntityType::Viewport(vp) = e {
|
||||||
|
if vp.common.handle == vp_handle {
|
||||||
|
if vp.frozen_layers.contains(&layer_handle) {
|
||||||
|
vp.frozen_layers.retain(|h| h != &layer_handle);
|
||||||
|
} else {
|
||||||
|
vp.frozen_layers.push(layer_handle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-sync layer panel with updated VP info
|
||||||
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
Message::LayerNew => {
|
Message::LayerNew => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let mut n = 1;
|
let mut n = 1;
|
||||||
|
|
@ -453,7 +492,8 @@ impl H7CAD {
|
||||||
let _ = self.tabs[i].scene.document.layers.add(DocLayer::new(&new_name));
|
let _ = self.tabs[i].scene.document.layers.add(DocLayer::new(&new_name));
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
let new_idx = self.tabs[i].layers.layers.iter()
|
let new_idx = self.tabs[i].layers.layers.iter()
|
||||||
.position(|l| l.name == new_name);
|
.position(|l| l.name == new_name);
|
||||||
if let Some(idx) = new_idx {
|
if let Some(idx) = new_idx {
|
||||||
|
|
@ -476,7 +516,8 @@ impl H7CAD {
|
||||||
self.tabs[i].scene.document.layers.remove(&name);
|
self.tabs[i].scene.document.layers.remove(&name);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.tabs[i].layers.selected = None;
|
self.tabs[i].layers.selected = None;
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
}
|
}
|
||||||
|
|
@ -549,7 +590,8 @@ impl H7CAD {
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
}
|
}
|
||||||
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
self.tabs[i].layers.sync_from_doc(&doc_layers);
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
self.tabs[i].layers.edit_buf.clear();
|
self.tabs[i].layers.edit_buf.clear();
|
||||||
self.sync_ribbon_layers();
|
self.sync_ribbon_layers();
|
||||||
}
|
}
|
||||||
|
|
@ -1682,6 +1724,10 @@ impl H7CAD {
|
||||||
} else if self.ribbon.active_is_layout() {
|
} else if self.ribbon.active_is_layout() {
|
||||||
self.ribbon.select(0);
|
self.ribbon.select(0);
|
||||||
}
|
}
|
||||||
|
// Refresh VP freeze columns for the new layout.
|
||||||
|
let doc_layers = self.tabs[i].scene.document.layers.clone();
|
||||||
|
let vp_info = self.tabs[i].scene.viewport_list();
|
||||||
|
self.tabs[i].layers.sync_with_viewports(&doc_layers, vp_info);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,37 @@ impl Scene {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List of user viewports in the current layout: (handle, label, frozen_layer_handles).
|
||||||
|
pub fn viewport_list(&self) -> Vec<(acadrust::Handle, String, Vec<acadrust::Handle>)> {
|
||||||
|
if self.current_layout == "Model" {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let layout_block = self.current_layout_block_handle();
|
||||||
|
if layout_block.is_null() {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let mut result: Vec<(acadrust::Handle, String, Vec<acadrust::Handle>)> = self
|
||||||
|
.document
|
||||||
|
.entities()
|
||||||
|
.filter_map(|e| {
|
||||||
|
if let EntityType::Viewport(vp) = e {
|
||||||
|
if vp.id > 1 && vp.common.owner_handle == layout_block {
|
||||||
|
Some((vp.common.handle, vp.id, vp.frozen_layers.clone()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(h, id, frozen)| (h, format!("VP {}", id - 1), frozen))
|
||||||
|
.collect();
|
||||||
|
result.sort_by_key(|(_, label, _)| label.clone());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/// Count of user viewports (id > 1) in the current layout.
|
/// Count of user viewports (id > 1) in the current layout.
|
||||||
pub fn viewport_count(&self) -> usize {
|
pub fn viewport_count(&self) -> usize {
|
||||||
if self.current_layout == "Model" {
|
if self.current_layout == "Model" {
|
||||||
|
|
|
||||||
134
src/ui/layers.rs
134
src/ui/layers.rs
|
|
@ -6,6 +6,7 @@ use acadrust::tables::layer::Layer as DocLayer;
|
||||||
use acadrust::tables::Table;
|
use acadrust::tables::Table;
|
||||||
use acadrust::types::aci_table::aci_to_rgb;
|
use acadrust::types::aci_table::aci_to_rgb;
|
||||||
use acadrust::types::{Color as AcadColor, LineWeight};
|
use acadrust::types::{Color as AcadColor, LineWeight};
|
||||||
|
use acadrust::Handle;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, column, combo_box, container, mouse_area, row, scrollable, text, text_input,
|
button, column, combo_box, container, mouse_area, row, scrollable, text, text_input,
|
||||||
};
|
};
|
||||||
|
|
@ -13,6 +14,14 @@ use iced::{Background, Border, Color, Element, Fill, Length, Theme};
|
||||||
use iced::Padding;
|
use iced::Padding;
|
||||||
use crate::ui::ROW_H;
|
use crate::ui::ROW_H;
|
||||||
|
|
||||||
|
// ── Per-viewport column descriptor ───────────────────────────────────────────
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct VpCol {
|
||||||
|
pub handle: Handle,
|
||||||
|
pub label: String,
|
||||||
|
}
|
||||||
|
|
||||||
// ── Row-height-derived constants ─────────────────────────────────────────
|
// ── Row-height-derived constants ─────────────────────────────────────────
|
||||||
/// SVG icon size inside a layer-table cell.
|
/// SVG icon size inside a layer-table cell.
|
||||||
const ICON_SZ: f32 = ROW_H * 0.62; // ≈16 px at ROW_H=26
|
const ICON_SZ: f32 = ROW_H * 0.62; // ≈16 px at ROW_H=26
|
||||||
|
|
@ -33,6 +42,8 @@ pub struct Layer {
|
||||||
pub linetype: String,
|
pub linetype: String,
|
||||||
pub lineweight: LineWeight,
|
pub lineweight: LineWeight,
|
||||||
pub transparency: i32,
|
pub transparency: i32,
|
||||||
|
/// Freeze state per-viewport, indexed parallel to LayerPanel::vp_cols.
|
||||||
|
pub vp_frozen: Vec<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layer {
|
impl Layer {
|
||||||
|
|
@ -46,6 +57,7 @@ impl Layer {
|
||||||
linetype: "Continuous".to_string(),
|
linetype: "Continuous".to_string(),
|
||||||
lineweight: LineWeight::Default,
|
lineweight: LineWeight::Default,
|
||||||
transparency: 0,
|
transparency: 0,
|
||||||
|
vp_frozen: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,6 +78,8 @@ pub struct LayerPanel {
|
||||||
pub color_full_palette: bool,
|
pub color_full_palette: bool,
|
||||||
pub linetype_combo: combo_box::State<LinetypeItem>,
|
pub linetype_combo: combo_box::State<LinetypeItem>,
|
||||||
pub lw_combo: combo_box::State<LwItem>,
|
pub lw_combo: combo_box::State<LwItem>,
|
||||||
|
/// Per-viewport columns (only populated when in a paper layout with viewports).
|
||||||
|
pub vp_cols: Vec<VpCol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LayerPanel {
|
impl Default for LayerPanel {
|
||||||
|
|
@ -84,27 +98,47 @@ impl Default for LayerPanel {
|
||||||
LinetypeItem { name: "Continuous".into(), art: String::new() }
|
LinetypeItem { name: "Continuous".into(), art: String::new() }
|
||||||
]),
|
]),
|
||||||
lw_combo: combo_box::State::new(lw_options()),
|
lw_combo: combo_box::State::new(lw_options()),
|
||||||
|
vp_cols: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayerPanel {
|
impl LayerPanel {
|
||||||
pub fn sync_from_doc(&mut self, doc_layers: &Table<DocLayer>) {
|
/// Sync layers + update per-viewport freeze columns.
|
||||||
|
/// `vp_info`: list of (vp_handle, vp_label, frozen_layer_handles) from scene.
|
||||||
|
pub fn sync_with_viewports(
|
||||||
|
&mut self,
|
||||||
|
doc_layers: &Table<DocLayer>,
|
||||||
|
vp_info: Vec<(Handle, String, Vec<Handle>)>,
|
||||||
|
) {
|
||||||
|
self.vp_cols = vp_info
|
||||||
|
.iter()
|
||||||
|
.map(|(h, label, _)| VpCol { handle: *h, label: label.clone() })
|
||||||
|
.collect();
|
||||||
|
|
||||||
self.layers = doc_layers
|
self.layers = doc_layers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| Layer {
|
.map(|l| {
|
||||||
name: l.name.clone(),
|
let layer_handle = l.handle;
|
||||||
visible: !l.flags.off,
|
let vp_frozen = vp_info
|
||||||
frozen: l.flags.frozen,
|
.iter()
|
||||||
locked: l.flags.locked,
|
.map(|(_, _, frozen_handles)| frozen_handles.contains(&layer_handle))
|
||||||
color: iced_color_from_acad(&l.color),
|
.collect();
|
||||||
linetype: if l.line_type.is_empty() {
|
Layer {
|
||||||
"Continuous".to_string()
|
name: l.name.clone(),
|
||||||
} else {
|
visible: !l.flags.off,
|
||||||
l.line_type.clone()
|
frozen: l.flags.frozen,
|
||||||
},
|
locked: l.flags.locked,
|
||||||
lineweight: l.line_weight,
|
color: iced_color_from_acad(&l.color),
|
||||||
transparency: 0,
|
linetype: if l.line_type.is_empty() {
|
||||||
|
"Continuous".to_string()
|
||||||
|
} else {
|
||||||
|
l.line_type.clone()
|
||||||
|
},
|
||||||
|
lineweight: l.line_weight,
|
||||||
|
transparency: 0,
|
||||||
|
vp_frozen,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
@ -143,28 +177,37 @@ impl LayerPanel {
|
||||||
.padding([4, 8]);
|
.padding([4, 8]);
|
||||||
|
|
||||||
// ── Column header ─────────────────────────────────────────────────
|
// ── Column header ─────────────────────────────────────────────────
|
||||||
let col_header = container(
|
let mut header_row = row![
|
||||||
row![
|
text("Status").size(10).color(DIM).width(50),
|
||||||
text("Status").size(10).color(DIM).width(50),
|
text("Name").size(10).color(DIM).width(Length::Fixed(COL_NAME)),
|
||||||
text("Name").size(10).color(DIM).width(Length::Fixed(COL_NAME)),
|
text("On").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
||||||
text("On").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
text("Freeze").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
||||||
text("Freeze").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
text("Lock").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
||||||
text("Lock").size(10).color(DIM).width(Length::Fixed(COL_ICON)),
|
text("Color").size(10).color(DIM).width(Length::Fixed(COL_COLOR)),
|
||||||
text("Color").size(10).color(DIM).width(Length::Fixed(COL_COLOR)),
|
text("Linetype").size(10).color(DIM).width(Length::Fixed(COL_LT)),
|
||||||
text("Linetype").size(10).color(DIM).width(Length::Fixed(COL_LT)),
|
text("Lineweight").size(10).color(DIM).width(Length::Fixed(COL_LW)),
|
||||||
text("Lineweight").size(10).color(DIM).width(Length::Fixed(COL_LW)),
|
text("Transparency").size(10).color(DIM).width(Length::Fixed(COL_TRANS)),
|
||||||
text("Transparency").size(10).color(DIM).width(Length::Fixed(COL_TRANS)),
|
]
|
||||||
]
|
.spacing(4)
|
||||||
.spacing(4)
|
.align_y(iced::Center);
|
||||||
.align_y(iced::Center),
|
|
||||||
)
|
for vp in &self.vp_cols {
|
||||||
.style(|_: &Theme| container::Style {
|
header_row = header_row.push(
|
||||||
background: Some(Background::Color(COL_HEADER_BG)),
|
text(vp.label.as_str())
|
||||||
border: Border { color: BORDER_COLOR, width: 1.0, radius: 0.0.into() },
|
.size(10)
|
||||||
..Default::default()
|
.color(DIM)
|
||||||
})
|
.width(Length::Fixed(COL_ICON)),
|
||||||
.padding([4, 8])
|
);
|
||||||
.width(Fill);
|
}
|
||||||
|
|
||||||
|
let col_header = container(header_row)
|
||||||
|
.style(|_: &Theme| container::Style {
|
||||||
|
background: Some(Background::Color(COL_HEADER_BG)),
|
||||||
|
border: Border { color: BORDER_COLOR, width: 1.0, radius: 0.0.into() },
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.padding([4, 8])
|
||||||
|
.width(Fill);
|
||||||
|
|
||||||
// ── Layer rows ────────────────────────────────────────────────────
|
// ── Layer rows ────────────────────────────────────────────────────
|
||||||
let mut rows_col = column![].spacing(0);
|
let mut rows_col = column![].spacing(0);
|
||||||
|
|
@ -182,6 +225,7 @@ impl LayerPanel {
|
||||||
|
|
||||||
rows_col = rows_col.push(layer_row(
|
rows_col = rows_col.push(layer_row(
|
||||||
i, layer, is_sel, is_current, is_editing, &self.edit_buf, color_open, ltc, lwc,
|
i, layer, is_sel, is_current, is_editing, &self.edit_buf, color_open, ltc, lwc,
|
||||||
|
&self.vp_cols,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Insert color picker dropdown below this row when open.
|
// Insert color picker dropdown below this row when open.
|
||||||
|
|
@ -258,6 +302,7 @@ fn layer_row<'a>(
|
||||||
color_picker_open: bool,
|
color_picker_open: bool,
|
||||||
lt_combo: Option<&'a combo_box::State<LinetypeItem>>,
|
lt_combo: Option<&'a combo_box::State<LinetypeItem>>,
|
||||||
lw_combo_state: Option<&'a combo_box::State<LwItem>>,
|
lw_combo_state: Option<&'a combo_box::State<LwItem>>,
|
||||||
|
vp_cols: &'a [VpCol],
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let svg_btn = |bytes: &'static [u8], on_press: Message| -> Element<'a, Message> {
|
let svg_btn = |bytes: &'static [u8], on_press: Message| -> Element<'a, Message> {
|
||||||
button(
|
button(
|
||||||
|
|
@ -443,7 +488,7 @@ fn layer_row<'a>(
|
||||||
|
|
||||||
let bg = if is_selected { ROW_SEL } else if index % 2 == 0 { ROW_EVEN } else { ROW_ODD };
|
let bg = if is_selected { ROW_SEL } else if index % 2 == 0 { ROW_EVEN } else { ROW_ODD };
|
||||||
|
|
||||||
let row_content = row![
|
let mut row_content = row![
|
||||||
container(status_dot).width(50).align_x(iced::Center).align_y(iced::Center),
|
container(status_dot).width(50).align_x(iced::Center).align_y(iced::Center),
|
||||||
name_cell,
|
name_cell,
|
||||||
container(svg_btn(vis_svg, Message::LayerToggleVisible(index)))
|
container(svg_btn(vis_svg, Message::LayerToggleVisible(index)))
|
||||||
|
|
@ -463,6 +508,21 @@ fn layer_row<'a>(
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Center);
|
.align_y(iced::Center);
|
||||||
|
|
||||||
|
// Per-viewport freeze columns
|
||||||
|
for (vp_idx, _vp_col) in vp_cols.iter().enumerate() {
|
||||||
|
let is_vp_frozen = layer.vp_frozen.get(vp_idx).copied().unwrap_or(false);
|
||||||
|
let vp_frz_svg: &'static [u8] = if is_vp_frozen {
|
||||||
|
include_bytes!("../../assets/icons/layers/layfrz.svg")
|
||||||
|
} else {
|
||||||
|
include_bytes!("../../assets/icons/layers/laythw.svg")
|
||||||
|
};
|
||||||
|
row_content = row_content.push(
|
||||||
|
container(svg_btn(vp_frz_svg, Message::LayerToggleVpFreeze(index, vp_idx)))
|
||||||
|
.width(Length::Fixed(COL_ICON))
|
||||||
|
.align_x(iced::Center),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
mouse_area(
|
mouse_area(
|
||||||
container(row_content)
|
container(row_content)
|
||||||
.style(move |_: &Theme| container::Style {
|
.style(move |_: &Theme| container::Style {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue