mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 13:47:21 -06:00
Character and Paragraph Styles: Alt-click on New asks for the new style's name
Squashed from #4402 onto main.
This commit is contained in:
@@ -366,11 +366,27 @@ pub(crate) fn selected_style_attrs(s: &Session, para: bool) -> Result<Option<Map
|
||||
selection_attrs(s, &json!({}), if para { Kind::Para } else { Kind::Char })
|
||||
}
|
||||
|
||||
/// The attributes `charStyle.new` (`para`: `paraStyle.new`) would give a style made now from
|
||||
/// `target` (its `id`, `start` and `end`; empty for the selected objects). `None` without text
|
||||
/// there.
|
||||
pub fn target_style_attrs(s: &Session, target: &Value, para: bool) -> Option<Map<String, Value>> {
|
||||
selection_attrs(s, target, if para { Kind::Para } else { Kind::Char }).ok().flatten()
|
||||
}
|
||||
|
||||
/// Whether the document has a character (`para`: paragraph) style `name`, and its attributes.
|
||||
pub(crate) fn style_attrs(d: &Document, para: bool, name: &str) -> Option<Map<String, Value>> {
|
||||
if para { Kind::Para } else { Kind::Char }.attrs(d, name)
|
||||
}
|
||||
|
||||
/// The name `charStyle.new` (`para`: `paraStyle.new`) gives a style when it is given none: the
|
||||
/// first "Character Style N" ("Paragraph Style N") that no character style (paragraph style) of the
|
||||
/// document has.
|
||||
pub fn new_style_name(d: &Document, para: bool) -> String {
|
||||
let kind = if para { Kind::Para } else { Kind::Char };
|
||||
let base = if para { "Paragraph Style" } else { "Character Style" };
|
||||
(1..).map(|i| format!("{base} {i}")).find(|n| kind.attrs(d, n).is_none()).unwrap_or_else(|| base.to_string())
|
||||
}
|
||||
|
||||
fn name_param<'a>(p: &'a Value, kind: Kind, verb: &str) -> Result<&'a str> {
|
||||
str_param(p, "name").ok_or_else(|| bad(&kind.cmd(verb), "missing `name`"))
|
||||
}
|
||||
@@ -436,10 +452,9 @@ fn new(s: &mut Session, p: &Value, kind: Kind) -> Result<Value> {
|
||||
},
|
||||
};
|
||||
let d = &s.doc()?.doc;
|
||||
let base = if kind == Kind::Char { "Character Style" } else { "Paragraph Style" };
|
||||
let name = match str_param(p, "name") {
|
||||
Some(n) => n.trim().to_string(),
|
||||
None => (1..).map(|i| format!("{base} {i}")).find(|n| kind.attrs(d, n).is_none()).unwrap_or_else(|| base.to_string()),
|
||||
None => new_style_name(d, kind == Kind::Para),
|
||||
};
|
||||
if name.is_empty() {
|
||||
return Err(bad(&c, "give the style a name"));
|
||||
|
||||
@@ -62,6 +62,7 @@ pub mod new_brush;
|
||||
pub mod new_color_group;
|
||||
mod new_document;
|
||||
pub mod new_swatch;
|
||||
pub mod new_text_style;
|
||||
pub mod office_export;
|
||||
pub mod package;
|
||||
pub(crate) mod path_ops;
|
||||
@@ -298,6 +299,7 @@ registry! {
|
||||
GradientStop: ["gradientStop"] => gradient_stop::SPEC,
|
||||
ColorPicker: [color_picker::KIND] => color_picker::SPEC,
|
||||
GraphicStyleOptions: [graphic_style_options::KIND] => graphic_style_options::SPEC,
|
||||
NewTextStyle: [new_text_style::KIND] => new_text_style::SPEC,
|
||||
EffectExists: [effect::EXISTS] => effect::EXISTS_SPEC,
|
||||
ColorGuideOptions: [color_guide_options::KIND] => color_guide_options::SPEC,
|
||||
ColorBalance: [color_balance::KIND] => color_balance::SPEC,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//! New Character Style and New Paragraph Style: the new style's name. OK makes the style from the
|
||||
//! text that was selected when the dialog opened (`charStyle.new`, `paraStyle.new`).
|
||||
//!
|
||||
//! Fields: `name`, `__para` (true for a paragraph style) and `__target` (the `id`, `start` and
|
||||
//! `end` of the Type tool's selection, empty for the selected objects, and the `attrs` that text had
|
||||
//! when the dialog opened).
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use super::swatch_options::{grid, label};
|
||||
use super::{DialogSpec, form};
|
||||
use crate::VectorcraftApp;
|
||||
use crate::state::Dialog;
|
||||
|
||||
/// The dialog kind of New Character Style and New Paragraph Style.
|
||||
pub const KIND: &str = "newTextStyle";
|
||||
|
||||
pub(super) const SPEC: DialogSpec = DialogSpec { heading, body, confirm, min_width: 320.0, ..DialogSpec::FORM };
|
||||
|
||||
fn para(d: &Dialog) -> bool {
|
||||
d.fields.get("__para").and_then(Value::as_bool).unwrap_or(false)
|
||||
}
|
||||
|
||||
fn heading(d: &Dialog) -> String {
|
||||
if para(d) { tl!("New Paragraph Style") } else { tl!("New Character Style") }.into()
|
||||
}
|
||||
|
||||
/// Open New Character Style (`para`: New Paragraph Style) with the name `charStyle.new` would give
|
||||
/// the style, to make it from the text `target` names.
|
||||
pub fn open(app: &mut VectorcraftApp, para: bool, target: Value) -> Result<Value, String> {
|
||||
let d = &app.session.active().ok_or("no document open")?.doc;
|
||||
let name = vectorcraft_engine::cmd::textstyles::new_style_name(d, para);
|
||||
let mut target = target;
|
||||
if let Some(attrs) = vectorcraft_engine::cmd::textstyles::target_style_attrs(&app.session, &target, para) {
|
||||
target["attrs"] = Value::Object(attrs);
|
||||
}
|
||||
app.ui.dialog = Some(Dialog::new(KIND, json!({ "name": name, "__para": para, "__target": target })));
|
||||
Ok(json!({ "dialog": KIND }))
|
||||
}
|
||||
|
||||
fn body(_: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
grid(ui, |ui| {
|
||||
label(ui, tl!("Style Name:"));
|
||||
form::text(ui, d, "name", 190.0);
|
||||
ui.end_row();
|
||||
});
|
||||
false
|
||||
}
|
||||
|
||||
/// OK: make the style with the name. A name another style has, or an empty one, keeps the dialog
|
||||
/// open.
|
||||
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
let mut params = d.fields.get("__target").filter(|t| t.is_object()).cloned().unwrap_or_else(|| json!({}));
|
||||
params["name"] = json!(d.str("name"));
|
||||
let r = app.run(if para(d) { "paraStyle.new" } else { "charStyle.new" }, params);
|
||||
if r.is_ok() {
|
||||
app.ui.dialog = None;
|
||||
}
|
||||
r
|
||||
}
|
||||
@@ -393,6 +393,7 @@ fn dialogs_do_not_stretch_to_the_screen() {
|
||||
("ui.swatchOptions", json!({"name": "White"})),
|
||||
("ui.colorPicker", json!({})),
|
||||
("ui.graphicStyleOptions", json!({})),
|
||||
("ui.newCharStyle", json!({})),
|
||||
("ui.newArtboard", json!({})),
|
||||
("ui.brushOptions", json!({"name": "3 pt. Round"})),
|
||||
("ui.brushOptions", json!({"name": "Bristle Round"})),
|
||||
|
||||
@@ -1963,6 +1963,7 @@ font-technology Variable Променливи
|
||||
Brush Art Графика на четка
|
||||
New Calligraphic Brush Нова калиграфска четка
|
||||
New Character Style Нов стил на знак
|
||||
New Character Style… Нов стил на знак…
|
||||
New Color Group Нова цветова група
|
||||
New Color Group… Нова цветова група…
|
||||
New Document Presets Предварителни настройки за нов документ
|
||||
@@ -1978,6 +1979,7 @@ font-technology Variable Променливи
|
||||
New Opacity Masks Are Clipping Новите маски за непрозрачност са изрязващи
|
||||
New Opacity Masks Are Inverted Новите маски за непрозрачност са инвертирани
|
||||
New Paragraph Style Нов стил на абзац
|
||||
New Paragraph Style… Нов стил на абзац…
|
||||
New Pattern Brush from Selection Нова щампова четка от селекцията
|
||||
New PDF Preset Нова предварителна настройка за PDF
|
||||
New Print Preset Нова предварителна настройка за печат
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4038,7 +4038,9 @@ font-technology Variable Variabilní
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt na
|
||||
New Character Style Nový styl znaků
|
||||
New Character Style… Nový styl znaků…
|
||||
New Paragraph Style Nový styl odstavce
|
||||
New Paragraph Style… Nový styl odstavce…
|
||||
Paragraph Style Options Možnosti stylu odstavce
|
||||
Redefine Character Style Předefinovat styl znaků
|
||||
Redefine Paragraph Style Předefinovat styl odstavce
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3773,7 +3773,9 @@ font-technology Variable Variable
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt per
|
||||
New Character Style Ny tegnstil
|
||||
New Character Style… Ny tegnstil…
|
||||
New Paragraph Style Ny afsnitsstil
|
||||
New Paragraph Style… Ny afsnitsstil…
|
||||
Paragraph Style Options Indstillinger for afsnitsstil
|
||||
Redefine Character Style Omdefinér tegnstil
|
||||
Redefine Paragraph Style Omdefinér afsnitsstil
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1976,6 +1976,7 @@ file-filter Templates Vorlagen
|
||||
Brush Art Pinselgrafik
|
||||
New Calligraphic Brush Neuer Kalligrafiepinsel
|
||||
New Character Style Neues Zeichenformat
|
||||
New Character Style… Neues Zeichenformat…
|
||||
New Color Group Neue Farbgruppe
|
||||
New Color Group… Neue Farbgruppe…
|
||||
New Document Presets Vorgaben für neue Dokumente
|
||||
@@ -1991,6 +1992,7 @@ file-filter Templates Vorlagen
|
||||
New Opacity Masks Are Clipping Neue Deckkraftmasken sind Schnittmasken
|
||||
New Opacity Masks Are Inverted Neue Deckkraftmasken sind invertiert
|
||||
New Paragraph Style Neues Absatzformat
|
||||
New Paragraph Style… Neues Absatzformat…
|
||||
New Pattern Brush from Selection Neuer Musterpinsel aus Auswahl
|
||||
New PDF Preset Neue PDF-Vorgabe
|
||||
New Print Preset Neue Druckvorgabe
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2749,6 +2749,7 @@ theme Appearance Εμφάνιση
|
||||
Flat Fan Επίπεδη βεντάλια
|
||||
New Calligraphic Brush Νέο καλλιγραφικό πινέλο
|
||||
New Character Style Νέο στυλ χαρακτήρων
|
||||
New Character Style… Νέο στυλ χαρακτήρων…
|
||||
New Color Group Νέα ομάδα χρωμάτων
|
||||
New Color Group… Νέα ομάδα χρωμάτων…
|
||||
New Document Presets Νέες προεπιλογές εγγράφου
|
||||
@@ -2763,6 +2764,7 @@ theme Appearance Εμφάνιση
|
||||
New Opacity Masks Are Clipping Οι νέες μάσκες αδιαφάνειας εφαρμόζουν αποκοπή
|
||||
New Opacity Masks Are Inverted Οι νέες μάσκες αδιαφάνειας είναι ανεστραμμένες
|
||||
New Paragraph Style Νέο στυλ παραγράφου
|
||||
New Paragraph Style… Νέο στυλ παραγράφου…
|
||||
New Pattern Brush from Selection Νέο πινέλο μοτίβου από επιλογή
|
||||
New PDF Preset Νέα προεπιλογή PDF
|
||||
New Print Preset Νέα προεπιλογή εκτύπωσης
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 164 and column 5.
|
@@ -2018,6 +2018,7 @@ font-technology Variable Variables
|
||||
Brush Art Ilustración del pincel
|
||||
New Calligraphic Brush Nuevo pincel caligráfico
|
||||
New Character Style Nuevo estilo de carácter
|
||||
New Character Style… Nuevo estilo de carácter…
|
||||
New Color Group Nuevo grupo de colores
|
||||
New Color Group… Nuevo grupo de colores…
|
||||
New Document Presets Preajustes de documento nuevo
|
||||
@@ -2033,6 +2034,7 @@ font-technology Variable Variables
|
||||
New Opacity Masks Are Clipping Las nuevas máscaras de opacidad recortan
|
||||
New Opacity Masks Are Inverted Las nuevas máscaras de opacidad se invierten
|
||||
New Paragraph Style Nuevo estilo de párrafo
|
||||
New Paragraph Style… Nuevo estilo de párrafo…
|
||||
New Pattern Brush from Selection Nuevo pincel de motivo a partir de la selección
|
||||
New PDF Preset Nuevo preajuste de PDF
|
||||
New Print Preset Nuevo preajuste de impresión
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3958,7 +3958,9 @@ font-technology Variable Muuttuvat
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt kohden
|
||||
New Character Style Uusi merkkityyli
|
||||
New Character Style… Uusi merkkityyli…
|
||||
New Paragraph Style Uusi kappaletyyli
|
||||
New Paragraph Style… Uusi kappaletyyli…
|
||||
Paragraph Style Options Kappaletyylin asetukset
|
||||
Redefine Character Style Määritä merkkityyli uudelleen
|
||||
Redefine Paragraph Style Määritä kappaletyyli uudelleen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2015,6 +2015,7 @@ font-technology Variable Variables
|
||||
Brush Art Illustration de la forme
|
||||
New Calligraphic Brush Nouvelle forme calligraphique
|
||||
New Character Style Nouveau style de caractère
|
||||
New Character Style… Nouveau style de caractère…
|
||||
New Color Group Nouveau groupe de couleurs
|
||||
New Color Group… Nouveau groupe de couleurs…
|
||||
New Document Presets Paramètres prédéfinis de nouveau document
|
||||
@@ -2030,6 +2031,7 @@ font-technology Variable Variables
|
||||
New Opacity Masks Are Clipping Les nouveaux masques d’opacité sont des masques d’écrêtage
|
||||
New Opacity Masks Are Inverted Les nouveaux masques d’opacité sont inversés
|
||||
New Paragraph Style Nouveau style de paragraphe
|
||||
New Paragraph Style… Nouveau style de paragraphe…
|
||||
New Pattern Brush from Selection Nouvelle forme de motif à partir de la sélection
|
||||
New PDF Preset Nouveau paramètre prédéfini PDF
|
||||
New Print Preset Nouveau paramètre prédéfini d’impression
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2456,6 +2456,7 @@ file-filter Templates Sablonok
|
||||
New Brush… Új ecset…
|
||||
New Calligraphic Brush Új kalligrafikus ecset
|
||||
New Character Style Új karakterstílus
|
||||
New Character Style… Új karakterstílus…
|
||||
New Color Group Új színcsoport
|
||||
New Color Group… Új színcsoport…
|
||||
New Data Set Új adatkészlet
|
||||
@@ -2477,6 +2478,7 @@ file-filter Templates Sablonok
|
||||
New Opacity Masks Are Clipping Új átlátszósági maszkok vágnak
|
||||
New Opacity Masks Are Inverted Új átlátszósági maszkok invertáltak
|
||||
New Paragraph Style Új bekezdésstílus
|
||||
New Paragraph Style… Új bekezdésstílus…
|
||||
New Pattern Brush from Selection Új mintázatecset a kijelölésből
|
||||
New PDF Preset Új PDF-előbeállítás
|
||||
New Print Preset Új nyomtatási előbeállítás
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3773,7 +3773,9 @@ font-technology Variable Variabel
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt per
|
||||
New Character Style Gaya karakter baru
|
||||
New Character Style… Gaya karakter baru…
|
||||
New Paragraph Style Gaya paragraf baru
|
||||
New Paragraph Style… Gaya paragraf baru…
|
||||
Paragraph Style Options Opsi gaya paragraf
|
||||
Redefine Character Style Definisikan ulang gaya karakter
|
||||
Redefine Paragraph Style Definisikan ulang gaya paragraf
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2169 and column 5.
|
@@ -2045,6 +2045,7 @@ file-filter Templates Modelli
|
||||
Brush Art Grafica del pennello
|
||||
New Calligraphic Brush Nuovo pennello calligrafico
|
||||
New Character Style Nuovo stile carattere
|
||||
New Character Style… Nuovo stile carattere…
|
||||
New Color Group Nuovo gruppo colori
|
||||
New Color Group… Nuovo gruppo colori…
|
||||
New Document Presets Preset nuovo documento
|
||||
@@ -2060,6 +2061,7 @@ file-filter Templates Modelli
|
||||
New Opacity Masks Are Clipping Le nuove maschere di opacità ritagliano
|
||||
New Opacity Masks Are Inverted Le nuove maschere di opacità sono invertite
|
||||
New Paragraph Style Nuovo stile paragrafo
|
||||
New Paragraph Style… Nuovo stile paragrafo…
|
||||
New Pattern Brush from Selection Nuovo pennello motivo dalla selezione
|
||||
New PDF Preset Nuovo preset PDF
|
||||
New Print Preset Nuovo preset di stampa
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2179,6 +2179,7 @@ font-technology Variable バリアブル
|
||||
Brush Art ブラシのアート
|
||||
New Calligraphic Brush 新規絵筆ブラシ
|
||||
New Character Style 新規文字スタイル
|
||||
New Character Style… 新規文字スタイル…
|
||||
New Color Group 新規カラーグループ
|
||||
New Color Group… 新規カラーグループ…
|
||||
New Document Presets 新規ドキュメントプリセット
|
||||
@@ -2192,6 +2193,7 @@ font-technology Variable バリアブル
|
||||
New Opacity Masks Are Inverted 新規不透明マスクを反転に設定
|
||||
New PDF Preset 新規 PDF プリセット
|
||||
New Paragraph Style 新規段落スタイル
|
||||
New Paragraph Style… 新規段落スタイル…
|
||||
New Pattern Brush from Selection 選択範囲から新規パターンブラシ
|
||||
New Print Preset 新規プリントプリセット
|
||||
New Scatter Brush from Selection 選択範囲から新規散布ブラシ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3554,7 +3554,9 @@ font-technology Variable ცვლადი
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt თითოზე
|
||||
New Character Style სიმბოლოს ახალი სტილი
|
||||
New Character Style… სიმბოლოს ახალი სტილი…
|
||||
New Paragraph Style აბზაცის ახალი სტილი
|
||||
New Paragraph Style… აბზაცის ახალი სტილი…
|
||||
Paragraph Style Options აბზაცის სტილის პარამეტრები
|
||||
Redefine Character Style სიმბოლოს სტილის ხელახლა განსაზღვრა
|
||||
Redefine Paragraph Style აბზაცის სტილის ხელახლა განსაზღვრა
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2174,6 +2174,7 @@ font-technology Variable 가변
|
||||
Brush Art 브러시 아트
|
||||
New Calligraphic Brush 새 캘리그래피 브러시
|
||||
New Character Style 새 문자 스타일
|
||||
New Character Style… 새 문자 스타일…
|
||||
New Color Group 새 색상 그룹
|
||||
New Color Group… 새 색상 그룹…
|
||||
New Document Presets 새 문서 사전 설정
|
||||
@@ -2187,6 +2188,7 @@ font-technology Variable 가변
|
||||
New Opacity Masks Are Inverted 새 불투명 마스크를 반전으로 설정
|
||||
New PDF Preset 새 PDF 사전 설정
|
||||
New Paragraph Style 새 단락 스타일
|
||||
New Paragraph Style… 새 단락 스타일…
|
||||
New Pattern Brush from Selection 선택 항목으로 새 패턴 브러시 만들기
|
||||
New Print Preset 새 인쇄 사전 설정
|
||||
New Scatter Brush from Selection 선택 항목으로 새 흩뿌리기 브러시 만들기
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3787,7 +3787,9 @@ font-technology Variable Variabel
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt per
|
||||
New Character Style Nieuwe tekenstijl
|
||||
New Character Style… Nieuwe tekenstijl…
|
||||
New Paragraph Style Nieuwe alineastijl
|
||||
New Paragraph Style… Nieuwe alineastijl…
|
||||
Paragraph Style Options Alineastijlopties
|
||||
Redefine Character Style Tekenstijl opnieuw definiëren
|
||||
Redefine Paragraph Style Alineastijl opnieuw definiëren
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3879,7 +3879,9 @@ font-technology Variable Zmienne
|
||||
Mojikumi Mojikumi
|
||||
N pt per N pt na
|
||||
New Character Style Nowy styl znakowy
|
||||
New Character Style… Nowy styl znakowy…
|
||||
New Paragraph Style Nowy styl akapitowy
|
||||
New Paragraph Style… Nowy styl akapitowy…
|
||||
Paragraph Style Options Opcje stylu akapitowego
|
||||
Redefine Character Style Zdefiniuj ponownie styl znakowy
|
||||
Redefine Paragraph Style Zdefiniuj ponownie styl akapitowy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1632,6 +1632,7 @@
|
||||
Brush Art Arte do Pincel
|
||||
New Calligraphic Brush Novo Pincel Caligráfico
|
||||
New Character Style Novo Estilo de Caractere
|
||||
New Character Style… Novo Estilo de Caractere…
|
||||
New Color Group Novo Grupo de Cores
|
||||
New Color Group… Novo Grupo de Cores…
|
||||
New Document Presets Novos Predefinidos de Documento
|
||||
@@ -1643,6 +1644,7 @@
|
||||
New Opacity Masks Are Inverted Novas Máscaras de Opacidade São Invertidas
|
||||
New PDF Preset Novo Predefinido de PDF
|
||||
New Paragraph Style Novo Estilo de Parágrafo
|
||||
New Paragraph Style… Novo Estilo de Parágrafo…
|
||||
New Pattern Brush from Selection Novo Pincel de Padrão a partir da Seleção
|
||||
New Print Preset Novo Predefinido de Impressão
|
||||
New Scatter Brush from Selection Novo Pincel de Dispersão a partir da Seleção
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2041,6 +2041,7 @@ file-filter Templates Шаблоны
|
||||
Brush Art Рисунок кисти
|
||||
New Calligraphic Brush Новая каллиграфическая кисть
|
||||
New Character Style Новый стиль символа
|
||||
New Character Style… Новый стиль символа…
|
||||
New Color Group Новая цветовая группа
|
||||
New Color Group… Новая цветовая группа…
|
||||
New Document Presets Наборы новых документов
|
||||
@@ -2056,6 +2057,7 @@ file-filter Templates Шаблоны
|
||||
New Opacity Masks Are Clipping Новые непрозрачные маски обрезают
|
||||
New Opacity Masks Are Inverted Новые непрозрачные маски инвертируются
|
||||
New Paragraph Style Новый стиль абзаца
|
||||
New Paragraph Style… Новый стиль абзаца…
|
||||
New Pattern Brush from Selection Новая узорная кисть из выделенного
|
||||
New PDF Preset Новый набор PDF
|
||||
New Print Preset Новый набор печати
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1963,6 +1963,7 @@ font-technology Variable Variabla
|
||||
Brush Art Penselgrafik
|
||||
New Calligraphic Brush Ny kalligrafisk pensel
|
||||
New Character Style Ny teckenstil
|
||||
New Character Style… Ny teckenstil…
|
||||
New Color Group Ny färggrupp
|
||||
New Color Group… Ny färggrupp…
|
||||
New Document Presets Förinställningar för nytt dokument
|
||||
@@ -1978,6 +1979,7 @@ font-technology Variable Variabla
|
||||
New Opacity Masks Are Clipping Nya opacitetsmasker är klippande
|
||||
New Opacity Masks Are Inverted Nya opacitetsmasker är inverterade
|
||||
New Paragraph Style Ny styckestil
|
||||
New Paragraph Style… Ny styckestil…
|
||||
New Pattern Brush from Selection Ny mönsterpensel från markeringen
|
||||
New PDF Preset Ny PDF-förinställning
|
||||
New Print Preset Ny utskriftsförinställning
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -1844,6 +1844,7 @@ font-technology Variable Değişken
|
||||
New Brush… Yeni Fırça…
|
||||
New Calligraphic Brush Yeni Kaligrafi Fırçası
|
||||
New Character Style Yeni Karakter Stili
|
||||
New Character Style… Yeni Karakter Stili…
|
||||
New Color Group Yeni Renk Grubu
|
||||
New Color Group… Yeni Renk Grubu…
|
||||
New Document Presets Yeni Belge Ön Ayarları
|
||||
@@ -1858,6 +1859,7 @@ font-technology Variable Değişken
|
||||
New Opacity Masks Are Clipping Yeni Opaklık Maskeleri Kırpılıyor
|
||||
New Opacity Masks Are Inverted Yeni Opaklık Maskeleri Ters Çevrildi
|
||||
New Paragraph Style Yeni Paragraf Stili
|
||||
New Paragraph Style… Yeni Paragraf Stili…
|
||||
New Pattern Brush from Selection Seçimden Yeni Desen Fırçası
|
||||
New PDF Preset Yeni PDF Hazır Ayarı
|
||||
New Print Preset Yeni Yazdırma Ön Ayarı
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -2037,6 +2037,7 @@ file-filter Templates Шаблони
|
||||
Brush Art Малюнок пензля
|
||||
New Calligraphic Brush Новий каліграфічний пензель
|
||||
New Character Style Новий стиль символу
|
||||
New Character Style… Новий стиль символу…
|
||||
New Color Group Нова колірна група
|
||||
New Color Group… Нова колірна група…
|
||||
New Document Presets Набір нових документів
|
||||
@@ -2052,6 +2053,7 @@ file-filter Templates Шаблони
|
||||
New Opacity Masks Are Clipping Нові маски непрозорості відсікають
|
||||
New Opacity Masks Are Inverted Нові маски непрозорості інвертуються
|
||||
New Paragraph Style Новий стиль абзацу
|
||||
New Paragraph Style… Новий стиль абзацу…
|
||||
New Pattern Brush from Selection Новий візерунковий пензель з виділеного
|
||||
New PDF Preset Новий набір PDF
|
||||
New Print Preset Новий набір друку
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 178 and column 5.
|
@@ -2263,6 +2263,7 @@ file-filter Templates Mẫu
|
||||
New Brush… Cọ mới…
|
||||
New Calligraphic Brush Cọ thư pháp mới
|
||||
New Character Style Kiểu ký tự mới
|
||||
New Character Style… Kiểu ký tự mới…
|
||||
New Color Group Nhóm màu mới
|
||||
New Color Group… Nhóm màu mới…
|
||||
New Data Set Tập dữ liệu mới
|
||||
@@ -2285,6 +2286,7 @@ file-filter Templates Mẫu
|
||||
New Opacity Masks Are Clipping Mặt nạ độ mờ mới là cắt
|
||||
New Opacity Masks Are Inverted Mặt nạ độ mờ mới bị đảo ngược
|
||||
New Paragraph Style Kiểu đoạn văn mới
|
||||
New Paragraph Style… Kiểu đoạn văn mới…
|
||||
New Pattern Brush from Selection Cọ họa tiết mới từ vùng chọn
|
||||
New PDF Preset Thiết lập sẵn PDF mới
|
||||
New Print Preset Thiết lập sẵn in mới
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 200 and column 5.
|
@@ -1918,6 +1918,7 @@ file-filter Templates 模板
|
||||
Brush Art 画笔图稿
|
||||
New Calligraphic Brush 新建书法画笔
|
||||
New Character Style 新建字符样式
|
||||
New Character Style… 新建字符样式…
|
||||
New Color Group 新建颜色组
|
||||
New Color Group… 新建颜色组…
|
||||
New Document Presets 新建文档预设
|
||||
@@ -1931,6 +1932,7 @@ file-filter Templates 模板
|
||||
New Opacity Masks Are Clipping 新建不透明度蒙版为剪切
|
||||
New Opacity Masks Are Inverted 新建不透明度蒙版为反相
|
||||
New Paragraph Style 新建段落样式
|
||||
New Paragraph Style… 新建段落样式…
|
||||
New Pattern Brush from Selection 从选区新建图案画笔
|
||||
New PDF Preset 新建 PDF 预设
|
||||
New Print Preset 新建打印预设
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2841,6 +2841,7 @@ file-filter Templates 範本
|
||||
Brush Art 筆刷圖稿
|
||||
New Calligraphic Brush 新增書法筆刷
|
||||
New Character Style 新增字元樣式
|
||||
New Character Style… 新增字元樣式…
|
||||
New Color Group 新增顏色群組
|
||||
New Color Group… 新增顏色群組…
|
||||
New Document Presets 新增文件預設集
|
||||
@@ -2856,6 +2857,7 @@ file-filter Templates 範本
|
||||
New Opacity Masks Are Clipping 新的不透明度遮色片為剪裁
|
||||
New Opacity Masks Are Inverted 新的不透明度遮色片為反轉
|
||||
New Paragraph Style 新增段落樣式
|
||||
New Paragraph Style… 新增段落樣式…
|
||||
New Pattern Brush from Selection 從選取範圍新增圖樣筆刷
|
||||
New PDF Preset 新增 PDF 預設集
|
||||
New Print Preset 新增列印預設集
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -587,6 +587,8 @@ fn run_ui_part7(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result<
|
||||
"ui.colorPicker" => crate::dialogs::open_color_picker(app, p),
|
||||
"ui.sampleScreenColor" => crate::screen_color::start(app, p),
|
||||
"ui.graphicStyleOptions" => crate::dialogs::graphic_style_options::open(app, s("name").as_deref()),
|
||||
"ui.newCharStyle" => crate::panels::text_styles::open_new(app, crate::panels::text_styles::Kind::Char),
|
||||
"ui.newParaStyle" => crate::panels::text_styles::open_new(app, crate::panels::text_styles::Kind::Para),
|
||||
"ui.symbolOptions" => {
|
||||
let name = s("name");
|
||||
let edit = p.get("edit").and_then(Value::as_bool).unwrap_or(false);
|
||||
|
||||
@@ -221,7 +221,7 @@ pub fn enabled(app: &VectorcraftApp, id: &str) -> bool {
|
||||
"ui.missingFontsDialog" => !cfg!(target_arch = "wasm32") && app.session.active().is_some(),
|
||||
"ui.findFontsInFolder" => crate::picks::can(app, &crate::picks::PickRequest::Folder) && app.session.active().is_some(),
|
||||
"ui.swatchOptions" | "ui.newSwatch" | "ui.newColorGroup" => app.session.active().is_some(),
|
||||
"ui.graphicStyleOptions" => app.session.active().is_some(),
|
||||
"ui.graphicStyleOptions" | "ui.newCharStyle" | "ui.newParaStyle" => app.session.active().is_some(),
|
||||
"ui.newArtboard" => app.session.active().is_some(),
|
||||
"ui.sampleScreenColor" => crate::screen_color::available(app),
|
||||
"ui.newBrush" => app.session.active().is_some(),
|
||||
|
||||
@@ -633,6 +633,18 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
"",
|
||||
"{name?} open Graphic Style Options (dialog `graphicStyleOptions`, field `name`): for style `name` OK renames it (graphicStyle.rename); without, OK makes a new style of that name from the selection (graphicStyle.new)",
|
||||
),
|
||||
(
|
||||
"ui.newCharStyle",
|
||||
"New Character Style…",
|
||||
"",
|
||||
"{} open New Character Style (dialog `newTextStyle`, field `name`, filled in with the name charStyle.new {} would give the style), what Alt-clicking the Character Styles panel's New button opens; OK runs charStyle.new with the name and the Type tool's selected characters (else the selected type) as they were when the dialog opened; Cancel adds no style",
|
||||
),
|
||||
(
|
||||
"ui.newParaStyle",
|
||||
"New Paragraph Style…",
|
||||
"",
|
||||
"{} open New Paragraph Style (dialog `newTextStyle`, field `name`, filled in with the name paraStyle.new {} would give the style), what Alt-clicking the Paragraph Styles panel's New button opens; OK runs paraStyle.new with the name and the paragraph of the Type tool's selection (else the selected type) as it was when the dialog opened; Cancel adds no style",
|
||||
),
|
||||
(
|
||||
"ui.symbolOptions",
|
||||
"Symbol Options…",
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
//!
|
||||
//! Click a style to apply it to the selected text (or the Type tool's selected characters);
|
||||
//! Alt-click applies it and clears overrides. The style of the selection is highlighted, with a
|
||||
//! "+" when the text overrides some of its attributes.
|
||||
//! "+" when the text overrides some of its attributes. New makes a style from the selected text;
|
||||
//! Alt-click on New first asks for its name (`ui.newCharStyle`, `ui.newParaStyle`).
|
||||
|
||||
use egui::{Sense, Ui, vec2};
|
||||
use serde_json::{Map, Value, json};
|
||||
use vectorcraft_engine::cmd::textstyles;
|
||||
|
||||
use super::character::{end_typing, text_editing, text_style};
|
||||
use super::{pstate, selection_len, set_pstate};
|
||||
use super::{alt_held, pstate, selection_len, set_pstate};
|
||||
use crate::VectorcraftApp;
|
||||
use crate::theme::Tokens;
|
||||
use crate::widgets::{self, menu_item};
|
||||
@@ -106,6 +107,15 @@ fn target(app: &VectorcraftApp, kind: Kind, mut p: Value) -> Value {
|
||||
p
|
||||
}
|
||||
|
||||
/// Open New Character Style (`Kind::Para`: New Paragraph Style) to name a style made from the
|
||||
/// selected text: `ui.newCharStyle` and `ui.newParaStyle`.
|
||||
pub(crate) fn open_new(app: &mut VectorcraftApp, kind: Kind) -> Result<Value, String> {
|
||||
// A later typing preview must not restore the document from before this capture.
|
||||
end_typing(app);
|
||||
let t = target(app, kind, json!({}));
|
||||
crate::dialogs::new_text_style::open(app, kind == Kind::Para, t)
|
||||
}
|
||||
|
||||
pub fn show(app: &mut VectorcraftApp, ui: &mut Ui, kind: Kind) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let all = styles(app, kind);
|
||||
@@ -176,7 +186,9 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui, kind: Kind) {
|
||||
}
|
||||
} else if new.clicked() {
|
||||
end_typing(app);
|
||||
if let Ok(r) = app.run(&format!("{}.new", kind.prefix()), target(app, kind, json!({}))) {
|
||||
if alt_held(ui) {
|
||||
app.run(if kind == Kind::Char { "ui.newCharStyle" } else { "ui.newParaStyle" }, json!({})).ok();
|
||||
} else if let Ok(r) = app.run(&format!("{}.new", kind.prefix()), target(app, kind, json!({}))) {
|
||||
highlight_made(ui.ctx(), kind, r["name"].as_str().map(str::to_string));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,6 +537,129 @@ fn click_new_style_footer_range(ctx: &egui::Context, app: &mut VectorcraftApp, i
|
||||
assert_eq!(text_editing(app), Some((id, start, end)), "footer capture preserves the Type range");
|
||||
}
|
||||
|
||||
/// Alt-click the production bottom bar's New button of the `kind` panel, then draw the dialog
|
||||
/// it opened: every text the last frame drew.
|
||||
fn alt_click_new(ctx: &egui::Context, app: &mut VectorcraftApp, kind: Kind) -> Vec<String> {
|
||||
click_new_with(ctx, app, kind, egui::Modifiers::ALT)
|
||||
}
|
||||
|
||||
fn click_new(ctx: &egui::Context, app: &mut VectorcraftApp, kind: Kind) {
|
||||
click_new_with(ctx, app, kind, egui::Modifiers::NONE);
|
||||
}
|
||||
|
||||
fn click_new_with(ctx: &egui::Context, app: &mut VectorcraftApp, kind: Kind, modifiers: egui::Modifiers) -> Vec<String> {
|
||||
let pos = std::cell::Cell::new(egui::Pos2::ZERO);
|
||||
let mut draw = |app: &mut VectorcraftApp, ui: &mut egui::Ui| {
|
||||
ui.set_width(280.0);
|
||||
let right = ui.max_rect().right();
|
||||
show(app, ui, kind);
|
||||
pos.set(egui::pos2(right - 40.0, ui.min_rect().bottom() - 12.0));
|
||||
};
|
||||
frame_events(ctx, app, vec![], &mut draw);
|
||||
frame_events(ctx, app, vec![], &mut draw);
|
||||
let at = pos.get();
|
||||
let button = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers };
|
||||
for e in [egui::Event::PointerMoved(at), button(true), button(false)] {
|
||||
frame_events(ctx, app, vec![egui::Event::ModifiersChanged(modifiers), e], &mut draw);
|
||||
}
|
||||
// A window draws its content from its second frame.
|
||||
frame_events(ctx, app, vec![], |app, ui| crate::dialogs::show(app, ui.ctx()));
|
||||
frame_events(ctx, app, vec![], |app, ui| crate::dialogs::show(app, ui.ctx())).into_iter().map(|(s, _)| s).collect()
|
||||
}
|
||||
|
||||
fn set_name(app: &mut VectorcraftApp, name: &str) {
|
||||
app.ui.dialog.as_mut().expect("the dialog is open").fields.insert("name".into(), json!(name));
|
||||
}
|
||||
|
||||
/// Alt-click on New Character Style opens New Character Style with the name a plain click's
|
||||
/// style gets, and adds no style yet. Cancel adds none. OK makes the style with the typed name
|
||||
/// from the Type tool's selected characters, in one undo step, and a name another style has keeps
|
||||
/// the dialog open.
|
||||
#[test]
|
||||
fn alt_clicking_new_character_style_asks_for_its_name() {
|
||||
let (mut app, id, ctx) = capture_app();
|
||||
select_type_range(&mut app, id, 3, 5);
|
||||
let names = |app: &VectorcraftApp| app.session.doc().unwrap().doc.char_styles.iter().map(|s| s.name.clone()).collect::<Vec<_>>();
|
||||
let before = names(&app);
|
||||
let shown = alt_click_new(&ctx, &mut app, Kind::Char);
|
||||
let d = app.ui.dialog.as_ref().expect("Alt-click on New opens a dialog");
|
||||
assert_eq!((d.kind.as_str(), d.str("name").as_str()), (crate::dialogs::new_text_style::KIND, "Character Style 1"));
|
||||
assert!(shown.iter().any(|s| s == "New Character Style"), "the dialog's heading: {shown:?}");
|
||||
assert_eq!(names(&app), before, "no style is added before OK");
|
||||
crate::dialogs::cancel(&mut app);
|
||||
assert_eq!(names(&app), before, "Cancel adds no style");
|
||||
|
||||
alt_click_new(&ctx, &mut app, Kind::Char);
|
||||
set_name(&mut app, "Untouched");
|
||||
assert!(crate::dialogs::confirm(&mut app).is_err(), "names are unique");
|
||||
assert!(app.ui.dialog.is_some(), "a taken name keeps the dialog open");
|
||||
set_name(&mut app, "Heading");
|
||||
let undo = app.session.doc().unwrap().history.undo.len();
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
assert!(app.ui.dialog.is_none());
|
||||
let doc = &app.session.doc().unwrap().doc;
|
||||
let heading = doc.char_styles.iter().find(|s| s.name == "Heading").expect("OK makes the style");
|
||||
assert_eq!(heading.attrs.get("size").and_then(Value::as_f64), Some(34.0), "made from the selected characters");
|
||||
assert_eq!(doc.char_styles.len(), before.len() + 1);
|
||||
assert_eq!(app.session.doc().unwrap().history.undo.len(), undo + 1);
|
||||
assert_eq!(text_editing(&app), Some((id, 3, 5)), "the Type selection stays");
|
||||
}
|
||||
|
||||
/// OK makes the style from the text's attributes as they were when the dialog opened: a later
|
||||
/// format change of the Type selection, or a change of the selected objects, does not reach it.
|
||||
#[test]
|
||||
fn new_style_dialog_keeps_the_attributes_from_when_it_opened() {
|
||||
let (mut app, id, ctx) = capture_app();
|
||||
select_type_range(&mut app, id, 3, 5);
|
||||
alt_click_new(&ctx, &mut app, Kind::Char);
|
||||
app.run("text.setRangeStyle", json!({"id": id.0, "start": 2, "end": 6, "size": 50})).unwrap();
|
||||
set_name(&mut app, "Range");
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
|
||||
app.session.select_tool("selection", Default::default()).unwrap();
|
||||
app.run("select.set", json!({"ids": [id.0]})).unwrap();
|
||||
assert_eq!(text_editing(&app), None);
|
||||
alt_click_new(&ctx, &mut app, Kind::Char);
|
||||
let count = app.session.doc().unwrap().doc.char_styles.len();
|
||||
app.run("text.setRangeStyle", json!({"id": id.0, "start": 0, "end": 2, "size": 60})).unwrap();
|
||||
set_name(&mut app, "Object");
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
|
||||
let doc = &app.session.doc().unwrap().doc;
|
||||
assert_eq!(doc.char_styles.len(), count + 1);
|
||||
let size = |n: &str| doc.char_styles.iter().find(|s| s.name == n).and_then(|s| s.attrs.get("size")).and_then(Value::as_f64);
|
||||
assert_eq!((size("Range"), size("Object")), (Some(34.0), Some(18.0)));
|
||||
}
|
||||
|
||||
/// Alt-click on New Paragraph Style opens New Paragraph Style for the selected type's paragraph;
|
||||
/// a plain click still makes the style at once.
|
||||
#[test]
|
||||
fn alt_clicking_new_paragraph_style_asks_for_its_name() {
|
||||
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 300, "height": 200})).unwrap();
|
||||
let id = app.run("text.create", json!({"x": 20, "y": 50, "text": "Body"})).unwrap()["id"].clone();
|
||||
app.run("select.set", json!({"ids": [id]})).unwrap();
|
||||
app.run("text.setFormat", json!({"composer": "singleLine"})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let shown = alt_click_new(&ctx, &mut app, Kind::Para);
|
||||
let d = app.ui.dialog.as_ref().expect("Alt-click on New opens a dialog");
|
||||
assert_eq!((d.kind.as_str(), d.str("name").as_str()), (crate::dialogs::new_text_style::KIND, "Paragraph Style 1"));
|
||||
assert!(shown.iter().any(|s| s == "New Paragraph Style"), "the dialog's heading: {shown:?}");
|
||||
assert!(app.session.doc().unwrap().doc.para_styles.is_empty(), "no style is added before OK");
|
||||
set_name(&mut app, "Body Copy");
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
let (_, attrs) = current(&app, Kind::Para).unwrap();
|
||||
let doc = &app.session.doc().unwrap().doc;
|
||||
assert_eq!(doc.para_styles.iter().map(|s| (s.name.as_str(), &s.attrs)).collect::<Vec<_>>(), [("Body Copy", &attrs)]);
|
||||
|
||||
// A plain click still makes "Paragraph Style 1" at once, with no dialog.
|
||||
click_new(&ctx, &mut app, Kind::Para);
|
||||
assert!(app.ui.dialog.is_none());
|
||||
let names: Vec<_> = app.session.doc().unwrap().doc.para_styles.iter().map(|s| s.name.clone()).collect();
|
||||
assert_eq!(names, ["Body Copy", "Paragraph Style 1"]);
|
||||
}
|
||||
|
||||
fn create_redefined_texts(app: &mut VectorcraftApp, ctx: &egui::Context, id: NodeId) -> (Option<NodeId>, Option<NodeId>) {
|
||||
let mut follower = None;
|
||||
let mut local_override = None;
|
||||
|
||||
Reference in New Issue
Block a user