diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index a84f8ffc8..82c384e6d 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -879,9 +879,12 @@ common = .sent-to-printer-printer = أُرسل إلى الطابعة: __ocs_fmt_0__ .set-current = تعيين كحالي .shade-plot = تظليل الطباعة + .shaded-with-edges = مظلل مع الحواف + .shades-of-gray = درجات الرمادي .shadow-flags = علامات الظلال .single = مفرد .size = الحجم + .sketchy = تخطيطي .snap-override-label-next-pick-only = تجاوز الالتقاط: __ocs_fmt_0__ (للاختيار التالي فقط). .solid-created = أُنشئ المجسم. .source-object-not-found = لم يُعثر على الكائن المصدر. @@ -6345,8 +6348,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index 543c66c93..244eaa4ab 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = Изпратено до принтер: __ocs_fmt_0__ .set-current = Задай като текущ .shade-plot = Плотиране със засенчване + .shaded-with-edges = Засенчен с ръбове + .shades-of-gray = Нюанси на сивото .shadow-flags = Флагове на сенки .single = Единично .size = Размер + .sketchy = Скициран .snap-override-label-next-pick-only = Прескачане на закачване: __ocs_fmt_0__ (само за следващото избиране). .solid-created = Тялото е създадено. .source-object-not-found = Изходният обект не е намерен. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index e573ce937..3ce2f3689 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = Odesláno do tiskárny: __ocs_fmt_0__ .set-current = Nastavit aktuální .shade-plot = Stínový pozemek + .shaded-with-edges = Stínovaný s hranami + .shades-of-gray = Odstíny šedi .shadow-flags = Stínové vlajky .single = Svobodný .size = Velikost + .sketchy = Náčrt .snap-override-label-next-pick-only = Přepsání uchopení: __ocs_fmt_0__ (pouze další výběr). .solid-created = Pevná látka vytvořena. .source-object-not-found = Zdrojový objekt nebyl nalezen. @@ -6330,8 +6333,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index b31c44a38..77b11dfa0 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -867,9 +867,12 @@ common = .sent-to-printer-printer = Gesendet an Drucker: __ocs_fmt_0__ .set-current = Aktuell setzen .shade-plot = Schattierter Plot + .shaded-with-edges = Schattiert mit Kanten + .shades-of-gray = Graustufen .shadow-flags = Schattenfahnen .single = Einzel .size = Größe + .sketchy = Skizzenhaft .snap-override-label-next-pick-only = Snap Übersteuerung: __ocs_fmt_0__ (nur nächste Auswahl). .solid-created = Volumenkörper erstellt. .source-object-not-found = Quellobjekt nicht gefunden. @@ -6331,8 +6334,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index 358f5399e..9ad372c94 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -868,9 +868,12 @@ common = .sent-to-printer-printer = Στάλθηκε στον εκτυπωτή: __ocs_fmt_0__ .set-current = Ορισμός ως τρέχον .shade-plot = Σκίαση εκτύπωσης + .shaded-with-edges = Σκιασμένο με ακμές + .shades-of-gray = Αποχρώσεις του γκρι .shadow-flags = Σημαίες σκιάς .single = Μονό .size = Μέγεθος + .sketchy = Σκίτσο .snap-override-label-next-pick-only = Παράκαμψη έλξης: __ocs_fmt_0__ (μόνο για την επόμενη επιλογή). .solid-created = Το στερεό δημιουργήθηκε. .source-object-not-found = Το αντικείμενο προέλευσης δεν βρέθηκε. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index 7c534a2b0..ba1e49828 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -865,9 +865,12 @@ common = .sent-to-printer-printer = Sent to printer: __ocs_fmt_0__ .set-current = Set Current .shade-plot = Shade plot + .shaded-with-edges = Shaded with edges + .shades-of-gray = Shades of Gray .shadow-flags = Shadow flags .single = Single .size = Size + .sketchy = Sketchy .snap-override-label-next-pick-only = Snap override: __ocs_fmt_0__ (next pick only). .solid-created = Solid created. .source-object-not-found = Source object not found. @@ -6332,8 +6335,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 6c0831926..4801085c6 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -867,9 +867,12 @@ common = .sent-to-printer-printer = Enviado a la impresora: __ocs_fmt_0__ .set-current = Establecer actual .shade-plot = Trazado sombreado + .shaded-with-edges = Sombreado con aristas + .shades-of-gray = Tonos de gris .shadow-flags = Indicadores de sombra .single = Único .size = Tamaño + .sketchy = Bosquejo .snap-override-label-next-pick-only = Modificación de referencia: __ocs_fmt_0__ (solo la siguiente designación). .solid-created = Se creó el sólido. .source-object-not-found = No se encontró el objeto de origen. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index 1aa58081d..747949931 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = Lähetetty tulostimelle: __ocs_fmt_0__ .set-current = Aseta nykyinen .shade-plot = Shade juoni + .shaded-with-edges = Varjostettu reunoilla + .shades-of-gray = Harmaasävyt .shadow-flags = Varjoliput .single = Sinkku .size = Koko + .sketchy = Luonnos .snap-override-label-next-pick-only = Snap-ohitus: __ocs_fmt_0__ (vain seuraava valinta). .solid-created = Kiinteä luotu. .source-object-not-found = Lähdeobjektia ei löydy. @@ -6330,8 +6333,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index a6c5a5ca4..1afb446ff 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -867,9 +867,12 @@ common = .sent-to-printer-printer = Envoyé à l'imprimante : __ocs_fmt_0__ .set-current = Définir comme courant .shade-plot = Terrain ombragé + .shaded-with-edges = Ombré avec arêtes + .shades-of-gray = Nuances de gris .shadow-flags = Drapeaux d'ombre .single = Un seul .size = Taille + .sketchy = Croquis .snap-override-label-next-pick-only = Accrochage temporaire : __ocs_fmt_0__ (prochaine sélection uniquement). .solid-created = Solide créé. .source-object-not-found = Objet source introuvable. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 051ecf45d..6632f91b9 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -855,9 +855,12 @@ common = .sent-to-printer-printer = प्रिंटर के लिए भेजा गया: __ocs_fmt_0__ .set-current = वर्तमान सेट करें .shade-plot = छाया कथा + .shaded-with-edges = किनारों सहित छायांकित + .shades-of-gray = ग्रे के शेड .shadow-flags = छाया झंडे .single = एकल .size = आकार + .sketchy = रेखाचित्र .snap-override-label-next-pick-only = स्नैप ओवरराइड: __ocs_fmt_0__ (अकेले केवल पिक)। .solid-created = ठोस बनाया गया। .source-object-not-found = स्रोत ऑब्जेक्ट नहीं मिला। @@ -6321,8 +6324,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index 98ce35472..0160741b2 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -871,9 +871,12 @@ common = .sent-to-printer-printer = Nyomtatóra küldve: __ocs_fmt_0__ .set-current = Aktuálissá tétel .shade-plot = Árnyalt nyomtatás + .shaded-with-edges = Árnyalt élekkel + .shades-of-gray = Szürkeárnyalatok .shadow-flags = Árnyékbeállítások .single = Egyetlen .size = Méret + .sketchy = Vázlatos .snap-override-label-next-pick-only = Ideiglenes tárgyraszter: __ocs_fmt_0__ (csak a következő pontnál). .solid-created = Test létrehozva. .source-object-not-found = A forrásobjektum nem található. @@ -6317,8 +6320,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index eb4da87ed..abf07c9af 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = Inviato alla stampante: __ocs_fmt_0__ .set-current = Imposta corrente .shade-plot = Stampa ombreggiatura + .shaded-with-edges = Ombreggiato con spigoli + .shades-of-gray = Sfumature di grigio .shadow-flags = Opzioni di ombreggiatura .single = Singolo .size = Dimensioni + .sketchy = Schizzo .snap-override-label-next-pick-only = Sostituzione dello snap: __ocs_fmt_0__ (solo scelta successiva). .solid-created = Solido creato. .source-object-not-found = Oggetto di origine non trovato. @@ -6332,8 +6335,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 57a2db5df..db28bd562 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -857,9 +857,12 @@ common = .sent-to-printer-printer = プリンターへ送信しました: __ocs_fmt_0__ .set-current = 現在に設定 .shade-plot = シェーディング印刷 + .shaded-with-edges = 陰影付き(エッジ表示) + .shades-of-gray = グレースケール .shadow-flags = 影フラグ .single = 単一 .size = サイズ + .sketchy = スケッチ .snap-override-label-next-pick-only = スナップ優先: __ocs_fmt_0__(次の選択のみ)。 .solid-created = ソリッドを作成しました。 .source-object-not-found = 元オブジェクトが見つかりません。 @@ -6321,8 +6324,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 8f3cb9d03..9664b3bd7 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = 프린터로 전송됨: __ocs_fmt_0__ .set-current = 현재 설정 .shade-plot = 음영 플롯 + .shaded-with-edges = 모서리로 음영처리됨 + .shades-of-gray = 회색 음영 .shadow-flags = 그림자 깃발 .single = 싱글 .size = 크기 + .sketchy = 스케치 .snap-override-label-next-pick-only = 스냅 재정의: __ocs_fmt_0__(다음 선택에만 해당) .solid-created = 솔리드가 생성되었습니다. .source-object-not-found = 소스 개체를 찾을 수 없습니다. @@ -6332,8 +6335,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/lo-LA/opencadstudio.ftl b/locales/lo-LA/opencadstudio.ftl index 06f0e9df0..87d1bf81d 100644 --- a/locales/lo-LA/opencadstudio.ftl +++ b/locales/lo-LA/opencadstudio.ftl @@ -872,9 +872,12 @@ common = .sent-to-printer-printer = ສົ່ງໄປເຄື່ອງພິມແລ້ວ: __ocs_fmt_0__ .set-current = ຕັ້ງເປັນປັດຈຸບັນ .shade-plot = ການພລັອດແບບແຮເງົາ + .shaded-with-edges = ມີເງົາພ້ອມຂອບ + .shades-of-gray = ໂທນສີເທົາ .shadow-flags = ແຟລກເງົາ .single = ດ່ຽວ .size = ຂະໜາດ + .sketchy = ແບບຮ່າງ .snap-override-label-next-pick-only = ປ່ຽນຄ່າສະແນັບຊົ່ວຄາວ: __ocs_fmt_0__ (ສຳລັບການເລືອກຄັ້ງຕໍ່ໄປເທົ່ານັ້ນ). .solid-created = ສ້າງຮູບຊົງຕັນແລ້ວ. .source-object-not-found = ບໍ່ພົບວັດຖຸຕົ້ນສະບັບ. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 4e5428981..380a2bd5c 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -865,9 +865,12 @@ common = .sent-to-printer-printer = Verzonden aan printer: __ocs_fmt_0__ .set-current = Actief maken .shade-plot = Schaduwplot + .shaded-with-edges = Gearceerd met randen + .shades-of-gray = Grijstinten .shadow-flags = Schaduwvlaggen .single = Enkel .size = Grootte + .sketchy = Schetsmatig .snap-override-label-next-pick-only = Objectmagneet negeren: __ocs_fmt_0__ (alleen volgende selectie). .solid-created = Vast gemaakt. .source-object-not-found = Bronobject niet gevonden. @@ -6331,8 +6334,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 7902fd682..e88fb5405 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = Wysłano do drukarki: __ocs_fmt_0__ .set-current = Ustaw prąd .shade-plot = Fabuła cienia + .shaded-with-edges = Cieniowany z krawędziami + .shades-of-gray = Odcienie szarości .shadow-flags = Flagi cienia .single = Pojedynczy .size = Rozmiar + .sketchy = Szkicowy .snap-override-label-next-pick-only = Nadpisanie przyciągania: __ocs_fmt_0__ (tylko następny wybór). .solid-created = Utworzono bryłę. .source-object-not-found = Nie znaleziono obiektu źródłowego. @@ -6332,8 +6335,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index bda3098fb..78269403a 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -867,9 +867,12 @@ common = .sent-to-printer-printer = Enviado à impressora: __ocs_fmt_0__ .set-current = Definir como atual .shade-plot = Plotagem sombreada + .shaded-with-edges = Sombreado com arestas + .shades-of-gray = Tons de cinza .shadow-flags = Indicadores de sombra .single = Único .size = Tamanho + .sketchy = Esboço .snap-override-label-next-pick-only = Substituição de snap: __ocs_fmt_0__ (somente a próxima escolha). .solid-created = Sólido criado. .source-object-not-found = Objeto de origem não encontrado. @@ -6333,8 +6336,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 5c060d07e..4833d808d 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -870,9 +870,12 @@ common = .sent-to-printer-printer = Отправлено на принтер: __ocs_fmt_0__ .set-current = Сделать текущим .shade-plot = Скриншоты игры Shade + .shaded-with-edges = Тонированный с кромками + .shades-of-gray = Оттенки серого .shadow-flags = Флаги теней .single = Одинарный .size = Размер + .sketchy = Эскизный .snap-override-label-next-pick-only = Переопределение по щелчку: __ocs_fmt_0__ (только следующий выбор). .solid-created = Твердое создание. .source-object-not-found = Источник объекта не найден. @@ -6334,8 +6337,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index f8fff2e47..f34ace8a2 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -855,9 +855,12 @@ common = .sent-to-printer-printer = Yazıcıya gönderildi: __ocs_fmt_0__ .set-current = Geçerli Yap .shade-plot = Gölgelendirilmiş yazdırma + .shaded-with-edges = Kenarlarla gölgeli + .shades-of-gray = Gri tonları .shadow-flags = Gölge bayrakları .single = Tek .size = Boyut + .sketchy = Eskiz .snap-override-label-next-pick-only = Yakalama geçersiz kılma: __ocs_fmt_0__ (yalnızca sonraki seçim). .solid-created = Katı oluşturuldu. .source-object-not-found = Kaynak nesne bulunamadı. @@ -6254,8 +6257,11 @@ view-background = .stretch = Uzat .tile = Döşe .scale = Ölçek - .fit = Ekrana sığdır - .aspect = Oranı koru + .aspect = En-boy oranını koru + .adjust = Ayarla + .reset = Sıfırla + .offset = Öteleme + .pixels = px .no-image = görüntü seçilmedi .canvas = çizim alanı rengi .info = Bilgi diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 93eba93e8..885baf7a7 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -854,9 +854,12 @@ common = .sent-to-printer-printer = 发送到打印机 : __ocs_fmt_0__ .set-current = 置为当前 .shade-plot = 着色打印 + .shaded-with-edges = 带边缘着色 + .shades-of-gray = 灰度 .shadow-flags = 阴影标志 .single = 单一 .size = 大小 + .sketchy = 勾画 .snap-override-label-next-pick-only = 抓取覆盖 : __ocs_fmt_0__ (仅选择下一步) 。 .solid-created = 实相所造. .source-object-not-found = 找不到源对象 。 @@ -6316,8 +6319,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index f52b4f1f1..c223b6202 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -866,9 +866,12 @@ common = .sent-to-printer-printer = 發送到印表機 : __ocs_fmt_0__ .set-current = 置為目前 .shade-plot = 著色列印 + .shaded-with-edges = 帶邊緣著色 + .shades-of-gray = 灰階 .shadow-flags = 陰影標誌 .single = 單一 .size = 大小 + .sketchy = 草圖 .snap-override-label-next-pick-only = 抓取覆蓋 : __ocs_fmt_0__ (僅選擇下一步) 。 .solid-created = 實相所造. .source-object-not-found = 找不到源物件 。 @@ -6328,8 +6331,11 @@ view-background = .stretch = Stretch .tile = Tile .scale = Scale - .fit = Fit to screen .aspect = Keep aspect ratio + .adjust = Adjust + .reset = Reset + .offset = Offset + .pixels = px .no-image = No image selected .canvas = Drawing area color .info = Info diff --git a/src/app/commands/pdf_dialogs.rs b/src/app/commands/pdf_dialogs.rs index b7a5b1887..1449afbea 100644 --- a/src/app/commands/pdf_dialogs.rs +++ b/src/app/commands/pdf_dialogs.rs @@ -584,6 +584,8 @@ impl OpenCADStudio { | PdfDialogMsg::BgAspect(_) | PdfDialogMsg::BgOffset(_) | PdfDialogMsg::BgScale(_) + | PdfDialogMsg::BgStep(..) + | PdfDialogMsg::BgReset | PdfDialogMsg::BgApply) => return self.update_view_background(message), message @ (PdfDialogMsg::SecPerimeter(_) | PdfDialogMsg::SecMaxPoints(_) diff --git a/src/app/commands/view_presets.rs b/src/app/commands/view_presets.rs index 7622f0f17..879198625 100644 --- a/src/app/commands/view_presets.rs +++ b/src/app/commands/view_presets.rs @@ -450,8 +450,14 @@ impl OpenCADStudio { image: String::new(), position: BgPosition::Center, aspect: false, - offset: [0.0, 0.0], - scale: [1.0, 1.0], + offset: ["0".into(), "0".into()], + scale: ["1".into(), "1".into()], + scale_base: [1.0, 1.0], + image_size: None, + viewport: { + let (width, height) = self.tabs[i].scene.selection.borrow().view.vp_size; + [width as f32, height as f32] + }, canvas: [0, 1, 2].map(|k| (canvas[k].clamp(0.0, 1.0) * 255.0).round() as u8), }; let document = &self.tabs[i].scene.document; @@ -478,8 +484,10 @@ impl OpenCADStudio { BgPosition::Center }; state.aspect = value.maintain_aspect_ratio; - state.offset = [value.offset.x, value.offset.y]; - state.scale = [value.scale.x, value.scale.y]; + state.offset = [value.offset.x, value.offset.y].map(crate::ui::window::pdf_dialogs::short); + state.scale = [value.scale.x, value.scale.y].map(crate::ui::window::pdf_dialogs::short); + state.scale_base = [value.scale.x, value.scale.y]; + state.image_size = image::image_dimensions(&value.filename).ok().map(|(w, h)| [w, h]); } _ => {} } @@ -504,11 +512,42 @@ impl OpenCADStudio { M::BgKind(kind) => state.kind = kind, M::BgThree(on) => state.three = on, M::BgRotation(value) => state.rotation = value, - M::BgImage(value) => state.image = value, + M::BgImage(value) => { + state.image_size = image::image_dimensions(value.trim()).ok().map(|(w, h)| [w, h]); + state.image = value; + } M::BgPosition(value) => state.position = value, M::BgAspect(on) => state.aspect = on, M::BgOffset(value) => state.offset = value, - M::BgScale(value) => state.scale = value, + M::BgScale(value) => { + // Keeping the aspect ratio, both scales follow the one changed. + state.scale = if state.aspect { + let changed = if value[0] != state.scale[0] { 0 } else { 1 }; + [value[changed].clone(), value[changed].clone()] + } else { + value + }; + } + M::BgStep(field, dir) => { + use crate::ui::window::pdf_dialogs::{bg_step, short}; + let current = |text: &String, default: f64| text.trim().parse::().ok().filter(|v| v.is_finite()).unwrap_or(default); + if field < 2 { + let k = field as usize; + state.offset[k] = short(bg_step(field, current(&state.offset[k], 0.0), dir)); + } else { + let k = field as usize - 2; + let next = short(bg_step(field, current(&state.scale[k], state.scale_base[k]), dir)); + if state.aspect { + state.scale = [next.clone(), next]; + } else { + state.scale[k] = next; + } + } + } + M::BgReset => { + state.offset = ["0".into(), "0".into()]; + state.scale = ["1".into(), "1".into()]; + } M::BgColor(slot, rgb) => match slot { 0 => state.solid = rgb, 1 => state.top = rgb, @@ -587,14 +626,36 @@ impl OpenCADStudio { self.command_line.push_error("Invalid Background Image File!"); return Task::none(); } + use crate::ui::window::pdf_dialogs::{BG_OFFSET_LIMIT, BG_SCALE_LIMIT}; + let number = |text: &String| text.trim().parse::().ok().filter(|v| v.is_finite()); + let (Some(ox), Some(oy), Some(sx), Some(sy)) = ( + number(&state.offset[0]), + number(&state.offset[1]), + number(&state.scale[0]), + number(&state.scale[1]), + ) else { + self.command_line.push_error(crate::t!("Requires a number.").as_ref()); + return Task::none(); + }; + // Within the reference's slider ranges; a zero scale + // is ignored there, so the image keeps its scale. + let scale = |value: f64, base: f64| { + if value.abs() < 1e-9 { base } else { value.clamp(-BG_SCALE_LIMIT, BG_SCALE_LIMIT) } + }; Some(D::ImageBackground(ImageBackground { class_version: 1, filename: state.image.trim().to_string(), fit_to_screen: state.position == BgPosition::Stretch, maintain_aspect_ratio: state.aspect, use_tiling: state.position == BgPosition::Tile, - offset: codec::types::Vector2::new(state.offset[0], state.offset[1]), - scale: codec::types::Vector2::new(state.scale[0], state.scale[1]), + offset: codec::types::Vector2::new( + ox.clamp(-BG_OFFSET_LIMIT, BG_OFFSET_LIMIT), + oy.clamp(-BG_OFFSET_LIMIT, BG_OFFSET_LIMIT), + ), + scale: codec::types::Vector2::new( + scale(sx, state.scale_base[0]), + scale(sy, state.scale_base[1]), + ), })) } }; diff --git a/src/app/control/actions.rs b/src/app/control/actions.rs index bc9ad7ed4..710f68159 100644 --- a/src/app/control/actions.rs +++ b/src/app/control/actions.rs @@ -1798,7 +1798,8 @@ impl OpenCADStudio { "ribbon_dropdown" => Message::ToggleRibbonDropdown(string(req, "value")?.into()), // The -VIEW Background dialog, one field per call: "type=gradient", // "color|top|middle|bottom=r,g,b", "three=1", "rotation=30", - // "image=", "position=center|stretch|tile", "aspect=1", "offset=x,y" (pixels), "scale=x,y" (non-zero), + // "image=", "position=center|stretch|tile", "aspect=1", "offset=x,y" (pixels), "scale=x,y", + // "step=offset_x|offset_y|scale_x|scale_y,+1|-1", "reset", // "apply" or "cancel". "view_background" => { use crate::ui::window::pdf_dialogs::{BgKind, BgPosition, PdfDialogMsg as P}; @@ -1841,20 +1842,31 @@ impl OpenCADStudio { })), "aspect" => Message::PdfDialog(P::BgAspect(value == "1")), "offset" | "scale" => { - let pair: Vec = value - .split(',') - .map(|part| part.trim().parse::()) - .collect::>() - .map_err(|_| bad())?; - let pair = <[f64; 2]>::try_from(pair).map_err(|_| bad())?; - if key == "offset" { - Message::PdfDialog(P::BgOffset(pair)) - } else if pair.iter().all(|v| v.is_finite() && *v != 0.0) { - Message::PdfDialog(P::BgScale(pair)) - } else { + let pair: Vec = value.split(',').map(|part| part.trim().to_string()).collect(); + let pair = <[String; 2]>::try_from(pair).map_err(|_| bad())?; + if pair.iter().any(|v| v.parse::().map_or(true, |v| !v.is_finite())) { return Err(bad()); } + if key == "offset" { + Message::PdfDialog(P::BgOffset(pair)) + } else { + Message::PdfDialog(P::BgScale(pair)) + } } + "step" => { + // step=offset_x|offset_y|scale_x|scale_y,+1|-1 + let (field, dir) = value.split_once(',').ok_or_else(bad)?; + let field = match field { + "offset_x" => 0, + "offset_y" => 1, + "scale_x" => 2, + "scale_y" => 3, + _ => return Err(bad()), + }; + let dir: i8 = dir.trim().parse().map_err(|_| bad())?; + Message::PdfDialog(P::BgStep(field, dir)) + } + "reset" => Message::PdfDialog(P::BgReset), _ => return Err(bad()), } } diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index f5a89f09d..56578d971 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -2994,6 +2994,8 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "Shade plot" => Some(("common", "shade-plot")), "Shaded" => Some(("view", "shaded")), "Shaded viewport options" => Some(("plot", "shaded-viewport-options")), + "Shaded with edges" => Some(("common", "shaded-with-edges")), + "Shades of Gray" => Some(("common", "shades-of-gray")), "Shadow flags" => Some(("common", "shadow-flags")), "Shadows" => Some(("properties", "shadows")), "Shape" => Some(("properties", "shape")), @@ -3020,6 +3022,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "SingleLine" => Some(("properties", "singleline")), "Size" => Some(("common", "size")), "Sketch" => Some(("draw", "sketch")), + "Sketchy" => Some(("common", "sketchy")), "Snap override: {label} (next pick only)." => Some(("common", "snap-override-label-next-pick-only")), "Snap to\nUnderlays" => Some(("insert", "snap-to-underlays")), "Softness" => Some(("properties", "softness")), diff --git a/src/ui/window/pdf_dialogs.rs b/src/ui/window/pdf_dialogs.rs index c27edfc5d..72869aad3 100644 --- a/src/ui/window/pdf_dialogs.rs +++ b/src/ui/window/pdf_dialogs.rs @@ -122,9 +122,13 @@ pub enum PdfDialogMsg { BgBrowse, BgPosition(BgPosition), BgAspect(bool), - /// An image background's offset (pixels) and scale. - BgOffset([f64; 2]), - BgScale([f64; 2]), + /// An image background's offset (pixels, x and y) and scale, as typed. + BgOffset([String; 2]), + BgScale([String; 2]), + /// A spinner step on offset x / y (0, 1) or scale x / y (2, 3). + BgStep(u8, i8), + /// Offset 0, scale 1. + BgReset, BgApply, } @@ -2181,19 +2185,23 @@ impl fmt::Display for BgPosition { } } -/// How an image background is scaled: to the screen, or keeping its -/// aspect ratio. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BgAspect(pub bool); +/// Image offsets the reference's Adjust Image sliders reach, in pixels. +pub const BG_OFFSET_LIMIT: f64 = 2000.0; +/// Image scales the reference's sliders reach (slider value / 10). +pub const BG_SCALE_LIMIT: f64 = 10.0; -impl fmt::Display for BgAspect { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&if self.0 { - crate::tr!("view-background", "aspect") - } else { - crate::tr!("view-background", "fit") - }) +/// One spinner step on an image background field: a pixel for an offset, a +/// tenth for a scale, which skips 0 (the reference ignores a zero scale). +pub fn bg_step(field: u8, value: f64, dir: i8) -> f64 { + let dir = f64::from(dir.signum()); + if field < 2 { + return (value.round() + dir).clamp(-BG_OFFSET_LIMIT, BG_OFFSET_LIMIT); } + let mut next = ((value * 10.0).round() + dir) / 10.0; + if next.abs() < 0.05 { + next += dir / 10.0; + } + next.clamp(-BG_SCALE_LIMIT, BG_SCALE_LIMIT) } /// The Background dialog's fields for one named view. @@ -2209,9 +2217,15 @@ pub struct ViewBackgroundState { pub image: String, pub position: BgPosition, pub aspect: bool, - /// The image's offset (pixels) and scale, kept from the view's image. - pub offset: [f64; 2], - pub scale: [f64; 2], + /// The image's offset (pixels) and scale as typed, and the scale the + /// view's image had (kept for a zero scale). + pub offset: [String; 2], + pub scale: [String; 2], + pub scale_base: [f64; 2], + /// The chosen image's size in pixels, for the preview. + pub image_size: Option<[u32; 2]>, + /// The drawing viewport's size, which the preview stands for. + pub viewport: [f32; 2], /// The drawing area colour, shown for no background. pub canvas: [u8; 3], } @@ -2271,20 +2285,68 @@ pub fn view_background<'a>( } BgKind::Image => { if std::path::Path::new(state.image.trim()).is_file() { - let fit = match (state.position, state.aspect) { - (BgPosition::Stretch, false) => iced::ContentFit::Fill, - (BgPosition::Stretch, true) => iced::ContentFit::Contain, - _ => iced::ContentFit::None, - }; - container( - image(image::Handle::from_path(state.image.trim())) - .content_fit(fit) - .width(Fill) - .height(Fill), - ) - .center(Fill) - .style(fill(Background::Color(rgb(state.canvas)))) - .into() + let handle = image::Handle::from_path(state.image.trim()); + let canvas = Background::Color(rgb(state.canvas)); + if state.position == BgPosition::Stretch { + // Filling the view; keeping the aspect ratio it covers + // the view and the overflow is cut off. + let fit = if state.aspect { iced::ContentFit::Cover } else { iced::ContentFit::Fill }; + container(image(handle).content_fit(fit).width(Fill).height(Fill)) + .center(Fill) + .clip(true) + .style(fill(canvas)) + .into() + } else { + // The image at its size times its scale, moved by its + // offset, in a view of the drawing viewport's shape. + let parse = |v: &String, d: f64| v.trim().parse::().ok().filter(|v| v.is_finite()).unwrap_or(d); + let offset = [parse(&state.offset[0], 0.0), parse(&state.offset[1], 0.0)]; + let scale = [0, 1].map(|k| { + let v = parse(&state.scale[k], state.scale_base[k]); + if v.abs() < 1e-9 { state.scale_base[k] } else { v } + }); + let [iw, ih] = state.image_size.unwrap_or([1, 1]); + let viewport = state.viewport; + let tile = state.position == BgPosition::Tile; + container(iced::widget::responsive(move |size| { + let factor = size.height / viewport[1].max(1.0); + let w = (iw as f32 * scale[0].abs() as f32 * factor).max(1.0); + let h = (ih as f32 * scale[1].abs() as f32 * factor).max(1.0); + let x = size.width / 2.0 + offset[0] as f32 * factor - w / 2.0; + let y = size.height / 2.0 + offset[1] as f32 * factor - h / 2.0; + let (cols, rows) = if tile { + ((size.width / w).ceil() as i32 + 1, (size.height / h).ceil() as i32 + 1) + } else { + (0, 0) + }; + let mut layers = iced::widget::Stack::new() + .width(Fill) + .height(Fill) + .push(container(Space::new()).width(Fill).height(Fill)); + let x0 = if tile { x - (x / w).ceil() * w } else { x }; + let y0 = if tile { y - (y / h).ceil() * h } else { y }; + for row_index in 0..=rows.min(60) { + for col_index in 0..=cols.min(60) { + let at = iced::Point::new(x0 + col_index as f32 * w, y0 + row_index as f32 * h); + layers = layers.push( + iced::widget::pin( + image(handle.clone()) + .content_fit(iced::ContentFit::Fill) + .width(Length::Fixed(w)) + .height(Length::Fixed(h)), + ) + .position(at), + ); + } + } + Element::::from(layers) + })) + .width(Fill) + .height(Fill) + .clip(true) + .style(fill(canvas)) + .into() + } } else { container(note(crate::tr!("view-background", "no-image"))) .center(Fill) @@ -2397,28 +2459,22 @@ pub fn view_background<'a>( ] .spacing(8) .align_y(iced::Center), - row![ - label(crate::tr!("view-background", "scale"), true), - pick_list( - Some(BgAspect(state.aspect)), - vec![BgAspect(false), BgAspect(true)], - |a: &BgAspect| a.to_string() - ) - .on_select(|a: BgAspect| msg(PdfDialogMsg::BgAspect(a.0))) - .text_size(12) - .padding([4, 8]) - .width(Fill), - ] - .spacing(8) - .align_y(iced::Center), + chip( + crate::tr!("view-background", "aspect"), + state.aspect, + msg(PdfDialogMsg::BgAspect(!state.aspect)) + ), ] .spacing(8), ), }; + let adjust = (state.kind == BgKind::Image).then(|| adjust_card(state)); + let mut body = column![kind, preview, options].spacing(10); + if let Some(adjust) = adjust { + body = body.push(adjust); + } column![ - kind, - preview, - options, + body, footer( "background", None, @@ -2431,3 +2487,85 @@ pub fn view_background<'a>( .width(sizing.width) .into() } + +/// The image's offset and scale (the reference's Adjust Image): pixel offsets +/// and scales with spinners and a reset; inactive while the image is +/// stretched over the view, where the reference ignores them. +fn adjust_card<'a>(state: &'a ViewBackgroundState) -> Element<'a, Message> { + let enabled = state.position != BgPosition::Stretch; + let dim = move |theme: &Theme| { + if enabled { + muted_style(theme) + } else { + text::Style { color: Some(theme.palette().background.strong.color) } + } + }; + let spin = |field: u8| -> Element<'a, Message> { + let value = if field < 2 { &state.offset[field as usize] } else { &state.scale[field as usize - 2] }; + let mut input = text_input("", value).size(11).padding([4, 8]).width(Length::Fixed(64.0)).style(field_style); + if enabled { + input = input.on_input(move |v| { + if field < 2 { + let mut pair = state.offset.clone(); + pair[field as usize] = v; + msg(PdfDialogMsg::BgOffset(pair)) + } else { + let mut pair = state.scale.clone(); + pair[field as usize - 2] = v; + msg(PdfDialogMsg::BgScale(pair)) + } + }); + } + let arrow = |up: bool| { + let mut b = button(crate::ui::icons::themed_arrow_toggle(up, 7.0)) + .style(button_style(false)) + .padding([1, 4]); + if enabled { + b = b.on_press(msg(PdfDialogMsg::BgStep(field, if up { 1 } else { -1 }))); + } + b + }; + row![input, column![arrow(true), arrow(false)].spacing(1)].spacing(2).align_y(iced::Center).into() + }; + let axis = |name: &'static str| text(name).size(11).style(dim); + let line = |label: String, a: u8, b: u8, unit: bool| -> Element<'a, Message> { + let mut r = row![ + text(label).size(11).style(dim).width(Length::Fixed(72.0)), + axis("X"), + spin(a), + axis("Y"), + spin(b), + ] + .spacing(6) + .align_y(iced::Center); + if unit { + r = r.push(text(crate::tr!("view-background", "pixels")).size(11).style(dim)); + } + r.into() + }; + let mut reset = button(text(crate::tr!("view-background", "reset")).size(11)) + .style(button_style(false)) + .padding([3, 10]); + if enabled { + reset = reset.on_press(msg(PdfDialogMsg::BgReset)); + } + container( + column![ + row![ + text(crate::tr!("view-background", "adjust").to_uppercase()).size(10).style(move |theme: &Theme| { + if enabled { accent_text(theme) } else { dim(theme) } + }), + Space::new().width(Fill), + reset, + ] + .align_y(iced::Center), + line(crate::tr!("view-background", "offset"), 0, 1, true), + line(crate::tr!("view-background", "scale"), 2, 3, false), + ] + .spacing(8), + ) + .padding([10, 12]) + .width(Fill) + .style(card_style) + .into() +}