Browse Source

Adding UITests

Josh Engebretson 10 years ago
parent
commit
d1008dbc79
53 changed files with 1351 additions and 0 deletions
  1. 16 0
      UITests/Resources/Components/Star.js
  2. 103 0
      UITests/Resources/Components/UI.js
  3. BIN
      UITests/Resources/Images/image_1.png
  4. BIN
      UITests/Resources/Images/image_2.png
  5. BIN
      UITests/Resources/Images/image_3.png
  6. BIN
      UITests/Resources/Images/image_4.png
  7. BIN
      UITests/Resources/Images/image_5.png
  8. BIN
      UITests/Resources/Images/image_6.png
  9. BIN
      UITests/Resources/Images/image_7.png
  10. BIN
      UITests/Resources/Images/image_8.png
  11. BIN
      UITests/Resources/Images/image_9.png
  12. 24 0
      UITests/Resources/Scripts/main.js
  13. BIN
      UITests/Resources/Skin/bg_tile.png
  14. BIN
      UITests/Resources/Skin/focus_r8.png
  15. BIN
      UITests/Resources/Skin/icon128.png
  16. BIN
      UITests/Resources/Skin/icon16.png
  17. BIN
      UITests/Resources/Skin/icon48.png
  18. BIN
      UITests/Resources/Skin/image_frame.png
  19. BIN
      UITests/Resources/Skin/remove.png
  20. 74 0
      UITests/Resources/Skin/skin.tb.txt
  21. BIN
      UITests/Resources/Skin/special_button.png
  22. BIN
      UITests/Resources/Skin/special_button_pressed.png
  23. BIN
      UITests/Resources/Skin/star_gold.png
  24. BIN
      UITests/Resources/Skin/[email protected]
  25. BIN
      UITests/Resources/Skin/[email protected]
  26. BIN
      UITests/Resources/Skin/[email protected]
  27. BIN
      UITests/Resources/Skin/star_gray.png
  28. BIN
      UITests/Resources/Skin/[email protected]
  29. BIN
      UITests/Resources/Skin/[email protected]
  30. BIN
      UITests/Resources/Skin/[email protected]
  31. BIN
      UITests/Resources/Sprites/star.png
  32. 35 0
      UITests/Resources/UI/EditWindow.ui.txt
  33. 58 0
      UITests/Resources/UI/Test.ui.txt
  34. 30 0
      UITests/Resources/UI/TestImageWidget.ui.txt
  35. 33 0
      UITests/Resources/UI/TestRadioCheckbox.ui.txt
  36. 21 0
      UITests/Resources/UI/resource_edit_test.tb.txt
  37. 38 0
      UITests/Resources/UI/resource_edit_window.tb.txt
  38. 16 0
      UITests/Resources/UI/test_animations.tb.txt
  39. 381 0
      UITests/Resources/UI/test_batching01.tb.txt
  40. 43 0
      UITests/Resources/UI/test_connections.tb.txt
  41. 55 0
      UITests/Resources/UI/test_layout01.tb.txt
  42. 39 0
      UITests/Resources/UI/test_layout02.tb.txt
  43. 21 0
      UITests/Resources/UI/test_layout03.tb.txt
  44. 6 0
      UITests/Resources/UI/test_list_item.tb.txt
  45. 125 0
      UITests/Resources/UI/test_scrollcontainer.tb.txt
  46. 25 0
      UITests/Resources/UI/test_scroller_snap.tb.txt
  47. 15 0
      UITests/Resources/UI/test_select.tb.txt
  48. 30 0
      UITests/Resources/UI/test_select_advanced.tb.txt
  49. 18 0
      UITests/Resources/UI/test_skin_conditions01.tb.txt
  50. 44 0
      UITests/Resources/UI/test_skin_conditions02.tb.txt
  51. 38 0
      UITests/Resources/UI/test_tabcontainer01.tb.txt
  52. 54 0
      UITests/Resources/UI/test_toggle_containers.tb.txt
  53. 9 0
      UITests/UIExample.atomic

+ 16 - 0
UITests/Resources/Components/Star.js

@@ -0,0 +1,16 @@
+var game = Atomic.game;
+var node = self.node;
+
+function start() {
+
+    var sprite2D = node.createComponent("StaticSprite2D");
+    sprite2D.sprite = game.getSprite2D("Sprites/star.png");
+    sprite2D.blendMode = Atomic.BLEND_ALPHA;
+
+}
+
+function update(timeStep) {
+
+    node.roll(timeStep * 100);
+    
+}

+ 103 - 0
UITests/Resources/Components/UI.js

