Skip to content

Commit

Permalink
first pass texbox styling done
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelselleck authored and zackbrown committed Feb 28, 2024
1 parent 3ab0e3f commit adb16d3
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 42 deletions.
13 changes: 10 additions & 3 deletions examples/src/playground/src/lib.pax
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
align_multiline: TextAlignHorizontal::Center
}
/>
<Textbox y=70% anchor_y=50% x=100px width=50% height=30px text={self.textbox_text} @textbox_change=self.textbox_change/>
<Textbox id=text
background={Color::rgba(0.0, 1.0, 0.0, 1.0)}
border_radius=100.0
stroke={
color: {Color::rgba(1.0, 0.0, 1.0, 1.0)}
width: 10px
}
y=70% anchor_y=50% x=100px width=50% height=30px text={self.textbox_text} @textbox_input=self.textbox_input/>
<Checkbox class=small y=50% anchor_y=50% x={50% - 100px} anchor_x=100% checked={self.checked} @checkbox_change=self.checkbox_change/>

<Image class=small class=centered path="assets/images/pax-logo-light.png"/>
Expand Down Expand Up @@ -43,10 +50,10 @@
style: {
font: {Font::system("Times New Roman", FontStyle::Normal, FontWeight::Bold)},
font_size: 32px,
fill: {Color::rgba(1.0, 1.0, 1.0, 1.0)},
fill: {Color::rgba(1.0, 0.0, 1.0, 1.0)},
align_vertical: TextAlignVertical::Center,
align_horizontal: TextAlignHorizontal::Center,
align_multiline: TextAlignHorizontal::Center
}
}
}
}
2 changes: 1 addition & 1 deletion examples/src/playground/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl Example {
}
}

