Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Corry committed Nov 23, 2023
1 parent 1f08981 commit 72585b9
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 81 deletions.
73 changes: 42 additions & 31 deletions src/element.toit
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ import math
import png_tools.png_reader show *

abstract class Element extends ElementOrTexture_:
style_/Style? := null
classes/List?
id/string?
style_/Style? := ?
classes/List? := ?
id/string? := ?
children/List? := ?

x_ /int? := null
y_ /int? := null

x -> int?: return x_
y -> int?: return y_

constructor --x/int?=null --y/int?=null --element_class/string?=null --.classes/List?=null --.id/string?=null:
constructor --x/int?=null --y/int?=null --style/Style?=null --element_class/string?=null --.classes/List?=null --.id/string?=null .children/List?=null:
x_ = x
y_ = y
style_ = style
if element_class:
if not classes: classes = []
classes.add element_class
Expand Down Expand Up @@ -58,12 +60,20 @@ abstract class Element extends ElementOrTexture_:
abstract min_w -> int
abstract min_h -> int

set_style style/Style -> none:
if not style_:
style_ = style
set_attributes

abstract set_attributes -> none
set_styles styles/List -> none:
styles_for_children := null
child_block := : | child_style/Style |
if children:
if not styles_for_children: styles_for_children = styles.copy
styles_for_children.add child_style
styles.do: | style/Style |
style.iterate_properties --type=type --classes=classes --id=id child_block: | key/string value |
set_attribute key value
if children:
children.do: | child/Element |
child.set_styles (styles_for_children or styles)

abstract set_attribute key/string value -> none

abstract type -> string

Expand Down Expand Up @@ -109,11 +119,11 @@ abstract class ResizableElement extends Element:
min_w: return w_
min_h: return h_

set_attributes -> none:
if not w_:
w = style_.get --type=type --classes=classes --id=id "width"
if not h_:
h = style_.get --type=type --classes=classes --id=id "height"
set_attribute key/string value -> none:
if key == "width":
w = value
else if key == "height":
h = value

abstract class RectangleElement extends ResizableElement implements ColoredElement:
color_ /int? := ?
Expand All @@ -129,10 +139,11 @@ abstract class RectangleElement extends ResizableElement implements ColoredEleme
color_ = color
super --x=x --y=y --w=w --h=h

set_attributes -> none:
super
if not color_:
color = style_.get --type=type --classes=classes --id=id "color"
set_attribute key/string value -> none:
if key == "color":
color = value
else:
super key value

class GradientSpecifier:
color/int
Expand Down Expand Up @@ -525,11 +536,11 @@ class Label extends Element implements ColoredElement:

type -> string: return "label"

set_attributes -> none:
if not color_:
color = style_.get --type=type --classes=classes --id=id "color"
if not font_:
font = style_.get --type=type --classes=classes --id=id "font"
set_attribute key/string value -> none:
if key == "color":
color = value
else if key == "font":
font = value

color -> int?: return color_

Expand Down Expand Up @@ -697,7 +708,7 @@ class BarCodeEanElement extends CustomElement:

type -> string: return "bar-code-ean"

set_attributes -> none:
set_attribute key/string value -> none:

min_w: return w
min_h: return h
Expand Down Expand Up @@ -998,11 +1009,11 @@ abstract class WindowElement extends BorderlessWindowElement implements Window:

type -> string: return "window"

set_attributes -> none:
if not inner_width:
w = style_.get --type=type --classes=classes --id=id "width"
if not inner_height:
h = style_.get --type=type --classes=classes --id=id "height"
set_attribute key/string value -> none:
if key == "width":
w = value
else if key == "height":
h = value

/**
A rectangular window with a fixed width colored border. The border is
Expand Down Expand Up @@ -1449,4 +1460,4 @@ class PngElement extends CustomElement:

type -> string: return "png"

set_attributes -> none:
set_attribute key/string value -> none:
97 changes: 47 additions & 50 deletions src/style.toit
Original file line number Diff line number Diff line change
Expand Up @@ -112,60 +112,57 @@ style := Style
*/
class Style:
map_/Map := {:}
id_map_/Map := {:}
class_map_/Map := {:}
type_map_/Map := {:}
parent/Style? // Set by parent.
id_map_/Map? := ?
class_map_/Map? := ?
type_map_/Map? := ?
parent/Style? := null // Set by parent.
constructor.empty: return EMPTY_STYLE_

