Multi-Selection — Move, Scale, Rotate & Parameter Bar
TYP-440 TYP-444 TYP-445 and more
Group bounding box overlay with corner scale handles and rotate zones for multi-selected elements
MultiMoveHandler, MultiScaleHandler, MultiRotateHandler for drag operations across all selected elements
Snap and alignment to guides and other elements during multi-move using a PageElementTemp proxy
Parameter bar for multi-selection: shows position and size of the enclosing bounding box, with lock and rotate controls
setParameters() routes to multi_info when more than one element is selected
Cmd+C / Cmd+V keyboard shortcuts fixed for non-rich-text and multi-selection contexts
Individual elements in a multi-selection display a frame outline instead of full selection handles
Linked Text Frame Overflow — Link Mode UI
Click-release-click interaction to connect two text frames via the overflow out-port icon
ESC cancels an active link operation cleanly via cancel_link_mode()
Link cursor shown correctly throughout the rubber-band phase
Out-port icon hit detection prioritised above scale handles in mouse_move and mouse_down so the link cursor and click handler are not intercepted by resize logic
Updated overflow icon hit area for easier clicking
Linked Text Frame Overflow — Cross-Frame Text Editing
Text input (typing, Enter, Backspace, Delete, Tab) in any overflow frame is routed through the root (canonical) editor; reflow distributes text to downstream frames
ArrowRight / ArrowDown at the end of a frame advances the cursor and focus to the next linked frame
ArrowLeft / ArrowUp at the start of a frame moves the cursor and focus to the previous frame, placed at the end of its visible text
Backspace at the start of an overflow frame deletes the last character of the previous frame and returns focus there
When typing causes a word to overflow into the next frame, the cursor follows automatically and is placed after the typed character — not at the frame start
When deletion causes text to reflow back into the previous frame, focus and cursor transfer back to the correct position
All of the above work in chains of three or more linked frames
The green focus ring tracks the currently active frame in the chain
Cursor y-position, overflow split point, and focus detection all use a consistent line-clipping formula matching the draw loop
Image Handling
Path editing: Double-clicking a PageElementImage that has native paths opens the PolyEditor for editing the image path directly
Image content box: The content box (closed hand cursor) is shown immediately on mousedown, not only after a drag begins
Rotate: Image content can be rotated via a dedicated rotate handler
Edge scale controls: Top, bottom, left and right edge handles added to the image content scale controls (in addition to corners)
Parameter bar numeric updates for PageElementPoly and PageElementImage
Menu & Keyboard Shortcuts
Cut: Cmd+X wired up with DoCut implementation
Arrange: Cmd+] / Cmd+[ (Bring Forward / Send Backward), Ctrl+Cmd+] / Ctrl+Cmd+[ (Bring to Front / Send to Back)
Group / Ungroup: Cmd+G / Shift+Cmd+G
Guides: Cmd+;
Frames: Ctrl+Cmd+H
Step & Repeat: Cmd+U
Fixed Cmd+A missing redraw() call
Fixed Bring to Front always-active state bug
Tab Ruler Palette
New floating TabPalette with drag bar, tab-type buttons (left / center / right / character), and inputs for X position, leader, and align-on character
Ruler canvas with tick marks, tab stop icons, click and drag to add, move and delete stops; magnet snap; horizontal resize handle
Undo / redo support for tab stop changes
Palette auto-shows when entering rich text edit mode if previously visible; hides on exit
Keyboard shortcut: Ctrl+Cmd+T
Show / Hide Tab Ruler item in the View menu with dynamic title
Tab stops copied to new paragraph on Enter
Minimum palette width 440 px; positions relative to the active element using canvas getBoundingClientRect
Images Content Bar
Images loaded from get_manifest.php when no document manifest or callback is set; PHP scans userdata/images/ and returns a manifest applied via set_manifest_data()
URL-encoding added for folder and file names containing special characters (e.g. #)
Search input filters asset tiles by name (case-insensitive), wired after loadimages() for both manifest and callback paths
Rich Text — Toolbar & Font Styles
Regular toolbar shown when a rich text element is selected; text toolbar shown only when the element is in edit (focus) mode
Font styles popup now populated correctly for PageElementRichText — previously showed empty list on open
Entering edit mode via double-click triggers set_active_object() so the toolbar switches to text mode immediately
Swatch & Color System
Text color in text mode: Swatch panel and color controls apply to text fill/stroke when the rich text editor has focus; apply to element fill/stroke when selected but not in focus
Selection-aware text color: With a text selection active, the chosen swatch is applied only to the selected character runs; without a selection it applies to the whole element
Single undo per swatch session: The show() / hide() pair of the swatch panel owns one undo record for the entire color-picking session
Gradient handles: Draggable start / end handles with dashed connecting line drawn on canvas for elements with gradient fill; tracks element rotation; parameter bar shows X, Y, length and angle
Gradient stop swatches: New stops created by interpolation are scoped to the dialog (local_swatches) and only transferred to the global library on OK — cancelled sessions leave the library clean
Shadow swatch sync: Shadow mode pre-selects the shadow swatch, applies changes to shadow (not fill), and syncs the shadow switch UI; shadow angle change triggers redraw and is undoable
Bug Fixes & Backend
Clips and assets list reloads fully on every refresh (was skipping reload when already populated)
PHP get_* scripts use a shared userdata path instead of per-session user paths
reflow_from() now triggers a redraw for standalone text frames (no overflow chain) — typing was silently not updating the canvas