forked from 1b-agent/opencadstudio-upstream
Select Color: bottom-aligned field, list view, name sorting, book names
- True Color opens in RGB; the gradient field, hex and nearest index sit at the bottom so CMYK's fourth slider doesn't move them; slider rows closer together. - Document tab: grid or list view (list drawn like the colour-book bars), and Name A–Z / Z–A sorting (translated in all locales). Swatches of colour-book colours show the colour's name. - A colour-book colour picked as the current colour (nothing selected) keeps its BOOK$NAME on the objects drawn with it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
This commit is contained in:
33 files changed
+221
-53
No files matched your search
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#B4B6B9" stroke-width="1.8" stroke-linejoin="round"><rect x="4" y="4" width="16" height="4" rx="1"/><rect x="4" y="10" width="16" height="4" rx="1"/><rect x="4" y="16" width="16" height="4" rx="1"/></svg>
|
||||
|
After Width: | Height: | Size: 285 B |
@@ -1359,6 +1359,8 @@ common =
|
||||
.color-recently-used = المستخدمة مؤخرًا
|
||||
.color-most-used = الأكثر استخدامًا
|
||||
.color-number = رقم اللون
|
||||
.color-name-az = الاسم أ–ي
|
||||
.color-name-za = الاسم ي–أ
|
||||
.color-in-drawing = الألوان في هذا الرسم
|
||||
.color-sort = فرز
|
||||
.color-no-drawing-colors = لا توجد ألوان في هذا الرسم بعد
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Наскоро използвани
|
||||
.color-most-used = Най-често използвани
|
||||
.color-number = Номер на цвят
|
||||
.color-name-az = Име А–Я
|
||||
.color-name-za = Име Я–А
|
||||
.color-in-drawing = Цветове в този чертеж
|
||||
.color-sort = Сортиране
|
||||
.color-no-drawing-colors = Все още няма цветове в този чертеж
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Naposledy použité
|
||||
.color-most-used = Nejpoužívanější
|
||||
.color-number = Číslo barvy
|
||||
.color-name-az = Název A–Z
|
||||
.color-name-za = Název Z–A
|
||||
.color-in-drawing = Barvy v tomto výkresu
|
||||
.color-sort = Řadit
|
||||
.color-no-drawing-colors = V tomto výkresu zatím nejsou žádné barvy
|
||||
|
||||
@@ -1347,6 +1347,8 @@ common =
|
||||
.color-recently-used = Zuletzt verwendet
|
||||
.color-most-used = Am häufigsten verwendet
|
||||
.color-number = Farbnummer
|
||||
.color-name-az = Name A–Z
|
||||
.color-name-za = Name Z–A
|
||||
.color-in-drawing = Farben in dieser Zeichnung
|
||||
.color-sort = Sortieren
|
||||
.color-no-drawing-colors = Noch keine Farben in dieser Zeichnung
|
||||
|
||||
@@ -1348,6 +1348,8 @@ common =
|
||||
.color-recently-used = Πρόσφατα χρησιμοποιημένα
|
||||
.color-most-used = Πιο συχνά χρησιμοποιημένα
|
||||
.color-number = Αριθμός χρώματος
|
||||
.color-name-az = Όνομα Α–Ω
|
||||
.color-name-za = Όνομα Ω–Α
|
||||
.color-in-drawing = Χρώματα σε αυτό το σχέδιο
|
||||
.color-sort = Ταξινόμηση
|
||||
.color-no-drawing-colors = Δεν υπάρχουν ακόμη χρώματα σε αυτό το σχέδιο
|
||||
|
||||
@@ -1347,6 +1347,8 @@ common =
|
||||
.color-recently-used = Recently used
|
||||
.color-most-used = Most used
|
||||
.color-number = Color number
|
||||
.color-name-az = Name A–Z
|
||||
.color-name-za = Name Z–A
|
||||
.color-in-drawing = Colors in this drawing
|
||||
.color-sort = Sort
|
||||
.color-no-drawing-colors = No colors in this drawing yet
|
||||
|
||||
@@ -1347,6 +1347,8 @@ common =
|
||||
.color-recently-used = Usados recientemente
|
||||
.color-most-used = Más usados
|
||||
.color-number = Número de color
|
||||
.color-name-az = Nombre A–Z
|
||||
.color-name-za = Nombre Z–A
|
||||
.color-in-drawing = Colores de este dibujo
|
||||
.color-sort = Ordenar
|
||||
.color-no-drawing-colors = Aún no hay colores en este dibujo
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Viimeksi käytetyt
|
||||
.color-most-used = Eniten käytetyt
|
||||
.color-number = Värin numero
|
||||
.color-name-az = Nimi A–Ö
|
||||
.color-name-za = Nimi Ö–A
|
||||
.color-in-drawing = Tämän piirustuksen värit
|
||||
.color-sort = Lajittele
|
||||
.color-no-drawing-colors = Tässä piirustuksessa ei ole vielä värejä
|
||||
|
||||
@@ -1347,6 +1347,8 @@ common =
|
||||
.color-recently-used = Utilisées récemment
|
||||
.color-most-used = Les plus utilisées
|
||||
.color-number = Numéro de couleur
|
||||
.color-name-az = Nom A–Z
|
||||
.color-name-za = Nom Z–A
|
||||
.color-in-drawing = Couleurs de ce dessin
|
||||
.color-sort = Trier
|
||||
.color-no-drawing-colors = Aucune couleur dans ce dessin pour l'instant
|
||||
|
||||
@@ -1335,6 +1335,8 @@ common =
|
||||
.color-recently-used = हाल ही में उपयोग किए गए
|
||||
.color-most-used = सबसे अधिक उपयोग किए गए
|
||||
.color-number = रंग संख्या
|
||||
.color-name-az = नाम A–Z
|
||||
.color-name-za = नाम Z–A
|
||||
.color-in-drawing = इस ड्रॉइंग के रंग
|
||||
.color-sort = क्रमबद्ध करें
|
||||
.color-no-drawing-colors = इस ड्रॉइंग में अभी तक कोई रंग नहीं है
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Legutóbb használt
|
||||
.color-most-used = Leggyakrabban használt
|
||||
.color-number = Színszám
|
||||
.color-name-az = Név A–Z
|
||||
.color-name-za = Név Z–A
|
||||
.color-in-drawing = Színek ebben a rajzban
|
||||
.color-sort = Rendezés
|
||||
.color-no-drawing-colors = Ebben a rajzban még nincsenek színek
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Usati di recente
|
||||
.color-most-used = Più usati
|
||||
.color-number = Numero colore
|
||||
.color-name-az = Nome A–Z
|
||||
.color-name-za = Nome Z–A
|
||||
.color-in-drawing = Colori in questo disegno
|
||||
.color-sort = Ordina
|
||||
.color-no-drawing-colors = Ancora nessun colore in questo disegno
|
||||
|
||||
@@ -1337,6 +1337,8 @@ common =
|
||||
.color-recently-used = 最近使用した色
|
||||
.color-most-used = 使用頻度の高い色
|
||||
.color-number = 色番号
|
||||
.color-name-az = 名前 (昇順)
|
||||
.color-name-za = 名前 (降順)
|
||||
.color-in-drawing = この図面の色
|
||||
.color-sort = 並べ替え
|
||||
.color-no-drawing-colors = この図面にはまだ色がありません
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = 최근 사용
|
||||
.color-most-used = 가장 많이 사용
|
||||
.color-number = 색상 번호
|
||||
.color-name-az = 이름 오름차순
|
||||
.color-name-za = 이름 내림차순
|
||||
.color-in-drawing = 이 도면의 색상
|
||||
.color-sort = 정렬
|
||||
.color-no-drawing-colors = 이 도면에는 아직 색상이 없습니다
|
||||
|
||||
@@ -1352,6 +1352,8 @@ common =
|
||||
.color-recently-used = ໃຊ້ຫຼ້າສຸດ
|
||||
.color-most-used = ໃຊ້ຫຼາຍທີ່ສຸດ
|
||||
.color-number = ເລກສີ
|
||||
.color-name-az = ຊື່ A–Z
|
||||
.color-name-za = ຊື່ Z–A
|
||||
.color-in-drawing = ສີໃນແບບແຕ້ມນີ້
|
||||
.color-sort = ຈັດລຽງ
|
||||
.color-no-drawing-colors = ຍັງບໍ່ມີສີໃນແບບແຕ້ມນີ້
|
||||
|
||||
@@ -1345,6 +1345,8 @@ common =
|
||||
.color-recently-used = Recent gebruikt
|
||||
.color-most-used = Meest gebruikt
|
||||
.color-number = Kleurnummer
|
||||
.color-name-az = Naam A–Z
|
||||
.color-name-za = Naam Z–A
|
||||
.color-in-drawing = Kleuren in deze tekening
|
||||
.color-sort = Sorteren
|
||||
.color-no-drawing-colors = Nog geen kleuren in deze tekening
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = Ostatnio używane
|
||||
.color-most-used = Najczęściej używane
|
||||
.color-number = Numer koloru
|
||||
.color-name-az = Nazwa A–Z
|
||||
.color-name-za = Nazwa Z–A
|
||||
.color-in-drawing = Kolory w tym rysunku
|
||||
.color-sort = Sortuj
|
||||
.color-no-drawing-colors = Brak kolorów w tym rysunku
|
||||
|
||||
@@ -1347,6 +1347,8 @@ common =
|
||||
.color-recently-used = Usadas recentemente
|
||||
.color-most-used = Mais usadas
|
||||
.color-number = Número da cor
|
||||
.color-name-az = Nome A–Z
|
||||
.color-name-za = Nome Z–A
|
||||
.color-in-drawing = Cores neste desenho
|
||||
.color-sort = Ordenar
|
||||
.color-no-drawing-colors = Ainda não há cores neste desenho
|
||||
|
||||
@@ -1350,6 +1350,8 @@ common =
|
||||
.color-recently-used = Недавно использованные
|
||||
.color-most-used = Чаще всего используемые
|
||||
.color-number = Номер цвета
|
||||
.color-name-az = Имя А–Я
|
||||
.color-name-za = Имя Я–А
|
||||
.color-in-drawing = Цвета в этом чертеже
|
||||
.color-sort = Сортировка
|
||||
.color-no-drawing-colors = В этом чертеже пока нет цветов
|
||||
|
||||
@@ -1333,6 +1333,8 @@ common =
|
||||
.color-recently-used = Son kullanılanlar
|
||||
.color-most-used = En çok kullanılanlar
|
||||
.color-number = Renk numarası
|
||||
.color-name-az = Ad A–Z
|
||||
.color-name-za = Ad Z–A
|
||||
.color-in-drawing = Bu çizimdeki renkler
|
||||
.color-sort = Sırala
|
||||
.color-no-drawing-colors = Bu çizimde henüz renk yok
|
||||
|
||||
@@ -1334,6 +1334,8 @@ common =
|
||||
.color-recently-used = 最近使用
|
||||
.color-most-used = 最常使用
|
||||
.color-number = 颜色编号
|
||||
.color-name-az = 名称 A–Z
|
||||
.color-name-za = 名称 Z–A
|
||||
.color-in-drawing = 此图形中的颜色
|
||||
.color-sort = 排序
|
||||
.color-no-drawing-colors = 此图形中还没有颜色
|
||||
|
||||
@@ -1346,6 +1346,8 @@ common =
|
||||
.color-recently-used = 最近使用
|
||||
.color-most-used = 最常使用
|
||||
.color-number = 顏色編號
|
||||
.color-name-az = 名稱 A–Z
|
||||
.color-name-za = 名稱 Z–A
|
||||
.color-in-drawing = 此圖面中的顏色
|
||||
.color-sort = 排序
|
||||
.color-no-drawing-colors = 此圖面中還沒有顏色
|
||||
|
||||
@@ -358,7 +358,11 @@ impl OpenCADStudio {
|
||||
if layer != "0" || entity.as_entity().layer().is_empty() {
|
||||
entity.as_entity_mut().set_layer(layer);
|
||||
}
|
||||
crate::scene::view::dispatch::apply_color(&mut entity, self.ribbon.active_color);
|
||||
crate::scene::view::dispatch::apply_named_color(
|
||||
&mut entity,
|
||||
self.ribbon.active_color,
|
||||
self.ribbon.active_color_name(),
|
||||
);
|
||||
crate::scene::view::dispatch::apply_common_prop(
|
||||
&mut entity,
|
||||
"linetype",
|
||||
@@ -476,7 +480,11 @@ impl OpenCADStudio {
|
||||
if layer != "0" || entity.as_entity().layer().is_empty() {
|
||||
entity.as_entity_mut().set_layer(layer);
|
||||
}
|
||||
crate::scene::view::dispatch::apply_color(&mut entity, self.ribbon.active_color);
|
||||
crate::scene::view::dispatch::apply_named_color(
|
||||
&mut entity,
|
||||
self.ribbon.active_color,
|
||||
self.ribbon.active_color_name(),
|
||||
);
|
||||
crate::scene::view::dispatch::apply_common_prop(
|
||||
&mut entity,
|
||||
"linetype",
|
||||
|
||||
@@ -3149,7 +3149,11 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
||||
}
|
||||
|
||||
if !preserve_entity_style {
|
||||
crate::scene::view::dispatch::apply_color(&mut entity, self.ribbon.active_color);
|
||||
crate::scene::view::dispatch::apply_named_color(
|
||||
&mut entity,
|
||||
self.ribbon.active_color,
|
||||
self.ribbon.active_color_name(),
|
||||
);
|
||||
crate::scene::view::dispatch::apply_common_prop(
|
||||
&mut entity,
|
||||
"linetype",
|
||||
|
||||
@@ -11699,6 +11699,9 @@ impl OpenCADStudio {
|
||||
};
|
||||
match target {
|
||||
crate::app::ColorPickTarget::Properties => {}
|
||||
crate::app::ColorPickTarget::Ribbon => {
|
||||
return (color, false, self.ribbon.active_color_name());
|
||||
}
|
||||
crate::app::ColorPickTarget::Layer(layer) => {
|
||||
let name = document.layers.get(layer).and_then(|layer| {
|
||||
match (&layer.book_name, &layer.color_name) {
|
||||
@@ -11767,6 +11770,7 @@ impl OpenCADStudio {
|
||||
let handles = self.property_target_handles(i);
|
||||
if handles.is_empty() {
|
||||
let task = self.on_ribbon_color_changed(color);
|
||||
self.ribbon.active_color_book = name.map(|name| (color, name));
|
||||
self.refresh_properties();
|
||||
return task;
|
||||
}
|
||||
|
||||
@@ -1215,7 +1215,11 @@ impl OpenCADStudio {
|
||||
Some(Message::PropColorFieldChanged { field, color })
|
||||
}
|
||||
Some(crate::app::ColorPickTarget::MText) => Some(Message::MTextColorChanged(color)),
|
||||
Some(crate::app::ColorPickTarget::Ribbon) => Some(Message::RibbonColorChanged(color)),
|
||||
Some(crate::app::ColorPickTarget::Ribbon) => {
|
||||
let task = self.update(Message::RibbonColorChanged(color));
|
||||
self.ribbon.active_color_book = name.map(|name| (color, name));
|
||||
return task;
|
||||
}
|
||||
Some(crate::app::ColorPickTarget::Layer(layer)) => {
|
||||
let i = self.active_tab;
|
||||
match self.layer_panel_index(i, &layer) {
|
||||
|
||||
@@ -4723,6 +4723,8 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Recently used" => Some(("common", "color-recently-used")),
|
||||
"Most used" => Some(("common", "color-most-used")),
|
||||
"Color number" => Some(("common", "color-number")),
|
||||
"Name A–Z" => Some(("common", "color-name-az")),
|
||||
"Name Z–A" => Some(("common", "color-name-za")),
|
||||
"Colors in this drawing" => Some(("common", "color-in-drawing")),
|
||||
"Sort" => Some(("common", "color-sort")),
|
||||
"No colors in this drawing yet" => Some(("common", "color-no-drawing-colors")),
|
||||
|
||||
@@ -21,21 +21,35 @@ pub struct DocColor {
|
||||
}
|
||||
|
||||
impl DocColor {
|
||||
/// The few characters drawn on the swatch: the index number, `RGB`, or
|
||||
/// the first word of the colour book.
|
||||
/// The text drawn on the swatch: the index number, `RGB`, or the
|
||||
/// colour-book colour's own name.
|
||||
pub fn tag(&self) -> String {
|
||||
match (&self.name, self.color) {
|
||||
(Some(name), _) => name
|
||||
.split(['$', ' '])
|
||||
.next()
|
||||
.unwrap_or_default()
|
||||
.chars()
|
||||
.take(5)
|
||||
.collect(),
|
||||
(Some(_), _) => self.label(),
|
||||
(None, AcadColor::Index(i)) => i.to_string(),
|
||||
_ => "RGB".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The name in the list view: the colour-book colour's own name (without
|
||||
/// the book), `ACI n` or `#RRGGBB`.
|
||||
pub fn label(&self) -> String {
|
||||
match &self.name {
|
||||
Some(name) => name
|
||||
.split_once('$')
|
||||
.map_or(name.as_str(), |(_, name)| name)
|
||||
.to_string(),
|
||||
None => math::short_name(self.color),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Swatches or a list of named bars.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum DocView {
|
||||
#[default]
|
||||
Grid,
|
||||
List,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
@@ -45,14 +59,18 @@ pub enum DocSort {
|
||||
Usage,
|
||||
Hue,
|
||||
Number,
|
||||
NameAsc,
|
||||
NameDesc,
|
||||
}
|
||||
|
||||
impl DocSort {
|
||||
pub const ALL: [DocSort; 4] = [
|
||||
pub const ALL: [DocSort; 6] = [
|
||||
DocSort::Recent,
|
||||
DocSort::Usage,
|
||||
DocSort::Hue,
|
||||
DocSort::Number,
|
||||
DocSort::NameAsc,
|
||||
DocSort::NameDesc,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -63,6 +81,8 @@ impl std::fmt::Display for DocSort {
|
||||
DocSort::Usage => crate::t!("Most used"),
|
||||
DocSort::Hue => crate::t!("Color"),
|
||||
DocSort::Number => crate::t!("Color number"),
|
||||
DocSort::NameAsc => crate::t!("Name A–Z"),
|
||||
DocSort::NameDesc => crate::t!("Name Z–A"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -163,6 +183,10 @@ pub fn sort(colors: &mut [DocColor], by: DocSort, recent: &[AcadColor]) {
|
||||
.then_with(|| a.name.cmp(&b.name))
|
||||
.then_with(|| key(a.color).cmp(&key(b.color)))
|
||||
}),
|
||||
DocSort::NameAsc => colors.sort_by_cached_key(|c| c.label().to_lowercase()),
|
||||
DocSort::NameDesc => {
|
||||
colors.sort_by_cached_key(|c| std::cmp::Reverse(c.label().to_lowercase()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +225,7 @@ mod tests {
|
||||
assert_eq!(colors[0].uses, 3);
|
||||
assert_eq!(colors[0].newest, Handle::new(3));
|
||||
assert_eq!(colors[3].name, None, "an empty name is no name");
|
||||
assert_eq!(colors[2].tag(), "RAL");
|
||||
assert_eq!(colors[2].tag(), "RAL 5015");
|
||||
assert_eq!(colors[0].tag(), "1");
|
||||
assert_eq!(colors[1].tag(), "RGB");
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@ use iced::{Background, Border, Color, Element, Gradient, Length, Radians, Theme}
|
||||
const ROW_HEIGHT: f32 = 26.0;
|
||||
const TRACK: f32 = 18.0;
|
||||
const STRIP_WIDTH: f32 = 22.0;
|
||||
const ROW_GAP: f32 = 8.0;
|
||||
const ROW_GAP: f32 = 6.0;
|
||||
const FIELD_HEIGHT: f32 = 96.0;
|
||||
const MODE_WIDTH: f32 = 48.0;
|
||||
const MODE_HEIGHT: f32 = 24.0;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum EditorMode {
|
||||
Rgb,
|
||||
#[default]
|
||||
Rgb,
|
||||
Hsb,
|
||||
Cmyk,
|
||||
}
|
||||
@@ -151,19 +151,19 @@ 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).
|
||||
/// With `fill` the field and hex row sit at the bottom of the space, so
|
||||
/// they stay put when CMYK adds a fourth slider.
|
||||
pub fn view<'a>(
|
||||
&'a self,
|
||||
mode_end: Option<Element<'a, Message>>,
|
||||
hex_end: Option<Element<'a, Message>>,
|
||||
fill: bool,
|
||||
) -> Element<'a, Message> {
|
||||
column![
|
||||
self.mode_row(mode_end),
|
||||
self.slider_rows(),
|
||||
self.field(),
|
||||
self.hex_row(hex_end),
|
||||
]
|
||||
.spacing(12)
|
||||
.into()
|
||||
let mut view = column![self.mode_row(mode_end), self.slider_rows()].spacing(12);
|
||||
if fill {
|
||||
view = view.push(Space::new().height(Length::Fill));
|
||||
}
|
||||
view.push(self.field()).push(self.hex_row(hex_end)).into()
|
||||
}
|
||||
|
||||
/// RGB, HSB and CMYK, with `end` at the far right.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! colour editor: no tabs, no index colours.
|
||||
|
||||
use super::book::ColorBook;
|
||||
use super::document::{self, DocColor, DocSort};
|
||||
use super::document::{self, DocColor, DocSort, DocView};
|
||||
use super::editor::{rgb_color, ColorEditor, EditorMsg};
|
||||
use super::eyedropper::{Eyedropper, EyedropperMsg};
|
||||
use super::math;
|
||||
@@ -54,6 +54,7 @@ pub enum ColorPickerMsg {
|
||||
/// A colour of the Document tab, by its place in the list.
|
||||
PickDocument(usize),
|
||||
DocSort(DocSort),
|
||||
DocView(DocView),
|
||||
/// Show another loaded colour book.
|
||||
Book(usize),
|
||||
BookPage(usize),
|
||||
@@ -94,6 +95,7 @@ pub struct ColorPicker {
|
||||
eyedropper: Option<Eyedropper>,
|
||||
doc: Vec<DocColor>,
|
||||
doc_sort: DocSort,
|
||||
doc_view: DocView,
|
||||
/// This drawing's colours picked this session, newest first.
|
||||
recent: Vec<AcadColor>,
|
||||
books: Arc<Vec<ColorBook>>,
|
||||
@@ -118,6 +120,7 @@ impl ColorPicker {
|
||||
eyedropper: None,
|
||||
doc: Vec::new(),
|
||||
doc_sort: DocSort::default(),
|
||||
doc_view: DocView::default(),
|
||||
recent: Vec::new(),
|
||||
books: Arc::default(),
|
||||
book: 0,
|
||||
@@ -284,6 +287,7 @@ impl ColorPicker {
|
||||
self.pending_name = name;
|
||||
}
|
||||
}
|
||||
ColorPickerMsg::DocView(view) => self.doc_view = view,
|
||||
ColorPickerMsg::DocSort(by) => {
|
||||
self.doc_sort = by;
|
||||
document::sort(&mut self.doc, by, &self.recent);
|
||||
@@ -358,8 +362,8 @@ impl ColorPicker {
|
||||
// height across its tabs, with the info line at the bottom.
|
||||
let mut body = column![body].spacing(8);
|
||||
if !editor_only {
|
||||
// Document and Color books fill the height themselves.
|
||||
if matches!(self.tab, ColorPickerTab::Index | ColorPickerTab::TrueColor) {
|
||||
// The other tabs fill the height themselves.
|
||||
if self.tab == ColorPickerTab::Index {
|
||||
body = body.push(Space::new().height(Length::Fill));
|
||||
}
|
||||
let fill =
|
||||
@@ -578,6 +582,11 @@ impl ColorPicker {
|
||||
.on_select(|by| picker_msg(ColorPickerMsg::DocSort(by)))
|
||||
.text_size(12)
|
||||
.padding([3, 6]),
|
||||
row![
|
||||
self.view_button(crate::ui::icons::GRID, DocView::Grid),
|
||||
self.view_button(crate::ui::icons::LIST, DocView::List),
|
||||
]
|
||||
.spacing(2),
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center);
|
||||
@@ -589,9 +598,59 @@ impl ColorPicker {
|
||||
.spacing(10)
|
||||
.into();
|
||||
}
|
||||
let grid = self.doc.chunks(DOC_COLUMNS).enumerate().fold(
|
||||
column![].spacing(4),
|
||||
|grid, (r, chunk)| {
|
||||
let list: Element<'_, Message> = if self.doc_view == DocView::List {
|
||||
self.doc
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(column![].spacing(2), |list, (i, entry)| {
|
||||
let fill = math::color_rgb(entry.color)
|
||||
.map_or(Color::from_rgb8(128, 128, 128), rgb_color);
|
||||
let selected = self.pending == entry.color && self.pending_name == entry.name;
|
||||
list.push(
|
||||
color_bar(
|
||||
entry.label(),
|
||||
fill,
|
||||
selected,
|
||||
ColorPickerMsg::PickDocument(i),
|
||||
)
|
||||
.height(26),
|
||||
)
|
||||
})
|
||||
.into()
|
||||
} else {
|
||||
self.doc_grid()
|
||||
};
|
||||
column![
|
||||
header,
|
||||
scrollable(list).height(Length::Fill).spacing(4).direction(
|
||||
scrollable::Direction::Vertical(
|
||||
scrollable::Scrollbar::new().width(4).scroller_width(4)
|
||||
)
|
||||
),
|
||||
]
|
||||
.spacing(10)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Grid or list toggle for the Document tab.
|
||||
fn view_button(&self, icon: &'static [u8], view: DocView) -> Element<'_, Message> {
|
||||
let active = self.doc_view == view;
|
||||
button(
|
||||
svg(crate::ui::icons::themed_handle(icon))
|
||||
.width(14)
|
||||
.height(14),
|
||||
)
|
||||
.on_press(picker_msg(ColorPickerMsg::DocView(view)))
|
||||
.padding(5)
|
||||
.style(move |theme: &Theme, status| toggle_style(theme, active, status))
|
||||
.into()
|
||||
}
|
||||
|
||||
fn doc_grid(&self) -> Element<'_, Message> {
|
||||
self.doc
|
||||
.chunks(DOC_COLUMNS)
|
||||
.enumerate()
|
||||
.fold(column![].spacing(4), |grid, (r, chunk)| {
|
||||
let line = chunk
|
||||
.iter()
|
||||
.enumerate()
|
||||
@@ -601,18 +660,8 @@ impl ColorPicker {
|
||||
let line = (chunk.len()..DOC_COLUMNS)
|
||||
.fold(line, |line, _| line.push(Space::new().width(Length::Fill)));
|
||||
grid.push(line)
|
||||
},
|
||||
);
|
||||
column![
|
||||
header,
|
||||
scrollable(grid).height(Length::Fill).spacing(4).direction(
|
||||
scrollable::Direction::Vertical(
|
||||
scrollable::Scrollbar::new().width(4).scroller_width(4)
|
||||
)
|
||||
),
|
||||
]
|
||||
.spacing(10)
|
||||
.into()
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
fn doc_swatch<'a>(&self, i: usize, entry: &'a DocColor) -> Element<'a, Message> {
|
||||
@@ -627,7 +676,8 @@ impl ColorPicker {
|
||||
)
|
||||
.align_y(iced::Bottom)
|
||||
.padding([1, 4])
|
||||
.height(Length::Fill),
|
||||
.height(Length::Fill)
|
||||
.clip(true),
|
||||
)
|
||||
.on_press(picker_msg(ColorPickerMsg::PickDocument(i)))
|
||||
.padding(0)
|
||||
@@ -863,7 +913,7 @@ impl ColorPicker {
|
||||
)
|
||||
};
|
||||
let nearest = (!self.editor_only()).then(|| self.nearest_button());
|
||||
self.editor.view(pipette, nearest)
|
||||
self.editor.view(pipette, nearest, !self.editor_only())
|
||||
}
|
||||
|
||||
fn nearest_button(&self) -> Element<'_, Message> {
|
||||
@@ -985,24 +1035,37 @@ fn book_bar(
|
||||
color: &super::book::BookColor,
|
||||
selected: Option<usize>,
|
||||
) -> Element<'_, Message> {
|
||||
let fill = rgb_color(color.rgb);
|
||||
color_bar(
|
||||
&color.name,
|
||||
rgb_color(color.rgb),
|
||||
selected == Some(i),
|
||||
ColorPickerMsg::PickBook(i),
|
||||
)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// A full-width colour bar with a name: the Color books pages and the
|
||||
/// Document tab's list.
|
||||
fn color_bar<'a>(
|
||||
name: impl text::IntoFragment<'a>,
|
||||
fill: Color,
|
||||
selected: bool,
|
||||
on_press: ColorPickerMsg,
|
||||
) -> button::Button<'a, Message> {
|
||||
button(
|
||||
container(
|
||||
text(&color.name)
|
||||
text(name)
|
||||
.size(12)
|
||||
.font(iced::Font::MONOSPACE)
|
||||
.color(ink(fill)),
|
||||
)
|
||||
.center(Length::Fill),
|
||||
)
|
||||
.on_press(picker_msg(ColorPickerMsg::PickBook(i)))
|
||||
.on_press(picker_msg(on_press))
|
||||
.padding(0)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.style(move |theme: &Theme, status| {
|
||||
swatch_button_style(theme, status, fill, selected == Some(i))
|
||||
})
|
||||
.into()
|
||||
.style(move |theme: &Theme, status| swatch_button_style(theme, status, fill, selected))
|
||||
}
|
||||
|
||||
/// A short gray note in the middle of the free space.
|
||||
|
||||
@@ -81,6 +81,7 @@ pub static PIN_ACTIVE: &[u8] = include_bytes!("../../assets/icons/ui/pin_active.
|
||||
pub static SPLIT_V: &[u8] = include_bytes!("../../assets/icons/ui/split_v.svg");
|
||||
pub static SPLIT_H: &[u8] = include_bytes!("../../assets/icons/ui/split_h.svg");
|
||||
pub static GRID: &[u8] = include_bytes!("../../assets/icons/ui/grid.svg");
|
||||
pub static LIST: &[u8] = include_bytes!("../../assets/icons/ui/list.svg");
|
||||
pub static SNAP: &[u8] = include_bytes!("../../assets/icons/ui/snap.svg");
|
||||
pub static DOC_NEW: &[u8] = include_bytes!("../../assets/icons/ui/doc_new.svg");
|
||||
pub static DOC: &[u8] = include_bytes!("../../assets/icons/ui/doc.svg");
|
||||
|
||||
@@ -82,6 +82,9 @@ pub struct Ribbon {
|
||||
pub layer_filter: String,
|
||||
/// Active object color — ACI / ByLayer / ByBlock.
|
||||
pub active_color: AcadColor,
|
||||
/// Colour-book identity (`BOOK$NAME`) of a colour picked from a colour
|
||||
/// book, with the colour it was picked as; see `active_color_name`.
|
||||
pub active_color_book: Option<(AcadColor, String)>,
|
||||
/// Active linetype override ("ByLayer", "Continuous", …).
|
||||
pub active_linetype: String,
|
||||
/// Active lineweight.
|
||||
@@ -171,6 +174,15 @@ fn position_ribbon_dropdown<'a>(
|
||||
}
|
||||
|
||||
impl Ribbon {
|
||||
/// The colour-book identity of the active colour, while the active colour
|
||||
/// is still the one picked from the book.
|
||||
pub fn active_color_name(&self) -> Option<String> {
|
||||
self.active_color_book
|
||||
.as_ref()
|
||||
.filter(|(color, _)| *color == self.active_color)
|
||||
.map(|(_, name)| name.clone())
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
modules: all_ribbon_modules(),
|
||||
@@ -195,6 +207,7 @@ impl Ribbon {
|
||||
layer_infos: vec![],
|
||||
layer_filter: String::new(),
|
||||
active_color: AcadColor::ByLayer,
|
||||
active_color_book: None,
|
||||
active_linetype: "ByLayer".to_string(),
|
||||
active_lineweight: LineWeight::ByLayer,
|
||||
available_linetypes: vec![LinetypeItem {
|
||||
|
||||
Reference in new issue
Block a user