pub fn textbox_change(&mut self, ctx: &NodeContext, args: ArgsTextboxChange) {
pub fn textbox_input(&mut self, ctx: &NodeContext, args: ArgsTextboxInput) {
self.textbox_text.set(args.text);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
import {ObjectManager} from "../../pools/object-manager";
import { TEXT_STYLE } from "../../pools/supported-objects";
import { TextStyle } from "../text";

export class TextboxUpdatePatch {
public id_chain?: number[];
public size_x?: number;
public size_y?: number;
public stroke_width?: number;
public stroke_color?: ColorGroup;
public background?: ColorGroup;
public border_radius: number;
public transform?: number[];
public text?: string;
objectManager: ObjectManager;
public style?: TextStyle;

constructor(objectManager: ObjectManager) {
this.objectManager = objectManager;
}

fromPatch(jsonMessage: any) {
fromPatch(jsonMessage: any, registeredFontFaces: Set<string>) {
this.id_chain = jsonMessage["id_chain"];
this.size_x = jsonMessage["size_x"];
this.size_y = jsonMessage["size_y"];
this.transform = jsonMessage["transform"];
this.text = jsonMessage["text"];
this.stroke_color = jsonMessage["stroke_color"];
this.stroke_width = jsonMessage["stroke_width"];
this.background = jsonMessage["background"];
this.border_radius = jsonMessage["border_radius"];
const styleMessage = jsonMessage["style"];

if (styleMessage) {
this.style = this.objectManager.getFromPool(TEXT_STYLE, this.objectManager);
this.style.build(styleMessage, registeredFontFaces)
}
}

cleanUp(){
Expand Down
58 changes: 39 additions & 19 deletions pax-chassis-web/interface/src/classes/native-element-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {OcclusionContext} from "./occlusion-context";
import {ObjectManager} from "../pools/object-manager";
import {INPUT, BUTTON, DIV, OBJECT, OCCLUSION_CONTEXT, SCROLLER} from "../pools/supported-objects";
import {arrayToKey, packAffineCoeffsIntoMatrix3DString, readImageToByteBuffer} from "../utils/helpers";
import {TextStyle, getAlignItems, getJustifyContent, getTextAlign} from "./text";
import {ColorGroup, TextStyle, getAlignItems, getJustifyContent, getTextAlign} from "./text";
import type {PaxChassisWeb} from "../types/pax-chassis-web";
import { CheckboxUpdatePatch } from "./messages/checkbox-update-patch";
import { TextboxUpdatePatch } from "./messages/textbox-update-patch";
Expand Down Expand Up @@ -240,6 +240,24 @@ export class NativeElementPool {
console.assert(leaf !== undefined);
let textbox = leaf.firstChild;

applyTextTyle(textbox, textbox, patch.style);
console.log(patch);

if (patch.background) {
textbox.style.background = toCssColor(patch.background);
}

if (patch.border_radius) {
textbox.style["border-radius"] = patch.border_radius + "px";
}

if (patch.stroke_color) {
textbox.style["border-color"] = toCssColor(patch.stroke_color);
}

if (patch.stroke_width) {
textbox.style["border-width"] = patch.stroke_width + "px";
}

// Apply the content
if (patch.text != null) {
Expand Down Expand Up @@ -591,7 +609,23 @@ export class NativeElementPool {

}


function toCssColor(color: ColorGroup): string {
if (color.Rgba != null) {
let p = color.Rgba;
return `rgba(${p[0] * 255},${p[1] * 255},${p[2] * 255},${p[3] * 255})`;
} else if (color.Hsla != null) {
let p = color.Hsla;
return `hsla(${p[0] * 255},${p[1] * 255},${p[2] * 255},${p[3] * 255})`;
} else if (color.Rgb != null) {
let p = color.Rgb;
return `rgb(${p[0] * 255},${p[1] * 255},${p[2] * 255})`;
} else if (color.Hsl != null) {
let p = color.Hsl;
return `hsl(${p[0] * 255},${p[1] * 255},${p[2] * 255})`;
} else {
throw new TypeError("Unsupported Color Format");
}
}

function applyTextTyle(textContainer: HTMLDivElement, textElem: HTMLDivElement, style: TextStyle | undefined) {

Expand All @@ -601,23 +635,7 @@ function applyTextTyle(textContainer: HTMLDivElement, textElem: HTMLDivElement,
style.font.applyFontToDiv(textContainer);
}
if (style.fill) {
let newValue = "";
if (style.fill.Rgba != null) {
let p = style.fill.Rgba;
newValue = `rgba(${p[0] * 255},${p[1] * 255},${p[2] * 255},${p[3] * 255})`;
} else if (style.fill.Hsla != null) {
let p = style.fill.Hsla;
newValue = `hsla(${p[0] * 255},${p[1] * 255},${p[2] * 255},${p[3] * 255})`;
} else if (style.fill.Rgb != null) {
let p = style.fill.Rgb;
newValue = `rgb(${p[0] * 255},${p[1] * 255},${p[2] * 255})`;
} else if (style.fill.Hsl != null) {
let p = style.fill.Hsl;
newValue = `hsl(${p[0] * 255},${p[1] * 255},${p[2] * 255})`;
} else {
throw new TypeError("Unsupported Color Format");
}
textElem.style.color = newValue;
textElem.style.color = toCssColor(style.fill);
}
if (style.font_size) {
textElem.style.fontSize = style.font_size + "px";
Expand All @@ -637,3 +655,5 @@ function applyTextTyle(textContainer: HTMLDivElement, textElem: HTMLDivElement,
}
}
}


2 changes: 1 addition & 1 deletion pax-chassis-web/interface/src/classes/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export function getAlignItems(verticalAlignment: string): string {
}
}

class ColorGroup {
export class ColorGroup {
Hsla?: number[];
Rgba?: number[];
Rgb?: number[];
Expand Down
2 changes: 1 addition & 1 deletion pax-chassis-web/interface/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export function processMessages(messages: any[], chassis: PaxChassisWeb, objectM
} else if (unwrapped_msg["TextboxUpdate"]){
let msg = unwrapped_msg["TextboxUpdate"]
let patch: TextboxUpdatePatch = objectManager.getFromPool(TEXTBOX_UPDATE_PATCH, objectManager);
patch.fromPatch(msg);
patch.fromPatch(msg, nativePool.registeredFontFaces);
nativePool.textboxUpdate(patch);
}else if (unwrapped_msg["TextboxDelete"]) {
let msg = unwrapped_msg["TextboxDelete"];
Expand Down
10 changes: 2 additions & 8 deletions pax-message/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ pub struct TextboxPatch {
pub size_y: Option<f64>,
pub text: Option<String>,
pub background: Option<ColorVariantMessage>,
pub stroke: Option<StrokeMessage>,
pub stroke_color: Option<ColorVariantMessage>,
pub stroke_width: Option<f64>,
pub border_radius: Option<f64>,
pub style: Option<TextStyleMessage>,
}
Expand Down Expand Up @@ -409,13 +410,6 @@ pub enum ColorVariantMessage {
Rgb([f64; 3]),
}

#[cfg_attr(debug_assertions, derive(Debug))]
#[derive(Serialize, Clone, PartialEq)]
#[repr(C)]
pub struct StrokeMessage {
color: Option<Color>,
}

impl Default for ColorVariantMessage {
fn default() -> Self {
ColorVariantMessage::Rgba([1.0, 0.5, 0.0, 1.0])
Expand Down
6 changes: 6 additions & 0 deletions pax-runtime/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::api::{
// via calls to `read()`
pub struct PropertyExpression<T: Default> {
pub id: usize,
pub has_been_evaluted: bool,
pub cached_value: T,
pub transition_manager: TransitionManager<T>,
}
Expand All @@ -22,12 +23,16 @@ impl<T: Default> PropertyExpression<T> {
id,
cached_value: Default::default(),
transition_manager: TransitionManager::new(),
has_been_evaluted: false,
}
}
}

impl<T: Default + Clone> PropertyInstance<T> for PropertyExpression<T> {
fn get(&self) -> &T {
if !self.has_been_evaluted {
panic!("expression width id {:?} has'nt been evaluated", self.id)
}
&self.cached_value
}

Expand All @@ -41,6 +46,7 @@ impl<T: Default + Clone> PropertyInstance<T> for PropertyExpression<T> {

fn set(&mut self, value: T) {
self.cached_value = value;
self.has_been_evaluted = true;
}

//FUTURE: when trait fields land, DRY this implementation vs. other <T: PropertyInstance> implementations
Expand Down
10 changes: 10 additions & 0 deletions pax-std/pax-std-primitives/src/rectangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ impl InstanceNode for RectangleInstance {
&expanded_node.stack,
&mut properties.stroke,
);
handle_vtable_update(
context.expression_table(),
&expanded_node.stack,
&mut properties.stroke.get_mut().color,
);
handle_vtable_update(
context.expression_table(),
&expanded_node.stack,
&mut properties.stroke.get_mut().width,
);
handle_vtable_update(
context.expression_table(),
&expanded_node.stack,
Expand Down
53 changes: 48 additions & 5 deletions pax-std/pax-std-primitives/src/textbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,24 @@ impl InstanceNode for TextboxInstance {

fn update(self: Rc<Self>, expanded_node: &Rc<ExpandedNode>, context: &mut RuntimeContext) {
expanded_node.with_properties_unwrapped(|properties: &mut Textbox| {
handle_vtable_update(
context.expression_table(),
&expanded_node.stack,
&mut properties.text,
);
let tbl = context.expression_table();
let stk = &expanded_node.stack;
handle_vtable_update(tbl, stk, &mut properties.text);
handle_vtable_update(tbl, stk, &mut properties.stroke);
handle_vtable_update(tbl, stk, &mut properties.stroke.get_mut().color);
handle_vtable_update(tbl, stk, &mut properties.stroke.get_mut().width);
handle_vtable_update(tbl, stk, &mut properties.border_radius);
handle_vtable_update(tbl, stk, &mut properties.background);
// Style
handle_vtable_update(tbl, stk, &mut properties.style);
let stl = properties.style.get_mut();
handle_vtable_update(tbl, stk, &mut stl.fill);
handle_vtable_update(tbl, stk, &mut stl.font);
handle_vtable_update(tbl, stk, &mut stl.font_size);
handle_vtable_update(tbl, stk, &mut stl.underline);
handle_vtable_update(tbl, stk, &mut stl.align_vertical);
handle_vtable_update(tbl, stk, &mut stl.align_horizontal);
handle_vtable_update(tbl, stk, &mut stl.align_multiline);
});
}

Expand Down Expand Up @@ -83,6 +96,36 @@ impl InstanceNode for TextboxInstance {
&mut patch.transform,
computed_tab.transform.coeffs().to_vec(),
),
patch_if_needed(
&mut old_state.style,
&mut patch.style,
properties.style.get().into(),
),
patch_if_needed(
&mut old_state.stroke_color,
&mut patch.stroke_color,
properties.stroke.get().color.get().into(),
),
patch_if_needed(
&mut old_state.stroke_width,
&mut patch.stroke_width,
properties
.stroke
.get()
.width
.get()
.get_pixels(computed_tab.bounds.0),
),
patch_if_needed(
&mut old_state.background,
&mut patch.background,
properties.background.get().into(),
),
patch_if_needed(
&mut old_state.border_radius,
&mut patch.border_radius,
properties.border_radius.get().get_as_float(),
),
];
if updates.into_iter().any(|v| v == true) {
context.enqueue_native_message(pax_message::NativeMessage::TextboxUpdate(patch));
Expand Down
8 changes: 5 additions & 3 deletions pax-std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ pub mod primitives {
use pax_runtime::api::Property;
use pax_runtime::api::Size;
use pax_runtime::api::StringBox;
use pax_runtime::numeric::Numeric;

use crate::types::text::TextStyle;
use crate::types::Color;
use crate::types::Fill;
use crate::types::PathSegment;
use crate::types::Stroke;
Expand Down Expand Up @@ -80,10 +82,10 @@ pub mod primitives {
#[primitive("pax_std_primitives::textbox::TextboxInstance")]
pub struct Textbox {
pub text: Property<StringBox>,
pub background: Property<Fill>,
pub background: Property<Color>,
pub stroke: Property<Stroke>,
pub border_radius: Property<Size>,
pub text_style: Property<TextStyle>,
pub border_radius: Property<Numeric>,
pub style: Property<TextStyle>,
}

#[pax]
Expand Down
2 changes: 2 additions & 0 deletions pax-std/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ impl Default for Color {
}
}
}

impl Into<ColorVariantMessage> for &Color {
fn into(self) -> ColorVariantMessage {
match self.color_variant {
Expand All @@ -213,6 +214,7 @@ impl Into<ColorVariantMessage> for &Color {
}
}
}

impl PartialEq<ColorVariantMessage> for Color {
fn eq(&self, other: &ColorVariantMessage) -> bool {
match self.color_variant {
Expand Down

0 comments on commit adb16d3

Please sign in to comment.