Merge pull request #1020 from redrun6767/feat/panel-sets-dock-columns
UI: floating panel sets and a multi-column dock
This commit is contained in:
commit
d7339804e6
|
|
@ -123,7 +123,7 @@ Ranked; detail in [docs/roadmap.md](docs/roadmap.md) and [docs/gaps.md](docs/gap
|
|||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-11 | Effect › Brush Strokes: Accented Edges, Angled Strokes, Crosshatch, Dark Strokes, Ink Outlines, Spatter, Sprayed Strokes, Sumi-e (G2). Command parameters from agents and files checked before anything changes (paint, place, cuts, dashes, crop, asset ids, anchors, paths, distort; #984–#999); command dialogs keep whole numbers whole, so Create Object Mosaic takes the tiles typed (#1000); stepper arrows take Shift (×10) and Ctrl/Cmd (÷10) like the arrow keys (#991). Exports and Rasterize supersample Art Optimized edges, so shapes meeting edge to edge leave no seam (#983). Character and paragraph styles take leading, kerning, mojikumi and the other attributes left out at their defaults (#1001). Drawing, typing and pasting with no layer shown and unlocked is refused instead of adding art to a hidden or locked layer (#1002). MCP `add_text` gives type on or in a path the colour asked for (#1003). MCP `screenshot` of a connected app renders the artboard asked for (#1004). `vectorcraft-cli run` ends quietly when its reader closes early (#1005). Select › All on Active Artboard selects on the artboard made active, not always the first (#1006). Reverse Gradient keeps off-centre midpoints, mirrored (#1007). A polar grid with no radial dividers draws none (#1008). Use Precise Cursors also covers the Pen's join pointer (#1009). SVGs with one absolute and one unitless root side import at their size, unstretched (#1010). DXF US survey inches, yards and miles open at their size and name (#1011). A file placed into a document with no other links follows its first change even while the app sits idle (#1031). PDF import keeps the style a font name says when the file doesn't embed the font (#1023). Shift selects ruler guides and art together, and Delete removes both (#1022). Open filled paths are hit by their fill on every side, the rotate cursor bows around the corner it is at, the flip icons match their flips, the Color Picker previews on the selection, and Properties › Transform reaches Scale Corners and Scale Strokes & Effects (#1036). Offset Path and the other booleans finish on outlines where the sweep used to loop until memory ran out (linesweeper 0.5, #1028). |
|
||||
| 2026-10-11 | Effect › Brush Strokes: Accented Edges, Angled Strokes, Crosshatch, Dark Strokes, Ink Outlines, Spatter, Sprayed Strokes, Sumi-e (G2). Command parameters from agents and files checked before anything changes (paint, place, cuts, dashes, crop, asset ids, anchors, paths, distort; #984–#999); command dialogs keep whole numbers whole, so Create Object Mosaic takes the tiles typed (#1000); stepper arrows take Shift (×10) and Ctrl/Cmd (÷10) like the arrow keys (#991). Exports and Rasterize supersample Art Optimized edges, so shapes meeting edge to edge leave no seam (#983). Character and paragraph styles take leading, kerning, mojikumi and the other attributes left out at their defaults (#1001). Drawing, typing and pasting with no layer shown and unlocked is refused instead of adding art to a hidden or locked layer (#1002). MCP `add_text` gives type on or in a path the colour asked for (#1003). MCP `screenshot` of a connected app renders the artboard asked for (#1004). `vectorcraft-cli run` ends quietly when its reader closes early (#1005). Select › All on Active Artboard selects on the artboard made active, not always the first (#1006). Reverse Gradient keeps off-centre midpoints, mirrored (#1007). A polar grid with no radial dividers draws none (#1008). Use Precise Cursors also covers the Pen's join pointer (#1009). SVGs with one absolute and one unitless root side import at their size, unstretched (#1010). DXF US survey inches, yards and miles open at their size and name (#1011). A file placed into a document with no other links follows its first change even while the app sits idle (#1031). PDF import keeps the style a font name says when the file doesn't embed the font (#1023). Shift selects ruler guides and art together, and Delete removes both (#1022). Open filled paths are hit by their fill on every side, the rotate cursor bows around the corner it is at, the flip icons match their flips, the Color Picker previews on the selection, and Properties › Transform reaches Scale Corners and Scale Strokes & Effects (#1036). Offset Path and the other booleans finish on outlines where the sweep used to loop until memory ran out (linesweeper 0.5, #1028). Floating panel groups stack into sets that move together, collapse to their tabs and dock as extra dock columns that scroll (#1020). |
|
||||
| 2026-10-10 | Initial live Revolve (Effect › 3D and Materials, #846, #605), in its own `three-d` crate. Progress docs re-measured and restructured to the craftrules standard (this page, `docs/target-app-parity.md`, `gaps.md`, `ui-parity.md`, the format, hardware, localization, effects and type checklists). Same day: v0.8.0; Effect › Distort, Pixelate and Texture filters (13); German interface; Variables (data merge); Graph Type value axes and tick marks; restart when the first frame never reaches the screen (#964) |
|
||||
| 2026-10-09 | Radial Blur, Smart Blur, Unsharp Mask (gap 2 begins); 340 commits, the busiest day |
|
||||
| 2026-10-08 | v0.5.0–v0.7.0; community contributions: Pen and shape-tool modifiers, Layers, Artboards, Japanese composition, Hebrew/Arabic type, interface languages, saved selections |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! The right dock: Properties | Layers | Libraries tabs, plus the collapsed icon-panel column
|
||||
//! whose panels pop out to the left. The double arrow at the top of the dock collapses the tabbed
|
||||
//! whose panels pop out to the left, and left of it the floating sets docked as columns
|
||||
//! ([`floating::docked_columns`]). The double arrow at the top of the dock collapses the tabbed
|
||||
//! group to icons at the top of the icon column (`window.collapseDock`); the arrow above the column
|
||||
//! then expands it again.
|
||||
|
||||
|
|
@ -23,6 +24,12 @@ fn column_left_id() -> egui::Id {
|
|||
egui::Id::new("dock-icon-column-left")
|
||||
}
|
||||
|
||||
/// Where the dock's left edge was drawn last: the icon column's, or the leftmost dock column's
|
||||
/// (egui temp memory, one frame old). Popped-out panels open left of it.
|
||||
fn dock_left_id() -> egui::Id {
|
||||
egui::Id::new("dock-left")
|
||||
}
|
||||
|
||||
/// Collapse the tabbed group to icons or expand it again (`window.collapseDock`). Expanding while
|
||||
/// one of its panels is popped out shows that panel's tab instead.
|
||||
pub fn set_collapsed(app: &mut VectorcraftApp, collapsed: bool) {
|
||||
|
|
@ -148,7 +155,10 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
|||
});
|
||||
let column = column.response.rect;
|
||||
let dock = group.map_or(column, |g| g.union(column));
|
||||
// Floating sets docked as columns, left of the icon column.
|
||||
let left = floating::docked_columns(app, ui).iter().map(|r| r.left()).fold(column.left(), f32::min);
|
||||
ui.ctx().data_mut(|d| {
|
||||
d.insert_temp(dock_left_id(), left);
|
||||
d.insert_temp(column_left_id(), column.left());
|
||||
d.insert_temp(floating::dock_rect_id(), dock);
|
||||
d.insert_temp(floating::icons_rect_id(), column);
|
||||
|
|
@ -226,7 +236,9 @@ pub fn floating_panel(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
|||
} else {
|
||||
screen.right()
|
||||
};
|
||||
let right = column - 6.0;
|
||||
let left = ctx.data(|d| d.get_temp::<f32>(dock_left_id())).filter(|x| x.is_finite() && *x > screen.left() && *x <= column).unwrap_or(column);
|
||||
let right = if app.ui.dock && app.ui.screen_mode < 3 { left } else { column };
|
||||
let right = right - 6.0;
|
||||
// The tabbed group's panels fill their height (Layers) or scroll (Properties): give them one
|
||||
// that keeps the flyout on screen.
|
||||
let width = panel_width(id);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -628,6 +628,7 @@
|
|||
% of all commits % všech commitů
|
||||
Lines +/− Řádky +/−
|
||||
Drag to move Přetažením přesunete
|
||||
Drag to move out of the set Přetažením přesunete mimo sadu
|
||||
Drag to float as a toolbar Přetažením vytvoříte plovoucí panel nástrojů
|
||||
Put back in the toolbar Vrátit do panelu nástrojů
|
||||
Float Panel Plovoucí panel
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3213,6 +3213,7 @@ axis Vertical Vertikal
|
|||
axis Both Beide
|
||||
theme Appearance Erscheinungsbild
|
||||
Drag to move Zum Verschieben ziehen
|
||||
Drag to move out of the set Ziehen, um aus dem Satz zu lösen
|
||||
Drag to float as a toolbar Ziehen, um als eigene Werkzeugleiste abzulösen
|
||||
Put back in the toolbar Zurück in die Werkzeugleiste setzen
|
||||
Float Panel Bedienfeld ablösen
|
||||
|
|
@ -3769,6 +3770,9 @@ theme Appearance Erscheinungsbild
|
|||
@msg tool (a tool id) is required tool (eine Werkzeug-ID) ist erforderlich
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} gehört zu keiner Werkzeuggruppe mit mehreren Werkzeugen
|
||||
@msg onto must name a panel floating in another group onto muss ein Bedienfeld nennen, das in einer anderen Gruppe schwebt
|
||||
@msg below and above must name a panel floating in another group below und above müssen ein Bedienfeld nennen, das in einer anderen Gruppe schwebt
|
||||
@msg give only one of onto, below and above nur eines von onto, below und above angeben
|
||||
@msg column must be true or a number from 1 column muss true oder eine Zahl ab 1 sein
|
||||
@msg x and y must both be numbers x und y müssen beide Zahlen sein
|
||||
@msg "{0}" is not a colour: write it as #rrggbb "{0}" ist keine Farbe: Schreiben Sie sie als #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead dies ist kein Logo aus flächigen Farben ({_1} % seiner einfarbigen Bereiche entsprechen wenigen flächigen Farben), daher würde der Modus „Flaches Logo“ seine Verläufe in Flecken zerlegen: Verwenden Sie stattdessen den Modus „Farbe“
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3317,6 +3317,7 @@ axis Horizontal Horizontal
|
|||
axis Vertical Vertical
|
||||
axis Both Ambos
|
||||
Drag to move Arrastrar para mover
|
||||
Drag to move out of the set Arrastrar para sacar del conjunto
|
||||
Drag to float as a toolbar Arrastrar para flotar como barra de herramientas
|
||||
Put back in the toolbar Devolver a la barra de herramientas
|
||||
Float Panel Hacer flotar el panel
|
||||
|
|
@ -3873,6 +3874,9 @@ axis Both Ambos
|
|||
@msg tool (a tool id) is required se requiere tool (un id de herramienta)
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} no está en un grupo de la barra de herramientas con varias herramientas
|
||||
@msg onto must name a panel floating in another group onto debe nombrar un panel que flote en otro grupo
|
||||
@msg below and above must name a panel floating in another group below y above deben nombrar un panel que flote en otro grupo
|
||||
@msg give only one of onto, below and above indica solo uno de onto, below y above
|
||||
@msg column must be true or a number from 1 column debe ser true o un número desde 1
|
||||
@msg x and y must both be numbers x e y deben ser números
|
||||
@msg "{0}" is not a colour: write it as #rrggbb "{0}" no es un color: escríbelo como #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead esto no es un logotipo de colores planos ({_1}% de sus zonas sólidas coinciden con unos pocos colores planos), así que el modo Logotipo plano convertiría sus degradados en manchas: usa el modo Color
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3314,6 +3314,7 @@ axis Horizontal Horizontal
|
|||
axis Vertical Vertical
|
||||
axis Both Les deux
|
||||
Drag to move Faire glisser pour déplacer
|
||||
Drag to move out of the set Faire glisser pour sortir de l’ensemble
|
||||
Drag to float as a toolbar Faire glisser pour détacher en barre d’outils flottante
|
||||
Put back in the toolbar Remettre dans la barre d’outils
|
||||
Float Panel Rendre le panneau flottant
|
||||
|
|
@ -3870,6 +3871,9 @@ axis Both Les deux
|
|||
@msg tool (a tool id) is required tool (un identifiant d’outil) est obligatoire
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} ne fait pas partie d’un groupe de plusieurs outils dans la barre d’outils
|
||||
@msg onto must name a panel floating in another group onto doit désigner un panneau flottant dans un autre groupe
|
||||
@msg below and above must name a panel floating in another group below et above doivent désigner un panneau flottant dans un autre groupe
|
||||
@msg give only one of onto, below and above indiquez un seul de onto, below et above
|
||||
@msg column must be true or a number from 1 column doit être true ou un nombre à partir de 1
|
||||
@msg x and y must both be numbers x et y doivent tous deux être des nombres
|
||||
@msg "{0}" is not a colour: write it as #rrggbb « {0} » n’est pas une couleur : écrivez-la sous la forme #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead ce n’est pas un logo en aplats ({_1} % de ses zones pleines correspondent à quelques couleurs unies), donc le mode Logo en aplats transformerait ses dégradés en taches : utilisez le mode Couleur
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3317,6 +3317,7 @@ axis Horizontal Orizzontale
|
|||
axis Vertical Verticale
|
||||
axis Both Entrambi
|
||||
Drag to move Trascina per spostare
|
||||
Drag to move out of the set Trascina per spostare fuori dall’insieme
|
||||
Drag to float as a toolbar Trascina per rendere mobile come barra degli strumenti
|
||||
Put back in the toolbar Riporta nella barra degli strumenti
|
||||
Float Panel Rendi mobile pannello
|
||||
|
|
@ -3873,6 +3874,9 @@ axis Both Entrambi
|
|||
@msg tool (a tool id) is required tool (un id di strumento) è obbligatorio
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} non fa parte di un gruppo di più strumenti nella barra degli strumenti
|
||||
@msg onto must name a panel floating in another group onto deve indicare un pannello mobile in un altro gruppo
|
||||
@msg below and above must name a panel floating in another group below e above devono indicare un pannello mobile in un altro gruppo
|
||||
@msg give only one of onto, below and above indica solo uno tra onto, below e above
|
||||
@msg column must be true or a number from 1 column deve essere true o un numero da 1
|
||||
@msg x and y must both be numbers x e y devono essere entrambi numeri
|
||||
@msg "{0}" is not a colour: write it as #rrggbb "{0}" non è un colore: scrivilo come #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead questo non è un logo a colori piatti ({_1}% delle sue aree piene corrisponde a pochi colori piatti), quindi la modalità Logo piatto trasformerebbe i suoi sfumati in macchie: usa la modalità Colore
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3265,6 +3265,7 @@ axis Horizontal 水平方向
|
|||
axis Vertical 垂直方向
|
||||
axis Both 両方
|
||||
Drag to move 移動するにはドラッグ
|
||||
Drag to move out of the set ドラッグしてセットから出す
|
||||
Drag to float as a toolbar ドラッグしてツールバーとして浮かせる
|
||||
Put back in the toolbar ツールバーに戻す
|
||||
Float Panel パネルをフローティング
|
||||
|
|
@ -3796,6 +3797,9 @@ theme Appearance 外観
|
|||
@msg give the path `id` and the width point `index` パスの `id` と幅ポイントの `index` を指定してください
|
||||
@msg no such width point 指定された幅ポイントが見つかりません
|
||||
@msg onto must name a panel floating in another group onto には、別のグループでフローティングしているパネルを指定してください
|
||||
@msg below and above must name a panel floating in another group below と above には別のグループでフローティングしているパネルを指定してください
|
||||
@msg give only one of onto, below and above onto、below、above のうち 1 つだけを指定してください
|
||||
@msg column must be true or a number from 1 column には true または 1 以上の数値を指定してください
|
||||
@msg unknown panel `{raw}` `{raw}` は不明なパネルです
|
||||
@msg x and y must both be numbers x と y はどちらも数値で指定してください
|
||||
@msg Downloaded {what} {what} をダウンロードしました
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -2697,6 +2697,7 @@
|
|||
% of all commits % de todos os commits
|
||||
Lines +/− Linhas +/−
|
||||
Drag to move Arraste para mover
|
||||
Drag to move out of the set Arraste para tirar do conjunto
|
||||
Drag to float as a toolbar Arraste para flutuar como barra de ferramentas
|
||||
Put back in the toolbar Devolver à barra de ferramentas
|
||||
Float Panel Flutuar Painel
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -3313,6 +3313,7 @@ axis Horizontal Горизонтально
|
|||
axis Vertical Вертикально
|
||||
axis Both Оба
|
||||
Drag to move Перетащите для перемещения
|
||||
Drag to move out of the set Перетащите, чтобы вынести из набора
|
||||
Drag to float as a toolbar Перетащите, чтобы сделать плавающей панелью инструментов
|
||||
Put back in the toolbar Вернуть на панель инструментов
|
||||
Float Panel Сделать панель плавающей
|
||||
|
|
@ -3869,6 +3870,9 @@ axis Both Оба
|
|||
@msg tool (a tool id) is required требуется tool (идентификатор инструмента)
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} не входит в группу панели инструментов из нескольких инструментов
|
||||
@msg onto must name a panel floating in another group onto должен называть панель, плавающую в другой группе
|
||||
@msg below and above must name a panel floating in another group below и above должны называть панель, плавающую в другой группе
|
||||
@msg give only one of onto, below and above укажите только один из onto, below и above
|
||||
@msg column must be true or a number from 1 column должен быть true или числом от 1
|
||||
@msg x and y must both be numbers x и y должны быть числами
|
||||
@msg "{0}" is not a colour: write it as #rrggbb «{0}» не является цветом: запишите его как #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead это не логотип из плоских цветов ({_1}% его сплошных областей совпадает с несколькими плоскими цветами), поэтому режим «Плоский логотип» превратил бы градиенты в пятна: используйте режим «Цвет»
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3305,6 +3305,7 @@ axis Horizontal Горизонтальна
|
|||
axis Vertical Вертикальна
|
||||
axis Both Обидві
|
||||
Drag to move Перетягніть для переміщення
|
||||
Drag to move out of the set Перетягніть, щоб винести з набору
|
||||
Drag to float as a toolbar Перетягніть, щоб від’єднати панель інструментів
|
||||
Put back in the toolbar Повернути на панель інструментів
|
||||
Float Panel Від’єднати панель
|
||||
|
|
@ -3856,6 +3857,9 @@ axis Both Обидві
|
|||
@msg tool (a tool id) is required потрібно tool (ідентифікатор інструменту)
|
||||
@msg {tool} isn't in a toolbar group of several tools {tool} не входить до групи панелі інструментів з кількох інструментів
|
||||
@msg onto must name a panel floating in another group onto має називати панель, що плаває в іншій групі
|
||||
@msg below and above must name a panel floating in another group below і above мають називати панель, що плаває в іншій групі
|
||||
@msg give only one of onto, below and above вкажіть лише один із onto, below і above
|
||||
@msg column must be true or a number from 1 column має бути true або числом від 1
|
||||
@msg x and y must both be numbers x і y мають бути числами
|
||||
@msg "{0}" is not a colour: write it as #rrggbb "{0}" не є кольором: запишіть його як #rrggbb
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead це не логотип із плоских кольорів ({_1}% його суцільних областей збігається з кількома плоскими кольорами), тому режим «Плоский логотип» перетворив би градієнти на плями: використовуйте режим «Колір»
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 13.
|
|
|
@ -3517,6 +3517,7 @@ axis Horizontal 水平
|
|||
axis Vertical 垂直
|
||||
axis Both 两者
|
||||
Drag to move 拖动以移动
|
||||
Drag to move out of the set 拖动以移出该组合
|
||||
Drag to float as a toolbar 拖动使其浮动为工具栏
|
||||
Put back in the toolbar 放回工具栏
|
||||
Float Panel 浮动面板
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
|
|
@ -3295,6 +3295,7 @@ axis Horizontal 水平
|
|||
axis Vertical 垂直
|
||||
axis Both 兩者
|
||||
Drag to move 拖曳以移動
|
||||
Drag to move out of the set 拖曳以移出該組合
|
||||
Drag to float as a toolbar 拖曳使其浮動為工具列
|
||||
Put back in the toolbar 放回工具列
|
||||
Float Panel 浮動面板
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -260,13 +260,13 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
|||
"window.panel.float",
|
||||
"Float Panel",
|
||||
"",
|
||||
"{panel: id or \"tools\", x?, y?, onto?: id, group?: bool} float a panel out of the dock (or out of its floating group) as its own floating group with its top-left corner at x, y in window points (default: cascaded), as dragging its tab out of the dock does; `onto` stacks it with the floating group holding that panel instead; `group` takes its whole group (its floating group, or the Properties | Layers | Libraries tabs left in the dock); a panel alone in its group is moved. \"tools\" floats the Tools panel. Returns {panel, floating, group, pos}",
|
||||
"{panel: id or \"tools\", x?, y?, onto?: id, below?: id, above?: id, group?: bool, collapsed?: bool} float a panel out of the dock (or out of its floating group) as its own floating group with its top-left corner at x, y in window points (default: cascaded), as dragging its tab out of the dock does; `onto` stacks it as a tab with the floating group holding that panel instead; `below` / `above` puts its group in a set with that group, right below or above it, as dropping it on that group's lower or upper half does (the set's groups stack top to bottom and move together); `group` takes its whole group (its floating group, or the Properties | Layers | Libraries tabs left in the dock); a panel alone in its group is moved (out of its set, given x, y); `collapsed` shows its group's tabs only, as a double-click on a tab does; a docked group floats its dock column. \"tools\" floats the Tools panel. Returns {panel, floating, group, set, pos, collapsed, column}",
|
||||
),
|
||||
(
|
||||
"window.panel.dock",
|
||||
"Dock Panel",
|
||||
"",
|
||||
"{panel: id or \"tools\", group?: bool} put a floating panel (with `group`, its whole group) back in the dock, as dropping it on the dock or its group's × does: Properties, Layers and Libraries in the tabbed group, the other panels in the icon column; \"tools\" docks the Tools panel at the window's left edge",
|
||||
"{panel: id or \"tools\", group?: bool, column?: true or n} put a floating panel (with `group`, its whole group) back in the dock, as dropping it on the dock or its group's × does: Properties, Layers and Libraries in the tabbed group, the other panels in the icon column; with `column`, dock its group and the rest of its set as a dock column instead, as dropping it on the left edge of the icon column or of a dock column does: `true` at the dock's left, n at that place (1: next to the icon column, counting left); \"tools\" docks the Tools panel at the window's left edge. Returns {panel, floating, column}",
|
||||
),
|
||||
(
|
||||
"window.collapseDock",
|
||||
|
|
@ -1126,6 +1126,7 @@ pub fn run_ui_command(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<R
|
|||
&& let Some(g) = crate::floating::group_of(&app.ui, p).and_then(|i| app.ui.floating_panels.get_mut(i))
|
||||
{
|
||||
g.active = g.panels.iter().position(|q| q == p).unwrap_or(g.active);
|
||||
g.collapsed = false;
|
||||
let out = json!({ "floating": g.panels });
|
||||
app.ui.dock = true;
|
||||
return Some(Ok(out));
|
||||
|
|
|
|||
|
|
@ -434,7 +434,12 @@ pub struct TaskBarPlace {
|
|||
}
|
||||
|
||||
/// A group of panels dragged out of the dock: it floats as a stack of tabs, one panel shown.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
///
|
||||
/// Groups sharing a `column` float as one set, stacked top to bottom in list order, like the panel
|
||||
/// groups of a dock in Illustrator's workspace
|
||||
/// (<https://helpx.adobe.com/illustrator/using/workspace-basics.html>): the set moves by the top
|
||||
/// group's title bar, and a group dragged by its tab strip leaves it.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FloatingPanels {
|
||||
/// Panel ids (`window.panel`), in tab order.
|
||||
pub panels: Vec<String>,
|
||||
|
|
@ -446,6 +451,17 @@ pub struct FloatingPanels {
|
|||
/// A width the group was given (the Tabs panel sized over its text), else its panels' own.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub width: Option<f32>,
|
||||
/// The set this group is stacked in with others (the same number), top to bottom in list
|
||||
/// order; none when it floats on its own.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub column: Option<u32>,
|
||||
/// Collapsed to its tabs (a double-click on a tab), its panel hidden.
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub collapsed: bool,
|
||||
/// Docked as a column of the dock (with the rest of its set) instead of floating: the columns
|
||||
/// stand left of the icon column, 1 next to it, counting left.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub docked: Option<u32>,
|
||||
}
|
||||
|
||||
impl FloatingPanels {
|
||||
|
|
@ -458,10 +474,45 @@ impl FloatingPanels {
|
|||
g.active = g.active.min(g.panels.len().saturating_sub(1));
|
||||
!g.panels.is_empty()
|
||||
});
|
||||
Self::tidy(groups);
|
||||
if toolbar_pos.is_some_and(|p| !p.iter().all(|v| v.is_finite())) {
|
||||
*toolbar_pos = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Keep each set's groups together in the list, after its first one and in the order they
|
||||
/// come, at its first one's position and in its dock column; a set left with one group floats
|
||||
/// (or stays docked) on its own; the dock columns are numbered 1, 2… without gaps.
|
||||
pub fn tidy(groups: &mut Vec<FloatingPanels>) {
|
||||
let mut out: Vec<FloatingPanels> = Vec::with_capacity(groups.len());
|
||||
for mut g in groups.drain(..) {
|
||||
match g.column.and_then(|c| out.iter().rposition(|o| o.column == Some(c))) {
|
||||
Some(i) => {
|
||||
if let Some(first) = out.iter().find(|o| o.column == g.column) {
|
||||
g.pos = first.pos;
|
||||
g.docked = first.docked;
|
||||
}
|
||||
out.insert(i + 1, g);
|
||||
}
|
||||
None => out.push(g),
|
||||
}
|
||||
}
|
||||
let alone: Vec<u32> = out.iter().filter_map(|g| g.column).filter(|c| out.iter().filter(|g| g.column == Some(*c)).count() < 2).collect();
|
||||
for g in &mut out {
|
||||
if g.column.is_some_and(|c| alone.contains(&c)) {
|
||||
g.column = None;
|
||||
}
|
||||
}
|
||||
let mut numbers: Vec<u32> = out.iter().filter_map(|g| g.docked).collect();
|
||||
numbers.sort_unstable();
|
||||
numbers.dedup();
|
||||
for g in &mut out {
|
||||
if let Some(d) = g.docked {
|
||||
g.docked = numbers.iter().position(|n| *n == d).and_then(|k| u32::try_from(k + 1).ok());
|
||||
}
|
||||
}
|
||||
*groups = out;
|
||||
}
|
||||
}
|
||||
|
||||
impl UiState {
|
||||
|
|
|
|||
|
|
@ -260,13 +260,26 @@ Floating panels: dragging a dock tab, a panel icon or a popped-out panel's title
|
|||
inside the window, and the strip right of the dock's tabs floats the whole Properties | Layers | Libraries group. A
|
||||
floating group moves by its title bar (or the strip right of its tabs); a tab dragged out of it floats on its own;
|
||||
dropped on another group's title bar or tabs it stacks with that group, and dropped on the dock (lit up while the
|
||||
pointer is over it) or closed with its × its panels go back to the tabbed group or the icon column.
|
||||
`window.panel.float {panel, x?, y?, onto?, group?}` floats a panel (with `group`, its whole group) with its top-left
|
||||
corner at `x`, `y` (window points; default cascaded), or stacks it with the floating group holding `onto`;
|
||||
`window.panel.dock {panel, group?}` puts it back. `panel` takes the `window.panel` ids and labels, and `"tools"` for
|
||||
pointer is over it) or closed with its × its panels go back to the tabbed group or the icon column. Dropped on the upper or
|
||||
lower half of another group, floating or docked (a line shows where), a group joins it in a set right above or below
|
||||
it: the groups stack top to bottom, each
|
||||
showing one of its panels, and move together by the top group's title bar, whose × docks them all; a group dragged by
|
||||
its tab strip (a lone panel's tab or the strip right of the tabs) leaves the set. A double-click on a tab collapses a
|
||||
group to its tabs, and another expands it. Dropped on the left edge of the icon column or of a dock column, a set
|
||||
docks as a new dock column there: its groups stack in it as in a floating set, take groups dropped on their edges and
|
||||
tabs, and leave it dragged by their tab strip; the strip along the column's top floats the whole column again, and
|
||||
its × puts its panels back where they live.
|
||||
`window.panel.float {panel, x?, y?, onto?, below?, above?, group?, collapsed?}` floats a panel (with `group`, its whole
|
||||
group) with its top-left corner at `x`, `y` (window points; default cascaded), or stacks it as a tab with the floating
|
||||
group holding `onto`, or puts its group in a set right `below` or `above` the group holding that panel; `collapsed`
|
||||
collapses or expands its group;
|
||||
`window.panel.dock {panel, group?, column?}` puts it back, or with `column` (`true`, or the place: 1 next to the icon
|
||||
column, counting left) docks its group and set as a dock column; `window.panel.float` on a docked panel floats its
|
||||
column. `panel` takes the `window.panel` ids and labels, and `"tools"` for
|
||||
the Tools panel, which floats by its title bar and docks on the window's left edge. `window.panel` on a floating
|
||||
panel shows its tab. `ui.floating_panels` in `ui.inspect` lists the groups (panel ids, the index of the tab shown,
|
||||
the top-left corner) and `ui.toolbar_pos` the Tools panel's corner (null: docked); both are saved with the
|
||||
panel shows its tab (expanding its group). `ui.floating_panels` in `ui.inspect` lists the groups (panel ids, the
|
||||
index of the tab shown, the top-left corner, `column`: the set it is stacked in, top to bottom in list order,
|
||||
`collapsed`, and `docked`: the dock column it stands in) and `ui.toolbar_pos` the Tools panel's corner (null: docked); both are saved with the
|
||||
preferences and in user workspaces (the built-in workspaces dock everything), and a corner saved on a bigger window
|
||||
is clamped into this one when drawn. Floating panels stay inside the app window (no separate OS windows).
|
||||
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
|||
- Hint bar, contextual task bar, 19 dock panels with ≡ menus.
|
||||
- The contextual task bar's handle drags it anywhere on the canvas (kept whole on it as the window resizes); unpinned it keeps that offset as it follows the selection, and its More Options menu hides it, pins its position across selection changes (`window.taskBar.pin`), resets it under the selection (`window.taskBar.reset`) and shows the Properties panel. As in Illustrator the position isn't kept across launches. Not done: the bar's tool-specific variants (only the selection tools show it).
|
||||
- Tool flyouts tear off: dragging or clicking the tear-off bar on a flyout's right side (or releasing the long press over it) floats its group as a strip of tool buttons, moved by the same bar and put back in the toolbar by the × at its top (`window.floatTools`). While a group floats, the presses that would open its flyout raise the strip instead. Floating strips are kept with the preferences and in user workspaces. Not done: turning a strip vertical, docking it.
|
||||
- Panels undock (#495): a dock tab, a panel icon or a popped-out panel's title dragged out of the dock floats that panel inside the window, and the strip right of the dock's tabs floats the whole tabbed group. A floating group moves by its title bar, a tab dragged out of it floats on its own, and dropped on another group's title bar or tabs it stacks with that group; dropped on the dock, which lights up under the pointer, its panels go back where they live (the tabbed group or the icon column), as its × and the panel menus' Float Panel / Dock Panel do (`window.panel.float`, `window.panel.dock`). The Tools panel floats by its title bar and docks again on the window's left edge. Floating panels and the Tools panel's position are kept with the preferences and in user workspaces, and clamped into a smaller window. Not done: panels in separate OS windows, docking a panel into a dock group it doesn't belong to, reordering tabs by dragging, collapsing a floating group to icons, resizing floating panels.
|
||||
- Panels undock (#495): a dock tab, a panel icon or a popped-out panel's title dragged out of the dock floats that panel inside the window, and the strip right of the dock's tabs floats the whole tabbed group. A floating group moves by its title bar, a tab dragged out of it floats on its own, and dropped on another group's title bar or tabs it stacks with that group; dropped on the dock, which lights up under the pointer, its panels go back where they live (the tabbed group or the icon column), as its × and the panel menus' Float Panel / Dock Panel do (`window.panel.float`, `window.panel.dock`). The Tools panel floats by its title bar and docks again on the window's left edge. Floating groups stack into sets: dropped on the upper or lower half of another group (a line shows where), a group joins it right above or below it, and the set's groups stack top to bottom, each showing one panel, moving together by the top group's title bar, whose × docks them all; a group dragged by its tab strip leaves the set (`window.panel.float {below, above}`). A double-click on a tab collapses a floating group to its tabs (`collapsed`). Sets dropped on the left edge of the icon column or of another dock column dock as dock columns (a multi-column dock, `window.panel.dock {column}`), whose groups stack, tab and tear out as a floating set's do, and whose top strip floats the column again. Floating panels, their sets and the Tools panel's position are kept with the preferences and in user workspaces, and clamped into a smaller window. Not done: panels in separate OS windows, docking a panel into the default tabbed group it doesn't belong to, reordering tabs by dragging, collapsing a set or dock column to icons, dock columns right of the default dock, resizing floating panels and the groups of a set.
|
||||
- The dock's double arrow collapses Properties, Layers and Libraries to icons at the top of the icon column, popping out like the other icon panels, and expands them again (`window.collapseDock`, kept with the preferences and in saved workspaces). The icon column's own arrow (expanding the icon panels into a full column) is not done.
|
||||
- Localised UI: menus (in-window and native), panels, dialogs, toolbar and Preferences read from per-language catalogs (`crates/ui-egui/src/i18n`, see `docs/development.md`); Traditional Chinese (Taiwan), Simplified Chinese (mainland), Japanese, German, Spanish, French, Italian, Russian and Ukrainian ship complete, and Czech and Brazilian Portuguese cover every menu label (and more), with system-locale detection on macOS, Windows, Linux and the web (the browser's languages, or `?lang=`), a Language preference and, on macOS, a VectorCraft ▸ Language menu. Names are never translated (fonts and their styles, layers, artboards, saved presets, user libraries, custom workspaces, recent files, plug-ins).
|
||||
- Native macOS menu bar, vector tool cursors, a ⌘K command palette, middle-button panning with any tool. Native menus explicitly end tracking on command selection, outside window presses and Escape; menu updates wait until tracking ends, and a dismissing press never starts a canvas gesture (M14.8).
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ Layers panel.
|
|||
|---|---|---|
|
||||
| ~40 panels with ≡ menus; dock, icon column, collapse, tabs | done | 51 panel modules incl. tests |
|
||||
| Panels float inside the window, stack, dock back | done | #495 |
|
||||
| Floating groups stack into sets; sets dock as extra dock columns (a multi-column dock); groups drop anywhere in a set or column, or onto its tabs; a column taller than the window scrolls | done | `window.panel.float {below, above}`, `window.panel.dock {column}` |
|
||||
| Panels outside the app window (another monitor) | missing | single OS window |
|
||||
| Properties panel per context (every selection type's Quick Actions) | partial | |
|
||||
| Contextual task bar | done | |
|
||||
|
|
|
|||
Loading…
Reference in New Issue