@@ -0,0 +1,103 @@
+
+var view = new Atomic.UIView();
+
+var window = new Atomic.UIWindow();
+window.load("UI/Test.ui.txt");
+window.text = "Turbo Badger";
+window.setSize(250, 630);
+window.setPosition(10, 50);
+view.addChild(window);
+
+var edit = new Atomic.UIWindow();
+edit.load("UI/EditWindow.ui.txt");
+edit.text = "Edit Window";
+edit.setSize(450, 630);
+edit.setPosition(280, 50);
+view.addChild(edit);
+
+window.getWidget("test-image").onClick = function() {
+
+  var testImage = new Atomic.UIWindow();
+  testImage.load("UI/TestImageWidget.ui.txt");
+  testImage.text = "Image Widget";
+
+  testImage.setSize(350, 500);
+
+  view.addChild(testImage);
+
+  testImage.center();
+
+  testImage.onEvent = function(evt) {
+
+    if (evt.target && evt.target.id == "remove") {
+      var image = evt.target.parent;
+      image.parent.removeChild(image);
+    }
+  }
+
+}
+
+window.getWidget("test-layout").onClick = function() {
+
+  var testLayout = new Atomic.UIWindow();
+  testLayout.load("UI/TestRadioCheckbox.ui.txt");
+  testLayout.text = "Radio & Checkbox";
+
+  var rect = testLayout.getResizeToFitContentRect();
+
+  testLayout.setSize(rect.width, rect.height);
+
+  view.addChild(testLayout);
+
+  testLayout.center();
+}
+
+var editfield = edit.getWidget("editfield");
+var menubutton = edit.getWidget("menu");
+
+edit.getWidget("clear").onClick = function() {
+
+  editfield.text = "";
+
+}
+
+menubutton.onClick = function() {
+
+  menubutton.popup({
+    "Toggle wrapping" : "toggle wrapping",
+    "-" : "",
+    "Align selected left" : "align left",
+    "Align selected center" : "align center",
+    "Align selected right" : "align right"
+  }, function(id) {
+
+    switch(id) {
+      case "align right":
+        editfield.textAlign = Atomic.TEXT_ALIGN_RIGHT;
+        break;
+      case "align center":
+        editfield.textAlign = Atomic.TEXT_ALIGN_CENTER;
+        break;
+      case "align left":
+        editfield.textAlign = Atomic.TEXT_ALIGN_LEFT;
+        break;
+      case "toggle wrapping":
+        editfield.wrapping = !editfield.wrapping;
+        break;
+    }
+
+  });
+
+}
+
+
+function start() {
+
+
+}
+
+function update(timeStep) {
+
+
+
+}

BIN
UITests/Resources/Images/image_1.png


BIN
UITests/Resources/Images/image_2.png


BIN
UITests/Resources/Images/image_3.png


BIN
UITests/Resources/Images/image_4.png


BIN
UITests/Resources/Images/image_5.png


BIN
UITests/Resources/Images/image_6.png


BIN
UITests/Resources/Images/image_7.png


BIN
UITests/Resources/Images/image_8.png


BIN
UITests/Resources/Images/image_9.png


+ 24 - 0
UITests/Resources/Scripts/main.js

@@ -0,0 +1,24 @@
+// This script is the main entry point of the game
+
+require("AtomicGame");
+
+Atomic.game.init(start, update);
+
+// called at the start of play
+function start() {
+
+    var game = Atomic.game;
+
+    // create a 2D scene
+    game.createScene2D();
+
+    var uiNode = game.scene.createChild("UI");
+    uiNode.createJSComponent("UI");
+
+}
+
+// called per frame
+function update(timeStep) {
+
+
+}

BIN
UITests/Resources/Skin/bg_tile.png


BIN
UITests/Resources/Skin/focus_r8.png


BIN
UITests/Resources/Skin/icon128.png


BIN
UITests/Resources/Skin/icon16.png


BIN
UITests/Resources/Skin/icon48.png


BIN
UITests/Resources/Skin/image_frame.png


BIN
UITests/Resources/Skin/remove.png


+ 74 - 0
UITests/Resources/Skin/skin.tb.txt

@@ -0,0 +1,74 @@
+# Demo skin override (contains some additions for the demo)
+elements
+	Icon16
+		bitmap icon16.png
+		min-width 16
+		min-height 16
+	Icon48
+		bitmap icon48.png
+			cut 4
+		min-width 20
+		min-height 20
+	Icon128
+		bitmap icon128.png
+	background
+		bitmap bg_tile.png
+		type Tile
+	background_solid
+		background-color #3b3b3b
+		padding 10
+	SpecialButton
+		bitmap special_button.png
+		cut 17
+		expand 7
+		padding 6 8
+		overrides
+			element SpecialButton.pressed
+				state pressed
+		overlays
+			element generic_focus_r8
+				state focused
+			element Star
+				condition: target: ancestors, property: skin, value: "Starry buttons"
+	SpecialButton.pressed
+		bitmap special_button_pressed.png
+		cut 17
+		expand 7
+		content-ofs-x 1
+		content-ofs-y 1
+	ImageCaption
+		background-color #00000066
+	ImageFrame
+		overlays
+			element ImageFrame.overlay
+				state all
+	ImageFrame.overlay
+		bitmap image_frame.png
+		cut 22
+		expand 15
+	Remove
+		bitmap remove.png
+		type Image
+		padding 5
+	Star
+		bitmap star_gray.png
+		type Image
+		img-position-x 0
+		img-position-y 0
+		img-ofs-x -8
+		img-ofs-y -12
+		overrides
+			element Star.active
+				condition: target: this, property: "window active"
+				condition: target: parent, property: hover
+	Star.active
+		bitmap star_gold.png
+		type Image
+		img-position-x 0
+		img-position-y 0
+		img-ofs-x -10
+		img-ofs-y -14
+	generic_focus_r8
+		bitmap focus_r8.png
+		cut 14
+		expand 4

