mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 13:47:21 -06:00
Brushes: Delete Brush asks first, and Alt-click deletes without asking
The Brushes panel's Delete Brush button and its panel menu item now ask before deleting the selected brushes, as Swatches and Graphic Styles do. OK deletes them in one undo step and strokes that used them become plain strokes; Cancel leaves the document unchanged. Alt-click (Option-click on macOS) on the button deletes without asking. The brush.delete command still deletes at once.
This commit is contained in:
@@ -742,6 +742,9 @@ font-technology Variable Променливи
|
||||
Yes Да
|
||||
No Не
|
||||
Delete Tab Изтриване на табулация
|
||||
Delete the brush “{name}”? Да се изтрие четката „{name}“?
|
||||
Delete these {count} brushes? Да се изтрият тези {count} четки?
|
||||
Strokes using deleted brushes become plain strokes. Щрихите, които използват изтритите четки, стават обикновени щрихи.
|
||||
Delete the graphic style “{name}”? Изтриване на графичния стил „{name}“?
|
||||
Delete Theme Изтриване на тема
|
||||
Delete theme Изтриване на тема
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1059,6 +1059,9 @@
|
||||
Yes Sí
|
||||
No No
|
||||
Delete Tab Suprimeix la tabulació
|
||||
Delete the brush “{name}”? Voleu suprimir el pinzell “{name}”?
|
||||
Delete these {count} brushes? Voleu suprimir aquests {count} pinzells?
|
||||
Strokes using deleted brushes become plain strokes. Els traços que utilitzen pinzells suprimits esdevenen traços normals.
|
||||
Delete the graphic style “{name}”? Voleu suprimir l’estil gràfic “{name}”?
|
||||
Delete the library “{name}”? Voleu suprimir la biblioteca “{name}”?
|
||||
Delete Theme Suprimeix el tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1558,6 +1558,9 @@ lighting Light Světlo
|
||||
Reverse Gradient Obrátit přechod
|
||||
Save to Swatches Uložit do vzorníku
|
||||
Delete Graphic Style (Alt-click: without asking) Odstranit grafický styl (Alt+kliknutí: bez dotazu)
|
||||
Delete the brush “{name}”? Odstranit štětec „{name}“?
|
||||
Delete these {count} brushes? Odstranit těchto {count} štětců?
|
||||
Strokes using deleted brushes become plain strokes. Tahy používající odstraněné štětce se změní na běžné tahy.
|
||||
Delete the graphic style “{name}”? Odstranit grafický styl „{name}“?
|
||||
Delete these {n} graphic styles? Odstranit tyto grafické styly ({n})?
|
||||
Delete this {n} graphic style? Odstranit tento grafický styl ({n})?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1472,6 +1472,9 @@ lighting Light Lys
|
||||
Reverse Gradient Omvend gradient
|
||||
Save to Swatches Gem i farveprøver
|
||||
Delete Graphic Style (Alt-click: without asking) Slet grafisk typografi (Alt-klik: uden at spørge)
|
||||
Delete the brush “{name}”? Slet penslen »{name}«?
|
||||
Delete these {count} brushes? Slet disse {count} pensler?
|
||||
Strokes using deleted brushes become plain strokes. Streger, der bruger slettede pensler, bliver almindelige streger.
|
||||
Delete the graphic style “{name}”? Slet den grafiske typografi »{name}«?
|
||||
Delete these {n} graphic styles? Slet disse {n} grafiske typografier?
|
||||
Delete this {n} graphic style? Slet denne {n} grafiske typografi?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -736,6 +736,9 @@ font-technology Variable Variabel
|
||||
Yes Ja
|
||||
No Nein
|
||||
Delete Tab Tabulator löschen
|
||||
Delete the brush “{name}”? Pinsel „{name}“ löschen?
|
||||
Delete these {count} brushes? Diese {count} Pinsel löschen?
|
||||
Strokes using deleted brushes become plain strokes. Konturen mit gelöschten Pinseln werden zu einfachen Konturen.
|
||||
Delete the graphic style “{name}”? Grafikstil „{name}“ löschen?
|
||||
Delete Theme Thema löschen
|
||||
Delete theme Thema löschen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -716,6 +716,9 @@ font-technology Variable Μεταβλητές
|
||||
Yes Ναι
|
||||
No Όχι
|
||||
Delete Tab Διαγραφή στηλοθέτη
|
||||
Delete the brush “{name}”? Να διαγραφεί το πινέλο «{name}»;
|
||||
Delete these {count} brushes? Να διαγραφούν αυτά τα {count} πινέλα;
|
||||
Strokes using deleted brushes become plain strokes. Οι πινελιές που χρησιμοποιούν διαγραμμένα πινέλα γίνονται απλές πινελιές.
|
||||
Delete the graphic style “{name}”? Να διαγραφεί το στυλ γραφικών «{name}»;
|
||||
Delete Theme Διαγραφή θέματος
|
||||
Delete theme Διαγραφή θέματος
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 164 and column 5.
|
@@ -757,6 +757,9 @@ font-technology Variable Variables
|
||||
Yes Sí
|
||||
No No
|
||||
Delete Tab Eliminar tabulación
|
||||
Delete the brush “{name}”? ¿Eliminar el pincel “{name}”?
|
||||
Delete these {count} brushes? ¿Eliminar estos {count} pinceles?
|
||||
Strokes using deleted brushes become plain strokes. Los trazos que usan pinceles eliminados se convierten en trazos simples.
|
||||
Delete the graphic style “{name}”? ¿Eliminar el estilo gráfico “{name}”?
|
||||
Delete Theme Eliminar tema
|
||||
Delete theme Eliminar tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1532,6 +1532,9 @@ lighting Light Valo
|
||||
Reverse Gradient Käännä liukuväri
|
||||
Save to Swatches Tallenna värimalleihin
|
||||
Delete Graphic Style (Alt-click: without asking) Poista grafiikkatyyli (Alt-napsautus: kysymättä)
|
||||
Delete the brush “{name}”? Poistetaanko sivellin ”{name}”?
|
||||
Delete these {count} brushes? Poistetaanko nämä {count} sivellintä?
|
||||
Strokes using deleted brushes become plain strokes. Poistettuja siveltimiä käyttävät viivat muuttuvat tavallisiksi viivoiksi.
|
||||
Delete the graphic style “{name}”? Poistetaanko grafiikkatyyli ”{name}”?
|
||||
Delete these {n} graphic styles? Poistetaanko nämä {n} grafiikkatyyliä?
|
||||
Delete this {n} graphic style? Poistetaanko tämä {n} grafiikkatyyli?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -759,6 +759,9 @@ font-technology Variable Variables
|
||||
Yes Oui
|
||||
No Non
|
||||
Delete Tab Supprimer la tabulation
|
||||
Delete the brush “{name}”? Supprimer la forme « {name} » ?
|
||||
Delete these {count} brushes? Supprimer ces {count} formes ?
|
||||
Strokes using deleted brushes become plain strokes. Les contours utilisant des formes supprimées deviennent des contours simples.
|
||||
Delete the graphic style “{name}”? Supprimer le style graphique « {name} » ?
|
||||
Delete Theme Supprimer le thème
|
||||
Delete theme Supprimer le thème
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -981,6 +981,9 @@ font-technology Variable Változó
|
||||
Yes Igen
|
||||
No Nem
|
||||
Delete Tab Tabulátor törlése
|
||||
Delete the brush “{name}”? Törlöd ezt az ecsetet: „{name}”?
|
||||
Delete these {count} brushes? Törlöd ezt a {count} ecsetet?
|
||||
Strokes using deleted brushes become plain strokes. A törölt ecseteket használó körvonalak egyszerű körvonalakká válnak.
|
||||
Delete the graphic style “{name}”? Törlöd ezt a grafikai stílust: „{name}”?
|
||||
Delete the library “{name}”? Törlöd ezt a könyvtárat: „{name}”?
|
||||
Delete Theme Téma törlése
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1472,6 +1472,9 @@ lighting Light Cahaya
|
||||
Reverse Gradient Balikkan gradien
|
||||
Save to Swatches Simpan ke swatch
|
||||
Delete Graphic Style (Alt-click: without asking) Hapus gaya grafis (Alt+klik: tanpa konfirmasi)
|
||||
Delete the brush “{name}”? Hapus kuas “{name}”?
|
||||
Delete these {count} brushes? Hapus {count} kuas ini?
|
||||
Strokes using deleted brushes become plain strokes. Goresan yang menggunakan kuas terhapus menjadi goresan biasa.
|
||||
Delete the graphic style “{name}”? Hapus gaya grafis “{name}”?
|
||||
Delete these {n} graphic styles? Hapus {n} gaya grafis ini?
|
||||
Delete this {n} graphic style? Hapus {n} gaya grafis ini?
|
||||
|
||||
|
@@ -757,6 +757,9 @@ font-technology Variable Variabili
|
||||
Yes Sì
|
||||
No No
|
||||
Delete Tab Elimina tabulazione
|
||||
Delete the brush “{name}”? Eliminare il pennello “{name}”?
|
||||
Delete these {count} brushes? Eliminare questi {count} pennelli?
|
||||
Strokes using deleted brushes become plain strokes. I tracciati che usano pennelli eliminati diventano tracciati semplici.
|
||||
Delete the graphic style “{name}”? Eliminare lo stile grafico “{name}”?
|
||||
Delete Theme Elimina tema
|
||||
Delete theme Elimina tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1308,6 +1308,9 @@ font-technology Variable バリアブル
|
||||
Delete Transparency Flattener Preset 透明の分割・統合プリセットを削除
|
||||
Delete Width Point 幅ポイントを削除
|
||||
Delete Workspace ワークスペースを削除
|
||||
Delete the brush “{name}”? ブラシ「{name}」を削除しますか?
|
||||
Delete these {count} brushes? これら {count} 個のブラシを削除しますか?
|
||||
Strokes using deleted brushes become plain strokes. 削除したブラシを使用する線は通常の線になります。
|
||||
Delete the graphic style “{name}”? グラフィックスタイル「{name}」を削除しますか?
|
||||
Delete theme テーマを削除
|
||||
Delete this saved preset この保存済みプリセットを削除
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1389,6 +1389,9 @@ lighting Light სინათლე
|
||||
Reverse Gradient გრადიენტის შებრუნება
|
||||
Save to Swatches ფერის ნიმუშებში შენახვა
|
||||
Delete Graphic Style (Alt-click: without asking) გრაფიკული სტილის წაშლა (Alt-დაწკაპუნებით: დაუკითხავად)
|
||||
Delete the brush “{name}”? წაიშალოს ფუნჯი „{name}“?
|
||||
Delete these {count} brushes? წაიშალოს ეს {count} ფუნჯი?
|
||||
Strokes using deleted brushes become plain strokes. წაშლილი ფუნჯებით დახატული შტრიხები ჩვეულებრივ შტრიხებად იქცევა.
|
||||
Delete the graphic style “{name}”? წაიშალოს გრაფიკული სტილი „{name}“?
|
||||
Delete these {n} graphic styles? წაიშალოს ეს გრაფიკული სტილები ({n})?
|
||||
Delete this {n} graphic style? წაიშალოს ეს გრაფიკული სტილი ({n})?
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1299,6 +1299,9 @@ font-technology Variable 가변
|
||||
Delete Transparency Flattener Preset 투명도 병합 프리셋 삭제
|
||||
Delete Width Point 너비 포인트 삭제
|
||||
Delete Workspace 작업 영역 삭제
|
||||
Delete the brush “{name}”? 브러시 “{name}”을(를) 삭제하시겠습니까?
|
||||
Delete these {count} brushes? 이 브러시 {count}개를 삭제하시겠습니까?
|
||||
Strokes using deleted brushes become plain strokes. 삭제된 브러시를 사용한 선은 일반 선이 됩니다.
|
||||
Delete the graphic style “{name}”? 그래픽 스타일 “{name}”을(를) 삭제하시겠습니까?
|
||||
Delete theme 테마 삭제
|
||||
Delete this saved preset 저장된 이 프리셋 삭제
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1486,6 +1486,9 @@ lighting Light Licht
|
||||
Reverse Gradient Verloop omkeren
|
||||
Save to Swatches Opslaan in stalen
|
||||
Delete Graphic Style (Alt-click: without asking) Grafische stijl verwijderen (Alt-klik: zonder vragen)
|
||||
Delete the brush “{name}”? Kwast „{name}” verwijderen?
|
||||
Delete these {count} brushes? Deze {count} kwasten verwijderen?
|
||||
Strokes using deleted brushes become plain strokes. Lijnen die verwijderde kwasten gebruiken, worden gewone lijnen.
|
||||
Delete the graphic style “{name}”? De grafische stijl „{name}” verwijderen?
|
||||
Delete these {n} graphic styles? Deze {n} grafische stijlen verwijderen?
|
||||
Delete this {n} graphic style? Deze {n} grafische stijl verwijderen?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1472,6 +1472,9 @@ lighting Light Światło
|
||||
Reverse Gradient Odwróć gradient
|
||||
Save to Swatches Zapisz w próbkach
|
||||
Delete Graphic Style (Alt-click: without asking) Usuń styl graficzny (kliknięcie z Alt: bez pytania)
|
||||
Delete the brush “{name}”? Usunąć pędzel „{name}”?
|
||||
Delete these {count} brushes? Usunąć te {count} pędzle?
|
||||
Strokes using deleted brushes become plain strokes. Obrysy używające usuniętych pędzli stają się zwykłymi obrysami.
|
||||
Delete the graphic style “{name}”? Usunąć styl graficzny „{name}”?
|
||||
Delete these {n} graphic styles? Usunąć te style graficzne ({n})?
|
||||
Delete this {n} graphic style? Usunąć ten styl graficzny ({n})?
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -674,6 +674,9 @@
|
||||
Delete Transparency Flattener Preset Excluir Predefinido de Achatamento de Transparência
|
||||
Delete Width Point Excluir Ponto de Largura
|
||||
Delete Workspace Excluir Espaço de Trabalho
|
||||
Delete the brush “{name}”? Excluir o pincel “{name}”?
|
||||
Delete these {count} brushes? Excluir estes {count} pincéis?
|
||||
Strokes using deleted brushes become plain strokes. Traços que usam pincéis excluídos tornam-se traços simples.
|
||||
Delete the graphic style “{name}”? Excluir o estilo gráfico “{name}”?
|
||||
Delete theme Excluir tema
|
||||
Delete this saved preset Excluir este predefinido salvo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -755,6 +755,9 @@ font-technology Variable Вариативные
|
||||
Yes Да
|
||||
No Нет
|
||||
Delete Tab Удалить табуляцию
|
||||
Delete the brush “{name}”? Удалить кисть «{name}»?
|
||||
Delete these {count} brushes? Удалить эти кисти ({count})?
|
||||
Strokes using deleted brushes become plain strokes. Обводки, использующие удалённые кисти, становятся обычными обводками.
|
||||
Delete the graphic style “{name}”? Удалить графический стиль «{name}»?
|
||||
Delete Theme Удалить тему
|
||||
Delete theme Удалить тему
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -744,6 +744,9 @@ font-technology Variable Variabla
|
||||
Yes Ja
|
||||
No Nej
|
||||
Delete Tab Radera tabb
|
||||
Delete the brush “{name}”? Radera penseln ”{name}”?
|
||||
Delete these {count} brushes? Radera dessa {count} penslar?
|
||||
Strokes using deleted brushes become plain strokes. Linjer som använder borttagna penslar blir vanliga linjer.
|
||||
Delete the graphic style “{name}”? Radera grafikstilen ”{name}”?
|
||||
Delete Theme Radera tema
|
||||
Delete theme Radera tema
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -736,6 +736,9 @@ font-technology Variable Değişken
|
||||
Yes Evet
|
||||
No Hayır
|
||||
Delete Tab Sekmeyi Sil
|
||||
Delete the brush “{name}”? “{name}” fırçası silinsin mi?
|
||||
Delete these {count} brushes? Bu {count} fırça silinsin mi?
|
||||
Strokes using deleted brushes become plain strokes. Silinen fırçaları kullanan konturlar düz konturlara dönüşür.
|
||||
Delete the graphic style “{name}”? “{name}” grafik stili silinsin mi?
|
||||
Delete Theme Temayı Sil
|
||||
Delete theme Temayı sil
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -751,6 +751,9 @@ font-technology Variable Варіативні
|
||||
Yes Так
|
||||
No Ні
|
||||
Delete Tab Видалити табуляцію
|
||||
Delete the brush “{name}”? Видалити пензель «{name}»?
|
||||
Delete these {count} brushes? Видалити ці пензлі ({count})?
|
||||
Strokes using deleted brushes become plain strokes. Обведення, що використовують видалені пензлі, стають звичайними обведеннями.
|
||||
Delete the graphic style “{name}”? Видалити графічний стиль «{name}»?
|
||||
Delete Theme Видалити тему
|
||||
Delete theme Видалити тему
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 178 and column 5.
|
@@ -877,6 +877,9 @@ font-technology Variable Biến thiên
|
||||
Yes Có
|
||||
No Không
|
||||
Delete Tab Xóa tab
|
||||
Delete the brush “{name}”? Xóa cọ “{name}”?
|
||||
Delete these {count} brushes? Xóa {count} cọ này?
|
||||
Strokes using deleted brushes become plain strokes. Các nét dùng cọ đã xóa trở thành nét thông thường.
|
||||
Delete the graphic style “{name}”? Xóa kiểu đồ họa “{name}”?
|
||||
Delete the library “{name}”? Xóa thư viện “{name}”?
|
||||
Delete Theme Xóa bộ màu
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 200 and column 5.
|
@@ -700,6 +700,9 @@
|
||||
Yes 是
|
||||
No 否
|
||||
Delete Tab 删除制表位
|
||||
Delete the brush “{name}”? 要删除画笔“{name}”吗?
|
||||
Delete these {count} brushes? 要删除这 {count} 个画笔吗?
|
||||
Strokes using deleted brushes become plain strokes. 使用已删除画笔的描边会变成普通描边。
|
||||
Delete the graphic style “{name}”? 要删除图形样式“{name}”吗?
|
||||
Delete Theme 删除主题
|
||||
Delete theme 删除主题
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -719,6 +719,9 @@ font-technology Variable 可變
|
||||
Yes 是
|
||||
No 否
|
||||
Delete Tab 刪除定位點
|
||||
Delete the brush “{name}”? 要刪除筆刷「{name}」嗎?
|
||||
Delete these {count} brushes? 要刪除這 {count} 個筆刷嗎?
|
||||
Strokes using deleted brushes become plain strokes. 使用已刪除筆刷的筆畫會變成一般筆畫。
|
||||
Delete the graphic style “{name}”? 要刪除繪圖樣式「{name}」嗎?
|
||||
Delete Theme 刪除主題
|
||||
Delete theme 刪除主題
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -204,6 +204,23 @@ fn run_on(app: &mut VectorcraftApp, id: &str, names: &[String]) {
|
||||
app.run(id, p).ok();
|
||||
}
|
||||
|
||||
/// Delete `names` after asking, or immediately when the bottom button was Alt-clicked.
|
||||
fn delete(app: &mut VectorcraftApp, names: &[String], now: bool) {
|
||||
let params = match names {
|
||||
[name] => json!({ "name": name }),
|
||||
_ => json!({ "names": names }),
|
||||
};
|
||||
if now {
|
||||
app.run("brush.delete", params).ok();
|
||||
return;
|
||||
}
|
||||
let message = match names {
|
||||
[name] => crate::i18n::fmt(tl!("Delete the brush “{name}”?"), &[("name", name)]),
|
||||
_ => crate::i18n::fmt(tl!("Delete these {count} brushes?"), &[("count", &names.len().to_string())]),
|
||||
};
|
||||
crate::dialogs::confirm::ask(app, &message, tl!("Strokes using deleted brushes become plain strokes."), "brush.delete", params);
|
||||
}
|
||||
|
||||
/// The names in `list` in the order the panel shows them: by type in [`KINDS`] order, without the
|
||||
/// hidden types.
|
||||
fn shown<'a>(list: &'a [(String, String)], hidden: &[String]) -> Vec<&'a str> {
|
||||
@@ -417,7 +434,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
app.status(e);
|
||||
}
|
||||
if widgets::icon_button_enabled(ui, "trash-2", tl!("Delete Brush"), false, !targets.is_empty(), 24.0).clicked() {
|
||||
run_on(app, "brush.delete", &targets);
|
||||
delete(app, &targets, ui.input(|i| i.modifiers.alt));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -452,7 +469,7 @@ pub fn menu(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
run_on(app, "brush.duplicate", &targets);
|
||||
}
|
||||
if menu_item(ui, tl!("Delete Brush"), !targets.is_empty(), false) {
|
||||
run_on(app, "brush.delete", &targets);
|
||||
delete(app, &targets, false);
|
||||
}
|
||||
if menu_item(ui, tl!("Remove Brush Stroke"), sel.is_some(), false) {
|
||||
app.run("brush.remove", json!({})).ok();
|
||||
|
||||
@@ -146,6 +146,23 @@ fn names(app: &mut VectorcraftApp) -> Vec<String> {
|
||||
brushes(app).0.into_iter().map(|b| b.0).collect()
|
||||
}
|
||||
|
||||
fn undo_count(app: &VectorcraftApp) -> usize {
|
||||
app.session.active().unwrap().history.undo.len()
|
||||
}
|
||||
|
||||
fn delete_button(ctx: &egui::Context, app: &mut VectorcraftApp, modifiers: egui::Modifiers, time: f64) {
|
||||
let out = frame_with(ctx, app, vec![], egui::Modifiers::NONE, time, show);
|
||||
let at = clickable(&out).into_iter().find(|(label, _)| label.as_deref() == Some("Delete Brush")).expect("Delete Brush button").1.center();
|
||||
click(ctx, app, at, modifiers, time + 0.5, show);
|
||||
}
|
||||
|
||||
fn assert_delete_dialog(app: &VectorcraftApp, message: &str) {
|
||||
let d = app.ui.dialog.as_ref().expect("Delete Brush asks first");
|
||||
assert_eq!(d.kind, crate::dialogs::confirm::KIND);
|
||||
assert_eq!(d.str("message"), message);
|
||||
assert_eq!(d.str("detail"), "Strokes using deleted brushes become plain strokes.");
|
||||
}
|
||||
|
||||
/// Click the panel menu's item `label` (frames at `time`, `time + 0.5`).
|
||||
fn menu_click(ctx: &egui::Context, app: &mut VectorcraftApp, label: &str, time: f64) {
|
||||
let out = frame_with(ctx, app, vec![], egui::Modifiers::NONE, time, menu);
|
||||
@@ -186,21 +203,23 @@ fn shift_and_command_clicks_select_brushes_for_delete_and_duplicate() {
|
||||
click(&ctx, &mut app, tiles[1].center(), egui::Modifiers::COMMAND, 3.0, show);
|
||||
let out = frame_with(&ctx, &mut app, vec![], egui::Modifiers::NONE, 3.5, show);
|
||||
assert_eq!(lit_tiles(&out), [0, 2]);
|
||||
let undo = |app: &VectorcraftApp| app.session.active().unwrap().history.undo.len();
|
||||
let before = (names(&mut app), undo(&app));
|
||||
let before = (names(&mut app), undo_count(&app));
|
||||
menu_click(&ctx, &mut app, "Duplicate Brush", 4.0);
|
||||
let copies = [format!("{} copy", three[0]), format!("{} copy", three[2])];
|
||||
assert_eq!(names(&mut app)[before.0.len()..], copies);
|
||||
assert_eq!(undo(&app), before.1 + 1);
|
||||
assert_eq!(undo_count(&app), before.1 + 1);
|
||||
// The bottom bar's last button, Delete Brush.
|
||||
let out = frame_with(&ctx, &mut app, vec![], egui::Modifiers::NONE, 5.0, show);
|
||||
let trash = clickable(&out).last().unwrap().1.center();
|
||||
click(&ctx, &mut app, trash, egui::Modifiers::NONE, 6.0, show);
|
||||
delete_button(&ctx, &mut app, egui::Modifiers::NONE, 5.0);
|
||||
assert_delete_dialog(&app, "Delete these 2 brushes?");
|
||||
assert_eq!(names(&mut app), [before.0.clone(), copies.to_vec()].concat());
|
||||
assert_eq!(brush_of(&app, rect).as_deref(), Some(three[0].as_str()));
|
||||
assert_eq!(undo_count(&app), before.1 + 1);
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
let left = names(&mut app);
|
||||
assert!(!left.contains(&three[0]) && !left.contains(&three[2]) && left.contains(&three[1]), "{left:?}");
|
||||
assert!(copies.iter().all(|c| left.contains(c)), "{left:?}");
|
||||
assert_eq!(brush_of(&app, rect), None);
|
||||
assert_eq!(undo(&app), before.1 + 2);
|
||||
assert_eq!(undo_count(&app), before.1 + 2);
|
||||
}
|
||||
|
||||
/// Selecting other art ends the multi-selection: selecting the first art again does not bring
|
||||
@@ -231,6 +250,9 @@ fn selecting_other_art_ends_the_brush_multi_selection() {
|
||||
let out = frame_with(&ctx, &mut app, vec![], egui::Modifiers::NONE, 4.0, show);
|
||||
assert_eq!(lit_tiles(&out), [1]);
|
||||
menu_click(&ctx, &mut app, "Delete Brush", 5.0);
|
||||
assert_delete_dialog(&app, &format!("Delete the brush “{}”?", three[1]));
|
||||
assert!(names(&mut app).contains(&three[1]));
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
let left = names(&mut app);
|
||||
assert!(left.contains(&three[0]) && !left.contains(&three[1]) && left.contains(&three[2]), "{left:?}");
|
||||
assert_eq!((brush_of(&app, a).as_deref(), brush_of(&app, c)), (Some(three[0].as_str()), None));
|
||||
@@ -297,10 +319,57 @@ fn select_all_unused_selects_the_brushes_no_stroke_paints_with() {
|
||||
let on: Vec<usize> = (0..tiles.len()).filter(|i| lit(&ctx, &out).contains(&tiles[*i])).collect();
|
||||
assert_eq!(on, (0..tiles.len()).filter(|i| *i != 1).collect::<Vec<_>>());
|
||||
menu_click(&ctx, &mut app, "Delete Brush", 3.0);
|
||||
assert_delete_dialog(&app, &format!("Delete these {} brushes?", list.len() - 1));
|
||||
assert_eq!(names(&mut app).len(), list.len());
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
assert_eq!(names(&mut app), [list[1].0.clone()]);
|
||||
assert_eq!(brush_of(&app, a), Some(list[1].0.clone()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_button_cancel_keeps_selected_brushes_strokes_and_history() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
|
||||
let rect = NodeId(app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 50, "height": 40})).unwrap()["id"].as_u64().unwrap());
|
||||
let ctx = egui::Context::default();
|
||||
ctx.enable_accesskit();
|
||||
let (three, _) = select_three(&ctx, &mut app, rect);
|
||||
let before = (names(&mut app), brush_of(&app, rect), undo_count(&app));
|
||||
delete_button(&ctx, &mut app, egui::Modifiers::NONE, 3.0);
|
||||
assert_delete_dialog(&app, "Delete these 3 brushes?");
|
||||
assert_eq!((names(&mut app), brush_of(&app, rect), undo_count(&app)), before);
|
||||
crate::dialogs::cancel(&mut app);
|
||||
assert!(app.ui.dialog.is_none());
|
||||
assert_eq!((names(&mut app), brush_of(&app, rect), undo_count(&app)), before);
|
||||
assert_eq!(before.1.as_deref(), Some(three[0].as_str()));
|
||||
app.run("brush.delete", json!({"name": three[0]})).unwrap();
|
||||
assert!(app.ui.dialog.is_none());
|
||||
assert_eq!(undo_count(&app), before.2 + 1);
|
||||
app.run("brush.delete", json!({"names": [three[1], three[2]]})).unwrap();
|
||||
assert!(app.ui.dialog.is_none());
|
||||
assert_eq!(undo_count(&app), before.2 + 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alt_delete_button_removes_selected_brushes_without_dialog() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
|
||||
let rect = NodeId(app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 50, "height": 40})).unwrap()["id"].as_u64().unwrap());
|
||||
let ctx = egui::Context::default();
|
||||
ctx.enable_accesskit();
|
||||
let (three, _) = select_three(&ctx, &mut app, rect);
|
||||
let before = undo_count(&app);
|
||||
delete_button(&ctx, &mut app, egui::Modifiers::NONE, 3.0);
|
||||
assert_delete_dialog(&app, "Delete these 3 brushes?");
|
||||
crate::dialogs::cancel(&mut app);
|
||||
delete_button(&ctx, &mut app, egui::Modifiers::ALT, 4.0);
|
||||
assert!(app.ui.dialog.is_none());
|
||||
let left = names(&mut app);
|
||||
assert!(three.iter().all(|name| !left.contains(name)));
|
||||
assert_eq!(brush_of(&app, rect), None);
|
||||
assert_eq!(undo_count(&app), before + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn art_dropped_on_the_panel_becomes_an_art_brush_and_a_brush_drags_out() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
|
||||
@@ -962,6 +962,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Hue Shift set by `brush.new` or `brush.options` without a key color takes the color the art's fills and strokes use most, as Brush Options already offers it, following the Brushes page, where the key color defaults to the color that stands out most in the art (<https://web.archive.org/web/20241230205225/https://helpx.adobe.com/illustrator/using/brushes.html>). The page does not state how prominence is measured. Counting the fills and strokes that use each solid color, with the first one found winning a tie and black for art with no solid color, is VectorCraft's own rule. A `brush.options` edit that gives only the method keeps the brush's key color, and one that gives only an art brush's start guide keeps its end guide. Evidence: `tests_brushsym::hue_shift_without_a_key_takes_the_most_used_art_color`, `tests_brushsym::art_brush_options_keep_the_scale_fields_an_edit_leaves_out`.
|
||||
Bristle Brush Options and `brush.new` take a bristle brush name of at most 31 characters, as the Brushes page states for the Bristle Brush Options. The Name field stops taking characters at 31, and `brush.new` and `brush.options` refuse a longer new name with an error that names the limit. The page does not say how the limit counts characters or what happens to longer names already saved; counting characters and the number added to a taken name, keeping longer saved names, and leaving `brush.duplicate` unlimited are VectorCraft's own rules. A bristle brush that a document or a saved file already holds under a longer name keeps it, and the other brush types take a name of any length. Test: `bristle_brush_names_have_at_most_31_characters` in `tests/brushsym.rs`. Public reference: [Brushes](https://web.archive.org/web/20241230205225/https://helpx.adobe.com/illustrator/using/brushes.html) (archived copy).
|
||||
In the Brushes panel, Shift-click selects a range of brushes and Ctrl/Cmd-click adds or removes one. Delete Brush and Duplicate Brush then act on all of them (`brush.delete {names}`, `brush.duplicate {names}`).
|
||||
The bottom Delete Brush button and the panel menu ask before deleting; Alt-click (Option-click on macOS) on the button deletes without asking.
|
||||
Document Info has a Brushes category after Graphic Styles. It lists the Brushes panel's brushes, or with Selection Only it lists the brushes that the selected objects' strokes use. The Document Info report and Package's report list them too (`document.info {category: "brushes"}`, `brushNames`).
|
||||
Document Info has a Repeat Objects category after Embedded Images. It lists each radial, grid and mirror Repeat object by name with its kind and the number of instances it makes. For a grid it gives the rows and columns instead, followed by the number of instances it draws when that is fewer. With Selection Only it lists the Repeat objects in the selection. The Document Info report and Package's report list them too (`document.info {category: "repeats"}`, `repeatObjects`).
|
||||
The Brushes panel menu's Select All Unused selects the brushes that are not used in the document, as the [Brushes](https://web.archive.org/web/20241230205225/https://helpx.adobe.com/illustrator/using/brushes.html) page (archived copy) describes. A brush counts as used when a stroke paints with it in the art (opacity masks included), in symbols, graph designs, pattern tiles or graphic styles, or in the art of a used brush (`brush.unused`).
|
||||
|
||||
Reference in New Issue
Block a user