Cargo: codec 76d2a1c, kernel e652b4d, graph 0545fa9; text styles, templates, solid edges

- Text styles keep their TrueType typeface through save and reopen (codec
  reads and writes the STYLE record's ACAD extended data) (#1633)
- Unnamed shape-file entries no longer show in text style lists (#1634)
- Save As offers DWT 2018; NEW asks for the template to start from, while
  Ctrl+N and the quick-access New run QNEW with the default template (#1635)
- An edge next to an earlier fillet of the same radius rounds together with
  it (kernel); the solid stays drawn and pickable while edges are chosen
  (#1625, #1107)
- A full cache rebuild drops the B-rep cache too, so an undone fillet does
  not come back with the next edge operation (#1107)
- Selected solids in shaded styles highlight only their visible edges (#1031)
- VIEW ISO / SWISO / SEISO / NEISO / NWISO snap to the isometric corners

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-06 18:32:43 +03:00
1 parent 1cbcc8f4c5
commit 1eae36e726
43 files changed
+152 -34

No files matched your search

+19 -1
View File
@@ -3,7 +3,25 @@ use super::*;
impl OpenCADStudio {
pub(super) fn dispatch_fileops(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
match cmd {
"NEW" => return Some(Task::done(Message::TabNew)),
// QNEW starts from the default template (Options > Files); NEW
// asks which template to start from (#1635).
"QNEW" => return Some(Task::done(Message::TabNew)),
"NEW" => {
return Some(Task::perform(
async {
crate::sys::file_dialog()
.set_title(crate::t!("Select Template").as_ref())
.add_filter(
crate::t!("Drawing Template (*.dwt)").as_ref(),
&["dwt", "DWT", "dwg", "DWG", "dxf", "DXF"],
)
.pick_file()
.await
.map(|handle| crate::sys::handle_path(&handle))
},
Message::NewFromTemplate,
));
}
"OPEN" => return Some(Task::done(Message::OpenFile)),
"SAVE" | "QSAVE" => return Some(Task::done(Message::SaveFile)),
// SAVEALL — write every open drawing that already has a file path.
+19 -2
View File
@@ -875,8 +875,25 @@ impl OpenCADStudio {
crate::scene::CubeRegion::Face(face),
)));
}
"ISO" | "ISOMETRIC" | "SWISO" => {
return Some(Task::done(Message::ViewCubeHome));
// Isometric presets snap to the matching ViewCube corner;
// ISO alone is the south-west one.
"ISO" | "ISOMETRIC" | "SWISO" | "SEISO" | "NEISO" | "NWISO" => {
let (x, y) = match sub.as_str() {
"SEISO" => (1.0, -1.0),
"NEISO" => (1.0, 1.0),
"NWISO" => (-1.0, 1.0),
_ => (-1.0, -1.0),
};
let want = glam::Vec3::new(x, y, 1.0).normalize();
let corner = (18..26)
.map(crate::scene::CubeRegion::Corner)
.max_by(|a, b| {
a.snap_direction()
.dot(want)
.total_cmp(&b.snap_direction().dot(want))
})
.expect("the cube has corners");
return Some(Task::done(Message::ViewCubeSnap(corner)));
}
// VIEW <name> shortcut for restore
_ => {
+1
View File
@@ -850,6 +850,7 @@ inventory::submit!(crate::command::CommandRegistration {
"CHSPACE",
"NAVVCUBE",
"NEW",
"QNEW",
"OBJIMPORT",
"OPEN",
"ORTHO",
+6 -1
View File
@@ -149,7 +149,12 @@ impl OpenCADStudio {
}
let doc = &self.tabs[i].scene.document;
let text_names: Vec<String> = doc.text_styles.iter().map(|s| s.name.clone()).collect();
let text_names: Vec<String> = doc
.text_styles
.iter()
.filter(|s| !s.is_shape_file)
.map(|s| s.name.clone())
.collect();
let active_text = doc.header.current_text_style_name.clone();
let active_text = if text_names.contains(&active_text) {
active_text
+2
View File
@@ -2299,6 +2299,8 @@ pub enum Message {
/// Options → Files: the default template for new drawings.
QnewTemplateChanged(String),
QnewTemplateBrowse,
/// NEW: the picked template a new drawing starts from (`None` = cancelled).
NewFromTemplate(Option<std::path::PathBuf>),
/// Set the default type/version used when first saving a new drawing.
DefaultSaveFormatChanged(String),
/// Select one of Iced's built-in themes or the editable Custom theme.
+1 -1
View File
@@ -27,7 +27,7 @@ pub(super) fn default_bindings() -> BTreeMap<String, String> {
("F12".to_string(), "DYNINPUT"),
(format!("{ACCEL}+0"), "CLEANSCREEN"),
(format!("{ACCEL}+1"), "PROPERTIES"),
(format!("{ACCEL}+N"), "NEW"),
(format!("{ACCEL}+N"), "QNEW"),
(format!("{ACCEL}+O"), "OPEN"),
(format!("{ACCEL}+P"), "PLOT"),
(format!("{ACCEL}+Q"), "QUIT"),
+8 -1
View File
@@ -234,7 +234,14 @@ impl OpenCADStudio {
v
};
match kind {
StyleKind::Text => doc.text_styles.iter().map(|s| s.name.clone()).collect(),
// Shape-file entries (complex linetype glyphs) are not text styles to
// pick or edit; they have no name (#1634).
StyleKind::Text => doc
.text_styles
.iter()
.filter(|s| !s.is_shape_file)
.map(|s| s.name.clone())
.collect(),
StyleKind::Dim => doc.dim_styles.iter().map(|s| s.name.clone()).collect(),
StyleKind::Table => from_objects(|o| match o {
ObjectType::TableStyle(s) => Some(s.name.as_str()),
+2
View File
@@ -3137,6 +3137,8 @@ impl OpenCADStudio {
let default_name = filename;
let (filter_label, filter_ext): (&str, &str) = if ext.eq_ignore_ascii_case("dxf") {
("DXF Files", "dxf")
} else if ext.eq_ignore_ascii_case("dwt") {
("Drawing Template (*.dwt)", "dwt")
} else {
("DWG Files", "dwg")
};
+16
View File
@@ -8028,6 +8028,22 @@ impl OpenCADStudio {
self.persist_settings_if_changed();
Task::none()
}
Message::NewFromTemplate(Some(path)) => {
let task = self.update(Message::TabNew);
let idx = self.active_tab;
match self.apply_template(&path.to_string_lossy()) {
Ok(_) => {
self.tabs[idx].dirty = false;
self.refresh_layer_panel();
self.sync_ribbon_styles();
}
Err(error) => self
.command_line
.push_error(error["error"].as_str().unwrap_or("template")),
}
task
}
Message::NewFromTemplate(None) => Task::none(),
Message::QnewTemplateBrowse => Task::perform(
async {
crate::sys::file_dialog()
+8 -2
View File
@@ -1152,7 +1152,9 @@ impl OpenCADStudio {
let mut lt_opts: Vec<String> = vec!["ByBlock".to_string()];
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
let mut textstyle_opts: Vec<String> = vec!["None".to_string()];
textstyle_opts.extend(doc.text_styles.iter().map(|t| t.name.clone()));
textstyle_opts.extend(
doc.text_styles.iter().filter(|t| !t.is_shape_file).map(|t| t.name.clone()),
);
let opt_block = |h: Option<codec::types::Handle>| -> String {
match h {
Some(h) => doc
@@ -1416,7 +1418,11 @@ impl OpenCADStudio {
let mut lt_opts: Vec<String> = vec!["ByBlock".to_string()];
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
let text_style_opts: Vec<String> =
doc.text_styles.iter().map(|style| style.name.clone()).collect();
doc.text_styles
.iter()
.filter(|style| !style.is_shape_file)
.map(|style| style.name.clone())
.collect();
let text_style_fixed_height = doc
.text_styles
.get(&self.ds_dimtxsty)