BIN
UITests/Resources/Skin/special_button.png


BIN
UITests/Resources/Skin/special_button_pressed.png


BIN
UITests/Resources/Skin/star_gold.png


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Skin/star_gray.png


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Skin/[email protected]


BIN
UITests/Resources/Sprites/star.png


+ 35 - 0
UITests/Resources/UI/EditWindow.ui.txt

@@ -0,0 +1,35 @@
+WindowInfo
+	title Text editing
+	position 280 50
+	size 450 630
+TBLayout: axis: y, distribution: available
+	TBLayout: distribution: gravity
+		TBButton: id: undo
+			TBSkinImage: skin: arrow.left
+		TBButton: id: redo
+			TBSkinImage: skin: arrow.right
+		TBButton: text: Clear, id: clear
+		TBLayout
+			gravity left right
+			distribution-position right bottom
+			TBTextField: id: info
+			TBButton: id: menu
+				TBSkinImage: skin: arrow.down
+				TBTextField: text: Menu
+				skin TBButton.flat
+	TBEditField: multiline: 1, styling: 1, gravity: all, id: editfield, autofocus: 1
+		text: "Turbo Badger - Fast UI toolkit\n\n" \
+				"<color #0794f8>Test zone</color>\n" \
+				"The menu to the left spawns some examples of features in turbo badger.\n\n" \
+				"The code in Demo/* is more like a developers test zone than organized tutorial-like samples. " \
+				"This would be good to fix of course (help is welcome! ;)\n\n" \
+				"<color #0794f8>Some things to try out</color>\n" \
+				" • All layouts provide panning of content automatically when squashed below the minimal size, so try resizing windows and pan.\n" \
+				" • Lines starting with a bullet sequence (like this one) should wrap in a smart way.\n" \
+				" • Message windows whose target is removed, are automatically removed. Close the menu window with open messages.\n" \
+				" • Keyboard navigation using tab.\n" \
+				" • <u>Underline</u>, <color #f44>Red</color>, <color #6f6>Green</color>, <color #aaf>Blue</color>\n\n" \
+				"<color #0794f8>Good to know</color>\n" \
+				" • The text widget handles styling and embedded content (Example: <widget TBSkinImage: skin: 'Icon16'> <widget TBButton: text: 'Nice!'>), but does not handle editing of those fully. Those features are only ment for read-only text widgets for now.\n" \
+				" • You can emulate touch input by holding down shift, ctrl or alt. Touch input behaves differently in some widgets (f.ex long click to open context menu in textfields), and only invoke movement when down.\n" \
+				" • All resources are UTF-8.\n"

+ 58 - 0
UITests/Resources/UI/Test.ui.txt

@@ -0,0 +1,58 @@
+WindowInfo
+	title Turbo Badger
+	position 10 50
+	size 250 630
+
+TBLayout: axis: y, distribution-position: "left top", distribution: "available"
+
+	TBSection: value: 1, text: "Misc features"
+		TBLayout: axis: y, spacing: 0, size: available
+			TBButton: skin: "TBButton.flat", text: "Radiobutton & Checkbox"
+				id: "test-layout"
+				data: "test_radio_checkbox.tb.txt"
+			TBButton: skin: "TBButton.flat", text: "TBSelectList", id: "test-list"
+			TBButton: skin: "TBButton.flat", text: "ScrollContainer & misc.", id: "test-scroll-container"
+			TBButton: skin: "TBButton.flat", text: "TBWidgetValue connections", id: "test-connections"
+			TBButton: skin: "TBButton.flat", text: "TBImage", id: "test-image"
+			TBButton: skin: "TBButton.flat", text: "TBScrollerSnapListener", id: "test-page"
+			TBButton: skin: "TBButton.flat", text: "Animations", id: "test-animations"
+			TBButton: skin: "TBButton.flat", text: "Skin conditions", id: "test-skin-conditions"
+			TBButton: skin: "TBButton.flat", text: "TBToggleContainer"
+				id: "test-layout"
+				data: "test_toggle_containers.tb.txt"
+			TBButton: skin: "TBButton.flat", text: "Close with dim & alert", id: "TBWindow.close"
+			TBButton: skin: "TBButton.flat", text: "ResourceEditWindow", id: "test-resource-edit"
+
+	TBSection: value: 0, text: "Layout tests"
+		TBLayout: axis: y, spacing: 0, size: available
+			TBButton: skin: "TBButton.flat", text: "Size, gravity, position"
+				id: "test-layout"
+				data: "test_layout01.tb.txt"
+			TBButton: skin: "TBButton.flat", text: "Distribution"
+				id: "test-layout"
+				data: "test_layout02.tb.txt"
+			TBButton: skin: "TBButton.flat", text: "TBWidget default"
+				id: "test-layout"
+				data: "test_layout03.tb.txt"
+
+	TBSection: value: 0, text: "Graphics tests"
+		TBLayout: axis: y, spacing: 0, size: available
+			TBClickLabel: text: "Continous repaint"
+				lp: max-width: 0
+				TBCheckBox: connection: continous-repaint
+			TBButton: skin: "TBButton.flat", text: "Reload skin bitmaps", id: "reload skin bitmaps"
+			TBButton: skin: "TBButton.flat", text: "Context lost & restore", id: "test context lost"
+
+	TBSection: value: 0, text: "Message tests"
+		TBLayout: axis: y, spacing: 0, size: available
+			TBButton: skin: "TBButton.flat", text: "PostMessage", id: "msg"
+			TBButton: skin: "TBButton.flat", text: "PostMessageDelayed", id: "delayedmsg"
+			TBClickLabel: text: "Busy message loop"
+				lp: max-width: 0
+				TBCheckBox: id: "busymsg"
+
+	# We want the debug button at the bottom if there is space over,
+	# so use an trailing layout which may expand a lot.
+	TBLayout: axis: y, distribution-position: bottom
+		lp: max-height: 10000
+		TBButton: id: "debug settings", text: "Runtime debug settings..."

+ 30 - 0
UITests/Resources/UI/TestImageWidget.ui.txt

@@ -0,0 +1,30 @@
+TBScrollContainer
+	adapt-content 1
+	TBLayout
+		axis y
+		spacing 20
+		TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1, adapt-to-content: 1
+			text: "Some images shown by TBImageWidget. This test requires enabling TB_IMAGE (see tb_config.h).\n" \
+					"Images are unloaded when all references are removed (this window is closed)."
+		TBImageWidget: filename: "Images/image_1.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+		TBImageWidget: filename: "Images/image_2.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+		TBImageWidget: filename: "Images/image_3.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+		TBImageWidget: filename: "Images/image_4.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+		TBImageWidget: filename: "Images/image_5.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+		TBImageWidget: filename: "Images/image_6.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+			TBTextField: skin: "ImageCaption", text: "Öland", gravity: bottom left right
+		TBImageWidget: filename: "Images/image_7.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+			TBTextField: skin: "ImageCaption", text: "Öland", gravity: bottom left right
+		TBImageWidget: filename: "Images/image_8.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+			TBTextField: skin: "ImageCaption", text: "Örebro", gravity: bottom left right
+		TBImageWidget: filename: "Images/image_9.png", skin: ImageFrame
+			TBButton: skin: "Remove", id: "remove", gravity: right
+			TBTextField: skin: "ImageCaption", text: "Stockholm", gravity: bottom left right

+ 33 - 0
UITests/Resources/UI/TestRadioCheckbox.ui.txt

@@ -0,0 +1,33 @@
+WindowInfo
+	title Radiobutton & checkbox
+TBLayout: position: left top, axis: y
+	TBTextField: text: "Radiobuttons, anonymous group:"
+	TBLayout: distribution: preferred
+		TBRadioButton
+		TBRadioButton
+		TBRadioButton: state: disabled
+	TBTextField: text: "Radiobuttons, group-id: 'R1'":
+	TBLayout: distribution: preferred
+		TBRadioButton: group-id: R1
+		TBRadioButton: group-id: R1
+		TBRadioButton: group-id: R1, state: disabled
+	TBTextField: text: "Radiobuttons, group-id: 'R2' value set":
+	TBLayout: distribution: preferred
+		TBRadioButton: group-id: R2, value: 1
+		TBRadioButton: group-id: R2
+		TBRadioButton: group-id: R2, state: disabled
+	TBTextField: text: "Checkboxes"
+	TBLayout: distribution: preferred
+		TBCheckBox
+		TBCheckBox: value: 1
+		TBCheckBox: state: disabled
+		TBCheckBox: state: disabled, value: 1
+	TBTextField: text: "TBClickLabel with radio & check"
+	TBClickLabel: text: Some text to click
+		TBCheckBox
+	TBClickLabel: text: Some text to click
+		TBRadioButton
+	TBClickLabel: text: Some text to click, state: disabled
+		TBCheckBox
+	TBClickLabel: text: Some text to click, state: disabled
+		TBRadioButton

+ 21 - 0
UITests/Resources/UI/resource_edit_test.tb.txt

@@ -0,0 +1,21 @@
+TBLayout
+	distribution available
+	axis y
+	TBLayout
+		TBButton
+			text Button 1
+		TBRadioButton
+		TBCheckBox
+	@if 1
+		TBContainer
+			TBLayout
+				TBSlider
+					value 0.5
+				TBScrollBar
+	TBEditField
+		multiline 1
+		readonly 1
+	TBEditField
+		text Hello world\nHello world
+		adapt-to-content 1
+		multiline 1

+ 38 - 0
UITests/Resources/UI/resource_edit_window.tb.txt

@@ -0,0 +1,38 @@
+TBLayout
+	distribution gravity
+	size available
+	TBLayout
+		gravity top bottom
+		distribution available
+		distribution-position top left
+		size available
+		axis y
+		TBLayout
+			distribution available
+			TBButton
+				text @new
+				state disabled
+			TBButton
+				text @save
+				state disabled
+			TBButton
+				text Test
+				id test
+		TBEditField
+			placeholder @search
+			type search
+			id widget_list_search
+		TBSelectList
+			id widget_list
+	TBLayout
+		distribution available
+		TBEditField
+			id source_edit
+			multiline 1
+			gravity all
+		TBLayout: axis: y, distribution: available, position: left
+			TBScrollContainer
+				id scroll_container
+				gravity all
+			TBClickLabel: text: "Adapt to container"
+				TBCheckBox: id: "constrained"

+ 16 - 0
UITests/Resources/UI/test_animations.tb.txt

@@ -0,0 +1,16 @@
+WindowInfo
+	title Animations
+TBLayout: axis: y
+	TBTextField: text: "Duration (in milliseconds):"
+	TBInlineSelect: id: "duration", min: 0, max: 100000, value: 500
+	TBTextField: text: "Curve:"
+	TBSelectList: id: "curve", value: 1
+		items
+			item: text: "Linear"
+			item: text: "Slow down"
+			item: text: "Speed up"
+			item: text: "Bezier"
+			item: text: "Smooth"
+	TBClickLabel: text: Fade
+		TBCheckBox: id: fade, value: 1
+	TBButton: text: "Animate!", id: "Animate!", skin: "SpecialButton"

+ 381 - 0
UITests/Resources/UI/test_batching01.tb.txt

@@ -0,0 +1,381 @@
+TBLayout
+	axis y
+	TBTextField: text: "For enabling \"Continuous repaint\" and test batching speed.
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"
+	TBLayout
+		TBButton: text: "A"
+		TBButton: text: "B"
+		TBButton: text: "C"
+		TBButton: text: "D"
+		TBButton: text: "E"
+		TBButton: text: "F"
+		TBButton: text: "G"
+		TBButton: text: "H"
+		TBButton: text: "I"
+		TBButton: text: "J"
+		TBButton: text: "K"
+		TBButton: text: "L"
+		TBButton: text: "M"
+		TBButton: text: "N"
+		TBButton: text: "O"
+		TBButton: text: "P"
+		TBButton: text: "Q"
+		TBButton: text: "R"
+		TBButton: text: "S"
+		TBButton: text: "T"
+		TBButton: text: "U"
+		TBButton: text: "V"
+		TBButton: text: "W"
+		TBButton: text: "X"
+		TBButton: text: "Y"
+		TBButton: text: "Z"

+ 43 - 0
UITests/Resources/UI/test_connections.tb.txt

@@ -0,0 +1,43 @@
+WindowInfo
+	title TBWidgetValue connections
+TBLayout
+	axis y
+	TBTextField
+		text Numeric widgets sharing a connection
+	TBContainer
+		gravity all
+		TBLayout
+			TBInlineSelect
+				connection master-volume
+				min 0
+				max 100
+			TBSlider
+				connection master-volume
+				min 0
+				max 100
+			TBSlider
+				axis y
+				connection master-volume
+				min 0
+				max 100
+			TBButton
+				text Reset
+				id reset-master-volume
+	TBTextField
+		text Text widgets sharing a connection
+	TBContainer
+		gravity all
+		TBLayout
+			TBEditField
+				placeholder User name
+				connection user-name
+				min 0
+				max 100
+			TBEditField
+				placeholder User name
+				connection user-name
+				min 0
+				max 100
+			TBButton
+				text Reset
+				id reset-user-name

+ 55 - 0
UITests/Resources/UI/test_layout01.tb.txt

@@ -0,0 +1,55 @@
+WindowInfo
+	title TBLayout size & gravity
+# Declare a branch of layout nodes that is included in all three containers below.
+test_layout_content
+	TBLayout
+		TBButton
+			text Default
+		TBCheckBox
+			value 1
+		TBButton
+			axis y
+			text Foo Bar
+			TBSkinImage
+				skin Icon16
+		TBButton
+			gravity all
+			text Gravity all
+		TBButton
+			gravity top
+			text Gravity top
+		TBButton
+			gravity bottom
+			text Gravity bottom
+TBLayout
+	axis y
+	TBLayout
+		TBSelectDropdown
+			text Select position
+			id select position
+			items
+				item: text: "LAYOUT_POSITION_CENTER"
+				item: text: "LAYOUT_POSITION_LEFT_TOP"
+				item: text: "LAYOUT_POSITION_RIGHT_BOTTOM"
+				item: text: "LAYOUT_POSITION_GRAVITY"
+		TBButton
+			text Toggle axis
+			id toggle axis
+	TBLayout
+		id switch_layout
+		axis y
+		TBTextField: text: "size: preferred"
+		TBContainer
+			@include test_layout_content
+				size preferred
+				id 1
+		TBTextField: text: "size: available"
+		TBContainer
+			@include test_layout_content
+				size available
+				id 2
+		TBTextField: text: "size: gravity"
+		TBContainer
+			@include test_layout_content
+				size gravity
+				id 3

+ 39 - 0
UITests/Resources/UI/test_layout02.tb.txt

@@ -0,0 +1,39 @@
+WindowInfo
+	title TBLayout distribution
+TBLayout: position: left top, axis: y
+	TBTextField: text: "distribution: preferred"
+	TBLayout: distribution: preferred
+		TBButton: text: tab 1
+		TBButton: text: tab 2
+		TBButton: text: tab 3
+		TBButton: text: tab 4
+		TBEditField: placeholder: @search, gravity: left right, type: "search"
+	TBTextField: text: "distribution: available"
+	TBLayout: distribution: available
+		TBButton: text: tab 1
+		TBButton: text: tab 2
+		TBButton: text: tab 3
+		TBButton: text: tab 4
+		TBEditField: placeholder: @search, gravity: left right, type: "search"
+	TBTextField: text: "distribution: gravity"
+	TBLayout: distribution: gravity
+		TBButton: text: tab 1
+		TBButton: text: tab 2
+		TBButton: text: tab 3
+		TBButton: text: tab 4
+		TBEditField: placeholder: @search, gravity: left right, type: "search"
+	TBTextField: text: gravity + trailing layout for right align
+	TBLayout: distribution: gravity
+		TBButton: text: tab 1
+		TBButton: text: tab 2
+		TBButton: text: tab 3
+		TBButton: text: tab 4
+		TBLayout: gravity: left right, distribution-position: right bottom
+			TBEditField: placeholder: @search, type: "search"
+	TBTextField: text: "gravity + mixed gravity"
+	TBLayout: distribution: gravity
+		TBButton: text: tab 1
+		TBEditField: placeholder: @search, gravity: left right, type: "search"
+		TBButton: text: tab 3
+		TBButton: text: tab 4
+		TBEditField: placeholder: @search, gravity: left right, type: "search"

+ 21 - 0
UITests/Resources/UI/test_layout03.tb.txt

@@ -0,0 +1,21 @@
+WindowInfo
+	title Default TBWidget positioning
+	size 350 350
+TBLayout: axis: y, distribution: gravity
+	TBLayout: distribution: available, gravity: left right
+		TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1
+			text: "Any widget may contain children and by default applies basic gravity positioning.\n" \
+					"To achieve more advanced layout, you would normally wrap a layouting " \
+					"widget (f.ex TBLayout) but sometimes the default is enough.\n" \
+					"The default preferred size is calculated to the largest child " \
+					"(or the skin if there are no children)."
+	TBContainer: gravity: all
+		TBTextField: text: "all", gravity: all
+		TBTextField: text: "top, left, right", gravity: top left right
+		TBTextField: text: "bottom, left, right", gravity: bottom left right
+		TBTextField: text: "left, top, bottom", gravity: left top bottom
+		TBTextField: text: "right, top, bottom", gravity: right top bottom
+		TBButton: text: Upper left
+		TBButton: text: Upper right, gravity: right
+		TBButton: text: Lower left, gravity: bottom
+		TBButton: text: Lower right, gravity: bottom right

+ 6 - 0
UITests/Resources/UI/test_list_item.tb.txt

@@ -0,0 +1,6 @@
+TBCheckBox: id: check
+TBSkinImage: id: icon, skin: Icon48, ignore-input: 1
+TBLayout: axis: y, position: left, spacing: 0, ignore-input: 1, size: available, position: left top
+	TBTextField: id: name, text-align: left
+	TBTextField: id: info, text-align: left, state: disabled
+TBButton: id: delete, skin: TBWindow.close

+ 125 - 0
UITests/Resources/UI/test_scrollcontainer.tb.txt

@@ -0,0 +1,125 @@
+WindowInfo
+	title TBScrollContainer with misc widgets
+	size 500 500
+TBLayout
+	gravity all
+	distribution available
+	axis y
+	TBScrollContainer
+		TBLayout
+			position left top
+			axis y
+			TBTextField: text: Buttons with different fonts:
+			TBLayout
+				TBButton
+					text: "Orange"
+					font: name: Orange
+				TBButton
+					text: "Segoe 14"
+					font: size: 14px
+				TBButton
+					text: "Segoe 28"
+					font: size: 28px
+			TBTextField: text: TBButton containing TBSkinImage:
+			TBLayout
+				TBButton
+					text Click for image!
+					id add img
+					TBSkinImage
+						skin Icon16
+				TBButton
+					axis y
+					text Click for image!
+					id add img
+					TBSkinImage
+						skin Icon16
+			TBTextField: text: "TBButton containing TBEditField:"
+			TBLayout
+				TBButton
+					TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1, adapt-to-content: 1, styling: 1
+						text: "A <color #0794f8>TBButton</color> with styled text that is able to wrap to multiple lines."
+			TBTextField: text: "Showing menu manually, and TBSelectDropdown:"
+			TBLayout
+				TBButton
+					text Give me a popup menu!
+					id showpopupmenu1
+				TBSelectDropdown
+					text Dropdown
+					id name dropdown
+				TBSelectDropdown
+					text Customized items in Dropdown
+					id advanced dropdown
+			TBLayout
+				overflow scroll
+				TBRadioButton
+				TBCheckBox
+					value 1
+				TBSkinImage
+					skin Icon16
+				TBSkinImage
+					skin Icon48
+				TBButton
+					image back
+				TBButton
+					image forward
+			TBTextField: text: "TBEditField:"
+			TBLayout
+				TBEditField
+					text Edit type text
+				TBEditField
+					type search
+					text Edit type search
+				TBEditField
+					type password
+					text pwd goes here
+				TBEditField
+					text In this field, multiple lines are enabled.
+					multiline 1
+			TBTextField: text: "TBSlider:"
+			TBLayout
+				TBSlider
+				TBSlider
+					min 100
+					max 200
+					value 150
+				TBSlider
+					axis y
+					min 0
+					max 100
+					connection master-volume
+			TBTextField: text: "TBScrollbar:"
+			TBLayout
+				TBScrollBar
+				TBScrollBar
+					axis y
+			TBTextField: text: Horizontal layout:
+			TBLayout
+				id horizontal_layout
+				TBButton
+					text "1 new button"
+					id new buttons
+					data 1
+				TBButton
+					text "100 new buttons!"
+					id new buttons
+					data 100
+				TBButton
+					text "10 new with delay!"
+					id new buttons delayed
+					data 10
+			TBTextField: text: Vertical layout:
+			TBLayout
+				id vertical_layout
+				axis y
+				TBButton
+					text "1 new button"
+					id new buttons
+					data 1
+				TBButton
+					text "100 new buttons!"
+					id new buttons
+					data 100
+				TBButton
+					text "10 new with delay!"
+					id new buttons delayed
+					data 10

