forked from 1b-agent/opencadstudio-upstream
feat(tablestyle): complete field coverage (flow, description, cell data + borders)
Table Style editor now exposes every TableStyle / RowCellStyle field: - General: description, flow direction (Down/Up dropdown). - Per cell: data type, unit type, format string, plus all six borders (left/right/top/bottom/horizontal-inside/vertical-inside) with line type (Single/Double), line weight, color (ACI), double-line spacing and a visibility toggle. Border type/visibility apply immediately; the numeric border fields and data/unit/format are written by the existing "Apply cell" button. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
6ae24cceee
commit
10d674f606
4 files changed
+308
-43
No files matched your search
+41
-4
@@ -323,11 +323,21 @@ pub(super) struct OpenCADStudio {
|
||||
/// Edit buffers for the table style's general margins.
|
||||
ts_hmargin: String,
|
||||
ts_vmargin: String,
|
||||
/// General table-style description buffer.
|
||||
ts_description: String,
|
||||
/// Per-cell edit buffers, indexed 0=Data, 1=Header, 2=Title.
|
||||
ts_cell_textstyle: [String; 3],
|
||||
ts_cell_height: [String; 3],
|
||||
ts_cell_textcolor: [String; 3],
|
||||
ts_cell_fillcolor: [String; 3],
|
||||
ts_cell_datatype: [String; 3],
|
||||
ts_cell_unittype: [String; 3],
|
||||
ts_cell_format: [String; 3],
|
||||
/// Per-cell, per-border numeric buffers ([cell][border], border order:
|
||||
/// 0=left 1=right 2=top 3=bottom 4=horizontal-inside 5=vertical-inside).
|
||||
ts_border_lw: [[String; 6]; 3],
|
||||
ts_border_color: [[String; 6]; 3],
|
||||
ts_border_spacing: [[String; 6]; 3],
|
||||
|
||||
// ── TextStyle Font Browser ────────────────────────────────────────────
|
||||
textstyle_selected: String,
|
||||
@@ -1043,6 +1053,26 @@ pub enum Message {
|
||||
},
|
||||
/// Write a cell's edit buffers back into the selected table style.
|
||||
TableStyleCellApply(u8),
|
||||
/// Set the table flow direction from the dropdown.
|
||||
TableStyleSetFlow(String),
|
||||
/// Update a per-cell, per-border numeric edit buffer.
|
||||
TableStyleBorderEdit {
|
||||
cell: u8,
|
||||
border: u8,
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
/// Set a border's line type (Single / Double).
|
||||
TableStyleBorderSetType {
|
||||
cell: u8,
|
||||
border: u8,
|
||||
value: String,
|
||||
},
|
||||
/// Toggle a border's visibility.
|
||||
TableStyleBorderToggleInvisible {
|
||||
cell: u8,
|
||||
border: u8,
|
||||
},
|
||||
// ── MLineStyle Dialog ─────────────────────────────────────────────────
|
||||
MlStyleDialogOpen,
|
||||
#[allow(dead_code)]
|
||||
@@ -1247,10 +1277,17 @@ impl OpenCADStudio {
|
||||
tablestyle_selected: "Standard".to_string(),
|
||||
ts_hmargin: "1.5".to_string(),
|
||||
ts_vmargin: "1.5".to_string(),
|
||||
ts_cell_textstyle: [String::new(), String::new(), String::new()],
|
||||
ts_cell_height: [String::new(), String::new(), String::new()],
|
||||
ts_cell_textcolor: [String::new(), String::new(), String::new()],
|
||||
ts_cell_fillcolor: [String::new(), String::new(), String::new()],
|
||||
ts_description: String::new(),
|
||||
ts_cell_textstyle: Default::default(),
|
||||
ts_cell_height: Default::default(),
|
||||
ts_cell_textcolor: Default::default(),
|
||||
ts_cell_fillcolor: Default::default(),
|
||||
ts_cell_datatype: Default::default(),
|
||||
ts_cell_unittype: Default::default(),
|
||||
ts_cell_format: Default::default(),
|
||||
ts_border_lw: Default::default(),
|
||||
ts_border_color: Default::default(),
|
||||
ts_border_spacing: Default::default(),
|
||||
// MLineStyle dialog
|
||||
mlstyle_selected: "Standard".to_string(),
|
||||
// MLeaderStyle dialog
|
||||
|
||||
@@ -5755,6 +5755,7 @@ impl OpenCADStudio {
|
||||
match field {
|
||||
"hmargin" => self.ts_hmargin = value,
|
||||
"vmargin" => self.ts_vmargin = value,
|
||||
"description" => self.ts_description = value,
|
||||
_ => {}
|
||||
}
|
||||
Task::none()
|
||||
@@ -5766,6 +5767,7 @@ impl OpenCADStudio {
|
||||
let name = self.tablestyle_selected.clone();
|
||||
let h: Option<f64> = self.ts_hmargin.trim().parse().ok();
|
||||
let v: Option<f64> = self.ts_vmargin.trim().parse().ok();
|
||||
let desc = self.ts_description.clone();
|
||||
self.push_undo_snapshot(i, "TABLESTYLE EDIT");
|
||||
for obj in self.tabs[i].scene.document.objects.values_mut() {
|
||||
if let ObjectType::TableStyle(s) = obj {
|
||||
@@ -5776,6 +5778,7 @@ impl OpenCADStudio {
|
||||
if let Some(v) = v {
|
||||
s.vertical_margin = v;
|
||||
}
|
||||
s.description = desc.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5783,6 +5786,20 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleSetFlow(value) => {
|
||||
use acadrust::objects::TableFlowDirection;
|
||||
let i = self.active_tab;
|
||||
if let Some(s) = self.tablestyle_mut(i) {
|
||||
s.flow_direction = match value.as_str() {
|
||||
"Up" => TableFlowDirection::Up,
|
||||
_ => TableFlowDirection::Down,
|
||||
};
|
||||
self.push_undo_snapshot(i, "TABLESTYLE EDIT");
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleCellEdit { row, field, value } => {
|
||||
let r = row as usize;
|
||||
if r < 3 {
|
||||
@@ -5791,12 +5808,69 @@ impl OpenCADStudio {
|
||||
"height" => self.ts_cell_height[r] = value,
|
||||
"textcolor" => self.ts_cell_textcolor[r] = value,
|
||||
"fillcolor" => self.ts_cell_fillcolor[r] = value,
|
||||
"datatype" => self.ts_cell_datatype[r] = value,
|
||||
"unittype" => self.ts_cell_unittype[r] = value,
|
||||
"format" => self.ts_cell_format[r] = value,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleBorderEdit {
|
||||
cell,
|
||||
border,
|
||||
field,
|
||||
value,
|
||||
} => {
|
||||
let (c, b) = (cell as usize, border as usize);
|
||||
if c < 3 && b < 6 {
|
||||
match field {
|
||||
"lw" => self.ts_border_lw[c][b] = value,
|
||||
"color" => self.ts_border_color[c][b] = value,
|
||||
"spacing" => self.ts_border_spacing[c][b] = value,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleBorderSetType {
|
||||
cell,
|
||||
border,
|
||||
value,
|
||||
} => {
|
||||
use acadrust::objects::TableBorderType;
|
||||
let i = self.active_tab;
|
||||
if let Some(s) = self.tablestyle_mut(i) {
|
||||
if let Some(bd) = Self::ts_cell_of(s, cell).and_then(|c| Self::ts_border_of(c, border))
|
||||
{
|
||||
bd.border_type = match value.as_str() {
|
||||
"Double" => TableBorderType::Double,
|
||||
_ => TableBorderType::Single,
|
||||
};
|
||||
}
|
||||
self.push_undo_snapshot(i, "TABLESTYLE EDIT");
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleBorderToggleInvisible { cell, border } => {
|
||||
let i = self.active_tab;
|
||||
if let Some(s) = self.tablestyle_mut(i) {
|
||||
if let Some(bd) = Self::ts_cell_of(s, cell).and_then(|c| Self::ts_border_of(c, border))
|
||||
{
|
||||
bd.is_invisible = !bd.is_invisible;
|
||||
}
|
||||
self.push_undo_snapshot(i, "TABLESTYLE EDIT");
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleCellToggleFill(row) => {
|
||||
let i = self.active_tab;
|
||||
if let Some(s) = self.tablestyle_mut(i) {
|
||||
@@ -5844,6 +5918,18 @@ impl OpenCADStudio {
|
||||
let height: Option<f64> = self.ts_cell_height[r].trim().parse().ok();
|
||||
let tc: Option<i16> = self.ts_cell_textcolor[r].trim().parse().ok();
|
||||
let fc: Option<i16> = self.ts_cell_fillcolor[r].trim().parse().ok();
|
||||
let dtype: Option<i32> = self.ts_cell_datatype[r].trim().parse().ok();
|
||||
let utype: Option<i32> = self.ts_cell_unittype[r].trim().parse().ok();
|
||||
let fmt = self.ts_cell_format[r].clone();
|
||||
// Per-border numeric edits for this cell.
|
||||
let border_vals: [(Option<i16>, Option<i16>, Option<f64>); 6] =
|
||||
std::array::from_fn(|b| {
|
||||
(
|
||||
self.ts_border_lw[r][b].trim().parse().ok(),
|
||||
self.ts_border_color[r][b].trim().parse().ok(),
|
||||
self.ts_border_spacing[r][b].trim().parse().ok(),
|
||||
)
|
||||
});
|
||||
if let Some(c) = self.tablestyle_mut(i).and_then(|s| Self::ts_cell_of(s, row)) {
|
||||
if !ts.is_empty() {
|
||||
c.text_style_name = ts;
|
||||
@@ -5857,6 +5943,26 @@ impl OpenCADStudio {
|
||||
if let Some(v) = fc {
|
||||
c.fill_color = acadrust::types::Color::from_index(v);
|
||||
}
|
||||
if let Some(v) = dtype {
|
||||
c.data_type = v;
|
||||
}
|
||||
if let Some(v) = utype {
|
||||
c.unit_type = v;
|
||||
}
|
||||
c.format_string = fmt;
|
||||
for (b, (lw, color, spacing)) in border_vals.into_iter().enumerate() {
|
||||
if let Some(bd) = Self::ts_border_of(c, b as u8) {
|
||||
if let Some(v) = lw {
|
||||
bd.line_weight = acadrust::types::LineWeight::from_value(v);
|
||||
}
|
||||
if let Some(v) = color {
|
||||
bd.color = acadrust::types::Color::from_index(v);
|
||||
}
|
||||
if let Some(v) = spacing {
|
||||
bd.double_line_spacing = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.push_undo_snapshot(i, "TABLESTYLE EDIT");
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
@@ -7115,6 +7221,23 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutable access to a cell's border by index
|
||||
/// (0=left 1=right 2=top 3=bottom 4=horizontal-inside 5=vertical-inside).
|
||||
fn ts_border_of(
|
||||
c: &mut acadrust::objects::RowCellStyle,
|
||||
border: u8,
|
||||
) -> Option<&mut acadrust::objects::TableCellBorder> {
|
||||
match border {
|
||||
0 => Some(&mut c.left_border),
|
||||
1 => Some(&mut c.right_border),
|
||||
2 => Some(&mut c.top_border),
|
||||
3 => Some(&mut c.bottom_border),
|
||||
4 => Some(&mut c.horizontal_inside_border),
|
||||
5 => Some(&mut c.vertical_inside_border),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Populate margin + per-cell edit buffers from the selected table style.
|
||||
fn load_tablestyle_bufs(&mut self, tab: usize) {
|
||||
use acadrust::objects::ObjectType;
|
||||
@@ -7133,6 +7256,7 @@ impl OpenCADStudio {
|
||||
};
|
||||
self.ts_hmargin = format!("{:.4}", s.horizontal_margin);
|
||||
self.ts_vmargin = format!("{:.4}", s.vertical_margin);
|
||||
self.ts_description = s.description.clone();
|
||||
for (r, c) in [&s.data_row_style, &s.header_row_style, &s.title_row_style]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
@@ -7143,6 +7267,23 @@ impl OpenCADStudio {
|
||||
c.text_color.index().map(|v| v.to_string()).unwrap_or_default();
|
||||
self.ts_cell_fillcolor[r] =
|
||||
c.fill_color.index().map(|v| v.to_string()).unwrap_or_default();
|
||||
self.ts_cell_datatype[r] = c.data_type.to_string();
|
||||
self.ts_cell_unittype[r] = c.unit_type.to_string();
|
||||
self.ts_cell_format[r] = c.format_string.clone();
|
||||
let borders = [
|
||||
&c.left_border,
|
||||
&c.right_border,
|
||||
&c.top_border,
|
||||
&c.bottom_border,
|
||||
&c.horizontal_inside_border,
|
||||
&c.vertical_inside_border,
|
||||
];
|
||||
for (b, bd) in borders.into_iter().enumerate() {
|
||||
self.ts_border_lw[r][b] = bd.line_weight.value().to_string();
|
||||
self.ts_border_color[r][b] =
|
||||
bd.color.index().map(|v| v.to_string()).unwrap_or_default();
|
||||
self.ts_border_spacing[r][b] = format!("{:.4}", bd.double_line_spacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,10 +119,17 @@ impl OpenCADStudio {
|
||||
selected_style,
|
||||
&self.ts_hmargin,
|
||||
&self.ts_vmargin,
|
||||
&self.ts_description,
|
||||
&self.ts_cell_textstyle,
|
||||
&self.ts_cell_height,
|
||||
&self.ts_cell_textcolor,
|
||||
&self.ts_cell_fillcolor,
|
||||
&self.ts_cell_datatype,
|
||||
&self.ts_cell_unittype,
|
||||
&self.ts_cell_format,
|
||||
&self.ts_border_lw,
|
||||
&self.ts_border_color,
|
||||
&self.ts_border_spacing,
|
||||
);
|
||||
}
|
||||
if Some(window_id) == self.mlstyle_window {
|
||||
|
||||
Reference in new issue
Block a user