diff --git a/assets/icons/refset_add.svg b/assets/icons/refset_add.svg new file mode 100644 index 000000000..e4d929681 --- /dev/null +++ b/assets/icons/refset_add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/refset_remove.svg b/assets/icons/refset_remove.svg new file mode 100644 index 000000000..4f2536ebe --- /dev/null +++ b/assets/icons/refset_remove.svg @@ -0,0 +1,4 @@ + + + + diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index f210ce5eb..a5d0bd4c9 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -6471,6 +6471,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = حدد المرجع: .reference-not-found = لم يتم العثور على المرجع. .not-valid-reference = الكائن ليس مرجعًا صالحًا diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index 694d37d17..cb7b8adaa 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Изберете препратка: .reference-not-found = Препратката не е намерена. .not-valid-reference = Обектът не е валидна препратка diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index 55dc8ab97..c457d22a0 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -6456,6 +6456,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Vyberte referenci: .reference-not-found = Reference nebyla nalezena. .not-valid-reference = Objekt není platná reference diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index ef91c0ea0..3f886bc55 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -6457,6 +6457,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Referenz wählen: .reference-not-found = Referenz nicht gefunden. .not-valid-reference = Objekt ist keine gültige Referenz diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index afa07b2fb..6c48ed829 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Επιλέξτε αναφορά: .reference-not-found = Η αναφορά δεν βρέθηκε. .not-valid-reference = Το αντικείμενο δεν είναι έγκυρη αναφορά diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index c0a15929d..30af1a99a 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -6458,6 +6458,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Select reference: .reference-not-found = Reference not found. .not-valid-reference = Object is not a valid reference diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 786b46eaf..106265737 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Seleccione la referencia: .reference-not-found = No se encuentra la referencia. .not-valid-reference = El objeto no es una referencia válida diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index 5381c7037..34e19e2cf 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -6456,6 +6456,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Valitse viittaus: .reference-not-found = Viittausta ei löydy. .not-valid-reference = Objekti ei ole kelvollinen viittaus diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index b9f67f2da..0b42a5f58 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Sélectionnez la référence : .reference-not-found = Référence introuvable. .not-valid-reference = L'objet n'est pas une référence valide diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 1626cd702..d8310aee9 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -6447,6 +6447,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = संदर्भ चुनें: .reference-not-found = संदर्भ नहीं मिला। .not-valid-reference = ऑब्जेक्ट मान्य संदर्भ नहीं है diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index fb17ef462..78da9fc17 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -6443,6 +6443,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Válassza ki a hivatkozást: .reference-not-found = A hivatkozás nem található. .not-valid-reference = Az objektum nem érvényes hivatkozás diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index 85e49acad..220b1f190 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -6458,6 +6458,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Selezionare il riferimento: .reference-not-found = Riferimento non trovato. .not-valid-reference = L'oggetto non è un riferimento valido diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 72df97414..7816a101b 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -6447,6 +6447,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = 参照を選択: .reference-not-found = 参照が見つかりません。 .not-valid-reference = オブジェクトは有効な参照ではありません diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 9899dbd75..fbfc25a63 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -6458,6 +6458,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = 참조 선택: .reference-not-found = 참조를 찾을 수 없습니다. .not-valid-reference = 객체가 유효한 참조가 아닙니다 diff --git a/locales/lo-LA/opencadstudio.ftl b/locales/lo-LA/opencadstudio.ftl index 3b9358f63..cc31a5004 100644 --- a/locales/lo-LA/opencadstudio.ftl +++ b/locales/lo-LA/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = ເລືອກການອ້າງອີງ: .reference-not-found = ບໍ່ພົບການອ້າງອີງ. .not-valid-reference = ວັດຖຸບໍ່ແມ່ນການອ້າງອີງທີ່ຖືກຕ້ອງ diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 25ce0ed57..b2b5d1d80 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -6457,6 +6457,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Selecteer referentie: .reference-not-found = Referentie niet gevonden. .not-valid-reference = Object is geen geldige referentie diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index eb2c2c96c..a3d31b0eb 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -6458,6 +6458,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Wybierz odnośnik: .reference-not-found = Nie znaleziono odnośnika. .not-valid-reference = Obiekt nie jest prawidłowym odnośnikiem diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index 120d5b580..58f5bc2f2 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -6459,6 +6459,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Selecione a referência: .reference-not-found = Referência não encontrada. .not-valid-reference = O objeto não é uma referência válida diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index e0838f93c..5e49037a0 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -6460,6 +6460,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = Выберите ссылку: .reference-not-found = Ссылка не найдена. .not-valid-reference = Объект не является допустимой ссылкой diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index c16d192e1..951e83b02 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -6380,6 +6380,9 @@ view-background = .select-image = Arka Plan Görüntüsü Seç ref-edit = + .add-to-working-set = Çalışma Kümesine Ekle + .remove-from-working-set = Çalışma Kümesinden Çıkar + .toolbar-objects = nesne .select-reference = Referans seçin: .reference-not-found = Referans bulunamadı. .not-valid-reference = Nesne geçerli bir referans değil diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 8a81b1bc1..37f4b2356 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -6442,6 +6442,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = 选择参照: .reference-not-found = 找不到参照。 .not-valid-reference = 对象不是有效的参照 diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index 28ac1a835..31217548c 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -6454,6 +6454,9 @@ view-background = .select-image = Select Background Image ref-edit = + .add-to-working-set = Add to Working Set + .remove-from-working-set = Remove from Working Set + .toolbar-objects = objects .select-reference = 選取參考: .reference-not-found = 找不到參考。 .not-valid-reference = 物件不是有效的參考 diff --git a/src/app/commands/refedit.rs b/src/app/commands/refedit.rs index bc8ec3732..b56d3edd5 100644 --- a/src/app/commands/refedit.rs +++ b/src/app/commands/refedit.rs @@ -21,7 +21,7 @@ impl OpenCADStudio { pub(super) fn dispatch_refedit(&mut self, cmd: &str, i: usize) -> Option> { match cmd { "REFEDIT" | "-REFEDIT" => Some(self.start_refedit(i, cmd == "-REFEDIT")), - "REFSET" => { + "REFSET" | "REFSET_ADD" | "REFSET_REMOVE" => { if self.tabs[i].refedit_session.is_none() { self.command_line.push_error(crate::t!(NOT_CHECKED_OUT).as_ref()); return Some(Task::none()); @@ -30,7 +30,12 @@ impl OpenCADStudio { crate::t!("Transfer objects between the RefEdit working set and host drawing...") .as_ref(), ); - let command = RefSetCommand::new(); + // The side toolbar's Add / Remove go straight to the selection. + let command = match cmd { + "REFSET_ADD" => RefSetCommand::selecting(true), + "REFSET_REMOVE" => RefSetCommand::selecting(false), + _ => RefSetCommand::new(), + }; use crate::command::CadCommand; self.command_line.push_info(&command.prompt()); self.tabs[i].active_cmd = Some(Box::new(command)); diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index 281bf3ead..dedfb3aa7 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -1687,9 +1687,18 @@ bg={bg_ms:.1}ms n={view_count}" // In-place block edit (REFEDIT): right-edge toolbar with Save / Discard // so the edit can be finished by clicking. (#136) - if tab.refedit_session.is_some() && !tab.is_start { - if let Some(tb) = crate::ui::side_toolbar::view( - &crate::modules::draw::modify::refedit::refedit_tools(), + if let (Some(session), false) = (tab.refedit_session.as_ref(), tab.is_start) { + use crate::modules::draw::modify::refedit::{refedit_set_tools, refedit_tools}; + let set_tools = refedit_set_tools(); + let close_tools = refedit_tools(); + let header = crate::ui::side_toolbar::refedit_header( + &session.block_name, + refedit_working_set_count(session, &tab.scene), + ); + if let Some(tb) = crate::ui::side_toolbar::view_sections( + Some(header), + &[&set_tools, &close_tools], + &|_| false, ) { viewport_stack = viewport_stack.push(tb); } @@ -4183,3 +4192,22 @@ mod tests { ); } } + +/// The objects in a REFEDIT session's working set: the checked-out copies and +/// objects added with REFSET still in it, and everything created in the +/// space since. +// ponytail: walks the document per frame while a session is open; keep a +// running count on the session if large drawings feel it. +fn refedit_working_set_count( + session: &crate::modules::draw::modify::refedit::RefEditSession, + scene: &crate::scene::Scene, +) -> usize { + let space = scene.current_layout_block_handle_pub(); + scene + .document + .entities() + .filter(|entity| { + entity.common().owner_handle == space && session.in_working_set(entity.common().handle) + }) + .count() +} diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index d903c1804..eeb68ca63 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -3,6 +3,8 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static str)> { match source { + "Add to Working Set" => Some(("ref-edit", "add-to-working-set")), + "Remove from Working Set" => Some(("ref-edit", "remove-from-working-set")), "Select reference:" => Some(("ref-edit", "select-reference")), "Reference not found." => Some(("ref-edit", "reference-not-found")), "Object is not a valid reference" => Some(("ref-edit", "not-valid-reference")), diff --git a/src/modules/draw/modify/refedit.rs b/src/modules/draw/modify/refedit.rs index 792628795..87396775f 100644 --- a/src/modules/draw/modify/refedit.rs +++ b/src/modules/draw/modify/refedit.rs @@ -20,6 +20,25 @@ use std::collections::HashSet; use crate::command::{CadCommand, CmdOption, CmdResult}; use crate::modules::{IconKind, ModuleEvent, ToolDef}; +/// Right-edge side-toolbar buttons that move objects into or out of the +/// working set while a REFEDIT session is active (REFSET Add / Remove). +pub fn refedit_set_tools() -> Vec { + vec![ + ToolDef { + id: "REFSET_ADD", + label: "Add to Working Set", + icon: IconKind::Svg(include_bytes!("../../../../assets/icons/refset_add.svg")), + event: ModuleEvent::Command("REFSET_ADD".to_string()), + }, + ToolDef { + id: "REFSET_REMOVE", + label: "Remove from Working Set", + icon: IconKind::Svg(include_bytes!("../../../../assets/icons/refset_remove.svg")), + event: ModuleEvent::Command("REFSET_REMOVE".to_string()), + }, + ] +} + /// Right-edge side-toolbar buttons shown while a REFEDIT session is active: /// save the in-place block edit, or discard it. (#136) pub fn refedit_tools() -> Vec { @@ -479,6 +498,15 @@ impl RefSetCommand { selected: Vec::new(), } } + + /// Straight to `Select objects:` for Add (`add`) or Remove. + pub fn selecting(add: bool) -> Self { + Self { + add, + gathering: true, + selected: Vec::new(), + } + } } impl CadCommand for RefSetCommand { diff --git a/src/ui/side_toolbar.rs b/src/ui/side_toolbar.rs index 5c415882c..941745f90 100644 --- a/src/ui/side_toolbar.rs +++ b/src/ui/side_toolbar.rs @@ -49,6 +49,53 @@ fn tip_panel(label: &'static str) -> Element<'static, Message> { .into() } +/// The REFEDIT session toolbar's head: the definition being edited as an +/// accent pill (REFEDITNAME) and how many objects the working set holds. +pub fn refedit_header(name: &str, count: usize) -> Element<'static, Message> { + // Long names are cut so the bar stays narrow; the full name is in the tip. + let short: String = if name.chars().count() > 7 { + format!("{}…", name.chars().take(6).collect::()) + } else { + name.to_string() + }; + let pill = container(text(short).size(10)) + .padding([1, 6]) + .style(|theme: &Theme| { + let palette = theme.palette(); + container::Style { + background: Some(Background::Color(palette.primary.base.color)), + border: Border { + radius: 8.0.into(), + ..Default::default() + }, + text_color: Some(palette.primary.base.text), + ..Default::default() + } + }); + let tip = container(text(name.to_string()).size(11)).padding([2, 6]).style(|theme: &Theme| { + let palette = theme.palette(); + container::Style { + background: Some(Background::Color(palette.background.strong.color)), + border: Border { + color: palette.background.neutral.color, + width: 1.0, + radius: 3.0.into(), + }, + text_color: Some(palette.background.strong.text), + ..Default::default() + } + }); + column![ + tooltip(pill, tip, tooltip::Position::Left).gap(6), + text(format!("{} {}", count, crate::tr!("ref-edit", "toolbar-objects"))) + .size(9) + .style(crate::ui::style::common::muted_style), + ] + .spacing(2) + .align_x(iced::Center) + .into() +} + /// Build the floating right-edge vertical toolbar from `tools`, vertically /// centred over the canvas. Returns `None` when `tools` is empty so the caller /// can skip pushing an overlay. @@ -61,12 +108,39 @@ pub fn view_with_active( tools: &[ToolDef], active: &dyn Fn(&str) -> bool, ) -> Option> { - if tools.is_empty() { + view_sections(None, &[tools], active) +} + +/// As [`view_with_active`], with `header` on top and a rule between the +/// groups of tools. +pub fn view_sections( + header: Option>, + groups: &[&[ToolDef]], + active: &dyn Fn(&str) -> bool, +) -> Option> { + if groups.iter().all(|g| g.is_empty()) { return None; } let mut col = column![].spacing(4).align_x(iced::Center); - for t in tools { + if let Some(header) = header { + col = col.push(header); + } + let tools = groups.iter().filter(|g| !g.is_empty()).enumerate().flat_map(|(group, tools)| { + tools.iter().enumerate().map(move |(k, t)| (group > 0 && k == 0, t)) + }); + for (starts_group, t) in tools { + if starts_group { + col = col.push( + container(iced::widget::Space::new()) + .width(Length::Fixed(BTN_SIZE - 4.0)) + .height(Length::Fixed(1.0)) + .style(|theme: &Theme| container::Style { + background: Some(Background::Color(theme.palette().background.neutral.color)), + ..Default::default() + }), + ); + } let on = active(t.id); let btn = button(icon_el(t.icon)) .on_press(Message::RibbonToolClick {