+ 25 - 0
UITests/Resources/UI/test_scroller_snap.tb.txt

@@ -0,0 +1,25 @@
+WindowInfo
+	title TBScrollerSnapListener
+definitions
+	pagesize
+		lp: width: 200, height: 300
+TBScrollContainer: id: "page-scroller"
+	@include definitions>pagesize
+	scroll-mode off
+	TBLayout
+		spacing 0
+		TBContainer
+			@include definitions>pagesize
+			TBTextField: text: "One - Swipe to next page"
+		TBContainer
+			@include definitions>pagesize
+			TBTextField: text: "Two"
+		TBContainer
+			@include definitions>pagesize
+			TBTextField: text: "Three"
+		TBContainer
+			@include definitions>pagesize
+			TBTextField: text: "Four"
+		TBContainer
+			@include definitions>pagesize
+			TBTextField: text: "Five - Last page"

+ 15 - 0
UITests/Resources/UI/test_select.tb.txt

@@ -0,0 +1,15 @@
+WindowInfo
+	title List and filter
+	position 1100 50
+TBLayout
+	axis y
+	distribution gravity
+	gravity all
+	TBEditField
+		id filter
+		gravity left right
+		placeholder @search
+		type search
+	TBSelectList
+		id list
+		gravity all

+ 30 - 0
UITests/Resources/UI/test_select_advanced.tb.txt

@@ -0,0 +1,30 @@
+WindowInfo
+	title Customized list items
+	position 770 50
+	size 300 300
+TBLayout
+	axis y
+	distribution gravity
+	gravity all
+	TBLayout
+		distribution gravity
+		TBEditField
+			id filter
+			gravity left right
+			placeholder @search
+			type search
+	TBSelectList
+		id list
+		gravity all
+	TBLayout
+		distribution gravity
+		TBEditField
+			id add_name
+			gravity left right
+			placeholder Name
+		TBButton
+			id add
+			text Add
+		TBButton
+			id delete all
+			text Delete all

+ 18 - 0
UITests/Resources/UI/test_skin_conditions01.tb.txt

@@ -0,0 +1,18 @@
+WindowInfo
+	title Skin conditions
+	position 200 170
+TBLayout: axis: y
+	TBTextField: text: Normal layout with buttons:
+	TBContainer
+		TBLayout
+			TBButton: text: "  A  ", skin: "SpecialButton"
+			TBButton: text: "  B  ", skin: "SpecialButton"
+			TBButton: text: "  C  ", skin: "SpecialButton"
+	TBTextField: text: Layout with skin "Starry buttons":
+	TBContainer
+		TBLayout: skin: Starry buttons
+			TBButton: text: "  A  ", skin: "SpecialButton"
+			TBButton: text: "  B  ", skin: "SpecialButton"
+			TBButton: text: "  C  ", skin: "SpecialButton"
+	TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1, adapt-to-content: 1
+		text The skin has a condition to show a upper left positioned overlay "Star" if placed under a ancestor widget with skin "Starry buttons". The Star skin has conditions to change bitmap if the window is active and the parent widget or any child to it is hovered.

+ 44 - 0
UITests/Resources/UI/test_skin_conditions02.tb.txt

@@ -0,0 +1,44 @@
+WindowInfo
+	title Skin conditions
+	position 500 170
+TBLayout
+	axis y
+	TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1, adapt-to-content: 1
+		text The TBButton skin has a condition to show a different skin when placed under a parent widget with skin "button_group". There is also conditions to use a different skin for the first and last button.
+	TBLayout
+		TBLayout: skin: button_group
+			TBButton
+				text <
+			TBButton
+				text >
+		TBLayout: skin: button_group
+			TBButton
+				text 1
+			TBButton
+				text 2
+			TBButton
+				text 3
+		TBLayout: skin: button_group
+			TBButton
+				text A
+			TBButton
+				text B
+			TBButton
+				text C
+	TBLayout: skin: button_group
+		TBButton
+			text Hello
+		TBButton
+			text World!
+	TBEditField: gravity: all, skin: 0, multiline: 1, readonly: 1, adapt-to-content: 1
+		text The "button_group" skin overrides default layout spacing. It can also be overridden in the UI resource.
+	TBLayout: skin: button_group
+		spacing 2
+		TBButton
+			text Group
+		TBButton
+			text with
+		TBButton
+			text spacing
+		TBButton
+			text 2

+ 38 - 0
UITests/Resources/UI/test_tabcontainer01.tb.txt

@@ -0,0 +1,38 @@
+WindowInfo
+	title TBTabContainer & misc tests
+	position 770 430
+TBTabContainer
+	gravity all
+	id tabcontainer
+	tabs
+		TBButton: text: "Tab with long text"
+		TBButton: text: "Skin"
+		TBButton: text: "Spinner"
+			TBSkinImage: skin: Icon16
+	TBLayout: axis: y
+		TBTextField: text: "Tab alignment:"
+		TBLayout
+			TBClickLabel: text: Left
+				TBRadioButton: group-id: set_align, id: set_align, data: 0
+			TBClickLabel: text: Up
+				TBRadioButton: group-id: set_align, id: set_align, data: 1, value: 1
+			TBClickLabel: text: Right
+				TBRadioButton: group-id: set_align, id: set_align, data: 2
+			TBClickLabel: text: Bottom
+				TBRadioButton: group-id: set_align, id: set_align, data: 3
+		TBButton
+			text Toggle tab axis
+			id toggle_tab_axis
+	TBLayout
+		TBLayout: axis: y, position: right bottom
+			TBButton: text: Normal button
+			TBButton: text: Overridden skin, skin: SpecialButton
+			TBButton: text: Disabled button, state: disabled
+		TBEditField
+			text TBEditField
+			multiline 1
+	TBLayout
+		axis y
+		TBButton: id: start_spinner, text: Start spinner
+		TBButton: id: stop_spinner, text: Stop spinner
+		TBProgressSpinner: id: spinner

+ 54 - 0
UITests/Resources/UI/test_toggle_containers.tb.txt

@@ -0,0 +1,54 @@
+WindowInfo
+	title TBToggleContainer
+TBLayout: axis: y
+	TBEditField: gravity: all, adapt-to-content: 1, multiline: 1, readonly: 1, skin: 0, virtual-width: 400
+		text: "TBToggleContainer used with TBWidgetValue connections to automatically toggle a group of items (no programming needed)."
+
+	TBLayout: position: top left
+		TBContainer
+			TBLayout: axis: y
+				TBClickLabel: text: "Check to enable stuff:"
+					TBCheckBox: connection: toggle_demo_1
+
+				# == Toggle enabled =====================================================
+				TBToggleContainer: connection: toggle_demo_1, toggle: enabled
+					TBLayout: axis: y
+						TBClickLabel: text: "Option 1"
+							TBRadioButton: group-id: group1, value: 1
+						TBClickLabel: text: "Option 2"
+							TBRadioButton: group-id: group1
+
+				TBClickLabel: text: "Check to disable stuff:"
+					TBCheckBox: connection: toggle_demo_2
+
+				# == Toggle enabled, with the invert flag set ===========================
+				TBToggleContainer: connection: toggle_demo_2, toggle: enabled, invert: 1
+					TBLayout: axis: y
+						TBClickLabel: text: "Option 1"
+							TBRadioButton: group-id: group2, value: 1
+						TBClickLabel: text: "Option 2"
+							TBRadioButton: group-id: group2
+
+		TBContainer
+			TBLayout: axis: y
+				TBClickLabel: text: "Check to show stuff:"
+					TBCheckBox: connection: toggle_demo_3
+
+				# == Toggle opacity =====================================================
+				TBToggleContainer: connection: toggle_demo_3, toggle: opacity
+					TBLayout: axis: y
+						TBClickLabel: text: "Option 1"
+							TBRadioButton: group-id: group3, value: 1
+						TBClickLabel: text: "Option 2"
+							TBRadioButton: group-id: group3
+
+				TBClickLabel: text: "Check to expand stuff:"
+					TBCheckBox: connection: toggle_demo_4
+
+				# == Toggle expand ======================================================
+				TBToggleContainer: connection: toggle_demo_4, toggle: expanded
+					TBLayout: axis: y
+						TBClickLabel: text: "Option 1"
+							TBRadioButton: group-id: group4, value: 1
+						TBClickLabel: text: "Option 2"
+							TBRadioButton: group-id: group4

+ 9 - 0
UITests/UIExample.atomic

@@ -0,0 +1,9 @@
+{
+   "version": 1,
+   "project": {
+      "version": "1.0.0"
+   },
+   "platforms": [
+      "mac", "windows"
+   ]
+}