refactor(editor): restore widget boundary invariants
This commit is contained in:
parent
c6ceca8999
commit
0ffbf4f77e
31
crates/op-editor-ui/src/font_catalog.rs
Normal file
31
crates/op-editor-ui/src/font_catalog.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//! Shared font-family catalog used by typography widgets and hosts.
|
||||
|
||||
/// TS `BUNDLED_FAMILIES` (use-system-fonts.ts:9-21).
|
||||
pub const BUNDLED_FONT_FAMILIES: [&str; 11] = [
|
||||
"Inter",
|
||||
"Poppins",
|
||||
"Roboto",
|
||||
"Montserrat",
|
||||
"Open Sans",
|
||||
"Lato",
|
||||
"Raleway",
|
||||
"DM Sans",
|
||||
"Playfair Display",
|
||||
"Nunito",
|
||||
"Source Sans 3",
|
||||
];
|
||||
|
||||
/// TS `FALLBACK_SYSTEM_FONTS` (use-system-fonts.ts:24-36).
|
||||
pub const FALLBACK_SYSTEM_FONTS: [&str; 11] = [
|
||||
"Arial",
|
||||
"Helvetica",
|
||||
"Helvetica Neue",
|
||||
"Georgia",
|
||||
"Times New Roman",
|
||||
"Courier New",
|
||||
"Verdana",
|
||||
"Trebuchet MS",
|
||||
"Tahoma",
|
||||
"Impact",
|
||||
"Comic Sans MS",
|
||||
];
|
||||
|
|
@ -31,6 +31,7 @@ pub use op_i18n as i18n;
|
|||
pub use op_editor_core::render_backend;
|
||||
|
||||
pub mod accessibility;
|
||||
pub mod font_catalog;
|
||||
pub mod layout_scene;
|
||||
pub mod layout_scene_hit;
|
||||
pub mod scene_vars;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub mod property_panel_visibility;
|
|||
pub mod property_panel_widget;
|
||||
#[cfg(test)]
|
||||
mod property_panel_widget_tests;
|
||||
pub mod text_input;
|
||||
mod text_selection;
|
||||
pub mod toolbar;
|
||||
|
||||
|
|
@ -223,6 +224,7 @@ pub mod variables_panel;
|
|||
mod variables_preset_menu;
|
||||
|
||||
pub use prop_row::PropertyRow;
|
||||
pub use text_input::TextInputWidget;
|
||||
pub use tree::{TreeItem, TreeWidget};
|
||||
|
||||
pub use layer_panel::{LayerItem, LayerPanel};
|
||||
|
|
|
|||
|
|
@ -28,36 +28,7 @@ use crate::widgets::PaintCx;
|
|||
use crate::{Point2D, Rect, TextLayout};
|
||||
use jian_widgets::components::select::{SelectHit, SelectState};
|
||||
|
||||
/// TS `BUNDLED_FAMILIES` (use-system-fonts.ts:9-21).
|
||||
pub const BUNDLED_FONT_FAMILIES: [&str; 11] = [
|
||||
"Inter",
|
||||
"Poppins",
|
||||
"Roboto",
|
||||
"Montserrat",
|
||||
"Open Sans",
|
||||
"Lato",
|
||||
"Raleway",
|
||||
"DM Sans",
|
||||
"Playfair Display",
|
||||
"Nunito",
|
||||
"Source Sans 3",
|
||||
];
|
||||
|
||||
/// TS `FALLBACK_SYSTEM_FONTS` (use-system-fonts.ts:24-36) — shown
|
||||
/// when no host enumeration is available (wasm host).
|
||||
pub const FALLBACK_SYSTEM_FONTS: [&str; 11] = [
|
||||
"Arial",
|
||||
"Helvetica",
|
||||
"Helvetica Neue",
|
||||
"Georgia",
|
||||
"Times New Roman",
|
||||
"Courier New",
|
||||
"Verdana",
|
||||
"Trebuchet MS",
|
||||
"Tahoma",
|
||||
"Impact",
|
||||
"Comic Sans MS",
|
||||
];
|
||||
pub use crate::font_catalog::{BUNDLED_FONT_FAMILIES, FALLBACK_SYSTEM_FONTS};
|
||||
|
||||
/// One selectable row (TS `FontInfo`).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
|
|||
93
crates/op-editor-ui/src/widgets/text_input.rs
Normal file
93
crates/op-editor-ui/src/widgets/text_input.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
//! OP widget facade for Jian's reusable single-line text input view.
|
||||
|
||||
use super::{LayoutBox, LayoutCx, PaintCx, Widget, WidgetId};
|
||||
use crate::{Point2D, Rect};
|
||||
use jian_core::text_input::TextInputState;
|
||||
use jian_widgets::components::text_input::TextInputView;
|
||||
use jian_widgets::Tokens;
|
||||
|
||||
const DEFAULT_WIDTH: f32 = 160.0;
|
||||
const DEFAULT_HEIGHT: f32 = 30.0;
|
||||
|
||||
pub struct TextInputWidget {
|
||||
pub id: WidgetId,
|
||||
pub state: TextInputState,
|
||||
pub placeholder: String,
|
||||
pub focused: bool,
|
||||
pub font_size: f32,
|
||||
pub now_ms: u64,
|
||||
pub pad_x: f32,
|
||||
pub tokens: Tokens,
|
||||
}
|
||||
|
||||
impl TextInputWidget {
|
||||
pub fn new(id: u64, state: TextInputState) -> Self {
|
||||
Self {
|
||||
id: WidgetId::new(id),
|
||||
state,
|
||||
placeholder: String::new(),
|
||||
focused: false,
|
||||
font_size: 13.0,
|
||||
now_ms: 0,
|
||||
pad_x: 8.0,
|
||||
tokens: Tokens::dark(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_placeholder(mut self, placeholder: impl Into<String>) -> Self {
|
||||
self.placeholder = placeholder.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for TextInputWidget {
|
||||
fn id(&self) -> WidgetId {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn layout(&self, cx: &LayoutCx) -> LayoutBox {
|
||||
LayoutBox {
|
||||
rect: Rect {
|
||||
origin: Point2D::new(0.0, 0.0),
|
||||
size: Point2D::new(cx.available_width.max(DEFAULT_WIDTH), DEFAULT_HEIGHT),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn paint(&self, cx: &mut PaintCx<'_>, rect: Rect) {
|
||||
let view = TextInputView {
|
||||
state: &self.state,
|
||||
placeholder: &self.placeholder,
|
||||
focused: self.focused,
|
||||
font_size: self.font_size,
|
||||
now_ms: self.now_ms,
|
||||
pad_x: self.pad_x,
|
||||
};
|
||||
view.paint(cx.backend, rect, &self.tokens);
|
||||
}
|
||||
|
||||
fn access_node(&self) -> accesskit::Node {
|
||||
let mut node = accesskit::Node::new(accesskit::Role::TextInput);
|
||||
let label = if self.placeholder.is_empty() {
|
||||
self.state.text()
|
||||
} else {
|
||||
&self.placeholder
|
||||
};
|
||||
node.set_label(label);
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn exposes_text_input_access_role() {
|
||||
let widget = TextInputWidget::new(401, TextInputState::with_text("hello"));
|
||||
|
||||
let node = widget.access_node();
|
||||
|
||||
assert_eq!(node.role(), accesskit::Role::TextInput);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,8 @@
|
|||
//! (`op_editor_ui::widgets::property_panel_typography`).
|
||||
|
||||
use super::WidgetHostNative;
|
||||
use op_editor_ui::widgets::property_panel_typography::{
|
||||
font_picker_entries, BUNDLED_FONT_FAMILIES,
|
||||
};
|
||||
use op_editor_ui::font_catalog::BUNDLED_FONT_FAMILIES;
|
||||
use op_editor_ui::widgets::property_panel_typography::font_picker_entries;
|
||||
use op_editor_ui::widgets::{PropertyPanel, TOP_BAR_HEIGHT};
|
||||
use op_editor_ui::{Point2D, Rect};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::repaint_ctx::RepaintContext;
|
|||
use jian_ops_schema::node::{PenNode, TextContent};
|
||||
use js_sys::{Array, Function, Promise, Reflect, Uint8Array};
|
||||
use op_editor_core::pen_node_ext::PenNodeExt;
|
||||
use op_editor_ui::widgets::property_panel_typography::BUNDLED_FONT_FAMILIES;
|
||||
use op_editor_ui::font_catalog::BUNDLED_FONT_FAMILIES;
|
||||
use wasm_bindgen::closure::Closure;
|
||||
use wasm_bindgen::{JsCast, JsValue};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use op_editor_ui::widgets::property_panel_typography::BUNDLED_FONT_FAMILIES;
|
||||
use op_editor_ui::font_catalog::BUNDLED_FONT_FAMILIES;
|
||||
|
||||
use super::WidgetHost;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue