Add icons for text alignment/justification

This commit is contained in:
Keavon Chambers 2026-05-06 19:26:26 -07:00
parent c0a8241f50
commit 2ae35a67e7
5 changed files with 45 additions and 83 deletions

View File

@ -1,2 +1,2 @@
https://github.com/Keavon/graphite-branded-assets/archive/1509880500e32cb21235343ba865adcf0579133f.tar.gz https://github.com/Keavon/graphite-branded-assets/archive/b83626b10f0f9102503c845354e9e3f161949ce0.tar.gz
89b4c58aee186b0c1610a8778bd199c9bdaf1191b4006e6b007dc40a402f4aa7 353e9cba90f420b11863055a32e554937638b47d1539632ef0e8a30f37a353d7

View File

@ -17,6 +17,7 @@ use crate::messages::tool::common_functionality::utility_functions::text_boundin
use crate::messages::tool::utility_types::ToolRefreshOptions; use crate::messages::tool::utility_types::ToolRefreshOptions;
use graph_craft::document::value::TaggedValue; use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput}; use graph_craft::document::{NodeId, NodeInput};
use graphene_std::choice_type::ChoiceTypeStatic;
use graphene_std::renderer::Quad; use graphene_std::renderer::Quad;
use graphene_std::text::{Font, FontCache, TextAlign, TypesettingConfig, lines_clipping}; use graphene_std::text::{Font, FontCache, TextAlign, TypesettingConfig, lines_clipping};
use graphene_std::vector::style::Fill; use graphene_std::vector::style::Fill;
@ -204,25 +205,23 @@ fn create_text_widgets(tool: &TextTool, font_catalog: &FontCatalog) -> Vec<Widge
.into() .into()
}) })
.widget_instance(); .widget_instance();
let align_entries: Vec<_> = [ let align_entries: Vec<_> = TextAlign::list()
TextAlign::AlignLeft, .iter()
TextAlign::AlignCenter, .flat_map(|section| section.iter())
TextAlign::AlignRight, .map(|(item, var_meta)| {
TextAlign::JustifyLeft, let align = *item;
TextAlign::JustifyCenter, let entry = RadioEntryData::new(var_meta.name)
TextAlign::JustifyRight, .tooltip_label(var_meta.label)
TextAlign::JustifyAll, .tooltip_description(var_meta.description.unwrap_or_default())
] .on_update(move |_| {
.into_iter() TextToolMessage::UpdateOptions {
.map(|align| { options: TextOptionsUpdate::Align(align),
RadioEntryData::new(format!("{align:?}")).label(align.to_string()).on_update(move |_| { }
TextToolMessage::UpdateOptions { .into()
options: TextOptionsUpdate::Align(align), });
} if let Some(icon) = var_meta.icon { entry.icon(icon) } else { entry.label(var_meta.label) }
.into()
}) })
}) .collect();
.collect();
let align = RadioInput::new(align_entries).selected_index(Some(tool.options.align as u32)).widget_instance(); let align = RadioInput::new(align_entries).selected_index(Some(tool.options.align as u32)).widget_instance();
vec![ vec![
font, font,
@ -232,7 +231,7 @@ fn create_text_widgets(tool: &TextTool, font_catalog: &FontCatalog) -> Vec<Widge
size, size,
Separator::new(SeparatorStyle::Related).widget_instance(), Separator::new(SeparatorStyle::Related).widget_instance(),
line_height_ratio, line_height_ratio,
Separator::new(SeparatorStyle::Related).widget_instance(), Separator::new(SeparatorStyle::Unrelated).widget_instance(),
align, align,
] ]
} }

View File

@ -199,6 +199,15 @@ import StackLower from "/../branding/assets/icon-16px-solid/stack-lower.svg";
import StackRaise from "/../branding/assets/icon-16px-solid/stack-raise.svg"; import StackRaise from "/../branding/assets/icon-16px-solid/stack-raise.svg";
import StackReverse from "/../branding/assets/icon-16px-solid/stack-reverse.svg"; import StackReverse from "/../branding/assets/icon-16px-solid/stack-reverse.svg";
import Stack from "/../branding/assets/icon-16px-solid/stack.svg"; import Stack from "/../branding/assets/icon-16px-solid/stack.svg";
import TextAlignCenter from "/../branding/assets/icon-16px-solid/text-align-center.svg";
import TextAlignLeft from "/../branding/assets/icon-16px-solid/text-align-left.svg";
import TextAlignRight from "/../branding/assets/icon-16px-solid/text-align-right.svg";
import TextAlignSpineAway from "/../branding/assets/icon-16px-solid/text-align-spine-away.svg";
import TextAlignSpineTowards from "/../branding/assets/icon-16px-solid/text-align-spine-towards.svg";
import TextJustifyAll from "/../branding/assets/icon-16px-solid/text-justify-all.svg";
import TextJustifyCenter from "/../branding/assets/icon-16px-solid/text-justify-center.svg";
import TextJustifyLeft from "/../branding/assets/icon-16px-solid/text-justify-left.svg";
import TextJustifyRight from "/../branding/assets/icon-16px-solid/text-justify-right.svg";
import TiltReset from "/../branding/assets/icon-16px-solid/tilt-reset.svg"; import TiltReset from "/../branding/assets/icon-16px-solid/tilt-reset.svg";
import Tilt from "/../branding/assets/icon-16px-solid/tilt.svg"; import Tilt from "/../branding/assets/icon-16px-solid/tilt.svg";
import TransformationGrab from "/../branding/assets/icon-16px-solid/transformation-grab.svg"; import TransformationGrab from "/../branding/assets/icon-16px-solid/transformation-grab.svg";
@ -318,6 +327,15 @@ const SOLID_16PX = {
StackLower: { svg: StackLower, size: 16 }, StackLower: { svg: StackLower, size: 16 },
StackRaise: { svg: StackRaise, size: 16 }, StackRaise: { svg: StackRaise, size: 16 },
StackReverse: { svg: StackReverse, size: 16 }, StackReverse: { svg: StackReverse, size: 16 },
TextAlignCenter: { svg: TextAlignCenter, size: 16 },
TextAlignLeft: { svg: TextAlignLeft, size: 16 },
TextAlignRight: { svg: TextAlignRight, size: 16 },
TextAlignSpineAway: { svg: TextAlignSpineAway, size: 16 },
TextAlignSpineTowards: { svg: TextAlignSpineTowards, size: 16 },
TextJustifyAll: { svg: TextJustifyAll, size: 16 },
TextJustifyCenter: { svg: TextJustifyCenter, size: 16 },
TextJustifyLeft: { svg: TextJustifyLeft, size: 16 },
TextJustifyRight: { svg: TextJustifyRight, size: 16 },
Tilt: { svg: Tilt, size: 16 }, Tilt: { svg: Tilt, size: 16 },
TiltReset: { svg: TiltReset, size: 16 }, TiltReset: { svg: TiltReset, size: 16 },
TransformationGrab: { svg: TransformationGrab, size: 16 }, TransformationGrab: { svg: TransformationGrab, size: 16 },

View File

@ -1,62 +0,0 @@
mod font_cache;
mod path_builder;
mod text_context;
mod to_path;
use dyn_any::DynAny;
pub use font_cache::*;
pub use text_context::TextContext;
pub use to_path::*;
/// Alignment of lines of type within a text block.
#[repr(C)]
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, DynAny, node_macro::ChoiceType)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[widget(Radio)]
pub enum TextAlign {
#[default]
Left,
Center,
Right,
#[label("Justify")]
JustifyLeft,
// TODO: JustifyCenter, JustifyRight, JustifyAll
}
impl From<TextAlign> for parley::Alignment {
fn from(val: TextAlign) -> Self {
match val {
TextAlign::Left => parley::Alignment::Left,
TextAlign::Center => parley::Alignment::Center,
TextAlign::Right => parley::Alignment::Right,
TextAlign::JustifyLeft => parley::Alignment::Justify,
}
}
}
#[derive(PartialEq, Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TypesettingConfig {
pub font_size: f64,
pub line_height_ratio: f64,
pub character_spacing: f64,
pub max_width: Option<f64>,
pub max_height: Option<f64>,
pub tilt: f64,
pub align: TextAlign,
}
impl Default for TypesettingConfig {
fn default() -> Self {
Self {
font_size: 24.,
line_height_ratio: 1.2,
character_spacing: 0.,
max_width: None,
max_height: None,
tilt: 0.,
align: TextAlign::default(),
}
}
}

View File

@ -31,12 +31,19 @@ pub use vector_types;
#[widget(Radio)] #[widget(Radio)]
pub enum TextAlign { pub enum TextAlign {
#[default] #[default]
#[icon("TextAlignLeft")]
AlignLeft, AlignLeft,
#[icon("TextAlignCenter")]
AlignCenter, AlignCenter,
#[icon("TextAlignRight")]
AlignRight, AlignRight,
#[icon("TextJustifyLeft")]
JustifyLeft, JustifyLeft,
#[icon("TextJustifyCenter")]
JustifyCenter, JustifyCenter,
#[icon("TextJustifyRight")]
JustifyRight, JustifyRight,
#[icon("TextJustifyAll")]
JustifyAll, JustifyAll,
} }