constructor --.parent=null
--color/int?=null
--font/Font?=null
--background/List?=null
--background=null
--border_color/int?=null
--class_map/Map?=null
--id_map/Map?=null:
if color != null: color= color
if font != null: font= font
if background != null: background= background
if class_map != null: class_map= class_map
if id_map != null: id_map= id_map

get_ --type/string --classes/List? --id/string? key/string:
return get_helper_ parent type classes id key this

static get_helper_ parent/Style? type/string classes/List? id/string? key/string child/Style:
leaf_lookup := : | style/Style key/string |
value := style.map_.get key
if value: return value

leaf_lookup.call child key
if not parent: return null
if id:
id_style := parent.id_map_.get id
if id_style and id_style != child:
leaf_lookup.call id_style key
if classes:
classes.do: | element_class/string |
class_style := parent.class_map_.get element_class
if class_style and class_style != child:
leaf_lookup.call class_style key
type_style := parent.type_map_.get type
if type_style and type_style != child:
leaf_lookup.call type_style key
default_style := parent.type_map_.get "*"
if default_style and default_style != child:
leaf_lookup.call default_style key
return get_helper_ parent.parent type classes id key parent

color --type/string --classes/List?=null --id/string?=null -> int?:
return get_ --type=type --classes=classes --id=id "color"

font --type/string --classes/List?=null --id/string?=null -> Font?:
return get_ --type=type --classes=classes --id=id "font"

background --type/string --classes/List?=null --id/string?=null -> List?:
return get_ --type=type --classes=classes --id=id "background"

get key/string --type/string --classes/List?=null --id/string?=null:
return get_ --type=type --classes=classes --id=id key
--id_map/Map?=null
--type_map/Map?=null:
if color != null: map_["color"] = color
if font != null: map_["font"] = font
if border_color != null: map_["border-color"] = border_color
if background != null:
map_["background"] = (background is List) ? background : [background]
class_map_ = class_map
id_map_ = id_map
type_map_ = type_map

[class_map_, id_map_, type_map_].do: | map/Map? |
if map:
map.do: | key/string value/Style |
value.parent = this

iterate_properties --type/string? --classes/List? --id/string? [child_block] [block]:
map_.do: | key/string value |
block.call key value
if type_map_ and type:
type_map_.get type --if_present=: | style/Style |
style.map_.do: | key/string value |
block.call key value
child_block.call style
if class_map_ and classes and classes.size != 0:
if classes.size == 1:
class_map_.get classes[0] --if_present=: | style/Style |
style.map_.do: | key/string value |
block.call key value
child_block.call style
else:
class_map_.do: | key/string style/Style |
if classes.contains key:
style.map_.do: | key/string value |
block.call key value
child_block.call style
if id_map_ and id:
id_map_.get id --if_present=: | style/Style |
style.map_.do: | key/string value |
block.call key value
child_block.call style
78 changes: 78 additions & 0 deletions tests/style_test.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (C) 2023 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the TESTS_LICENSE file.
import expect show *

import pixel_display.common show Canvas
import pixel_display.element show Element
import pixel_display.style show *

toit_doc_examples_test:
style := Style
--type-map={
"button": Style --color=0xffffff --background=0x606060,
}
--class-map={
"box": Style --border-color=0xff0000,
}
--id-map={
"fish": Style --color=0x00ff00,
}

style2 := Style
--class-map={
"box": Style
--type-map={
"p": Style --color=0xffffff,
},
}

FISH-OR-FOWL-STYLE ::= Style --color=0xffffff --background=0x606060

style3 := Style
--class-map={
"fish": FISH-OR-FOWL-STYLE,
"fowl": FISH-OR-FOWL-STYLE,
}

style4 := Style
--class-map={
"fish-or-fowl": Style --color=0xffffff --background=0x606060,
}

element_tree_test:

abstract class TestElement extends Element:
constructor --style/Style?=null --element_class/string?=null --classes/List?=null --id/string?=null children/List?=null:
super --style=style --element_class=element_class --classes=classes --id=id children

invalidate -> none:
unreachable

draw canvas/Canvas -> none:
unreachable

min_w -> int:
unreachable

min_h -> int:
unreachable

class Square extends TestElement:
type -> string: return "square"
w/int? := null
h/int? := null

constructor --style/Style?=null --element_class/string?=null --classes/List?=null --id/string?=null:
super --style=style --element_class=element_class --classes=classes --id=id

set_attribute key/string value -> none:
if key == "width":
w = value
else if key == "height":
h = value

main:
toit_doc_examples_test
element_tree_test

0 comments on commit 72585b9

Please sign in to comment.