diff --git a/src/element.toit b/src/element.toit index fd6ec53..f761b1a 100644 --- a/src/element.toit +++ b/src/element.toit @@ -22,6 +22,7 @@ abstract class Element implements Window: classes/List? := ? id/string? := ? children/List? := ? + children-styles_/List? := null background_ := null border_/Border? := null @@ -89,6 +90,7 @@ abstract class Element implements Window: add element/Element -> none: if not children: children = [] children.add element + if children-styles_: element.set-styles children-styles_ element.change-tracker = this element.invalidate @@ -158,14 +160,14 @@ abstract class Element implements Window: style.matching-styles --type=type --classes=classes --id=id: | style/Style | style.iterate-properties: | key/string value | set-attribute_ key value - if children: - if not styles-for-children: styles-for-children = styles.copy - styles-for-children.add style + if not styles-for-children: styles-for-children = styles.copy + styles-for-children.add style styles.do install-style if style_: style_.iterate-properties: | key/string value | set-attribute_ key value install-style.call style_ + children-styles_ = styles-for-children or styles if children: children.do: | child/Element | child.set-styles (styles-for-children or styles) diff --git a/src/pixel-display-impl_.toit b/src/pixel-display-impl_.toit index 676ed01..0217354 100644 --- a/src/pixel-display-impl_.toit +++ b/src/pixel-display-impl_.toit @@ -39,9 +39,19 @@ For example, implemented by the drivers in https://pkg.toit.io/package/github.com%2Ftoitware%2Ftoit-ssd1306 */ abstract class AbstractDriver: + /** The width of the display. */ abstract width -> int + + /** The height of the display. */ abstract height -> int + + /** + The flags of the display. + + See $FLAG-2-COLOR and similar for the possible flags. + */ abstract flags -> int + x-rounding -> int: return 8 y-rounding -> int: return 8 start-partial-update speed/int -> none: @@ -137,6 +147,8 @@ abstract class PixelDisplay implements Window: transform_ /Transform + styles_ /List? := null + /** Constructs a display connected via a $driver_ to a device. The display is suitable for true-color (24 bit color) display drivers. @@ -257,6 +269,7 @@ abstract class PixelDisplay implements Window: child-invalidated_ 0 0 driver_.width driver_.height set-styles styles/List -> none: + styles_ = styles elements_.do: if it is Element: element := it as Element @@ -273,6 +286,7 @@ abstract class PixelDisplay implements Window: add element/Element -> none: elements_.add element element.change-tracker = this + if styles_: element.set-styles styles_ element.invalidate /** @@ -757,6 +771,22 @@ interface Window: */ get-element-by-id id/string -> any + /** + Sets the given $styles. + + Replaces the existing styles (if there are any) with the + new $styles. + + Each element of the list must be of type $Style. + Use an empty list to remove the current styles. + + # Inheritance + If subclasses can have children, then they should store the + list so that the style can be applied when a new child + is added at a later point. + */ + set-styles styles/List -> none + /** A canvas to draw on. When the display is being redrawn, the area that needs updating is diff --git a/tests/style-test.toit b/tests/style-test.toit index f6199d8..3a4f879 100644 --- a/tests/style-test.toit +++ b/tests/style-test.toit @@ -4,7 +4,13 @@ import expect show * -import pixel-display show Canvas Element SolidBorder Style +import pixel-display show + AbstractDriver + Canvas + Element + PixelDisplay + SolidBorder + Style /// Test that the examples from style.toit are well-formed. toit-doc-examples-test: @@ -140,6 +146,34 @@ no-global-style-test: expect-equals "bar" (elements.get-element-by-id "first-foo-haver").foo + +/** +Tests that an element can be added or moved to a new parent and + receives the style from the parent. +*/ +add-test: + style := Style + --type-map={ + "foo-haver": Style { "foo": "bar" }, + } + + elements := Div --style=style [] + haver := FooHaver --id="first-foo-haver" + elements.add haver + + expect-equals "bar" + (elements.get-element-by-id "first-foo-haver").foo + + display := PixelDisplay.gray-scale TestDriver + display.set-styles [style] + + haver2 := FooHaver --id="second-foo-haver" + display.add haver2 + + expect-equals "bar" + (display.get-element-by-id "second-foo-haver").foo + + /// A class that stubs out the display methods we don't need /// for test purposes. abstract class TestElement extends Element: @@ -194,11 +228,16 @@ class FooHaver extends TestElement: constructor --style/Style?=null --classes/List?=null --id/string?=null children/List?=null: super --style=style --classes=classes --id=id children - + set-attribute_ key/string value -> none: if key == "foo": foo = value +class TestDriver extends AbstractDriver: + width -> int: return 320 + height -> int: return 240 + flags -> int: return 0 + main: toit-doc-examples-test element-tree-test @@ -206,3 +245,4 @@ main: single-element-style-test extra-properties-test no-global-style-test + add-test