Align table properties and editing behavior
This commit is contained in:
parent
4a08f7fe80
commit
95279d10c0
8 changed files with 1629 additions and 235 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -72,7 +72,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "acadrust"
|
name = "acadrust"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "git+https://github.com/HakanSeven12/cadcodec.git?rev=94df2c3#94df2c3f87fa051b16ffc3923f80e9247c85c5fd"
|
source = "git+https://github.com/ramox81/cadcodec.git?rev=1fa0a5e#1fa0a5e22f53dd45c6b0b9d8c63f7fc7730a3a8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.8.12",
|
"ahash 0.8.12",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ glam = { version = "0.33", features = ["bytemuck"] }
|
||||||
rfd = "0.17"
|
rfd = "0.17"
|
||||||
clap = { version = "4", features = ["derive"] }
|
clap = { version = "4", features = ["derive"] }
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "94df2c3", features = ["serde"] }
|
acadrust = { git = "https://github.com/ramox81/cadcodec.git", rev = "1fa0a5e", features = ["serde"] }
|
||||||
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "76de3b3", features = ["acis", "offset"] }
|
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "76de3b3", features = ["acis", "offset"] }
|
||||||
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
|
|
@ -60,6 +60,9 @@ ashpd = { version = "0.13.13", default-features = false, features = ["async-io",
|
||||||
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||||
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||||
|
|
||||||
|
[patch."https://github.com/HakanSeven12/cadcodec.git"]
|
||||||
|
acadrust = { git = "https://github.com/ramox81/cadcodec.git", rev = "1fa0a5e" }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] }
|
ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] }
|
||||||
meshopt = "0.6.2"
|
meshopt = "0.6.2"
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
crate::scene::view::dispatch::set_prop_current_vertex(prop_vertex);
|
crate::scene::view::dispatch::set_prop_current_vertex(prop_vertex);
|
||||||
crate::entities::table::set_prop_current_cell(prop_vertex);
|
crate::entities::table::set_prop_current_cell(prop_vertex);
|
||||||
|
crate::entities::table::set_prop_current_cell_active(prop_vertex_indicator_active);
|
||||||
|
|
||||||
let annotation_scale_handle = self.tabs[i].scene.displayed_annotation_scale_handle();
|
let annotation_scale_handle = self.tabs[i].scene.displayed_annotation_scale_handle();
|
||||||
let new_panel = {
|
let new_panel = {
|
||||||
|
|
@ -1299,6 +1300,10 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acadrust::EntityType::Table(table) => {
|
acadrust::EntityType::Table(table) => {
|
||||||
|
use acadrust::entities::table::{
|
||||||
|
CellEdgeFlags, CellStylePropertyFlags, CellValueType,
|
||||||
|
};
|
||||||
|
|
||||||
let mut names: Vec<String> = doc
|
let mut names: Vec<String> = doc
|
||||||
.objects
|
.objects
|
||||||
.values()
|
.values()
|
||||||
|
|
@ -1313,15 +1318,17 @@ impl OpenCADStudio {
|
||||||
.collect();
|
.collect();
|
||||||
names.sort_by_key(|name| name.to_ascii_lowercase());
|
names.sort_by_key(|name| name.to_ascii_lowercase());
|
||||||
names.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
|
names.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
|
||||||
let selected = table
|
let selected_style = table
|
||||||
.table_style_handle
|
.table_style_handle
|
||||||
.and_then(|handle| doc.objects.get(&handle))
|
.and_then(|handle| doc.objects.get(&handle))
|
||||||
.and_then(|object| match object {
|
.and_then(|object| match object {
|
||||||
acadrust::objects::ObjectType::TableStyle(style) => {
|
acadrust::objects::ObjectType::TableStyle(style) => {
|
||||||
Some(style.name.clone())
|
Some(style)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
});
|
||||||
|
let selected = selected_style
|
||||||
|
.map(|style| style.name.clone())
|
||||||
.unwrap_or_else(|| "Standard".to_string());
|
.unwrap_or_else(|| "Standard".to_string());
|
||||||
if !names.iter().any(|name| name.eq_ignore_ascii_case(&selected)) {
|
if !names.iter().any(|name| name.eq_ignore_ascii_case(&selected)) {
|
||||||
names.insert(0, selected.clone());
|
names.insert(0, selected.clone());
|
||||||
|
|
@ -1334,6 +1341,311 @@ impl OpenCADStudio {
|
||||||
options: names,
|
options: names,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let title_suppressed =
|
||||||
|
crate::entities::table::resolved_title_suppressed(
|
||||||
|
table,
|
||||||
|
selected_style,
|
||||||
|
);
|
||||||
|
let header_suppressed =
|
||||||
|
crate::entities::table::resolved_header_suppressed(
|
||||||
|
table,
|
||||||
|
selected_style,
|
||||||
|
);
|
||||||
|
let flow_up = crate::entities::table::resolved_flow_up(
|
||||||
|
table,
|
||||||
|
selected_style,
|
||||||
|
);
|
||||||
|
let (horizontal_margin, vertical_margin) =
|
||||||
|
crate::entities::table::resolved_table_margins(
|
||||||
|
table,
|
||||||
|
selected_style,
|
||||||
|
);
|
||||||
|
update_row_toggle(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_title_suppressed",
|
||||||
|
title_suppressed,
|
||||||
|
);
|
||||||
|
update_row_toggle(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_header_suppressed",
|
||||||
|
header_suppressed,
|
||||||
|
);
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_flow_direction",
|
||||||
|
if flow_up { "Up" } else { "Down" }.to_string(),
|
||||||
|
);
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_horizontal_margin",
|
||||||
|
crate::entities::common::format_length(horizontal_margin),
|
||||||
|
);
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_vertical_margin",
|
||||||
|
crate::entities::common::format_length(vertical_margin),
|
||||||
|
);
|
||||||
|
|
||||||
|
let columns = table.column_count();
|
||||||
|
if columns > 0 {
|
||||||
|
let cell_index = prop_vertex.min(
|
||||||
|
table.row_count()
|
||||||
|
.saturating_mul(columns)
|
||||||
|
.saturating_sub(1),
|
||||||
|
);
|
||||||
|
let row_index = cell_index / columns;
|
||||||
|
let column_index = cell_index % columns;
|
||||||
|
if let (Some(row), Some(cell)) = (
|
||||||
|
table.rows.get(row_index),
|
||||||
|
table.cell(row_index, column_index),
|
||||||
|
) {
|
||||||
|
let document_row_style = selected_style.map(|style| {
|
||||||
|
let kind = match (
|
||||||
|
title_suppressed,
|
||||||
|
header_suppressed,
|
||||||
|
row_index,
|
||||||
|
) {
|
||||||
|
(false, _, 0) => 0,
|
||||||
|
(false, false, 1) | (true, false, 0) => 1,
|
||||||
|
_ => 2,
|
||||||
|
};
|
||||||
|
match kind {
|
||||||
|
0 => &style.title_row_style,
|
||||||
|
1 => &style.header_row_style,
|
||||||
|
_ => &style.data_row_style,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let local = |property| {
|
||||||
|
crate::entities::table::style_for_property(
|
||||||
|
table,
|
||||||
|
row,
|
||||||
|
column_index,
|
||||||
|
cell,
|
||||||
|
property,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let alignment = local(CellStylePropertyFlags::ALIGNMENT)
|
||||||
|
.map(|style| style.alignment)
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style.map(|style| style.alignment as i32)
|
||||||
|
})
|
||||||
|
.unwrap_or(5);
|
||||||
|
let alignment = match alignment {
|
||||||
|
1 => "Top Left",
|
||||||
|
2 => "Top Center",
|
||||||
|
3 => "Top Right",
|
||||||
|
4 => "Middle Left",
|
||||||
|
6 => "Middle Right",
|
||||||
|
7 => "Bottom Left",
|
||||||
|
8 => "Bottom Center",
|
||||||
|
9 => "Bottom Right",
|
||||||
|
_ => "Middle Center",
|
||||||
|
};
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_alignment",
|
||||||
|
alignment.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let text_style_name = local(CellStylePropertyFlags::TEXT_STYLE)
|
||||||
|
.map(|style| style.text_style_name.clone())
|
||||||
|
.filter(|name| !name.is_empty())
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style
|
||||||
|
.map(|style| style.text_style_name.clone())
|
||||||
|
.filter(|name| !name.is_empty())
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| "Standard".to_string());
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_text_style",
|
||||||
|
text_style_name,
|
||||||
|
);
|
||||||
|
let text_height = local(CellStylePropertyFlags::TEXT_HEIGHT)
|
||||||
|
.map(|style| style.text_height)
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style.map(|style| style.text_height)
|
||||||
|
})
|
||||||
|
.unwrap_or(0.18);
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_text_height",
|
||||||
|
crate::entities::common::format_length(text_height),
|
||||||
|
);
|
||||||
|
let content_color = local(
|
||||||
|
CellStylePropertyFlags::CONTENT_COLOR,
|
||||||
|
)
|
||||||
|
.map(|style| style.content_color)
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style.map(|style| style.text_color)
|
||||||
|
})
|
||||||
|
.unwrap_or(acadrust::types::Color::ByBlock);
|
||||||
|
update_row_color(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_content_color",
|
||||||
|
content_color,
|
||||||
|
);
|
||||||
|
let background_style =
|
||||||
|
local(CellStylePropertyFlags::BACKGROUND_COLOR);
|
||||||
|
let background_color = background_style
|
||||||
|
.map(|style| style.background_color)
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style.map(|style| style.fill_color)
|
||||||
|
})
|
||||||
|
.unwrap_or(acadrust::types::Color::ByBlock);
|
||||||
|
update_row_color(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_background_color",
|
||||||
|
background_color,
|
||||||
|
);
|
||||||
|
update_row_toggle(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_fill",
|
||||||
|
background_style
|
||||||
|
.map(|style| style.fill_enabled)
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style
|
||||||
|
.map(|style| style.fill_enabled)
|
||||||
|
})
|
||||||
|
.unwrap_or(false),
|
||||||
|
);
|
||||||
|
let format = local(CellStylePropertyFlags::DATA_FORMAT)
|
||||||
|
.map(|style| style.value_format.clone())
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style
|
||||||
|
.map(|style| style.format_string.clone())
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_format",
|
||||||
|
format,
|
||||||
|
);
|
||||||
|
let data_type = cell
|
||||||
|
.contents
|
||||||
|
.first()
|
||||||
|
.map(|content| content.value.value_type)
|
||||||
|
.filter(|kind| *kind != CellValueType::Unknown)
|
||||||
|
.or_else(|| {
|
||||||
|
local(CellStylePropertyFlags::DATA_TYPE)
|
||||||
|
.map(|style| {
|
||||||
|
CellValueType::from(
|
||||||
|
style.value_data_type.max(0) as u32,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
document_row_style.map(|style| {
|
||||||
|
CellValueType::from(style.data_type.max(0) as u32)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap_or(CellValueType::String);
|
||||||
|
let data_type = match data_type {
|
||||||
|
CellValueType::Long => "Integer",
|
||||||
|
CellValueType::Double => "Decimal",
|
||||||
|
CellValueType::Date => "Date",
|
||||||
|
CellValueType::Point2D => "Point 2D",
|
||||||
|
CellValueType::Point3D => "Point 3D",
|
||||||
|
CellValueType::Handle => "Handle",
|
||||||
|
_ => "Text",
|
||||||
|
};
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
"tbl_cell_data_type",
|
||||||
|
data_type.to_string(),
|
||||||
|
);
|
||||||
|
for (field, property, fallback) in [
|
||||||
|
(
|
||||||
|
"tbl_cell_margin_left",
|
||||||
|
CellStylePropertyFlags::MARGIN_LEFT,
|
||||||
|
horizontal_margin,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tbl_cell_margin_top",
|
||||||
|
CellStylePropertyFlags::MARGIN_TOP,
|
||||||
|
vertical_margin,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tbl_cell_margin_right",
|
||||||
|
CellStylePropertyFlags::MARGIN_RIGHT,
|
||||||
|
horizontal_margin,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tbl_cell_margin_bottom",
|
||||||
|
CellStylePropertyFlags::MARGIN_BOTTOM,
|
||||||
|
vertical_margin,
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let value = local(property)
|
||||||
|
.map(|style| match field {
|
||||||
|
"tbl_cell_margin_left" => style.margin_left,
|
||||||
|
"tbl_cell_margin_top" => style.margin_top,
|
||||||
|
"tbl_cell_margin_right" => style.margin_right,
|
||||||
|
_ => style.margin_bottom,
|
||||||
|
})
|
||||||
|
.unwrap_or(fallback);
|
||||||
|
update_row_text(
|
||||||
|
&mut sections,
|
||||||
|
field,
|
||||||
|
crate::entities::common::format_length(value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let border_visible = |edge: CellEdgeFlags| {
|
||||||
|
let local_style = [
|
||||||
|
cell.style.as_ref(),
|
||||||
|
row.style.as_ref(),
|
||||||
|
table
|
||||||
|
.columns
|
||||||
|
.get(column_index)
|
||||||
|
.and_then(|column| column.style.as_ref()),
|
||||||
|
table.base_style.as_ref(),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.find(|style| {
|
||||||
|
style.applied_border_edges.contains(edge)
|
||||||
|
});
|
||||||
|
if let Some(style) = local_style {
|
||||||
|
return if edge == CellEdgeFlags::TOP {
|
||||||
|
!style.top_border.invisible
|
||||||
|
} else if edge == CellEdgeFlags::RIGHT {
|
||||||
|
!style.right_border.invisible
|
||||||
|
} else if edge == CellEdgeFlags::BOTTOM {
|
||||||
|
!style.bottom_border.invisible
|
||||||
|
} else {
|
||||||
|
!style.left_border.invisible
|
||||||
|
};
|
||||||
|
}
|
||||||
|
document_row_style
|
||||||
|
.map(|style| {
|
||||||
|
if edge == CellEdgeFlags::TOP {
|
||||||
|
!style.top_border.is_invisible
|
||||||
|
} else if edge == CellEdgeFlags::RIGHT {
|
||||||
|
!style.right_border.is_invisible
|
||||||
|
} else if edge == CellEdgeFlags::BOTTOM {
|
||||||
|
!style.bottom_border.is_invisible
|
||||||
|
} else {
|
||||||
|
!style.left_border.is_invisible
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or(true)
|
||||||
|
};
|
||||||
|
for (field, edge) in [
|
||||||
|
("tbl_cell_border_top", CellEdgeFlags::TOP),
|
||||||
|
("tbl_cell_border_right", CellEdgeFlags::RIGHT),
|
||||||
|
("tbl_cell_border_bottom", CellEdgeFlags::BOTTOM),
|
||||||
|
("tbl_cell_border_left", CellEdgeFlags::LEFT),
|
||||||
|
] {
|
||||||
|
update_row_toggle(
|
||||||
|
&mut sections,
|
||||||
|
field,
|
||||||
|
border_visible(edge),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -2469,6 +2781,79 @@ fn set_row_value(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_row_text(
|
||||||
|
sections: &mut [crate::scene::model::object::PropSection],
|
||||||
|
field: &str,
|
||||||
|
value: String,
|
||||||
|
) {
|
||||||
|
use crate::scene::model::object::PropValue;
|
||||||
|
for section in sections.iter_mut() {
|
||||||
|
let Some(row) = section.props.iter_mut().find(|property| property.field == field) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
match &mut row.value {
|
||||||
|
PropValue::ReadOnly(current)
|
||||||
|
| PropValue::EditText(current)
|
||||||
|
| PropValue::PlainText(current) => *current = value,
|
||||||
|
PropValue::ReadOnlyWithTooltip { value: current, .. } => *current = value,
|
||||||
|
PropValue::Choice { selected, .. } => *selected = value,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_row_toggle(
|
||||||
|
sections: &mut [crate::scene::model::object::PropSection],
|
||||||
|
field: &str,
|
||||||
|
value: bool,
|
||||||
|
) {
|
||||||
|
use crate::scene::model::object::PropValue;
|
||||||
|
for section in sections.iter_mut() {
|
||||||
|
let Some(row) = section.props.iter_mut().find(|property| property.field == field) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
match &mut row.value {
|
||||||
|
PropValue::BoolToggle { value: current, .. } => *current = value,
|
||||||
|
PropValue::ReadOnly(current) => {
|
||||||
|
*current = if value { t!("Yes") } else { t!("No") }.into_owned()
|
||||||
|
}
|
||||||
|
PropValue::ReadOnlyWithTooltip { value: current, .. } => {
|
||||||
|
*current = if value { t!("Yes") } else { t!("No") }.into_owned()
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_row_color(
|
||||||
|
sections: &mut [crate::scene::model::object::PropSection],
|
||||||
|
field: &str,
|
||||||
|
color: acadrust::types::Color,
|
||||||
|
) {
|
||||||
|
use crate::scene::model::object::PropValue;
|
||||||
|
let label = match color {
|
||||||
|
acadrust::types::Color::None => "None".to_string(),
|
||||||
|
acadrust::types::Color::ByLayer => "ByLayer".to_string(),
|
||||||
|
acadrust::types::Color::ByBlock => "ByBlock".to_string(),
|
||||||
|
acadrust::types::Color::Index(index) => index.to_string(),
|
||||||
|
acadrust::types::Color::Rgb { r, g, b } => format!("{r},{g},{b}"),
|
||||||
|
};
|
||||||
|
for section in sections.iter_mut() {
|
||||||
|
let Some(row) = section.props.iter_mut().find(|property| property.field == field) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
match &mut row.value {
|
||||||
|
PropValue::ColorChoice(current) => *current = color,
|
||||||
|
PropValue::ReadOnly(current) => *current = label,
|
||||||
|
PropValue::ReadOnlyWithTooltip { value: current, .. } => *current = label,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The lineweight dropdown options (named defaults + the standard millimetre
|
/// The lineweight dropdown options (named defaults + the standard millimetre
|
||||||
/// steps), matching the labels `dim_lineweight_label` produces.
|
/// steps), matching the labels `dim_lineweight_label` produces.
|
||||||
pub(crate) fn lineweight_options() -> Vec<String> {
|
pub(crate) fn lineweight_options() -> Vec<String> {
|
||||||
|
|
|
||||||
|
|
@ -2109,6 +2109,29 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
self.tabs[i].scene.bump_entities(&changes);
|
self.tabs[i].scene.bump_entities(&changes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if field == "tbl_style_handle" {
|
||||||
|
let style_handle = self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.objects
|
||||||
|
.iter()
|
||||||
|
.find_map(|(handle, object)| match object {
|
||||||
|
acadrust::objects::ObjectType::TableStyle(style)
|
||||||
|
if style.name.eq_ignore_ascii_case(value.trim()) =>
|
||||||
|
{
|
||||||
|
Some(*handle)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
if let Some(style_handle) = style_handle {
|
||||||
|
for &handle in &handles {
|
||||||
|
if let Some(acadrust::EntityType::Table(table)) =
|
||||||
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
{
|
||||||
|
table.table_style_handle = Some(style_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if field == "transparency" {
|
} else if field == "transparency" {
|
||||||
for &handle in &handles {
|
for &handle in &handles {
|
||||||
if self.tabs[i].scene.is_layer_locked(handle) {
|
if self.tabs[i].scene.is_layer_locked(handle) {
|
||||||
|
|
@ -2248,6 +2271,15 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if field.starts_with("tbl_") {
|
||||||
|
for &handle in &handles {
|
||||||
|
if let Some(acadrust::EntityType::Table(table)) =
|
||||||
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
{
|
||||||
|
table.block_record_handle = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.invalidate_property_targets(i, &handles);
|
self.invalidate_property_targets(i, &handles);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.tabs[i].properties.edit_choice_open = false;
|
self.tabs[i].properties.edit_choice_open = false;
|
||||||
|
|
@ -2555,6 +2587,15 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if field.starts_with("tbl_") {
|
||||||
|
for &handle in &handles {
|
||||||
|
if let Some(acadrust::EntityType::Table(table)) =
|
||||||
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
{
|
||||||
|
table.block_record_handle = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.invalidate_property_targets(i, &handles);
|
self.invalidate_property_targets(i, &handles);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
|
|
|
||||||
|
|
@ -4651,6 +4651,47 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"tbl_title_suppressed" | "tbl_header_suppressed" => {
|
||||||
|
let next = {
|
||||||
|
let document = &self.tabs[i].scene.document;
|
||||||
|
let Some(acadrust::EntityType::Table(table)) =
|
||||||
|
document.get_entity(handle)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let table_style = table.table_style_handle.and_then(|style_handle| {
|
||||||
|
document.objects.get(&style_handle).and_then(|object| {
|
||||||
|
match object {
|
||||||
|
acadrust::objects::ObjectType::TableStyle(style) => {
|
||||||
|
Some(style)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
let current = if field == "tbl_title_suppressed" {
|
||||||
|
crate::entities::table::resolved_title_suppressed(
|
||||||
|
table,
|
||||||
|
table_style,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
crate::entities::table::resolved_header_suppressed(
|
||||||
|
table,
|
||||||
|
table_style,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
!current
|
||||||
|
};
|
||||||
|
if let Some(entity) =
|
||||||
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
{
|
||||||
|
crate::scene::view::dispatch::apply_geom_prop(
|
||||||
|
entity,
|
||||||
|
field,
|
||||||
|
if next { "true" } else { "false" },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(entity) =
|
if let Some(entity) =
|
||||||
self.tabs[i].scene.document.get_entity_mut(handle)
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
|
@ -4662,6 +4703,15 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if field.starts_with("tbl_") {
|
||||||
|
for &handle in &handles {
|
||||||
|
if let Some(acadrust::EntityType::Table(table)) =
|
||||||
|
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||||
|
{
|
||||||
|
table.block_record_handle = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.invalidate_property_targets(i, &handles);
|
self.invalidate_property_targets(i, &handles);
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
|
|
@ -4889,6 +4939,13 @@ impl OpenCADStudio {
|
||||||
cell_index / columns,
|
cell_index / columns,
|
||||||
cell_index % columns,
|
cell_index % columns,
|
||||||
) {
|
) {
|
||||||
|
use acadrust::entities::table::CellStateFlags;
|
||||||
|
if cell.state.intersects(
|
||||||
|
CellStateFlags::FORMAT_LOCKED
|
||||||
|
| CellStateFlags::FORMAT_READ_ONLY,
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let style = cell.style.get_or_insert_with(Default::default);
|
let style = cell.style.get_or_insert_with(Default::default);
|
||||||
if field == "tbl_cell_content_color" {
|
if field == "tbl_cell_content_color" {
|
||||||
style.content_color = color;
|
style.content_color = color;
|
||||||
|
|
@ -4903,6 +4960,7 @@ impl OpenCADStudio {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table.block_record_handle = None;
|
||||||
}
|
}
|
||||||
self.invalidate_property_targets(i, &handles);
|
self.invalidate_property_targets(i, &handles);
|
||||||
self.tabs[i].properties.open_color_field = None;
|
self.tabs[i].properties.open_color_field = None;
|
||||||
|
|
|
||||||
|
|
@ -4412,25 +4412,23 @@ impl OpenCADStudio {
|
||||||
let mut down = horizontal
|
let mut down = horizontal
|
||||||
.cross(normal)
|
.cross(normal)
|
||||||
.normalize_or(glam::DVec3::NEG_Y);
|
.normalize_or(glam::DVec3::NEG_Y);
|
||||||
let flows_up = table
|
let table_style = table.table_style_handle.and_then(|style_handle| {
|
||||||
.table_style_handle
|
|
||||||
.and_then(|style_handle| {
|
|
||||||
self.tabs[i]
|
self.tabs[i]
|
||||||
.scene
|
.scene
|
||||||
.document
|
.document
|
||||||
.objects
|
.objects
|
||||||
.get(&style_handle)
|
.get(&style_handle)
|
||||||
|
.and_then(|object| match object {
|
||||||
|
acadrust::objects::ObjectType::TableStyle(style) => {
|
||||||
|
Some(style)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
})
|
})
|
||||||
.is_some_and(|object| {
|
|
||||||
matches!(
|
|
||||||
object,
|
|
||||||
acadrust::objects::ObjectType::TableStyle(style)
|
|
||||||
if matches!(
|
|
||||||
style.flow_direction,
|
|
||||||
acadrust::objects::TableFlowDirection::Up
|
|
||||||
)
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
let flows_up = crate::entities::table::resolved_flow_up(
|
||||||
|
table,
|
||||||
|
table_style,
|
||||||
|
);
|
||||||
if flows_up {
|
if flows_up {
|
||||||
down = -down;
|
down = -down;
|
||||||
}
|
}
|
||||||
|
|
@ -4461,10 +4459,19 @@ impl OpenCADStudio {
|
||||||
Some(*offset)
|
Some(*offset)
|
||||||
})
|
})
|
||||||
.position(|end| y <= end)?;
|
.position(|end| y <= end)?;
|
||||||
|
let locked = table.cell(row, column).is_some_and(|cell| {
|
||||||
|
use acadrust::entities::table::CellStateFlags;
|
||||||
|
cell.state.intersects(
|
||||||
|
CellStateFlags::CONTENT_LOCKED
|
||||||
|
| CellStateFlags::CONTENT_READ_ONLY,
|
||||||
|
)
|
||||||
|
});
|
||||||
Some((
|
Some((
|
||||||
|
(!locked).then(|| {
|
||||||
crate::modules::annotate::table_cmd::TableCellEditCommand::new(
|
crate::modules::annotate::table_cmd::TableCellEditCommand::new(
|
||||||
handle, table, row, column,
|
handle, table, row, column,
|
||||||
),
|
)
|
||||||
|
}),
|
||||||
row * table.column_count() + column,
|
row * table.column_count() + column,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
@ -4475,9 +4482,11 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].properties.prop_vertex_indicator_active = true;
|
self.tabs[i].properties.prop_vertex_indicator_active = true;
|
||||||
crate::entities::table::set_prop_current_cell(cell_index);
|
crate::entities::table::set_prop_current_cell(cell_index);
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
|
if let Some(command) = command {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info(&crate::command::CadCommand::prompt(&command));
|
.push_info(&crate::command::CadCommand::prompt(&command));
|
||||||
self.tabs[i].active_cmd = Some(Box::new(command));
|
self.tabs[i].active_cmd = Some(Box::new(command));
|
||||||
|
}
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// Any text-bearing entity opens its in-place editor
|
// Any text-bearing entity opens its in-place editor
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -520,6 +520,7 @@ impl CadCommand for TableCellEditCommand {
|
||||||
return Some(CmdResult::Cancel);
|
return Some(CmdResult::Cancel);
|
||||||
}
|
}
|
||||||
cell.set_text(text);
|
cell.set_text(text);
|
||||||
|
self.table.block_record_handle = None;
|
||||||
Some(CmdResult::ReplaceMany(
|
Some(CmdResult::ReplaceMany(
|
||||||
vec![(self.handle, vec![EntityType::Table(self.table.clone())])],
|
vec![(self.handle, vec![EntityType::Table(self.table.clone())])],
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue