Select Color: review cleanups

- Split ColorEditor::view into mode_row, slider_rows, field_view,
  hex_row and hex_field; output is unchanged.
- hex_string reuses config::rgb_to_hex, and parse_hex documents why it
  stays separate (it also accepts #RGB).
- ink_is_dark uses Color::into_rgba8 instead of rounding by hand.
- Remove four translation keys the old dialog used and nothing
  references any more, from the catalog and all 22 locales.
- Eyedropper: without a main window there is no screenshot to wait for,
  so leave the eyedropper; keep the magnifier inside small windows.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
This commit is contained in:
Claude committed 2026-10-12 19:21:38 +00:00
1 parent cc40722f70
commit fefd526c98
28 files changed
+147 -221

No files matched your search

-4
View File
@@ -1334,8 +1334,6 @@ common =
.dismiss = إغلاق
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = لا توجد ألوان حديثة بعد
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1343,9 +1341,7 @@ common =
.nearest-index-color = أقرب فهرس
.exact-index-match = تطابق تام مع الفهرس
.cad-color-index-aci-10-249 = فهرس ألوان ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = المستخدمة مؤخرًا
.isometric-drafting = الرسم متساوي القياس
.f5-cycles-the-active-plane = يبدّل F5 المستوى النشط بالتتابع.
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Затваряне
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Все още няма скорошни цветове
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Най-близък индекс
.exact-index-match = Точно съвпадение с индекс
.cad-color-index-aci-10-249 = ACI Цветови индекс 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Последно използвани
.isometric-drafting = Изометрично чертане
.f5-cycles-the-active-plane = F5 превключва последователно активната равнина.
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Zavřít
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Zatím žádné nedávné barvy
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Nejbližší index
.exact-index-match = Přesná shoda s indexem
.cad-color-index-aci-10-249 = Barevný index ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Nedávno použité
.isometric-drafting = Izometrické kreslení
.f5-cycles-the-active-plane = F5 cyklicky přepíná aktivní rovinu.
.units-5430a1 = { common.units }…
-4
View File
@@ -1322,8 +1322,6 @@ common =
.dismiss = Schließen
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Noch keine zuletzt verwendeten Farben
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1331,9 +1329,7 @@ common =
.nearest-index-color = Nächster Index
.exact-index-match = Exakter Index-Treffer
.cad-color-index-aci-10-249 = ACI Farbindex 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Zuletzt verwendet
.isometric-drafting = Isometrisches Zeichnen
.f5-cycles-the-active-plane = F5 wechselt die aktive Ebene der Reihe nach.
.units-5430a1 = { common.units }…
-4
View File
@@ -1323,8 +1323,6 @@ common =
.dismiss = Κλείσιμο
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Δεν υπάρχουν ακόμη πρόσφατα χρώματα
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1332,9 +1330,7 @@ common =
.nearest-index-color = Πλησιέστερος δείκτης
.exact-index-match = Ακριβής αντιστοίχιση δείκτη
.cad-color-index-aci-10-249 = Δείκτης χρώματος ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Πρόσφατα χρησιμοποιημένα
.isometric-drafting = Ισομετρική σχεδίαση
.f5-cycles-the-active-plane = Το F5 εναλλάσσει το ενεργό επίπεδο.
.units-5430a1 = { common.units }…
-4
View File
@@ -1323,8 +1323,6 @@ common =
.dismiss = Dismiss
.value-8a8de8 = ?
.select-color-8dddf1 = Select Color...
.no-recent-colors-yet = No recent colors yet
.true-color-rgb = True Color RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = Index Color
.true-color = True Color
.standard-colors = Standard colors
@@ -1332,9 +1330,7 @@ common =
.nearest-index-color = Nearest index
.exact-index-match = Exact index match
.cad-color-index-aci-10-249 = CAD Color Index (ACI) 10–249
.color-family-shade-intensity = Color family → · Shade / intensity ↓
.grayscale-250-255 = Grayscale 250–255
.recently-used = Recently used
.isometric-drafting = Isometric drafting
.f5-cycles-the-active-plane = F5 cycles the active plane.
.units-5430a1 = Units…
-4
View File
@@ -1322,8 +1322,6 @@ common =
.dismiss = Cerrar
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Aún no hay colores recientes
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1331,9 +1329,7 @@ common =
.nearest-index-color = Índice más cercano
.exact-index-match = Coincide con un índice
.cad-color-index-aci-10-249 = Índice de color ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Usados recientemente
.isometric-drafting = Dibujo isométrico
.f5-cycles-the-active-plane = F5 alterna el plano activo.
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Sulje
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Ei vielä viimeksi käytettyjä värejä
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Lähin indeksi
.exact-index-match = Täsmälleen indeksiväri
.cad-color-index-aci-10-249 = ACI väriindeksi 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Viimeksi käytetyt
.isometric-drafting = Isometrinen piirtäminen
.f5-cycles-the-active-plane = F5 vaihtaa aktiivista tasoa.
.units-5430a1 = { common.units }…
-4
View File
@@ -1322,8 +1322,6 @@ common =
.dismiss = Fermer
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Aucune couleur récente
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1331,9 +1329,7 @@ common =
.nearest-index-color = Index le plus proche
.exact-index-match = Correspondance exacte d'index
.cad-color-index-aci-10-249 = ACI Indice de couleur 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Utilisés récemment
.isometric-drafting = Dessin isométrique
.f5-cycles-the-active-plane = F5 fait défiler les plans actifs.
.units-5430a1 = { common.units }…
-4
View File
@@ -1310,8 +1310,6 @@ common =
.dismiss = बंद करें
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = अभी कोई हालिया रंग नहीं है
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1319,9 +1317,7 @@ common =
.nearest-index-color = निकटतम इंडेक्स
.exact-index-match = इंडेक्स से सटीक मेल
.cad-color-index-aci-10-249 = ACI रंग सूचकांक 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = हाल में उपयोग किए गए
.isometric-drafting = सममितीय आरेखन
.f5-cycles-the-active-plane = F5 सक्रिय तल को क्रम से बदलता है।
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Bezárás
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Még nincsenek legutóbbi színek
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Legközelebbi index
.exact-index-match = Pontos indexegyezés
.cad-color-index-aci-10-249 = ACI színindex 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Legutóbb használt
.isometric-drafting = Izometrikus rajzolás
.f5-cycles-the-active-plane = Az F5 váltja az aktív síkot.
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Chiudi
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Nessun colore recente
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Indice più vicino
.exact-index-match = Corrispondenza esatta indice
.cad-color-index-aci-10-249 = ACI Indice colori 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Usati di recente
.isometric-drafting = Disegno isometrico
.f5-cycles-the-active-plane = F5 alterna il piano attivo.
.units-5430a1 = { common.units }…
-4
View File
@@ -1312,8 +1312,6 @@ common =
.dismiss = 閉じる
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = 最近使った色はありません
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1321,9 +1319,7 @@ common =
.nearest-index-color = 最も近いインデックス
.exact-index-match = インデックスと完全一致
.cad-color-index-aci-10-249 = ACI カラーインデックス 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = 最近使用した色
.isometric-drafting = アイソメ図作成
.f5-cycles-the-active-plane = F5でアクティブな平面を順に切り替えます。
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = 닫기
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = 최근 사용한 색상이 없습니다
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = 가장 가까운 인덱스
.exact-index-match = 인덱스와 정확히 일치
.cad-color-index-aci-10-249 = ACI 컬러 인덱스 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = 최근 사용
.isometric-drafting = 등각 제도
.f5-cycles-the-active-plane = F5 키로 활성 평면을 순환 전환합니다.
.units-5430a1 = { common.units }…
-4
View File
@@ -1323,8 +1323,6 @@ common =
.dismiss = ປິດອອກ
.value-8a8de8 = ?
.select-color-8dddf1 = ເລືອກສີ...
.no-recent-colors-yet = ຍັງບໍ່ມີສີຫຼ້າສຸດ
.true-color-rgb = True Color RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = ສີດັດຊະນີ
.true-color = True Color
.standard-colors = ສີມາດຕະຖານ
@@ -1332,9 +1330,7 @@ common =
.nearest-index-color = ດັດຊະນີທີ່ໃກ້ທີ່ສຸດ
.exact-index-match = ກົງກັບດັດຊະນີພໍດີ
.cad-color-index-aci-10-249 = CAD Color Index (ACI) 10–249
.color-family-shade-intensity = ກຸ່ມສີ → · ລະດັບສີ / ຄວາມເຂັ້ມ ↓
.grayscale-250-255 = ລະດັບສີເທົາ 250–255
.recently-used = ໃຊ້ຫຼ້າສຸດ
.isometric-drafting = ການຂຽນແບບໄອໂຊເມຕຣິກ
.f5-cycles-the-active-plane = F5 ປ່ຽນລະນາບທີ່ໃຊ້ງານວຽນໄປ.
.units-5430a1 = ຫົວໜ່ວຍ…
-4
View File
@@ -1320,8 +1320,6 @@ common =
.dismiss = Sluiten
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Nog geen recente kleuren
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1329,9 +1327,7 @@ common =
.nearest-index-color = Dichtstbijzijnde index
.exact-index-match = Exacte indexkleur
.cad-color-index-aci-10-249 = ACI Kleurindex 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Recent gebruikt
.isometric-drafting = Isometrisch tekenen
.f5-cycles-the-active-plane = F5 wisselt het actieve vlak.
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = Zamknij
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Brak ostatnio używanych kolorów
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = Najbliższy indeks
.exact-index-match = Dokładne dopasowanie indeksu
.cad-color-index-aci-10-249 = Indeks kolorów ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Ostatnio używane
.isometric-drafting = Rysowanie izometryczne
.f5-cycles-the-active-plane = F5 przełącza aktywną płaszczyznę.
.units-5430a1 = { common.units }…
-4
View File
@@ -1322,8 +1322,6 @@ common =
.dismiss = Fechar
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Nenhuma cor recente ainda
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1331,9 +1329,7 @@ common =
.nearest-index-color = Índice mais próximo
.exact-index-match = Corresponde exatamente ao índice
.cad-color-index-aci-10-249 = Índice de cor ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Usados recentemente
.isometric-drafting = Desenho isométrico
.f5-cycles-the-active-plane = F5 alterna o plano ativo.
.units-5430a1 = { common.units }…
-4
View File
@@ -1325,8 +1325,6 @@ common =
.dismiss = Закрыть
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Недавно использованных цветов пока нет
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1334,9 +1332,7 @@ common =
.nearest-index-color = Ближайший индекс
.exact-index-match = Точное совпадение с индексом
.cad-color-index-aci-10-249 = Индекс цвета ACI 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Недавно использованные
.isometric-drafting = Изометрическое черчение
.f5-cycles-the-active-plane = F5 циклически переключает активную плоскость.
.units-5430a1 = { common.units }…
-4
View File
@@ -1308,8 +1308,6 @@ common =
.dismiss = Kapat
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = Henüz son kullanılan renk yok
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1317,9 +1315,7 @@ common =
.nearest-index-color = En yakın indeks
.exact-index-match = Tam indeks eşleşmesi
.cad-color-index-aci-10-249 = ACI renk dizini 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = Son kullanılanlar
.isometric-drafting = İzometrik çizim
.f5-cycles-the-active-plane = F5 etkin düzlemi sırayla değiştirir.
.units-5430a1 = { common.units }…
-4
View File
@@ -1309,8 +1309,6 @@ common =
.dismiss = 关闭
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = 尚无最近使用的颜色
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1318,9 +1316,7 @@ common =
.nearest-index-color = 最接近的索引色
.exact-index-match = 与索引色完全匹配
.cad-color-index-aci-10-249 = ACI 颜色索引 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = 最近使用
.isometric-drafting = 等轴测绘图
.f5-cycles-the-active-plane = F5 循环切换活动平面。
.units-5430a1 = { common.units }…
-4
View File
@@ -1321,8 +1321,6 @@ common =
.dismiss = 關閉
.value-8a8de8 = ?
.select-color-8dddf1 = { common.select-color }…
.no-recent-colors-yet = 尚無最近使用的顏色
.true-color-rgb = { common.true-color } RGB __ocs_fmt_0__, __ocs_fmt_1__, __ocs_fmt_2__
.index-color = { common.color } (ACI)
.true-color = { common.color } (RGB)
.standard-colors = { common.standard } · { common.color }
@@ -1330,9 +1328,7 @@ common =
.nearest-index-color = 最接近的索引色
.exact-index-match = 與索引色完全相符
.cad-color-index-aci-10-249 = ACI 顏色索引 10–249
.color-family-shade-intensity = { common.color-family } → · { common.shade } / { properties.intensity } ↓
.grayscale-250-255 = { common.grayscale } 250–255
.recently-used = 最近使用
.isometric-drafting = 等角製圖
.f5-cycles-the-active-plane = F5 循環切換作用中平面。
.units-5430a1 = { common.units }…
+7 -4
View File
@@ -11039,13 +11039,16 @@ impl OpenCADStudio {
}
Some(crate::ui::color_select::Outcome::Screenshot) => {
use crate::ui::color_select::{eyedropper::EyedropperMsg, ColorPickerMsg};
self.main_window.map_or_else(Task::none, |id| {
iced::window::screenshot(id).map(|shot| {
match self.main_window {
Some(id) => iced::window::screenshot(id).map(|shot| {
Message::ColorPicker(ColorPickerMsg::Eyedropper(
EyedropperMsg::Shot(shot),
))
})
})
}),
// Nothing to capture: leave the eyedropper instead
// of waiting for a screenshot that never comes.
None => self.update(Message::ColorPicker(ColorPickerMsg::Cancel)),
}
}
None => Task::none(),
}
-4
View File
@@ -4689,8 +4689,6 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"Dismiss" => Some(("common", "dismiss")),
"?" => Some(("common", "value-8a8de8")),
"Select Color..." => Some(("common", "select-color-8dddf1")),
"No recent colors yet" => Some(("common", "no-recent-colors-yet")),
"True Color RGB {r}, {g}, {b}" => Some(("common", "true-color-rgb")),
"Index Color" => Some(("common", "index-color")),
"True Color" => Some(("common", "true-color")),
"Standard colors" => Some(("common", "standard-colors")),
@@ -4698,9 +4696,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"Nearest index" => Some(("common", "nearest-index-color")),
"Exact index match" => Some(("common", "exact-index-match")),
"CAD Color Index (ACI) 10–249" => Some(("common", "cad-color-index-aci-10-249")),
"Color family → · Shade / intensity ↓" => Some(("common", "color-family-shade-intensity")),
"Grayscale 250–255" => Some(("common", "grayscale-250-255")),
"Recently used" => Some(("common", "recently-used")),
"Isometric drafting" => Some(("common", "isometric-drafting")),
"F5 cycles the active plane." => Some(("common", "f5-cycles-the-active-plane")),
"Units…" => Some(("common", "units-5430a1")),
+129 -118
View File
@@ -138,14 +138,25 @@ impl ColorEditor {
/// `mode_end` sits at the far right of the mode buttons (the pipette);
/// `hex_end` at the far right of the hex row (the nearest index colour).
/// The field view shows the hex value beside H, S and B and leaves out
/// `hex_end`; the slider views end on a hex row.
pub fn view<'a>(
&'a self,
mode_end: Option<Element<'a, Message>>,
hex_end: Option<Element<'a, Message>>,
) -> Element<'a, Message> {
let Hsb { h, s, b } = self.hsb;
let (r, g, bl) = self.rgb;
let view = column![self.mode_row(mode_end)].spacing(12);
match self.mode {
EditorMode::Hsb | EditorMode::Rgb => view
.push(self.slider_rows())
.push(self.hex_row(hex_end))
.into(),
EditorMode::Field => view.push(self.field_view()).into(),
}
}
/// HSB, RGB and the gradient-field button, with `end` at the far right.
fn mode_row<'a>(&self, end: Option<Element<'a, Message>>) -> Element<'a, Message> {
let mode_button = |content: Element<'a, Message>, mode: EditorMode| {
let active = self.mode == mode;
button(container(content).center(Length::Fill))
@@ -189,32 +200,50 @@ impl ColorEditor {
Space::new().width(Length::Fill),
]
.spacing(6);
if let Some(end) = mode_end {
if let Some(end) = end {
modes = modes.push(end);
}
modes.into()
}
let hex = self
.hex_draft
.clone()
.unwrap_or_else(|| math::hex_string(r, g, bl));
let hex_field = move || {
row![
text(t!("Hex")).size(11).style(super::picker::muted_text),
text_input("", &hex)
.on_input(|value| msg(EditorMsg::HexInput(value)))
.on_submit(msg(EditorMsg::HexSubmit))
.size(12)
.font(iced::Font::MONOSPACE)
.padding([5, 6])
.width(Length::Fixed(74.0)),
/// Three gradient sliders: hue, saturation and brightness, or red, green
/// and blue.
fn slider_rows<'a>(&self) -> Element<'a, Message> {
let Hsb { h, s, b } = self.hsb;
let (r, g, bl) = self.rgb;
let rows = if self.mode == EditorMode::Rgb {
let ends = |lo: (u8, u8, u8), hi: (u8, u8, u8)| {
vec![(0.0, rgb_color(lo)), (1.0, rgb_color(hi))]
};
let byte = |f: fn(u8) -> EditorMsg| move |v: f32| f(v.round() as u8);
column![
channel(
"R",
f32::from(r),
255.0,
None,
ends((0, g, bl), (255, g, bl)),
byte(EditorMsg::Red)
),
channel(
"G",
f32::from(g),
255.0,
None,
ends((r, 0, bl), (r, 255, bl)),
byte(EditorMsg::Green)
),
channel(
"B",
f32::from(bl),
255.0,
None,
ends((r, g, 0), (r, g, 255)),
byte(EditorMsg::Blue)
),
]
.spacing(8)
.align_y(iced::Center)
};
let field_mode = self.mode == EditorMode::Field;
let editor: Element<'a, Message> = match self.mode {
EditorMode::Hsb => column![
} else {
column![
channel("H", h, 360.0, Some('°'), hue_stops(), EditorMsg::Hue),
channel(
"S",
@@ -233,103 +262,85 @@ impl ColorEditor {
EditorMsg::Brightness,
),
]
.spacing(ROW_GAP)
.into(),
EditorMode::Rgb => {
let ends = |lo: (u8, u8, u8), hi: (u8, u8, u8)| {
vec![(0.0, rgb_color(lo)), (1.0, rgb_color(hi))]
};
let byte = |f: fn(u8) -> EditorMsg| move |v: f32| f(v.round() as u8);
column![
channel(
"R",
f32::from(r),
255.0,
None,
ends((0, g, bl), (255, g, bl)),
byte(EditorMsg::Red)
),
channel(
"G",
f32::from(g),
255.0,
None,
ends((r, 0, bl), (r, 255, bl)),
byte(EditorMsg::Green)
),
channel(
"B",
f32::from(bl),
255.0,
None,
ends((r, g, 0), (r, g, 255)),
byte(EditorMsg::Blue)
),
]
.spacing(ROW_GAP)
.into()
}
EditorMode::Field => {
let area =
ColorArea::new(hsb_color(h, 1.0, 1.0), rgb_color(self.rgb), s, b, |s, b| {
msg(EditorMsg::Field(s, b))
})
.height(Length::Fixed(FIELD_HEIGHT));
// A vertical slider grows upwards; the strip runs red at the top.
let strip = stack![
container(Space::new())
.width(STRIP_WIDTH)
.height(FIELD_HEIGHT)
.style(|_theme: &Theme| gradient_box(std::f32::consts::PI, &hue_stops())),
vertical_slider(0.0..=360.0, 360.0 - h, |v| msg(EditorMsg::Hue(360.0 - v)))
.width(STRIP_WIDTH)
.height(FIELD_HEIGHT)
.style(handle_style),
];
let value = |letter: &'static str,
v: f32,
max: f32,
unit: char,
f: fn(f32) -> EditorMsg| {
row![
text(letter).size(12).font(iced::Font::MONOSPACE),
number_box(v, max, Some(unit), f),
]
.spacing(4)
.align_y(iced::Center)
};
column![
row![area, strip].spacing(12),
// H, S and B on the left, the hex value on the right.
row![
value("H", h, 360.0, '°', EditorMsg::Hue),
value("S", s * 100.0, 100.0, '%', EditorMsg::Saturation),
value("B", b * 100.0, 100.0, '%', EditorMsg::Brightness),
Space::new().width(Length::Fill),
hex_field(),
]
.spacing(10)
.align_y(iced::Center),
]
// 108 + 10 matches the slider views' 3 × 26 + 2 × 14 + 12.
.spacing(10)
.into()
}
};
rows.spacing(ROW_GAP).into()
}
// The field view shows the hex value beside H, S and B and leaves out
// the nearest index colour; the slider views end on a hex row.
let mut view = column![modes, editor].spacing(12);
if !field_mode {
let mut hex_row = row![hex_field(), Space::new().width(Length::Fill)]
.spacing(8)
.align_y(iced::Center);
if let Some(end) = hex_end {
hex_row = hex_row.push(end);
}
view = view.push(hex_row);
/// The saturation/brightness field with its hue strip, and below it H, S
/// and B on the left and the hex value on the right.
fn field_view<'a>(&self) -> Element<'a, Message> {
let Hsb { h, s, b } = self.hsb;
let area = ColorArea::new(hsb_color(h, 1.0, 1.0), rgb_color(self.rgb), s, b, |s, b| {
msg(EditorMsg::Field(s, b))
})
.height(Length::Fixed(FIELD_HEIGHT));
// A vertical slider grows upwards; the strip runs red at the top.
let strip = stack![
container(Space::new())
.width(STRIP_WIDTH)
.height(FIELD_HEIGHT)
.style(|_theme: &Theme| gradient_box(std::f32::consts::PI, &hue_stops())),
vertical_slider(0.0..=360.0, 360.0 - h, |v| msg(EditorMsg::Hue(360.0 - v)))
.width(STRIP_WIDTH)
.height(FIELD_HEIGHT)
.style(handle_style),
];
let value =
|letter: &'static str, v: f32, max: f32, unit: char, f: fn(f32) -> EditorMsg| {
row![
text(letter).size(12).font(iced::Font::MONOSPACE),
number_box(v, max, Some(unit), f),
]
.spacing(4)
.align_y(iced::Center)
};
column![
row![area, strip].spacing(12),
row![
value("H", h, 360.0, '°', EditorMsg::Hue),
value("S", s * 100.0, 100.0, '%', EditorMsg::Saturation),
value("B", b * 100.0, 100.0, '%', EditorMsg::Brightness),
Space::new().width(Length::Fill),
self.hex_field(),
]
.spacing(10)
.align_y(iced::Center),
]
// 108 + 10 matches the slider views' 3 × 26 + 2 × 14 + 12.
.spacing(10)
.into()
}
/// The hex value with `end` (the nearest index colour) at the far right.
fn hex_row<'a>(&self, end: Option<Element<'a, Message>>) -> Element<'a, Message> {
let mut hex_row = row![self.hex_field(), Space::new().width(Length::Fill)]
.spacing(8)
.align_y(iced::Center);
if let Some(end) = end {
hex_row = hex_row.push(end);
}
view.into()
hex_row.into()
}
fn hex_field<'a>(&self) -> Element<'a, Message> {
let (r, g, b) = self.rgb;
let hex = self
.hex_draft
.clone()
.unwrap_or_else(|| math::hex_string(r, g, b));
row![
text(t!("Hex")).size(11).style(super::picker::muted_text),
text_input("", &hex)
.on_input(|value| msg(EditorMsg::HexInput(value)))
.on_submit(msg(EditorMsg::HexSubmit))
.size(12)
.font(iced::Font::MONOSPACE)
.padding([5, 6])
.width(Length::Fixed(74.0)),
]
.spacing(8)
.align_y(iced::Center)
.into()
}
}
+5 -2
View File
@@ -119,16 +119,19 @@ impl Eyedropper {
let size = GRID as f32 * CELL + 8.0;
let window_w = shot.size.width as f32 / shot.scale_factor;
let window_h = shot.size.height as f32 / shot.scale_factor;
// In a very small window neither side fits; stay inside the top-left.
let x = if cursor.x + OFFSET + size > window_w {
cursor.x - OFFSET - size
} else {
cursor.x + OFFSET
};
}
.max(0.0);
let y = if cursor.y + OFFSET + size + 20.0 > window_h {
cursor.y - OFFSET - size - 20.0
} else {
cursor.y + OFFSET
};
}
.max(0.0);
stack![catcher, pin(loupe).x(x).y(y)].into()
}
}
+4 -3
View File
@@ -78,12 +78,13 @@ pub fn nearest_aci(r: u8, g: u8, b: u8) -> u8 {
codec::types::aci_table::nearest_aci(r, g, b)
}
/// `#RRGGBB`, upper case.
/// `#RRGGBB`, upper case — the same format the Options hex fields store.
pub fn hex_string(r: u8, g: u8, b: u8) -> String {
format!("#{r:02X}{g:02X}{b:02X}")
crate::app::config::rgb_to_hex([r, g, b])
}
/// Parse `#RRGGBB`, `RRGGBB`, `#RGB` or `RGB`.
/// Parse `#RRGGBB`, `RRGGBB`, `#RGB` or `RGB`. Unlike `config::parse_hex`,
/// which Options uses, this also accepts the short three-digit form.
pub fn parse_hex(text: &str) -> Option<(u8, u8, u8)> {
let digits = text.trim().trim_start_matches('#');
if !digits.chars().all(|c| c.is_ascii_hexdigit()) {
+2 -2
View File
@@ -510,8 +510,8 @@ fn picker_msg(msg: ColorPickerMsg) -> Message {
}
fn ink_is_dark(color: Color) -> bool {
let byte = |c: f32| (c * 255.0).round() as u8;
math::ink_is_dark(byte(color.r), byte(color.g), byte(color.b))
let [r, g, b, _] = color.into_rgba8();
math::ink_is_dark(r, g, b)
}
fn filled(color: Color) -> container::Style {