Continues the gradient + property-panel polish from the previous commit and rounds out two new flows the TS app already has: Gradient stops + effects: - ColorTarget gains GradientStop(i) + EffectColor(i); HSV picker preserves alpha across hue/SV drags so a transparent stop stays transparent. Hex pill stays 6-char; alpha is reattached at commit and the swatch sits on a 2x2 alpha checker so #00000000 reads as transparent rather than empty. - Effects section reflowed into card-style blocks (image #9 spec): title + minus, X/Y and Blur/Spread 2-col grids, color row with swatch + rgba(...) text; clicking the swatch opens an HSV picker bound to that effect index via SetEffectColor. - Press dispatch on both hosts anchors picker overlays at the clicked y so they pop adjacent to the swatch instead of the top. Image + SVG import (toolbar + Fill section "图片" row): - New FileAction::ImportImageOrSvg / PickFillImage; persistence_image pops rfd, decodes raster as data: URL, inserts an Image node or rewrites the selected node's primary fill. - ImageNode actually renders on the canvas: NodePayload + SceneNode carry image_src, canvas_viewport_paint.rs decodes the data URL once and hands raw bytes to RenderBackend::draw_image with a src-hash cache id. Grey placeholder paints only when decode fails so transparent PNGs don't get a grey matte underneath. - SVG import ported to TS-parity (packages/pen-engine svg-parser): recursive <g> tree walk with inherited fill/stroke/style="...", viewBox-aware scaling with maxDim cap, multi-subpath split, raw d preserved on PathNode. Imports land wrapped in a Group named after the source file. Locale-aware first run: - settings_io detects the OS locale (LC_ALL/LANG/LC_MESSAGES with zh-Hans/zh-Hant heuristics) and seeds editor_ui.locale before settings.json is read; persisted user choice still wins. - macOS bundle declares CFBundleLocalizations + AllowMixedLocalizations so NSOpenPanel / NSSavePanel render in the same language as the rest of the chrome. Web host kept exhaustive across the new variants (PickFillImage, OpenEffectColorPicker, ColorTarget::EffectColor, GradientStop). Two new files: persistence_image.rs (file-pick handlers, ≤120 lines) and svg_path_data.rs (path-d tokenizer + bbox + normaliser, split from svg_import.rs to stay under the 800-line cap). 277 op-editor-core tests pass.
34 lines
1.2 KiB
TOML
34 lines
1.2 KiB
TOML
[package]
|
|
name = "op-editor-ui"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
description = "OpenPencil editor UI — platform-agnostic widget facade + theme + layout-resolved render scene"
|
|
|
|
[lib]
|
|
name = "op_editor_ui"
|
|
path = "src/lib.rs"
|
|
|
|
[dependencies]
|
|
# Widget facade internals: glam Vec2 as Point2D, bitflags for flags.
|
|
glam = { version = "0.29", default-features = false, features = ["std"] }
|
|
bitflags = "2"
|
|
# Every Widget exposes an `accesskit::Node` so the host can build a
|
|
# unified accessibility tree. Pinned to 0.24 to match the hosts.
|
|
accesskit = "0.24"
|
|
|
|
# Canonical jian render/gesture types + the .op document schema.
|
|
jian-core = { path = "../../vendor/jian/crates/jian-core", version = "0.0.1" }
|
|
jian-ops-schema = { path = "../../vendor/jian/crates/jian-ops-schema" }
|
|
|
|
# i18n string tables + the canonical editor state model.
|
|
op-i18n = { path = "../op-i18n" }
|
|
op-editor-core = { path = "../op-editor-core" }
|
|
|
|
# Decode `data:image/...;base64,...` URLs in the canvas painter so a
|
|
# pasted / picked image lands on the canvas instead of the grey
|
|
# placeholder. Workspace pinned via the same `base64` op-host-desktop
|
|
# uses for the file picker.
|
|
base64 = "0.22"
|