forked from 1b-agent/opencadstudio-upstream
Merge commit 'ac9a6b07' into codex/pointcloud-attach
# Conflicts: # locales/ar-SA/opencadstudio.ftl # locales/bg-BG/opencadstudio.ftl # locales/cs-CZ/opencadstudio.ftl # locales/de-DE/opencadstudio.ftl # locales/el-GR/opencadstudio.ftl # locales/en-US/opencadstudio.ftl # locales/es-ES/opencadstudio.ftl # locales/fi-FI/opencadstudio.ftl # locales/fr-FR/opencadstudio.ftl # locales/hi-IN/opencadstudio.ftl # locales/hu-HU/opencadstudio.ftl # locales/it-IT/opencadstudio.ftl # locales/ja-JP/opencadstudio.ftl # locales/ko-KR/opencadstudio.ftl # locales/nl-NL/opencadstudio.ftl # locales/pl-PL/opencadstudio.ftl # locales/pt-BR/opencadstudio.ftl # locales/ru-RU/opencadstudio.ftl # locales/tr-TR/opencadstudio.ftl # locales/zh-CN/opencadstudio.ftl # locales/zh-TW/opencadstudio.ftl # src/app/control/actions.rs # src/locale_catalog.rs
This commit is contained in:
commit
ee0d4aedb5
35 files changed
+673
-13
No files matched your search
@@ -740,6 +740,8 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"EXPORTSTEP",
|
||||
"EXPORTSTL",
|
||||
"EXTERNALREFERENCES",
|
||||
"POINTCLOUDMANAGER",
|
||||
"POINTCLOUDMANAGERCLOSE",
|
||||
"EXTRIM",
|
||||
"FILETAB",
|
||||
"FIND",
|
||||
|
||||
@@ -34,7 +34,13 @@ impl OpenCADStudio {
|
||||
common.color.clone()
|
||||
};
|
||||
let color = color.rgb().map_or([255; 3], |(r, g, b)| [r, g, b]);
|
||||
if let Some(placed) = crate::scene::model::point_cloud::placed(document, data, color, None) {
|
||||
if let Some(placed) = crate::scene::model::point_cloud::placed(
|
||||
document,
|
||||
data,
|
||||
color,
|
||||
None,
|
||||
&crate::scene::model::point_cloud::hidden(common),
|
||||
) {
|
||||
clouds.push((common.handle, placed));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,59 @@ impl OpenCADStudio {
|
||||
self.refresh_properties();
|
||||
}
|
||||
|
||||
/// A Point Cloud Manager click: a switch writes the cloud's visibility
|
||||
/// extended data as one undo step; the rest is palette state.
|
||||
pub(in crate::app) fn update_pc_manager(&mut self, message: crate::ui::window::pc_manager::PcManagerMsg) -> Task<Message> {
|
||||
use crate::scene::model::point_cloud::VISIBILITY_APP;
|
||||
use crate::ui::window::pc_manager::{self, PcManagerMsg};
|
||||
let i = self.active_tab;
|
||||
match message {
|
||||
PcManagerMsg::Toggle(handle, row) => {
|
||||
let Some(cloud) =
|
||||
pc_manager::clouds(&self.tabs[i].scene.document, &[]).into_iter().find(|c| c.handle == handle)
|
||||
else {
|
||||
return Task::none();
|
||||
};
|
||||
if self.tabs[i].scene.is_layer_locked(handle) {
|
||||
return Task::none();
|
||||
}
|
||||
let hidden = pc_manager::toggled(&cloud.hidden, &cloud.scans, &row);
|
||||
self.push_undo_snapshot(i, "POINTCLOUDMANAGER");
|
||||
self.tabs[i].scene.ensure_app_id(VISIBILITY_APP);
|
||||
let app_handle = self.tabs[i].scene.document.app_ids.get(VISIBILITY_APP).map(|a| a.handle.value());
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
let data = &mut entity.common_mut().extended_data;
|
||||
if let Some(app) = app_handle {
|
||||
data.raw_dwg_eed.retain(|(a, _)| *a != app);
|
||||
}
|
||||
data.remove_record(VISIBILITY_APP);
|
||||
if !hidden.is_empty() {
|
||||
let mut record = codec::xdata::ExtendedDataRecord::new(VISIBILITY_APP);
|
||||
for name in hidden {
|
||||
record.add_value(codec::xdata::XDataValue::String(name));
|
||||
}
|
||||
data.add_record(record);
|
||||
}
|
||||
}
|
||||
self.tabs[i].scene.bump_entities(&[(handle, crate::scene::ChangeKind::Modified)]);
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
PcManagerMsg::Expand(key) => {
|
||||
if !self.pc_manager.collapsed.remove(&key) {
|
||||
self.pc_manager.collapsed.insert(key);
|
||||
}
|
||||
}
|
||||
PcManagerMsg::Select(key) => self.pc_manager.selected = Some(key),
|
||||
PcManagerMsg::Search(text) => self.pc_manager.search = text,
|
||||
PcManagerMsg::CollapseAll => {
|
||||
let clouds = pc_manager::clouds(&self.tabs[i].scene.document, &[]);
|
||||
self.pc_manager.collapsed.extend(pc_manager::folding_keys(&clouds));
|
||||
}
|
||||
PcManagerMsg::ExpandAll => self.pc_manager.collapsed.clear(),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
/// One undo step that edits every selected PDF underlay.
|
||||
fn edit_selected_underlays(&mut self, i: usize, label: &str, edit: impl Fn(&mut Underlay)) {
|
||||
let handles: Vec<_> = self
|
||||
@@ -319,7 +372,23 @@ impl OpenCADStudio {
|
||||
crop.inverted = !crop.inverted;
|
||||
}
|
||||
}),
|
||||
"_PCUNCROP" => self.edit_selected_point_clouds(i, "POINTCLOUDUNCROP", |data| data.croppings.clear()),
|
||||
// The Point Cloud Manager docks on the right like External
|
||||
// References and opens expanded.
|
||||
"POINTCLOUDMANAGER" => {
|
||||
let id = crate::ui::dock::PanelId::PointCloudManager;
|
||||
self.pc_manager.show = true;
|
||||
if self.dock.location(id).is_none() {
|
||||
self.dock.dock(id, crate::app::config::DockSide::Right, usize::MAX);
|
||||
}
|
||||
self.dock_expanded = Some(id);
|
||||
}
|
||||
"POINTCLOUDMANAGERCLOSE" => {
|
||||
self.pc_manager.show = false;
|
||||
if self.dock_expanded == Some(crate::ui::dock::PanelId::PointCloudManager) {
|
||||
self.dock_expanded = None;
|
||||
}
|
||||
}
|
||||
"_PCUNCROP" =>self.edit_selected_point_clouds(i, "POINTCLOUDUNCROP", |data| data.croppings.clear()),
|
||||
"_PDFULUNCLIP" => {
|
||||
self.edit_selected_underlays(i, "PDFCLIP", |u| {
|
||||
u.clip_boundary_vertices.clear();
|
||||
|
||||
@@ -71,6 +71,7 @@ pub(super) const NAMES: &[&str] = &[
|
||||
"close_modal",
|
||||
"pdf_dialog_ok",
|
||||
"pdf_layer_toggle",
|
||||
"pc_manager_toggle",
|
||||
"pdf_page_select",
|
||||
"pc_colormap",
|
||||
"ribbon_tab",
|
||||
@@ -719,6 +720,19 @@ impl OpenCADStudio {
|
||||
_ => return Err(failure("invalid_value", "Unknown color map edit")),
|
||||
})
|
||||
}
|
||||
// Point Cloud Manager: flip a row's switch, "<handle>:<row>" with
|
||||
// row cloud, unassigned, scans or scan:<name>.
|
||||
"pc_manager_toggle" => {
|
||||
use crate::ui::window::pc_manager::{PcManagerMsg, Row};
|
||||
let value = string(req, "value")?;
|
||||
let parsed = value.split_once(':').and_then(|(handle, row)| {
|
||||
Some((codec::Handle::new(u64::from_str_radix(handle, 16).ok()?), Row::parse(row)?))
|
||||
});
|
||||
let Some((handle, row)) = parsed else {
|
||||
return Err(failure("bad_value", "Expected <handle>:<row>"));
|
||||
};
|
||||
Message::PcManager(PcManagerMsg::Toggle(handle, row))
|
||||
}
|
||||
// Attach dialog: choose pages by index ("0,2").
|
||||
"pdf_page_select" => {
|
||||
let pages: Vec<usize> = string(req, "value")?
|
||||
|
||||
@@ -793,6 +793,8 @@ pub(super) struct OpenCADStudio {
|
||||
/// Whether the Browser panel is shown. Off until BROWSER opens it, so
|
||||
/// the default layout is unchanged for existing users.
|
||||
pub(crate) show_browser: bool,
|
||||
/// Point Cloud Manager palette (POINTCLOUDMANAGER).
|
||||
pub(crate) pc_manager: crate::ui::window::pc_manager::PcManager,
|
||||
/// Which viewport background the colour wheel is editing, or `None` when
|
||||
/// it is closed. One slot, because only one wheel can be open at a time.
|
||||
pub(crate) bg_picker: Option<BgTarget>,
|
||||
@@ -3845,6 +3847,8 @@ pub enum Message {
|
||||
PdfImportPick,
|
||||
/// An edit in one of the PDF dialogs.
|
||||
PdfDialog(crate::ui::window::pdf_dialogs::PdfDialogMsg),
|
||||
/// A click or search in the Point Cloud Manager.
|
||||
PcManager(crate::ui::window::pc_manager::PcManagerMsg),
|
||||
PdfImportPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
|
||||
/// Result of the PDFATTACH file picker.
|
||||
PdfAttachPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
|
||||
@@ -4160,6 +4164,7 @@ impl OpenCADStudio {
|
||||
graph_undo_open: false,
|
||||
show_external_references: false,
|
||||
show_browser: false,
|
||||
pc_manager: Default::default(),
|
||||
bg_picker: None,
|
||||
block_palette: Default::default(),
|
||||
xref_manager: Default::default(),
|
||||
|
||||
@@ -608,6 +608,9 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
||||
PanelId::NodeGraph => {
|
||||
self.show_node_graph = false;
|
||||
}
|
||||
PanelId::PointCloudManager => {
|
||||
self.pc_manager.show = false;
|
||||
}
|
||||
PanelId::Properties => {
|
||||
self.show_properties = false;
|
||||
self.ribbon.set_properties(false);
|
||||
@@ -712,6 +715,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
||||
PanelId::ExternalReferences => self.show_external_references,
|
||||
PanelId::Browser => self.show_browser,
|
||||
PanelId::NodeGraph => self.show_node_graph,
|
||||
PanelId::PointCloudManager => self.pc_manager.show,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1806,6 +1806,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
Message::PdfDialog(message) => self.update_pdf_dialog(message),
|
||||
Message::PcManager(message) => self.update_pc_manager(message),
|
||||
Message::RibbonSelectTab(idx) => {
|
||||
self.ribbon.select(idx);
|
||||
Task::none()
|
||||
|
||||
@@ -1870,6 +1870,7 @@ bg={bg_ms:.1}ms n={view_count}"
|
||||
crate::ui::dock::PanelId::ExternalReferences => self.show_external_references,
|
||||
crate::ui::dock::PanelId::Browser => self.show_browser,
|
||||
crate::ui::dock::PanelId::NodeGraph => self.show_node_graph,
|
||||
crate::ui::dock::PanelId::PointCloudManager => self.pc_manager.show,
|
||||
}
|
||||
};
|
||||
let edge_stack = |side: crate::app::config::DockSide| -> Option<Element<'_, Message>> {
|
||||
@@ -2994,6 +2995,13 @@ impl OpenCADStudio {
|
||||
auto_collapse,
|
||||
),
|
||||
crate::ui::dock::PanelId::NodeGraph => tab.graph.panel(width, auto_collapse),
|
||||
crate::ui::dock::PanelId::PointCloudManager => crate::ui::window::pc_manager::view(
|
||||
&self.pc_manager,
|
||||
&tab.scene.document,
|
||||
&tab.scene.selected_handles_in_order(),
|
||||
width,
|
||||
auto_collapse,
|
||||
),
|
||||
};
|
||||
let divider = dock_divider(id);
|
||||
match side {
|
||||
|
||||
Reference in new issue
Block a user