├── README.md
├── 001-Guides
├── 008-Themes.md
├── 003-Binding.md
├── 006-Scripting.md
├── 007-Animation.md
├── _assets
│ ├── native_native.png
│ ├── styling_scope.png
│ ├── native_dropdown.png
│ ├── styling_spacing.png
│ ├── composite_dropdown.png
│ ├── native_composite.png
│ ├── styling_css_names.png
│ ├── styling_angry_button.png
│ ├── styling_butons_sizes.png
│ ├── styling_button_style.png
│ ├── styling_buttons_100.png
│ ├── styling_schema_flow.png
│ ├── styling_absolute_layout.png
│ ├── styling_autosized_vbox.png
│ ├── styling_buttons_percent.png
│ ├── styling_css_selectors.png
│ ├── styling_css_direct_child.png
│ └── styling_buttons_pixel_size.png
├── 001-Backends.md
├── 009-Native.md
├── 000-Modules.md
├── 005-Events.md
├── 004-Styling.md
└── 002-Custom Components.md
├── _screenshot_app
├── src
│ ├── haxeui-heaps.properties
│ ├── haxeui-hxwidgets.properties
│ ├── haxeui-flixel.properties
│ ├── Main.hx
│ └── MainView.hx
├── .gitmodules
├── html5.hxml
├── raylib.hxml
├── heaps-js.hxml
├── hxwidgets.hxml
├── heaps-hl.hxml
├── khafile.js
├── project.nmml
├── application.xml
├── kha-html5.hxml
├── project.xml
└── assets
│ └── main-view.xml
├── 000-Getting Started
├── _assets
│ ├── welcome-system.jpg
│ ├── hello-world-ui2.png
│ ├── hello-world-ui3.png
│ ├── hello-world-ui4.png
│ ├── hello-world-button.png
│ └── hello-world-file_tree.png
├── 003-Backends
│ ├── 000-Composite Backends
│ │ ├── _assets
│ │ │ ├── haxeui-kha-preview.png
│ │ │ ├── haxeui-nme-preview.png
│ │ │ ├── haxeui-heaps-preview.png
│ │ │ ├── haxeui-html5-preview.png
│ │ │ ├── haxeui-flixel-preview.png
│ │ │ ├── haxeui-openfl-preview.png
│ │ │ └── haxeui-raylib_preview.png
│ │ ├── 006-haxeui-raylib.md
│ │ ├── 004-haxeui-nme.md
│ │ ├── 002-haxeui-openfl.md
│ │ ├── 003-haxeui-flixel.md
│ │ ├── 005-haxeui-heaps.md
│ │ ├── 000-haxeui-html5.md
│ │ └── 001-haxeui-kha.md
│ └── 001-Native Backends
│ │ ├── _assets
│ │ ├── haxeui-hxwidgets-preview_osx.png
│ │ ├── haxeui-hxwidgets-preview_ubuntu.png
│ │ └── haxeui-hxwidgets-preview_windows.png
│ │ └── 000-haxeui-hxwidgets.md
├── 001-Installing Haxe.md
├── 005-Next Steps.md
├── 002-Installing HaxeUI.md
├── 000-Welcome.md
└── 004-Hello World.md
└── .gitignore
/README.md:
--------------------------------------------------------------------------------
1 | # haxeui-guides
--------------------------------------------------------------------------------
/001-Guides/008-Themes.md:
--------------------------------------------------------------------------------
1 | Themes
2 | ================================
--------------------------------------------------------------------------------
/001-Guides/003-Binding.md:
--------------------------------------------------------------------------------
1 | Binding
2 | ================================
--------------------------------------------------------------------------------
/001-Guides/006-Scripting.md:
--------------------------------------------------------------------------------
1 | Scripting
2 | ================================
--------------------------------------------------------------------------------
/001-Guides/007-Animation.md:
--------------------------------------------------------------------------------
1 | Animation
2 | ================================
--------------------------------------------------------------------------------
/_screenshot_app/src/haxeui-heaps.properties:
--------------------------------------------------------------------------------
1 | haxe.ui.heaps.engine.background.color=#ffffff
2 |
--------------------------------------------------------------------------------
/_screenshot_app/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Kha"]
2 | path = Kha
3 | url = https://github.com/KTXSoftware/Kha
4 |
--------------------------------------------------------------------------------
/_screenshot_app/src/haxeui-hxwidgets.properties:
--------------------------------------------------------------------------------
1 | haxe.ui.hxwidgets.frame.fit=true
2 | haxe.ui.hxwidgets.frame.title=Main
3 |
--------------------------------------------------------------------------------
/001-Guides/_assets/native_native.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/native_native.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_scope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_scope.png
--------------------------------------------------------------------------------
/001-Guides/_assets/native_dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/native_dropdown.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_spacing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_spacing.png
--------------------------------------------------------------------------------
/001-Guides/_assets/composite_dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/composite_dropdown.png
--------------------------------------------------------------------------------
/001-Guides/_assets/native_composite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/native_composite.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_css_names.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_css_names.png
--------------------------------------------------------------------------------
/_screenshot_app/html5.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main Main
3 |
4 | -lib haxeui-core
5 | -lib haxeui-html5
6 |
7 | -js build/html5/Main.js
8 |
--------------------------------------------------------------------------------
/_screenshot_app/src/haxeui-flixel.properties:
--------------------------------------------------------------------------------
1 | haxe.ui.flixel.background.color=#FFFFFF
2 | haxe.ui.flixel.mouse.useSystemCursor=true
3 |
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_angry_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_angry_button.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_butons_sizes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_butons_sizes.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_button_style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_button_style.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_buttons_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_buttons_100.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_schema_flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_schema_flow.png
--------------------------------------------------------------------------------
/000-Getting Started/_assets/welcome-system.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/welcome-system.jpg
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_absolute_layout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_absolute_layout.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_autosized_vbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_autosized_vbox.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_buttons_percent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_buttons_percent.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_css_selectors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_css_selectors.png
--------------------------------------------------------------------------------
/000-Getting Started/_assets/hello-world-ui2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/hello-world-ui2.png
--------------------------------------------------------------------------------
/000-Getting Started/_assets/hello-world-ui3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/hello-world-ui3.png
--------------------------------------------------------------------------------
/000-Getting Started/_assets/hello-world-ui4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/hello-world-ui4.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_css_direct_child.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_css_direct_child.png
--------------------------------------------------------------------------------
/_screenshot_app/raylib.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main Main
3 |
4 | -lib haxeui-core
5 | -lib haxeui-raylib
6 | -lib raylib-haxe
7 |
8 | -cpp build/raylib
9 |
--------------------------------------------------------------------------------
/000-Getting Started/_assets/hello-world-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/hello-world-button.png
--------------------------------------------------------------------------------
/001-Guides/_assets/styling_buttons_pixel_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/001-Guides/_assets/styling_buttons_pixel_size.png
--------------------------------------------------------------------------------
/000-Getting Started/_assets/hello-world-file_tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/_assets/hello-world-file_tree.png
--------------------------------------------------------------------------------
/_screenshot_app/heaps-js.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main Main
3 |
4 | -lib heaps
5 | -lib haxeui-core
6 | -lib haxeui-heaps
7 |
8 | -D resourcesPath=assets
9 |
10 | -js build/heaps/js/Main.js
11 |
--------------------------------------------------------------------------------
/_screenshot_app/hxwidgets.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main Main
3 |
4 | -lib haxeui-core
5 | -lib haxeui-hxwidgets
6 | -lib hxWidgets
7 |
8 | -D ABI=-MD
9 | -D WXSTATIC
10 |
11 | -cpp build/hxwidgets
12 |
--------------------------------------------------------------------------------
/_screenshot_app/heaps-hl.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -main Main
3 |
4 | -lib heaps
5 | -lib hlsdl
6 | -lib haxeui-core
7 | -lib haxeui-heaps
8 |
9 | -D resourcesPath=assets
10 |
11 | -hl build/heaps/hl/Main.hl
12 |
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-kha-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-kha-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-nme-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-nme-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-heaps-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-heaps-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-html5-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-html5-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-flixel-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-flixel-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-openfl-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-openfl-preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-raylib_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/000-Composite Backends/_assets/haxeui-raylib_preview.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_osx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_osx.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_ubuntu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_ubuntu.png
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_windows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/haxeui/haxeui-guides/HEAD/000-Getting Started/003-Backends/001-Native Backends/_assets/haxeui-hxwidgets-preview_windows.png
--------------------------------------------------------------------------------
/_screenshot_app/khafile.js:
--------------------------------------------------------------------------------
1 | let project = new Project('Main');
2 |
3 | //project.addAssets('./assets/**');
4 | project.addSources('./src');
5 |
6 | project.addLibrary('haxeui-core');
7 | project.addLibrary('haxeui-kha');
8 |
9 | resolve(project);
10 |
--------------------------------------------------------------------------------
/_screenshot_app/src/Main.hx:
--------------------------------------------------------------------------------
1 | package ;
2 |
3 | import haxe.ui.HaxeUIApp;
4 |
5 | class Main {
6 | public static function main() {
7 | var app = new HaxeUIApp();
8 | app.ready(function() {
9 | app.addComponent(new MainView());
10 |
11 | app.start();
12 | });
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/000-Getting Started/001-Installing Haxe.md:
--------------------------------------------------------------------------------
1 | Installing Haxe
2 | ================================
3 |
4 | Haxe is an open source high-level strictly typed programming language that allows code to be transpiled into various other languages.
5 |
6 | HaxeUI, in turn, is built on top of Haxe. The best way to install Haxe is to download the official latest distribution from the [haxe.org](http://www.haxe.org) website and follow any instructions for your operating system.
--------------------------------------------------------------------------------
/_screenshot_app/project.nmml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/_screenshot_app/application.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/000-Getting Started/005-Next Steps.md:
--------------------------------------------------------------------------------
1 | Next Steps
2 | ================================
3 |
4 | Now you have installed HaxeUI, installed a backend and compiled a "Hello World" application there are a few other resources that will help you one your way:
5 |
6 | * [component-explorer](http://haxeui.org/explorer) - Browse HaxeUI components
7 | * [playground](http://haxeui.org/builder) - Write and test HaxeUI layouts in your browser
8 | * [component-examples](https://github.com/haxeui/component-examples) - Various componet examples
9 | * [haxeui-api](http://haxeui.org/api/haxe/ui/) - The HaxeUI api docs
10 | * [haxeui-guides](http://haxeui.org/api/guides/index.html) - Set of guides to working with HaxeUI and backends
11 |
--------------------------------------------------------------------------------
/_screenshot_app/kha-html5.hxml:
--------------------------------------------------------------------------------
1 | -cp D:\Work\HaxeUI\haxeui-guides\_screenshot_app\Kha\Sources
2 | -cp D:\Work\HaxeUI\haxeui-guides\_screenshot_app\Kha\Backends\HTML5
3 | -cp D:\Work\HaxeUI\haxeui-guides\_screenshot_app\src
4 | -cp D:/work/HaxeUI/haxeui-core/
5 | -cp D:/Work/HaxeUI/backends/haxeui-kha/
6 | -D hxcpp_smart_strings
7 | -D haxeui-core
8 | -D haxeui-kha
9 | -D sys_g1
10 | -D sys_g2
11 | -D sys_g3
12 | -D sys_a1
13 | -D sys_a2
14 | -D kha_js
15 | -D kha_g1
16 | -D kha_g2
17 | -D kha_g3
18 | -D kha_a1
19 | -D kha_a2
20 | -D canvas_id=khanvas
21 | -D script_name=kha
22 | -D sys_g4
23 | -D kha_g4
24 | -D kha_webgl
25 | -D sys_html5
26 | -D kha_html5
27 | -D kha_html5_js
28 | -D kha
29 | -D kha_version=1810
30 | -D kha_project_name=Main
31 | -js build/kha/html5/kha.js
32 | -main Main
33 |
--------------------------------------------------------------------------------
/_screenshot_app/src/MainView.hx:
--------------------------------------------------------------------------------
1 | package ;
2 |
3 | import haxe.ui.containers.VBox;
4 | import haxe.ui.events.MouseEvent;
5 |
6 | @:build(haxe.ui.ComponentBuilder.build("assets/main-view.xml"))
7 | class MainView extends VBox {
8 | public function new() {
9 | super();
10 |
11 | var root = tv1.addNode({text: "Root A", icon: "haxeui-core/styles/shared/folder-light.png"});
12 | root.expanded = true;
13 | root.addNode({text: "Child A-1", icon: "haxeui-core/styles/shared/warning-small.png"});
14 | var root = tv1.addNode({text: "Root B", icon: "haxeui-core/styles/shared/folder-light.png"});
15 | root.expanded = true;
16 | root.addNode({text: "Child B-1", icon: "haxeui-core/styles/shared/help-small.png"});
17 | root.addNode({text: "Child B-2", icon: "haxeui-core/styles/shared/help-small.png"});
18 | root.addNode({text: "Child B-3", icon: "haxeui-core/styles/shared/help-small.png"});
19 | root.addNode({text: "Child B-4", icon: "haxeui-core/styles/shared/help-small.png"});
20 | }
21 | }
--------------------------------------------------------------------------------
/000-Getting Started/002-Installing HaxeUI.md:
--------------------------------------------------------------------------------
1 | Installing HaxeUI
2 | ================================
3 |
4 | Haxe comes with package manager named HaxeLib, this is the simplest method to install HaxeUI and can be achieved by opening a terminal and using the command:
5 |
6 | ```
7 | haxelib install haxeui-core
8 | ```
9 |
10 | And thats it! You now have the core library of HaxeUI installed, however, haxeui-core by itself will do little - it needs to be coupled with a [backend](backends/index.html) in order to be used.
11 |
12 | HaxeUI Command Line Tools
13 | -------------------------
14 |
15 | HaxeUI comes with an optional command line too that can make project creation that little bit simpler. It takes the form of a haxelib run command, and can be used in the following manner:
16 |
17 | ```
18 | haxelib run haxeui-core {command} {options}
19 | ```
20 |
21 | For example, to create a blank html5 project using haxeui-html5, simply create an empty directory, open a command prompt in that directory and use:
22 |
23 | ```
24 | haxelib run haxeui-core create html5
25 | ```
26 |
27 | To get help with the command line tool use
28 |
29 | ```
30 | haxelib run haxeui-core help
31 | ```
32 |
33 | _Note: You can also set up an alias for "haxelib run haxeui-core" to make commands even shorter, once that is done you can simply use things like "haxeui help" or "haxeui create html5"_
--------------------------------------------------------------------------------
/000-Getting Started/000-Welcome.md:
--------------------------------------------------------------------------------
1 | Welcome
2 | ================================
3 |
4 | This guide will serve as a starting point to get your system configured to write rich, cross platform, cross framework Haxe GUI applications.
5 |
6 | By the end of this guide you will have a fully functioning HaxeUI installation (with a least one [backend](backends/index.html)) and a simple "[Hello World](hello-world.html)" application.
7 |
8 | Backends
9 | -------------------------
10 | HaxeUI can target multiple frameworks (including native frameworks) by utilising a "backend system"
11 |
12 | 
13 |
14 | This means that the logic of HaxeUI (inside haxeui-core) is separated from the code that actually performs the drawing, or in the case of native GUIs, creates the native controls. There are many backends to choose from, and no limitation on new backends that could be written.
15 |
16 | Backends come in two flavours: Composite Backends and Native Backends
17 |
18 | #### Composite Backends
19 |
20 | Composite backends are backends that usually utilise some type of drawing framework, this means that the logic of the control is 100% handled inside HaxeUI and the drawing is delegated to the backend.
21 |
22 | One backend that is an exception this is haxeui-html5 which doesnt really "draw" anything, instead the backend is responsible for creating a set of DOM nodes
23 |
24 | #### Native Backends
25 |
26 | Native backends differ from composite backends in that the creating of the actual component is delegated to the backend, this is useful for creating 100% native user interfaces while still leveraging the outward facing HaxeUI api.
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/006-haxeui-raylib.md:
--------------------------------------------------------------------------------
1 | haxeui-raylib
2 | ================================
3 |
4 | haxeui-raylib is the RayLib backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-raylib has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-raylib can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-raylib
13 | ```
14 |
15 | ### Raylib
16 | haxeui-openfl also has a dependency on raylib-haxe, this can be installed via haxelib using the following command:
17 |
18 | ```
19 | haxelib install raylib-haxe
20 | ```
21 |
22 | You will also need to install raylib.
23 |
24 | https://github.com/raysan5/raylib/releases
25 |
26 | ## Usage
27 | The simplest method to create a new native application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-heaps create a new folder and use the following command:
28 |
29 | ```
30 | haxelib run haxeui-core create raylib
31 | ```
32 |
33 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
34 |
35 | ### Haxe build.hxml
36 |
37 | If you are using a command line build (via a .hxml file) then add these lines:
38 |
39 | ```
40 | -lib haxeui-core
41 | -lib haxeui-raylib
42 | -lib raylib-haxe
43 | ```
44 |
45 |
46 | ## Toolkit initialisation and usage
47 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
48 |
49 | ```haxe
50 | Toolkit.init();
51 | ```
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/004-haxeui-nme.md:
--------------------------------------------------------------------------------
1 | haxeui-nme
2 | ================================
3 |
4 | haxeui-nme is the NME backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 |
10 | haxeui-nme has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-nme can be installed using:
11 |
12 | ```
13 | haxelib install haxeui-nme
14 | ```
15 |
16 | ### NME
17 | haxeui-nme also has a dependency on NME, this can be installed via haxelib using the following commands:
18 |
19 | ```
20 | haxelib install nme
21 | haxelib run nme setup
22 | ```
23 |
24 | ## Usage
25 | The simplest method to create a new NME application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-nme run the following command in the folder where Kha has been installed:
26 |
27 | ```
28 | haxelib run haxeui-core create nme
29 | ```
30 |
31 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
32 |
33 | ### project.nmml
34 |
35 | Simply add the following lines to your `project.nmml`.
36 |
37 | ```xml
38 |
39 |
40 | ```
41 |
42 | ## Toolkit initialisation and usage
43 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
44 |
45 | ```haxe
46 | Toolkit.init();
47 | ```
48 |
49 | ## NME specifics
50 | As well as using the generic `Screen.instance.addComponent`, since HaxeUI components in haxeui-nme extend from `nme.display.Sprite` it is also possible to add components directly to any other NME sprite (eg: `Lib.current.stage.addChild`).
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/002-haxeui-openfl.md:
--------------------------------------------------------------------------------
1 | haxeui-openfl
2 | ================================
3 |
4 | haxeui-openfl is the OpenFL backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-openfl has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-openfl can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-openfl
13 | ```
14 |
15 | ### OpenFL
16 | haxeui-openfl also has a dependency on OpenFL, this can be installed via haxelib using the following commands:
17 |
18 | ```
19 | haxelib install openfl
20 | haxelib run openfl setup
21 | ```
22 |
23 | ## Usage
24 | The simplest method to create a new OpenFL application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-openfl create a new folder and use the following command:
25 |
26 | ```
27 | haxelib run haxeui-core create openfl
28 | ```
29 |
30 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
31 |
32 | ### project.xml / application.xml
33 | Simply add the following lines to your `project.xml` or your `application.xml`.
34 |
35 | ```xml
36 |
37 |
38 | ```
39 |
40 | ## Toolkit initialisation and usage
41 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
42 |
43 | ```haxe
44 | Toolkit.init();
45 | ```
46 |
47 | ## OpenFL specifics
48 | As well as using the generic `Screen.instance.addComponent`, since HaxeUI components in haxeui-openfl extend from `openfl.display.Sprite` it is also possible to add components directly to any other OpenFL sprite (eg: `Lib.current.stage.addChild`).
--------------------------------------------------------------------------------
/001-Guides/001-Backends.md:
--------------------------------------------------------------------------------
1 | Backends
2 | ================================
3 | A `backend` is the term used to refer to what HaxeUI uses to delegate component creation, event registration and rendering to. The core of the library (`haxeui-core`) handles layout, scripting, binding, invalidation sequence and such common tasks, whilst the backend in question is responsible for actually displaying something on screen, mapping of events from HaxeUI's generic `UIEvent` to something the host backend uses and such framework specific tasks.
4 |
5 | In general getting HaxeUI to work with one of the supported backends is fairly trivial and follows these general steps:
6 |
7 | * Install `haxeui-core`
8 | * Install haxeui backend library
9 | * Install dependencies of backend library
10 |
11 | Haxelib itself should handle these steps for you. They are only listed here for completeness.
12 |
13 | Supported Backends
14 | -------------------------
15 | The following list is all of the currently supported HaxeUI backends:
16 |
17 | Framework | Backend Library | Dependencies | Platforms |
18 | --------- | ---------------- | -------------------- | ---------
19 | Flambe | haxeui-flambe | flambe | Mobile, Browser
20 | HTML5 | haxeui-html5 | none | Browser **
21 | Kha | haxeui-kha | kha | Desktop, Mobile, Browser
22 | Luxe | haxeui-luxe | luxe | Desktop, Mobile, Browser
23 | NME | haxeui-nme | nme | Desktop, Mobile, Browser
24 | OpenFL | haxeui-openfl | openfl, lime | Desktop, Mobile, Browser
25 | PixiJS | haxeui-pixi | pixijs | Browser
26 | hxWidgets | haxeui-hxwidgets | hxWidgets, wxWidgets | Desktop **
27 | Raylib | haxeui-raylib | raylib-haxe | Desktop
28 | Heaps | haxeui-heaps | heaps | Desktop, Mobile, Browser
29 | PDCurses | haxeui-pdcurses | | Desktop
30 | Flixel | haxeui-flixel | flixel | Desktop, Mobile, Browser
31 |
32 | ** Produces OS native components
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/003-haxeui-flixel.md:
--------------------------------------------------------------------------------
1 | haxeui-flixel
2 | ================================
3 |
4 | haxeui-flixel is the Flixel backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-flixel has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-flixel can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-flixel
13 | ```
14 |
15 | ### OpenFL
16 | HaxeFlixel itself is built ontop of OpenFL and is therefore a dependency that must be installed and setup, this can be done via haxelib using the following commands:
17 |
18 | ```
19 | haxelib install openfl
20 | haxelib run openfl setup
21 | ```
22 |
23 | ### Flixel
24 | Once OpenFL is installed and setup installing HaxeFlixel can be done with the following commands:
25 |
26 | ```
27 | haxelib install flixel
28 | haxelib run lime setup flixel
29 | ```
30 |
31 | ## Usage
32 | The simplest method to create a new Flixel application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-flixel create a new folder and use the following command:
33 |
34 | ```
35 | haxelib run haxeui-core create flixel
36 | ```
37 |
38 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
39 |
40 | ### project.xml / application.xml
41 | Simply add the following lines to your `project.xml` or your `application.xml`.
42 |
43 | ```xml
44 |
45 |
46 | ```
47 |
48 | ## Toolkit initialisation and usage
49 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
50 |
51 | ```haxe
52 | Toolkit.init();
53 | ```
54 |
55 | ## Flixel specifics
56 | As well as using the generic `Screen.instance.addComponent`, since HaxeUI components in haxeui-flixel extend from `flixel.group.FlxSpriteGroup` it is also possible to add components directly to any other Flixel sprite / state (eg: `FlxState.add`).
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/005-haxeui-heaps.md:
--------------------------------------------------------------------------------
1 | haxeui-heaps
2 | ================================
3 |
4 | haxeui-heaps is the Heaps backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-heaps has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-heaps can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-heaps
13 | ```
14 |
15 | ### Heaps
16 | haxeui-heaps also has a dependency on Heaps, this can be installed via haxelib using the following command:
17 |
18 | ```
19 | haxelib install heaps
20 | ```
21 |
22 | _Important: If you want to use heaps in a desktop applicaiton (ie, via HashLink) then you also need install the SDL libraries for heaps using the following command: haxelib run install hsdl_
23 |
24 | ## Usage
25 | The simplest method to create a new native application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-heaps create a new folder and use the following command:
26 |
27 | ```
28 | haxelib run haxeui-core create heaps
29 | ```
30 |
31 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
32 |
33 | ### Haxe build.hxml
34 |
35 | If you are using a command line build (via a .hxml file) then add these lines:
36 |
37 | ```
38 | -lib heaps
39 | -lib haxeui-core
40 | -lib haxeui-heaps
41 | ```
42 |
43 | _Important: If you are using heaps in a desktop applicaiton (ie, via HashLink) then you also need include the SDL library into your application with the following: -lib hsdl_
44 |
45 | ## Toolkit initialisation and usage
46 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
47 |
48 | ```haxe
49 | Toolkit.init();
50 | ```
51 |
52 | ## Heaps specifics
53 | As well as using the generic `Screen.instance.addComponent`, since HaxeUI components in haxeui-heaps extend from `h2d.Object` it is also possible to add components directly to any other Heaps s2d object (eg: `hxd.App.s2d`).
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/000-haxeui-html5.md:
--------------------------------------------------------------------------------
1 | haxeui-html5
2 | ================================
3 |
4 | haxeui-html5 is the pure HTML5 backend for HaxeUI. It has no other framework dependency except haxeui-core itself and outputs a DOM tree.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-html5 has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-html5 can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-html5
13 | ```
14 |
15 | ## Usage
16 | The simplest method to create a new HTML5 application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-html5 create a new folder and use the following command:
17 |
18 | ```
19 | haxelib run haxeui-core create html5
20 | ```
21 |
22 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
23 |
24 | ### Haxe build.hxml
25 |
26 | If you are using a command line build (via a .hxml file) then add these two lines:
27 |
28 | ```
29 | -lib haxeui-core
30 | -lib haxeui-html5
31 | ```
32 |
33 | If you are using an IDE, like Haxe Develop, add these lines via the project settings window (or the appropriate place for your IDE of choice).
34 |
35 | ## Toolkit initialisation and usage
36 |
37 | Initialising the toolkit requires you to add this single line somewhere before you start to actually use HaxeUI in your application:
38 |
39 | ```haxe
40 | Toolkit.init();
41 | ```
42 |
43 | ## HTML5 specifics
44 |
45 | As well as using the generic `Screen.instance.addComponent`, it is also possible to add components directly to any other DOM node: the haxeui-html5 backend exposes a special element property for this purpose. Eg:
46 |
47 | ```haxe
48 | js.Browser.document.getElementById("myContainer").appendChild(main.element);
49 | ```
50 |
51 | ### Initialisation options
52 |
53 | The configuration options that may be passed to Tookit.init() are as follows:
54 |
55 | ```haxe
56 | Toolkit.init({
57 | // where 'Screen' will place components (defaults to the document body)
58 | container: js.Browser.document.getElementById("myContainer")
59 | });
60 | ```
61 |
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/000-Composite Backends/001-haxeui-kha.md:
--------------------------------------------------------------------------------
1 | haxeui-kha
2 | ================================
3 |
4 | haxeui-kha is the Kha backend for HaxeUI.
5 |
6 | 
7 |
8 | ## Installation
9 | haxeui-kha has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-kha can be installed using:
10 |
11 | ```
12 | haxelib install haxeui-kha
13 | ```
14 |
15 | ### Kha
16 | haxeui-kha also has a dependency on Kha, this can be installed in an empty directory via git using the following commands:
17 |
18 | ```
19 | git init
20 | git submodule add https://github.com/KTXSoftware/Kha
21 | git submodule update --init --recursive
22 | ```
23 |
24 | _Note: HaxeUI comes with a set of command line tools that can also perform this step for you using:
25 | haxelib run haxeui-core install kha_
26 |
27 | ## Usage
28 | The simplest method to create a new Kha application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-kha run the following command in the folder where Kha has been installed:
29 |
30 | ```
31 | haxelib run haxeui-core create kha
32 | ```
33 |
34 | ### khamake.js
35 | Simply add the following lines to your khamake.js and rebuild your project files.
36 |
37 | ```js
38 | project.addLibrary('haxeui-core');
39 | project.addLibrary('haxeui-kha');
40 | ```
41 |
42 | ## Toolkit initialisation and usage
43 | The Kha system itself must be initialised and a render loop started. This can be done by using code similar to:
44 |
45 | ```haxe
46 | class Main {
47 | public static function main() {
48 | kha.System.start({}, function ( _ ) {
49 | kha.Assets.loadEverything(function() {
50 | haxe.ui.Toolkit.init();
51 |
52 | final screen = haxe.ui.core.Screen.instance;
53 | final ui = haxe.ui.ComponentBuilder.fromFile("ui.xml");
54 |
55 | screen.addComponent(ui);
56 |
57 | kha.System.notifyOnFrames(function( framebuffers: Array ) {
58 | final fb = framebuffers[0];
59 | final g2 = fb.g2;
60 | g2.begin(true, kha.Color.White);
61 | screen.renderTo(g2);
62 | g2.end();
63 | });
64 | });
65 | });
66 | }
67 | }
68 | ```
69 |
70 | ## HTML5 specifics
71 | As well as using the generic `Screen.instance.addComponent`, it is also possible to render a component to a specific surface use the components special `renderTo` function. Eg:
72 |
73 | ```haxe
74 | main.renderTo(...);
75 | ```
--------------------------------------------------------------------------------
/001-Guides/009-Native.md:
--------------------------------------------------------------------------------
1 | Native
2 | ================================
3 |
4 |
5 |
6 | | Composite | Native |
7 | | ------------------------------------------------------------ | ------------------------------------------------------------ |
8 | | Built entirely out of HaxeUI components  | Creation delegated to backend  |
9 | | Themes are applicable | Themes most likely selective at best |
10 | | Consistent yet custom look & feel  | Look & feel matches host operating system  |
11 | | Every visible aspect configurable via CSS | Hard to create totally custom UIs |
12 | | Logic layout handed via core | Reports size back into core(if autosized) |
13 |
14 |
15 |
16 | Hybrid user interfaces
17 |
18 | - Mix and match composite and native components
19 | - Get best of both worlds
20 | - "Fill in gaps" in native toolkits
21 |
22 | There are no hybrid user interface for now. HTML5 was an hybrid interface, but it is now a pure composite one.
23 |
24 |
25 |
26 | ## How does "native" work
27 |
28 |
29 | Native means that instead of using the normal haxeui-core class it will use one specific to the platform
30 |
31 | So for dropdowns, in haxe-ui hxWidgets instead of using `haxe.ui.components.DropDown` it will use `hx.widgets.Choice` . It will also replace behaviours events, with the native ones.
32 |
33 | ```xml
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ```
47 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .vscode
8 | .haxeui
9 | .metadata
10 | bin/
11 | tmp/
12 | *.tmp
13 | *.bak
14 | *.swp
15 | *~.nib
16 | local.properties
17 | .classpath
18 | .settings/
19 | Kha/
20 | .loadpath
21 |
22 | # External tool builders
23 | .externalToolBuilders/
24 |
25 | # Locally stored "Eclipse launch configurations"
26 | *.launch
27 |
28 | # CDT-specific
29 | .cproject
30 |
31 | # PDT-specific
32 | .buildpath
33 |
34 |
35 | #################
36 | ## Visual Studio
37 | #################
38 |
39 | ## Ignore Visual Studio temporary files, build results, and
40 | ## files generated by popular Visual Studio add-ons.
41 |
42 | # User-specific files
43 | *.suo
44 | *.user
45 | *.sln.docstates
46 |
47 | # Build results
48 | *_i.c
49 | *_p.c
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.vspscc
64 | .builds
65 | *.dotCover
66 |
67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
68 | #packages/
69 |
70 | # Visual C++ cache files
71 | ipch/
72 | *.aps
73 | *.ncb
74 | *.opensdf
75 | *.sdf
76 |
77 | # Visual Studio profiler
78 | *.psess
79 | *.vsp
80 |
81 | # ReSharper is a .NET coding add-in
82 | _ReSharper*
83 |
84 | # Installshield output folder
85 | [Ee]xpress
86 |
87 | # DocProject is a documentation generator add-in
88 | DocProject/buildhelp/
89 | DocProject/Help/*.HxT
90 | DocProject/Help/*.HxC
91 | DocProject/Help/*.hhc
92 | DocProject/Help/*.hhk
93 | DocProject/Help/*.hhp
94 | DocProject/Help/Html2
95 | DocProject/Help/html
96 |
97 | # Click-Once directory
98 | publish
99 |
100 | # Others
101 | [Bb]in
102 | [Oo]bj
103 | sql
104 | TestResults
105 | *.Cache
106 | ClientBin
107 | stylecop.*
108 | ~$*
109 | *.dbmdl
110 | Generated_Code #added for RIA/Silverlight projects
111 |
112 | # Backup & report files from converting an old project file to a newer
113 | # Visual Studio version. Backup files are not needed, because we have git ;-)
114 | _UpgradeReport_Files/
115 | Backup*/
116 | UpgradeLog*.XML
117 |
118 |
119 |
120 | ############
121 | ## Windows
122 | ############
123 |
124 | # Windows image file caches
125 | Thumbs.db
126 |
127 | # Folder config file
128 | Desktop.ini
129 |
130 |
131 | #############
132 | ## Python
133 | #############
134 |
135 | *.py[co]
136 |
137 | # Packages
138 | *.egg
139 | *.egg-info
140 | dist
141 | build
142 | eggs
143 | parts
144 | bin
145 | var
146 | sdist
147 | develop-eggs
148 | .installed.cfg
149 |
150 | # Installer logs
151 | pip-log.txt
152 |
153 | # Unit test / coverage reports
154 | .coverage
155 | .tox
156 |
157 | #Translations
158 | *.mo
159 |
160 | #Mr Developer
161 | .mr.developer.cfg
162 |
163 | # Mac crap
164 | .DS_Store
165 |
166 |
167 | *.backup
168 | dox.xml
--------------------------------------------------------------------------------
/_screenshot_app/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/_screenshot_app/assets/main-view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/000-Getting Started/004-Hello World.md:
--------------------------------------------------------------------------------
1 | Hello World
2 | ================================
3 |
4 | Assuming you have now installed HaxeUI and at least one backend a "Hello World" application is a good place to start. In this section we will be using the haxeui-html5 backend as its quick to compile and has zero other dependecies, however, once this application is complete its trivial to add another backend to the same application!
5 |
6 | Project Creation
7 | -------------------------
8 | The first thing we want to do is to use the HaxeUI command line tools to create a simple project for us. Create an empty directory somewhere, open a command prompt in that directory and use the following command:
9 |
10 | ```
11 | haxelib run haxeui-core create html5
12 | ```
13 |
14 | This command will create a few files and folders inside your root directory:
15 |
16 | 
17 |
18 | * **src/Main.hx** - this is the main entry point for the HaxeUI application, in this example it uses the optional cross framework HaxeUIApp which means its is trivial to run the same code on multiple backends
19 | * **assets/main-view.xml** - HaxeUI allows you to optionally use a markup lanugage (like xml) to design your views, these can later be converted into code at compile time. This file will be used inside the main application entry point.
20 | * **html5.hxml** - this is the build file for the haxeui-html5 version of this application, generally, when you later add more backends to this example only new build files will appear
21 |
22 | Building and Running
23 | -------------------------
24 | Compiling and exeucting this application couldnt be simpler, in the same terminal window simply use:
25 |
26 | ```
27 | haxe html5.hxml
28 | ```
29 |
30 | In a second or two the haxe command will complete and you will have a `Main.js` along side the `index.html` in the `build/html5` folder. Simply open that file in any browser by double clicking on it and you will see a basic button:
31 |
32 | 
33 |
34 | And thats it! You now have a functioning HaxeUI application, that is ready to have more components and controls added to it!
35 |
36 |
37 | Adding Components
38 | -------------------------
39 | There are two main ways to add components in HaxeUI: via markup like XML, or by using Haxe code. They can be used interchangeably and whether you choose one or the other is mostly a matter of taste, although generally using markup seperates your layout code from your application logic better.
40 |
41 | #### Adding Components via XML
42 |
43 | HaxeUI allows you add your components using a markup language like XML, this is generally a better option for applications that have big UIs as managing the view creation and layout via code can become unweidly and a mental burden for large applications. Its also generally better to seperate layout from logic and using XML can help greatly in this regard.
44 |
45 | _Note: HaxeUI comes with XML support out of the box, but the parsing of that XML into something that can be used to create code is abstracted meaning that other markup languages (like JSON or YAML) can be plugged in, even custom markup would be possible!_
46 |
47 | Building on the previous example, all we need to do is open `assets/main-view.xml` in a text editor and add more compents to it, for example:
48 |
49 | ```xml
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | ```
83 |
84 | 
85 |
86 | Obviously this is a very simple example and in no way shows the full component set of HaxeUI, but its a good introduction into how to add components via XML
87 |
88 | #### Adding Components via Code
89 |
90 | Components can also be added using regular haxe code, although its perfectly acceptable to add components in this way, it can become hard to move components around once an application gets a little larger. To build on the previous example we can open `src/Main.hx` and add the following pretty much anywhere in the `app.ready` callback:
91 |
92 | ```haxe
93 | app.ready(function() {
94 | var mainView:Component = ComponentBuilder.fromFile("assets/main-view.xml");
95 | app.addComponent(mainView);
96 |
97 | var hbox = new HBox();
98 | var button = new Button();
99 | button.text = "Button A";
100 | hbox.addComponent(button);
101 | var button = new Button();
102 | button.text = "Button B";
103 | hbox.addComponent(button);
104 | var button = new Button();
105 | button.text = "Button C";
106 | hbox.addComponent(button);
107 | mainView.addComponent(hbox);
108 |
109 | app.start();
110 | });
111 | ```
112 |
113 | 
114 |
115 | As you can see, we have now added another set of horizontal buttons on the bottom of the main view via code. You may also be able to tell that although perfectly functional, this method of adding components can get very out of hand for applications with 100s of components.
116 |
117 | _Note: HaxeUI can further help you split up your UI into smaller, more managable peices by the use of custom components / views, more information can be found out about them in "Next Steps"_
118 |
119 | Adding Another Backend
120 | -------------------------
121 | The final part to this "Hello World" application is to show how powerful the backend system is inside HaxeUI by adding another backend to this example application. In this case we will be using haxeui-hxwidgets, this is a native backend and has quite alot of dependencies which must be installed and worked.
122 |
123 | If you arent interested in native UIs or the cross framework capabilities of HaxeUI you can stop now and head over to next steps.
124 |
125 | In order to add another backend to the existing project simply go back to the command prompt used earlier and use:
126 |
127 | ```
128 | haxelib run haxeui-core create hxwidgets
129 | ```
130 |
131 | This will create files for the haxeui-hxwidgets backend but wont overwrite any existing files, meaning the changes made so far will be unaffected. You should now have a `hxwidgets.hxml` file in the root directory. To compile simply use:
132 |
133 | ```
134 | haxe hxwidgets.hxml
135 | ```
136 |
137 | This may take a little time (since it will be using C++) but once complete you should have an executable in the `build/hxwidgets` folder named `Main`
138 |
139 | Since this HaxeUI application is 100% native it may look different on different systems, for example this what it looks like on Windows 10:
140 |
141 | 
142 |
143 |
144 |
--------------------------------------------------------------------------------
/001-Guides/000-Modules.md:
--------------------------------------------------------------------------------
1 | Modules
2 | ================================
3 | Modules are a fundamental part of HaxeUI. Everything from an application to a library is considered a module in HaxeUI terms. The core of HaxeUI (`haxeui-core`) is itself a module.
4 |
5 | Modules allow you to do and configure many things inside and application/library:
6 |
7 | * Compile resources into an application (as haxe resources)
8 | * Expose component classes and packages
9 | * Create component classes from markup (eg: xml) files
10 | * Set-up which classes scriptlets have access to (and stop them be eliminated by dead code elimination)
11 | * Create and append to themes
12 |
13 | Creation
14 | -------------------------
15 | Modules themselves are simply files that contain markup. By default HaxeUI supports xml. It is, however, possible to inject custom parsers into the the module parsing engine should the need arise.
16 |
17 | To create a module simply create a file called `module.xml` (this example uses xml) somewhere on your classpath. HaxeUI will automatically find this file and load it as part of its module processing phase.
18 |
19 | The next step is to simply add the required root node to the xml file:
20 |
21 | ```xml
22 |
23 |
24 | ```
25 | _Note: the id attribute is optional but recommended_
26 |
27 | Resources
28 | -------------------------
29 | Modules allow you to compile resources directly into your application as haxe resources. This is useful as if you were to share a library you might want to use this feature to make sure that any required resource files would always be available. For example, `haxeui-core` compiles a few small images into the application by default to be used by the default theme. This means that these resources will be available to any and all supported backends without the need for the client application do include them in some framework specific way.
30 |
31 | _Note: from an API perspective you never need to think about if a resource is a haxe resource or a backend specific resource. When you use resource in HaxeUI the framework will work out if its a haxe resource or not and automatically convert it into the correct type for the framework that is currently being used._
32 |
33 | To set-up a module to discover and compile in resources, use the `` node. Here is an example from the `haxeui-core` module:
34 |
35 | ```xml
36 |
37 |
38 |
39 | ```
40 |
41 | * `path` specifies where on the classpath to look for resources.
42 | * `prefix` specifies what name should be added before the resolved resource path
43 |
44 | The resource compilation stage is fully recursive meaning all files in all folders will be discovered and added as haxe resources. The prefix is important if you want to make your names a little more user friendly. Assuming you had the following folder structure:
45 |
46 | ```
47 | haxe
48 | |-- ui
49 | |-- _module
50 | |-- styles
51 | |-- myimage.png
52 | |-- myfolder
53 | |-- myotherimage.png
54 | ```
55 |
56 | Then you would end up with this resource names:
57 |
58 | * haxeui-core/styles/myimage.png
59 | * haxeui-core/styles/myfolder/myotherimage.png
60 |
61 | Components
62 | -------------------------
63 | Within HaxeUI its necessary to let the framework know what components should be available to a given application. This is also achieved via modules. It lets the framework know what classes or packages to scan looking for classes that extend `Component` and register them in the component registry. This stage is required mainly to allow for xml (and other mark up) to be used to be build user interfaces. If a component wasnt registered in a module then it is still fully accessible to normal haxe code, it however, wouldnt be available to xml (or markup based) UI definitions.
64 |
65 | To register components, or sets of components with the framework simply use the `` node. Here is an example from the `haxeui-core` module:
66 |
67 | ```xml
68 |
69 |
70 |
71 |
72 |
73 |
74 | ```
75 |
76 | * `name` specifies which class is extended from `Component`
77 | * `package` specifies an entire package to scan
78 |
79 |
80 | Its important to realise that having these classes registered via the module makes no guarantee that they wont be eliminated by dead code elimination if they havent been used in an application.
81 |
82 | ## Components from XML
83 |
84 | It is also possible to create entire custom components from XML alone and a later use them in either markup or in code. This is also achieved by using the `module.xml`:
85 |
86 | ```xml
87 |
88 |
89 |
90 |
91 | ```
92 |
93 | * `file` specifies an xml file to use when building a custom component class
94 | * `folder`allows the creation of multiple custom component classes from a folder
95 |
96 | As an example, suppose you had the following directory structure:
97 |
98 | ```
99 | custom
100 | |-- sub
101 | |-- custom2.xml
102 | |-- custom3.xml
103 | |-- custom1.xml
104 |
105 | ```
106 |
107 | When this is used with the module configuration above you would end up with 3 new haxe classes (that can be used in code):
108 |
109 | * `custom.Custom1`
110 | * `custom.sub.Custom2`
111 | * `custom.sub.Custom3`
112 |
113 | you would also end up with three entries in the class registry for use with markup (xml):
114 |
115 | * ``
116 | * ``
117 | * ``
118 |
119 | There are many ways to create custom components in HaxeUI, this is simply one of them, see "Custom Components" for a more detailed list
120 |
121 | Scripting
122 | -------------------------
123 | HaxeUI supports a fully feature scripting environment provided via `hscript`. This can allow very quick debugging and dynamic functionality to an application with ease. Setting up certain configurations in the module can greatly help with basic scripting issues, namely class naming and dead code elimination.
124 |
125 | The first slight annoyance is that in `hscript` you have to use fully qualified names since there is no such things as `import` statements. This means to create button dynamically in a HaxeUI `scriptlet` you would have to do something similar along then lines of:
126 |
127 | ```haxe
128 | var button = new haxe.ui.components.Button();
129 | ```
130 |
131 | This is fine of course, but it would be nicer to not have to think about quite so much and just use `Button`. This is achieved by _registering_ which classes will be available to scripts so that the script interpreter can intercept calls to `new`and decide to substitute a fully qualified path. An example would be:
132 |
133 | ```xml
134 |
135 |
136 |
137 | ```
138 |
139 | This lets HaxeUI know that the class `Component` and all the classes in `haxe.ui.components` and `haxe.ui.containers` should be able to be referred to by just thier class name. With this in _any_ module, we can use sciptlets like the following:
140 |
141 | ```haxe
142 | var button = new Button();
143 | var view = new ScrollView();
144 | ```
145 |
146 | This however, does not mean that this scriptlet would run correctly. If dead code elimination is enabled (and it should be) then the haxe compiler would have no idea that these classes are actually going to be used in the application (unless they are used else where in _real_ haxe code). To remedy this we could use the `keep` attribute in the module:
147 |
148 | ```xml
149 |
150 |
151 | ```
152 | These classes will now be marked using meta data so the haxe compiler will stop them from being dead code eliminated.
153 |
154 | _Note: the `keep` attribute can also be used for entire package_
155 |
156 | The final thing the module can do in regards to scriptlets is to allow the addition of helper classes to be automatically included in the scripting environment. This is simply achieved with the `static` attribute as shown below:
157 |
158 | ```xml
159 |
160 |
161 | ```
162 |
163 | The haxe utility classes `Std` and `Math` will now be available for use inside every scripting environment created.
164 |
165 | _Note: dead code elimination also applies to helper classes and so these are also marked as `keep`_
166 |
167 | For completeness the following listing shows how things are configured by default via the `haxeui-core` module:
168 |
169 | ```xml
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | ```
181 |
182 | Themes
183 | -------------------------
184 | Modules are a good place to create and extend themes that are available to HaxeUI. They can be defined simply by using the `` node. Here is an example from the `haxeui-core` module:
185 |
186 | ```xml
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | ```
199 |
200 |
201 |
--------------------------------------------------------------------------------
/001-Guides/005-Events.md:
--------------------------------------------------------------------------------
1 | Events
2 | ================================
3 |
4 |
5 | An event is a signal that the system fires to tell something has occured. Code can be written to listen to this signal and act on it.
6 |
7 | There are many types of events, here are a few examples:
8 | - it can be mouse event, the user has clicked a component
9 | - it can be a UI event, a component has been shown
10 | - it can be keyboard event, something has been typed
11 | - and many others
12 |
13 | Haxe-ui provides multiple easy ways to listen to these events.
14 |
15 | ## Listening to events
16 |
17 |
18 | ### The XML way
19 |
20 | Using xml, it is easy to listen to events. For example:
21 |
22 | ```xml
23 |
24 |
25 |
26 | ```
27 |
28 | will trace something if you click on the red box.
29 |
30 |
31 | Let's look at the actual code produced by haxeui
32 |
33 | ```haxe
34 | c0.registerEvent("click", function(event:haxe.ui.events.UIEvent) {
35 | var __this__ = c0;
36 | {
37 | `trace("you clicked on red", {fileName : "src/MainView.hx", lineNumber : 6, className : "MainView", methodName : "new"});
38 | };
39 | });
40 | ```
41 |
42 | What does it teach us ?
43 |
44 | First thing, to listen to an event, you just have to know the event name, and do `on`+ the name of the event type.
45 | `onclick`, `onClick`, `onCLICK` all work.
46 |
47 | This work for any events `onShown`, `onReady`, etc also work
48 |
49 | Second thing, is that you have also access to the event instance, by using the `event` variable.
50 |
51 | ```xml
52 |
53 |
54 |
55 | ```
56 |
57 |
58 | ### In Code
59 |
60 | #### Using the macro "@:bind"
61 |
62 | You can use the macro bind, which is quite convenient
63 |
64 | `@:bind(component, event)`
65 |
66 | ```haxe
67 | @:bind(button, MouseEvent.CLICK)
68 | function onClickButton(_) {
69 | trace("you've just clicked on the button");
70 | }
71 | ```
72 |
73 | let's look at the produced haxe code
74 |
75 | ```haxe
76 | public function new() {
77 | var _gthis = this;
78 | super();
79 | [...]
80 | var c = this.button;
81 | if ((c != null)) c.registerEvent(haxe.ui.events.MouseEvent.CLICK, this.onClickButton) else `trace("WARNING: could not find component to register event (" + "this" + ")", {fileName : "src/MainView.hx", lineNumber : 12, className : "MainView", methodName : "new"});
82 |
83 | ```
84 |
85 | You can use multiple binds before a function
86 | ```haxe
87 | @:bind(button, MouseEvent.CLICK)
88 | @:bind(button1, MouseEvent.CLICK)
89 | function onClickButton(_) {
90 | trace("you've just clicked on some button");
91 | }
92 | ```
93 |
94 |
95 | You can actually bind an event to whatever component you can access in the class which exist at the creation of the component so `this` or `button`.
96 | You cannot access `parentComponent` for example, because the parentComponent is set when the component is added to its parent, which is after the creation of the component.
97 |
98 | ```haxe
99 | @:bind(this, MouseEvent.CLICK)
100 | function onClickButton(_) {
101 | trace("you've just clicked me");
102 | }
103 | ```
104 |
105 | This brings on to the registerEvent method
106 |
107 | #### Using the register event method
108 |
109 | To register events to a component you can use directly the haxe function `registerEvent`.
110 |
111 | Here is the definition
112 |
113 | ```haxe
114 | registerEvent(type:EventType, listener:T->Void, priority:Int = 0)
115 | ```
116 |
117 | Using directly the function enables us to set the priority parameter which is useful when registering multiple time the same events
118 |
119 | ```haxe
120 | registerEvent(haxe.ui.events.MouseEvent.CLICK, function(e){ trace("written second"); }, 88);
121 | registerEvent(haxe.ui.events.MouseEvent.CLICK, function(e){ trace("written first"); }, 888);
122 | ```
123 |
124 | Or to make an event happen before the default haxeui behaviour.
125 |
126 | The bigger the number, the higher the priority.
127 |
128 |
129 | Using the function makes it more natural to also unregisterEvents.
130 |
131 | ```haxe
132 | registerEvent(haxe.ui.events.MouseEvent.CLICK, doStuff, 888);
133 | unregisterEvent(haxe.ui.events.MouseEvent.CLICK, doStuff);
134 | ```
135 |
136 | You don't need to unregister events. *Events that are attached to components are automatically unregistered when the components are destroyed.*
137 |
138 | But if you only use once the type of event, and want to register and unregister multiple times a function, better to use a convenience variable.
139 |
140 | #### Using the convenience variables
141 |
142 | Components have convenience pvariables for most used events.
143 |
144 | `onChange`
145 |
146 | `onClick`
147 | `onMouseOver`
148 | `onMouseOut`
149 | `onDblClick`
150 | `onRightClick`
151 |
152 | `onDragStart`
153 | `onDrag`
154 | `onDragEnd`
155 | `onAnimationStart`
156 | `onAnimationFrame`
157 | `onAnimationEnd`
158 |
159 | The make it easy to change functions to trigger without having to unregister the event
160 |
161 | ```haxe
162 | onClick = function(e) {
163 | // do stuff;
164 | onClick = function(e) {
165 | // do different stuff now
166 | }
167 | }
168 |
169 | ```
170 |
171 | #### Overriding functions
172 |
173 |
174 | There is also another way to change default events of a component.
175 | Simply by overriding the registered called functions.
176 |
177 | For example,
178 |
179 | ```haxe
180 | public override function onReady() {
181 | super.onReady();
182 | // do stuff
183 | }
184 | ```
185 |
186 | You can also the same for `onInitialize()`, `onResized()` and others depending on the component
187 |
188 |
189 |
190 | ## Type of events
191 |
192 | There are many events that are generated by haxeui. Let's look at some of some them
193 |
194 |
195 | ### UI Events
196 |
197 | UI events are usually attached to a component
198 |
199 | #### CHANGE
200 |
201 | A `change` event is dispatched when the value of the component has changed.
202 |
203 | #### READY
204 |
205 | A `ready` event is dispatched when the value when size is calculated
206 |
207 | #### RESIZE
208 |
209 | A `resize` event is dispatched when the value of the component has been resized.
210 |
211 | #### DESTROY
212 | #### INITIALIZE
213 | #### MOVE
214 | #### HIDDEN
215 | #### SHOWN
216 | #### ENABLED
217 | #### DISABLED
218 | #### COMPONENT_ADDED
219 | #### COMPONENT_REMOVED
220 | #### COMPONENT_ADDED_TO_PARENT
221 | #### COMPONENT_REMOVED_FROM_PARENT
222 |
223 |
224 | #### Others are specific to certain components
225 |
226 | - BEFORE_CHANGE
227 | - SUBMIT_START
228 | - SUBMIT
229 | - RENDERER_CREATED
230 | - RENDERER_DESTROYED
231 | - BEFORE_CLOSE
232 | - CLOSE
233 | - PROPERTY_CHANGE
234 |
235 |
236 | ### Mouse Events
237 |
238 |
239 |
240 |
241 | ### Keyboard Events
242 |
243 | You don't attach keyboard events to a component but to a screen instance.
244 | That's why you musn't forget to unregister it
245 |
246 | ```haxe
247 | function shortcut (e) {
248 | // function
249 | }
250 | Screen.instance.registerEvent(KeyboardEvent.PRESS, shortcut)
251 |
252 | registerEvent(UIEvent.DESTROY, function f(e) {
253 | Screen.instance.unregisterEvent(KeyboardEvent.PRESS, shortcut)
254 | });
255 | ```
256 |
257 |
258 | ### Action Events
259 |
260 | Action events are a way to separate the intention of the event from the source of it.
261 |
262 | It works a little differently than other events.
263 | There are only two types
264 | ```haxe
265 | ACTION_START // when the action starts
266 | ACTION_END // when the action stops
267 | ```
268 |
269 | For most actions, you only need to use `ACTION_START`.
270 | `ACTION_END` is mostly used by button release or keys up.
271 |
272 |
273 |
274 | Then you have to switch on the type of action to know which it was
275 | ```haxe
276 | @:bind(this, ActionEvent.ACTION_START)
277 | private function onActionStart(event:ActionEvent) {
278 | switch (event.action) {
279 | case ActionType.DOWN:
280 | goDown();
281 | case ActionType.UP:
282 | goUp();
283 | case ActionType.LEFT:
284 | goLeft();
285 | case ActionType.RIGHT:
286 | goRight();
287 | case _:
288 | }
289 | }
290 | ```
291 |
292 |
293 | For example, there are multiple action types
294 | ```haxe
295 | var PRESS = "actionPress";
296 | var LEFT = "actionLeft";
297 | var RIGHT = "actionRight";
298 | var UP = "actionUp";
299 | var DOWN = "actionDown";
300 | var NEXT = "actionNext";
301 | var PREVIOUS = "actionPrevious";
302 | var BACK = "actionBack";
303 | var OK = "actionOK";
304 | var CONFIRM = "actionConfirm";
305 | var CANCEL = "actionCancel";
306 | ```
307 |
308 |
309 | These actions can be produced by multiple sources a keyboard, a keypad, a mouse, the buttons of a smartphone, a touchscreen etc. But all will send the correct action if they are registered and configured correctly.
310 | By default, only keyboards are configured and registered.
311 |
312 | There are multiple advantages of using action events.
313 |
314 | - having multiple sources for the same event
315 | - being able to configure the source as you wish. You can imagine, some keyboard players setting the wasd keyboard for example.
316 | - having these events attached to a component instead of the screen for keyboard events, it makes it easier to manage.
317 |
318 |
319 |
320 | Actions sources are added in the module
321 |
322 | ```xml
323 |
324 |
325 |
326 | ```
327 |
328 |
329 |
330 | ### Repeating events
331 |
332 | Some actions can be considered repeated if they haven't ended.
333 | For example, if you do an `ActionType.DOWN` when typing the the down arrow. You usually want multiple events to dispatch even if you only pressed the down button once.
334 |
335 | The event will continue to dispatch until there's a `ACTION_END` that happens.
336 |
337 | In this case you can set up the `event.repeater` to `true`
338 | To control the interval between each dispatching of the event.
339 | You can use the `actionRepeatInterval` variable of the component.
340 |
341 | ```haxe
342 | actionRepeatInterval = 100; // this is the default, it's in ms
343 | @:bind(this, ActionEvent.ACTION_START)
344 | private function onActionStart(event:ActionEvent) {
345 | switch (event.action) {
346 | case ActionType.DOWN:
347 | goDown();
348 | // If the user one ActionType.DOWN, by pressing the the key
349 | // Every 100ms an event will be dispatched until the user release the key.
350 | event.repeater = true;
351 | case _:
352 | }
353 | }
354 | ```
355 |
356 | ## Pausing and resuming events
357 |
358 | You can pause event by using the function `pauseEvent(type:String, recursive:Bool = false)`
359 |
360 | and `resumeEvent(type:String, recursive:Bool = false)`
361 |
362 | ## Canceling events
363 |
364 |
365 |
366 | ## Creating your own custom events
367 |
368 |
369 |
370 |
371 |
372 |
--------------------------------------------------------------------------------
/000-Getting Started/003-Backends/001-Native Backends/000-haxeui-hxwidgets.md:
--------------------------------------------------------------------------------
1 | haxeui-hxwidgets
2 | ================
3 |
4 | haxeui-hxwidgets is the wxWidgets backend for HaxeUI. It produces a GUI that is built from native components via the wxWidgets framework
5 |
6 | 
7 |
8 | 
9 |
10 | 
11 |
12 | ## Installation
13 |
14 | haxeui-hxwidgets has a number of dependencies since it produces native components via the wxWidgets library.
15 |
16 | ### wxWidgets
17 |
18 | wxWidgets is a C++ library that lets developers create applications for Windows, macOS, Linux and other platforms with a single code base. This is the library that haxeui-hxwidgets uses to create native components (via its haxe externs hxWidgets).
19 |
20 | ### wxWidgets - Windows
21 |
22 | * Download and install wxWidgets using installer from https://www.wxwidgets.org/downloads/
23 | * Create `WXWIN` environment var if setup didnt (eg: `C:\wxWidgets-3.0.2`)
24 | * Run `vcvarsall.bat` from Visual Studio dir (eg: `"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"`)
25 | * Build shared and static releases of wxWidgets:
26 | * `cd %WXWIN%\build\msw\`
27 | * `nmake.exe -f makefile.vc BUILD=release`
28 | * `nmake.exe -f makefile.vc BUILD=release SHARED=1`
29 |
30 | ### wxWidgets - OSX
31 |
32 | You need at least OSX 10.7 and you can install wxWidgets with:
33 |
34 | ```
35 | brew update
36 | brew install wxwidgets
37 | ```
38 |
39 | ### wxWidgets - Linux
40 |
41 | wxWidgets can be installed on debian/ubuntu with:
42 |
43 | debian/ubuntu 20.04 (or later):
44 |
45 | ```
46 | apt-get install libwxgtk3.0-gtk3-dev libwxbase3.0-dev libwxgtk-webview3.0-gtk3-dev
47 | ```
48 |
49 | debian/ubuntu (older versions):
50 |
51 | ```
52 | apt-get install libwxgtk3.0-dev libwxbase3.0-dev libwxgtk-webview3.0-dev
53 | ```
54 |
55 | _Important: while using the packaged wxWidgets on OSX and Linux may suffice they are often fairly out of date and can cause various problems both visually and during compilation. Its usually better to build directly from source, for these platforms this is described below._
56 |
57 | ### wxWidgets - Building From Source (OSX & Linux)
58 |
59 | Often it is useful to have the most up-to-date version of wxWidgets running on a Linux or OSX system, to do this follow these steps:
60 |
61 | * download source archive from: https://www.wxwidgets.org/downloads/
62 | * unzip to, for example: `/home/users/username/wxwidgets3.1.3/`
63 | * create a folder there: `mkdir wx_build`
64 | * enter folder: `cd wx_build`
65 | * `configure: ../configure --with-opengl --disable-shared`
66 | * if you get errors during configure you likely need to run one (or all) of the following (on linux):
67 | * sudo apt install build-essential
68 | * sudo apt install libgtk2.0-dev
69 | * sudo apt install libgtk-3-dev
70 | * sudo apt install freeglut3-dev
71 | * make: `make`
72 | * once built, install: `make install` (may need sudo if not default `/usr/local` location)
73 | * wx-config --version should now show the version you just built
74 | * you may need to add the unzip folder to your `$PATH` var if it doesnt show the right version
75 |
76 | ### hxWidgets
77 |
78 | hxWidgets is a set of externs (and wrappers) for haxe that allows haxeui-hxwidgets to use the wxWidgets C++ library from Haxe. This can be installed from HaxeLib as follows:
79 |
80 | ```
81 | haxelib install hxcpp
82 | haxelib install hxWidgets
83 | ```
84 |
85 | ### haxeui-hxwidgets
86 |
87 | Now you have both wxWidgets and hxWidgets installed, you can install haxeui-hxwidgets. This has a dependency to haxeui-core, and so that too must be installed. Once haxeui-core is installed, haxeui-hxwidgets can be installed using:
88 |
89 | ```
90 | haxelib install haxeui-hxwidgets
91 | ```
92 |
93 | ## Usage
94 |
95 | The simplest method to create a new native application that is HaxeUI ready is to use the HaxeUI command line tools. These tools will allow you to start a new project rapidly with HaxeUI support baked in. To create a new skeleton application using haxeui-hxwidgets create a new folder and use the following command:
96 |
97 | ```
98 | haxelib run haxeui-core create hxwidgets
99 | ```
100 |
101 | If however you already have an existing application, then incorporating HaxeUI into that application is straightforward:
102 |
103 | ### Haxe build.hxml
104 |
105 | If you are using a command line build (via a .hxml file) then add these three lines:
106 |
107 | ```
108 | -lib hxWidgets
109 | -lib haxeui-core
110 | -lib haxeui-hxwidgets
111 | ```
112 |
113 | ## Toolkit initialisation and usage
114 |
115 | The hxWidgets application itself must be initialised and an event loop started. This can be done by using code similar to:
116 |
117 | ```haxe
118 | static function main() {
119 | var app = new App();
120 | app.init();
121 |
122 | var frame:Frame = new Frame(null, "My App");
123 | frame.resize(800, 600);
124 |
125 | frame.show();
126 | app.run();
127 | app.exit();
128 | }
129 | ```
130 |
131 | Initialising the toolkit requires you to add these lines somewhere before you start to actually use HaxeUI in your application and after the hxWidgets frame has been created:
132 |
133 | ```haxe
134 | Toolkit.init({
135 | frame: frame // the frame on which 'Screen' will place components
136 | });
137 | ```
138 |
139 | _Note: The skeleton project that is created when using the command line tools uses the HaxeUI universal Application class which handles the creation of the top level frame as well as the event loop (and some other parts), and although not mandatory, is a much easier way to handle application lifecycle and initialisation_
140 |
141 | ## hxWidgets specifics
142 |
143 | Components in haxeui-hxwidgets expose a special window property that allows you to access the hxWidgets Window, this could then be used in other UIs that arent using HaxeUI components.
144 |
145 | ### Initialisation options
146 |
147 | The configuration options that may be passed to Tookit.init() are as follows:
148 |
149 | ```haxe
150 | Toolkit.init({
151 | frame: frame // the frame on which 'Screen' will place components
152 | });
153 | ```
154 |
155 | ### haxeui-hxwidgets.properties
156 |
157 | In the file `haxeui-hxwidgets.properties`, you can set a few properties specific to hxwidgets
158 | You can have all these properties
159 |
160 |
161 | | property | type | description |
162 | | ------------------------------------- | :-------- | --------------------------------------------------------------------------------------------------------------------------- |
163 | | haxe.ui.hxwidgets.frame.fit | boolean | will resize the top level frame to the contents of the UI |
164 | | haxe.ui.hxwidgets.frame.title | string | the title of the frame, you dont have to set it here, but its an easy way. |
165 | | haxe.ui.hxwidgets.frame.width | number | the default width of the main frame (800 if not set), note, this property is ignored if haxe.ui.hxwidgets.frame.fit=true |
166 | | haxe.ui.hxwidgets.frame.height | number | the default height of the main frame (600 if not set), note, this property is ignored if haxe.ui.hxwidgets.frame.fit=true |
167 | | haxe.ui.hxwidgets.frame.minWidth | number | the minimum width of the main frame (-1 if not set) |
168 | | haxe.ui.hxwidgets.frame.minHeight | number | the minimum height of the main frame (-1 if not set) |
169 | | haxe.ui.hxwidgets.frame.maxWidth | number | the maximum width of the main frame (-1 if not set) |
170 | | haxe.ui.hxwidgets.frame.maxHeight | number | the maximum height of the main frame (-1 if not set) |
171 | | haxe.ui.hxwidgets.frame.left | number | the position of frame (x axis) defaults to center screen |
172 | | haxe.ui.hxwidgets.frame.top | number | the position of frame (y axis) defaults to center screen |
173 | | haxe.ui.hxwidgets.frame.maximized | boolean | whether to start the frame is a maximized state |
174 | | haxe.ui.hxwidgets.frame.maximizable | boolean | |
175 | | haxe.ui.hxwidgets.frame.minimizable | boolean | |
176 | | haxe.ui.hxwidgets.frame.closeable | boolean | |
177 | | haxe.ui.hxwidgets.frame.resizable | boolean | |
178 |
179 | ### Styling
180 |
181 | You cannot do much styling in wxwidgets except maybe for some colors.
182 | But if you want, you can use system colors, so that wxwidgets will still use the same color theme as your system.
183 |
184 | To access platform colors in CSS you can do
185 |
186 | ```CSS
187 | background-color: platform-color(window);
188 | ```
189 |
190 | You have access to all these [system colors](https://docs.wxwidgets.org/3.1.3/settings_8h.html)
191 |
192 | Here are some of them:
193 |
194 | * app-workspace
195 | * hotlight
196 | * gradient-active-caption
197 | * gradient-inactive-caption
198 | * menu-hilight
199 | * background
200 | * 3d-shadow
201 |
202 | ### Platforms
203 |
204 | To nave a different style for each platform, you can use in the css:
205 |
206 | `.platform-mac` or `.platform-linux` or `.platform-windows`
207 |
208 | ### Compilation Flags
209 |
210 |
211 | | Macros | |
212 | | :----------------- | -------------------------------------------- |
213 | | PLATFORM_MAC | |
214 | | PLATFORM_WINDOWS | |
215 | | PLATFORM_OTHER | |
216 | | wxMAJOR_VERSION | |
217 | | wxMINOR_VERSION | |
218 | | wxRELEASE_NUMBER | |
219 | | wxWidgetsVersion | #if (wxWidgetsVersion >= version("3.1.6")) |
220 |
221 |
222 | | Flags | |
223 | | :------------------------------------ | --------------------------------------------------------------- |
224 | | WEBVIEW | If you want to want to use webviews ( not exposed in haxe-ui) |
225 | | STYLEDTEXTCTRL | (true) to be able to use colors/bold/etc. in text |
226 | | haxeui_hxwidgets_ignorescroll_sizes | |
227 | | haxeui_emulate_dbl_click | |
228 |
229 | ### Menubar
230 |
231 | If you want a menubar to be easily accessible with shortcuts for menu, you can put a "&" before the letter you want the shortcut to use.
232 |
233 | ```xml
234 |
235 |
238 |
240 | ```
241 |
242 | Now you can do `Alt+F` to open the menu.
243 | On hxWidgets, the shortcutText will also automatically be binded to a menuitem selection.
244 | So in this case, you can do `Ctrl+P`
245 |
246 | ### OptionBoxes
247 |
248 | They work a little bit differently on hxWidgets.
249 | Optionboxes created at the same time will be in the same group.
250 | It makes it more difficult to create two options boxes separated by a button, for example.
251 |
252 | ### UIEvent.SHOWN
253 |
254 | Doesn't work as well as in other backends.
255 |
--------------------------------------------------------------------------------
/001-Guides/004-Styling.md:
--------------------------------------------------------------------------------
1 | Styling
2 | =======
3 |
4 | Sizing
5 | -------------------
6 |
7 | ### Autosizing
8 |
9 | By default, components size to their children, that's what we call *autosizing* For example
10 |
11 | ```xml
12 |
13 |
14 |
15 | ```
16 |
17 | 
18 |
19 | You'll notice that the vbox has taken the size of the label. (The label has the size of the text)
20 |
21 | ### Using specific size
22 |
23 | You can use of course specific size
24 |
25 | ```xml
26 |
27 |
28 |
29 |
30 |
31 | ```
32 |
33 | 
34 |
35 | It doesn't need to be pixels
36 |
37 | ```xml
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ```
47 |
48 | 
49 |
50 | ### Percent size of parent
51 |
52 | ```xml
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | ```
66 |
67 | 
68 |
69 | Notice how the third box seems buggy, it's because the button is 50% of the vbox which doesn't have size (and therefore is *autosized*). Be careful, you'll likely cause this in your own layouts at least once by giving children a percent size of parent whose size cant be calculated.
70 |
71 | The button "button 50%" in the second vbox works, because the *autosized* vbox took its size from the "button 100px".
72 |
73 | ### Having children components of the same size
74 |
75 | Usually if you want a box with 3 buttons of the same size you would do:
76 |
77 | ```xml
78 |
79 |
80 |
81 |
82 |
83 | ```
84 |
85 | But what if you add a fourth one, you would have to change all the sizes
86 |
87 | ```xml
88 |
89 |
90 |
91 |
92 |
93 |
94 | ```
95 |
96 | This is quite bug prone, and if you dynamically add buttons it makes the code quite complicated.
97 |
98 | 
99 |
100 | The best way to achieve this is to mark all components as 100% - HaxeUI will then caculate the appropriate size for each one.
101 |
102 | ```xml
103 |
104 |
105 |
106 |
107 |
108 |
109 | ```
110 |
111 | **Note**: you can also have fixed sized components there too, HaxeUI will calculate the sizes based on the *remaining* available space.
112 |
113 | How styling works
114 | -----------------
115 |
116 | 
117 |
118 |
119 | Creating styles with CSS
120 | ------------------------
121 |
122 | First, let's learn the basics about CSS
123 |
124 | ### Apply the css to a component or stylename
125 |
126 | #### . selector
127 |
128 | ```css
129 | .button {
130 | width: 120px;
131 | }
132 | ```
133 |
134 | As you can see the **selector starts with dot**
135 |
136 | .component signifies the component name or a component with a specific style name
137 |
138 | In context:
139 |
140 | ```xml
141 |
142 |
147 |
148 |
149 |
150 | ```
151 |
152 | 
153 |
154 | #### Spaced selectors
155 |
156 | ```css
157 | .hbox .button {
158 | color: red;
159 | }
160 | ```
161 |
162 | The two dotted selectors are separated by a space (**.component .child**). This means that first any component with `hbox` style will be matched, and then any other component that is a child of that match with a `button` style.
163 |
164 | ```xml
165 |
166 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | ```
184 |
185 | **Note**: there is no limit to the number of items you can match in a rule tree - and the style names dont have to be directly related.
186 |
187 | 
188 |
189 | #### Non Spaced selectors
190 |
191 | ```css
192 | .button.angry {
193 | color: red;
194 | }
195 | ```
196 |
197 | Two dotted selectors without separation (**.name1.name2**) means the component must have both style names.
198 |
199 | ```xml
200 |
201 |
206 |
207 |
208 |
209 |
210 | ```
211 |
212 | 
213 |
214 | #### Hashtags
215 |
216 | ```css
217 | #myButton {
218 |
219 | }
220 | ```
221 |
222 | You can use the hashtag when referencing a component with the given Id
223 |
224 | ```xml
225 |
226 |
239 |
240 |
241 |
242 |
243 |
244 | ```
245 |
246 | 
247 |
248 | #### > operator
249 |
250 | ```css
251 | .vbox > .button {
252 | color: red;
253 | }
254 |
255 | ```
256 |
257 | ">" is used only for direct children (children, not grandchildren).
258 | It means that it will apply to the direct child button of a vbox.
259 |
260 | ```xml
261 |
262 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 | ```
276 |
277 | 
278 |
279 | You can see some explanations here https://community.haxeui.org/t/css-operator-addition/266
280 |
281 | #### ":" pseudo-classes
282 |
283 | ":" is used to apply the style only if some external factors happen.
284 |
285 | For example "hover" happens when the mouse is moved over the component.
286 |
287 | ```css
288 | .button:hover {
289 | color:red;
290 | }
291 | ```
292 |
293 | #### "*" to match every element
294 |
295 | ```css
296 | * {
297 | font-name: 'assets/fonts/main.ttf';
298 | }
299 | ```
300 |
301 | #### "," to use multiple rules
302 |
303 | You can also use apply styles to multiple rules by using a comma
304 |
305 | ```css
306 |
307 | /* instead of doing this
308 | .label {
309 | font-size: 13px;
310 | }
311 | .textfield{
312 | font-size: 13px;
313 | }
314 | .textarea {
315 | font-size: 13px;
316 | }
317 |
318 | */
319 | /* you can do this */
320 | .label, .textfield, .textarea {
321 | font-size: 13px;
322 | }
323 | ```
324 |
325 | #### Mixing it all together
326 |
327 | Its worth mentioning that all of the above rules can be used together in order to create very tight (or very expansive) rules to select, and therefore style, groups of components. The following is perfectly valid (although somewhat contrived):
328 |
329 | ```css
330 | #myComponent .vbox > .hbox .foo > .bar .myStyle#someId .bar.foo .something:hover {
331 | }
332 | ```
333 |
334 | ### Using CSS inside a XML Layout
335 |
336 | There are multiple ways to use CSS inside a XML Layout
337 |
338 | #### Using the **style** tag
339 |
340 | This is a way used in most examples in this guide. It enables quick prototyping, and makes it easy to use in the builder.
341 |
342 | ```xml
343 |
344 |
350 |
351 |
352 | ```
353 |
354 | Important! The style tag will apply not only inside the vbox but everywhere, it has a global scope by default.
355 |
356 | You can still have a local scope using
367 |
368 |
369 |
374 |
375 |
376 |
377 |
382 |
383 |
384 |
385 | ```
386 |
387 | 
388 |
389 | #### Using the style attribute
390 |
391 | This is a way used in most examples in this guide. It enables quick prototyping, and makes it easy to use in the builder. It is okay for simple styles. It will also have the highest priority.
392 |
393 | ```xml
394 |
395 | ```
396 |
397 | #### Modifying the style attribute with code
398 |
399 | The style attribute is directly coded into the `styleString` property.
400 |
401 | Which means you can also do this in code
402 |
403 | ```haxe
404 | c.styleString = "font-size: 36px;";
405 | ```
406 |
407 | ### Using CSS in a separate file
408 |
409 | You need to configure the path to the .css in the module.xml
410 |
411 | ```xml
412 |
413 |
414 |
415 |
416 |
417 | ```
418 |
419 | The advantages are that it easier to make themes. That you can use syntax highlighting etc in your IDE.
420 |
421 | ### Applying a CSS stylesheet via code
422 |
423 | ```haxe
424 | myComponent.styleSheet = new StyleSheet();
425 | myComponent.styleSheet.parse("...")
426 | ```
427 |
428 | It enables to parse some style sheets at runtime.
429 |
430 | Layouts
431 | -------
432 |
433 | A layout is what enables to control position and dimension of children components.
434 |
435 | Core layouts for boxes:
436 |
437 | * default
438 | * absolute
439 | * vertical
440 | * horizontal
441 | * grid
442 |
443 | But some components do also have a layout when on a composite backend, because they are composite components, they are made of other components : for example steppers have also a "classic" layout.
444 |
445 | #### How to set layouts
446 |
447 | ##### By xml
448 |
449 | ```xml
450 |
451 |
452 | ```
453 |
454 | ##### By using styles or CSS
455 |
456 | ```css
457 | #my_box {
458 | layout:absolute;
459 | }
460 | ```
461 |
462 | ##### By code
463 |
464 | #### Absolute Layout
465 |
466 | 
467 |
468 | You can check it on the [builder](https://haxeui.org/explorer/#layouts/absolute_layouts)
469 |
470 |
471 | ```xml
472 |
473 |
474 | ```
475 |
476 | An **Absolute** is a special component, it is a box with an absolute layout. So you can also do :
477 |
478 | ```xml
479 |
480 |
481 | ```
482 |
483 | The position of the child component depends on :
484 |
485 | * **top**
486 | * **left**
487 |
488 | TIP : if you want to set a child to the "bottom" or to the "right". You can use a default layout instead and use this [trick](#emulating-an-absolute-bottom-or-right)
489 |
490 | #### Default
491 |
492 | You can check it on the [builder](https://haxeui.org/explorer/#layouts/box_layouts)
493 |
494 | The position of the child component depends on :
495 |
496 | * **padding**
497 | * **vertical-align**
498 | * **horizontal-align**
499 | * **margin**
500 |
501 | ##### Emulating an absolute bottom or right
502 |
503 | ```xml
504 |
505 | ```
506 |
507 | #### Horizontal
508 |
509 |
510 | You can check it on the [builder](https://haxeui.org/explorer/#layouts/horizonal_layouts)
511 |
512 | A **HBox** is a special component, it is a box with a horizontal layout. So you can also do :
513 |
514 | ```xml
515 |
516 |
517 | ```
518 |
519 | The position of the child component depends on :
520 |
521 | * **padding**
522 | * **vertical-align**
523 | * **index of child**
524 | * **horizontal spacing**
525 | * **margin**
526 |
527 | #### Vertical
528 |
529 | You can check it on the [builder](https://haxeui.org/explorer/#layouts/vertical_layouts)
530 |
531 | A **VBox** is a special component, it is a box with a vertical layout. So you can also do :
532 |
533 | ```xml
534 |
535 |
536 | ```
537 |
538 | The position of the child component depends on :
539 |
540 | * **padding**
541 | * **horizontal-align**
542 | * **index of child**
543 | * **vertical spacing**
544 | * **margin**
545 |
546 | #### Grid
547 |
548 |
549 | You can check it on the [builder](https://haxeui.org/explorer/#layouts/grid_layouts)
550 |
551 | A **Grid** is a special component, it is a box with a vertical grid layout. So you can also do :
552 |
553 | ```xml
554 |
555 |
556 | ```
557 |
558 | The position of the child component depends on :
559 |
560 | * **padding**
561 | * **horizontal-align**
562 | * **vertical-align**
563 | * **index of child**
564 | * **number of columns**
565 | * **spacing**
566 | * **margin**
567 |
568 | Attributes description
569 | ----------------------
570 |
571 | ### Layout attributes
572 |
573 | #### Spacing
574 |
575 | Spacing is the spacing between a container's children.
576 | It is used by vbox, hbox, grid.
577 |
578 | 
579 |
580 | spacing
581 |
582 | ```css
583 | .no-spacing {
584 | spacing:0; /* both horizontal spacing and vertical spacing will be set to O;
585 | }
586 | ```
587 |
588 | horizontal-spacing
589 |
590 | ```css
591 | .spacing {
592 | horizontal-spacing:20;
593 | vertical-spacing:40;
594 | /* you can also do spacing: %horizontal %vertical
595 | spacing:20 40;
596 | */
597 | }
598 | ```
599 |
600 | ### Styling attributes
601 |
--------------------------------------------------------------------------------
/001-Guides/002-Custom Components.md:
--------------------------------------------------------------------------------
1 | # Custom Components
2 |
3 | Custom components are a great way to reuse code / markup from within a HaxeUI application. They aren't strictly required for any HaxeUI application but they serve a great way to split up an application make it more modular and maintainable. With that in mind there are a fair few different methods that can be utilised to create custom components in HaxeUI.
4 |
5 | ## A note about `module.xml`
6 |
7 | Its important to mention `module.xml` here and the role it plays in exposing HaxeUI component classes to the markup parser (eg: xml). If you are using HaxeUI _solely_ through code (ie, creating instances of components in haxe code manually) then `module.xml` need play no part. However, if you plan to use any of the markup parsing features (ie, creating instances of components and layouts in xml) then you need to be aware that these are exposed to HaxeUI via a `module.xml`. There are various ways to do this depending on the way that you are creating custom components but the general principle is that you create a `module.xml` file somewhere on your class path and let HaxeUI know about your custom components:
8 |
9 | ```xml
10 |
11 |
12 |
13 |
14 |
15 | ```
16 |
17 | The actual attributes used in the `` node vary depending on what you would like to expose and how, and these will be detailed below (when relevant). See "Modules" for more details about how modules work.
18 |
19 | ## Using code
20 |
21 | The simplest and most straight forward way to create a custom component in HaxeUI is to simply build it, and its entire hierarchy in plain haxe code. Although certainly the most straightforward method it is, by far, the most laborious to maintain. Consider the following class:
22 |
23 | ```haxe
24 | package custom;
25 |
26 | class MyComponent extends HBox {
27 | public function new() {
28 | super();
29 | var textfield = new TextField();
30 | textfield.text = "0";
31 | addComponent(_textfield);
32 |
33 | var button = new Button();
34 | button.text = "-";
35 | button.onClick = function(e) {
36 | var n = Std.parseInt(textfield.text) - 1;
37 | textfield.text = Std.string(n);
38 | }
39 | addComponent(button);
40 |
41 | var button = new Button();
42 | button.text = "+";
43 | button.onClick = function(e) {
44 | var n = Std.parseInt(textfield.text) + 1;
45 | textfield.text = Std.string(n);
46 | }
47 | addComponent(button);
48 | }
49 | }
50 | ```
51 |
52 | This simple component will place a textfield with two buttons horizontally, clicking the buttons with increment / de-increment the value in the textfield. The purpose and functionality of this custom component is fairly simply to work out, however, with larger more complicated classes adding (or removing) from the custom component can be laborious and prone to errors.
53 |
54 | #### `module.xml`
55 |
56 | This custom component class will be fully available for use with haxe code. However, if you want to use it from markup you will need to let HaxeUI know about its existence. This can be done by creating a `module.xml`and adding something similar to:
57 |
58 | ```xml
59 |
60 |
61 |
62 |
65 |
66 |
67 | ```
68 |
69 | This component will now be available to xml via ``.
70 |
71 | trivia: when using xml in HaxeUI various operations are performed on node names to allow more flexibility and code style. For example, with the component above any of these node names would lead to the `custom.MyComponent`haxe class: ``, ``, ``, ``
72 |
73 | ## Using a macro
74 |
75 | A slight improvement on creating a custom component purely through code is to use a macro that would build the layout code for you. This will simplfy layout and component creation, consider the following xml file:
76 |
77 | ```xml
78 |
79 |
80 |
81 |
82 |
83 | ```
84 |
85 | We can then use this xml in a haxe class similar to the following:
86 |
87 | ```haxe
88 | class MyComponent extends HBox {
89 | public function new() {
90 | super();
91 | var ui = ComponentBuilder.fromFile("assets/my-component.xml");
92 | var textfield = ui.findComponent("textfield", TextField);
93 | ui.findComponent("deinc", Button).onClick = function(e) {
94 | var n = Std.parseInt(textfield.text) - 1;
95 | textfield.text = Std.string(n);
96 | }
97 | ui.findComponent("inc", Button).onClick = function(e) {
98 | var n = Std.parseInt(textfield.text) + 1;
99 | textfield.text = Std.string(n);
100 | }
101 | addComponent(ui);
102 | }
103 | }
104 | ```
105 |
106 | This new class has he exact same functionality except now the actual building of a component is delegate to a macro (which simply creates haxe code that adds components to a UI as if you had done it by hand). At first it may not seem much simpler (and indeed there are further refinements and simplifications that can be made below), but the important part here is that the UI layout itself is now coming from xml rather then written by hand. This means its extremely trivial (and easy to visualise) moving components around and creating new ones - something that becomes invaluable in larger applications / components.
107 |
108 | Note: exposing this classes using `module.xml`is exactly the same as if you created it using code in the first section above.
109 |
110 | ## Using a build macro
111 |
112 | A further refinement we can make to the `MyComponent`class is to use a build macro to build many parts of the class for us and eliminate alot of the boiler plate. Using the exact same xml file:
113 |
114 | ```xml
115 |
116 |
117 |
118 |
119 |
120 | ```
121 |
122 | We can now create a custom component using a build macro similar to the following:
123 |
124 | ```haxe
125 | @:build(haxe.ui.ComponentBuilder.build("assets/my-component.xml"))
126 | class MyComponent extends HBox {
127 | public function new() {
128 | super();
129 | deinc.onClick = function(e) {
130 | var n = Std.parseInt(textfield.text) - 1;
131 | textfield.text = Std.string(n);
132 | }
133 | inc.onClick = function(e) {
134 | var n = Std.parseInt(textfield.text) + 1;
135 | textfield.text = Std.string(n);
136 | }
137 | }
138 | }
139 | ```
140 |
141 | The most important things to notice here is that we have now removed the need to add a UI to our custom component (`addComponent` in the previous example) as well as the need to perform any `findComponent` calls in order to access named components from the xml - any component with an `id` attribute will now be a correctly typed member variable of the class with that name.
142 |
143 | #### Using binding
144 |
145 | Although not required a further refinement we can make here to remove boilerplate is the use of binding. By using binding metadata we can automatically link up values and events:
146 |
147 | ```haxe
148 | @:build(haxe.ui.ComponentBuilder.build("assets/my-component.xml"))
149 | class MyComponent extends HBox {
150 | @:bind(textfield.text)
151 | public var textfieldText:String = "10";
152 |
153 | @:bind(deinc, MouseEvent.CLICK)
154 | function onDeinc(e) {
155 | var n = Std.parseInt(textfieldText) - 1;
156 | textfieldText = Std.string(n);
157 | }
158 |
159 | @:bind(inc, MouseEvent.CLICK)
160 | function onInc(e) {
161 | var n = Std.parseInt(textfieldText) + 1;
162 | textfieldText = Std.string(n);
163 | }
164 | }
165 | ```
166 |
167 | #### Additional parameters to the build macro
168 |
169 | There is an additional parameter that the build macro accepts which is an object representing parameters to use with this xml file, for example:
170 |
171 | ```xml
172 |
173 |
174 |
175 |
176 |
177 | ```
178 |
179 | This variant of the xml file contains a `startValue` parameter, we can set that by using the following:
180 |
181 | ```haxe
182 | @:build(haxe.ui.ComponentBuilder.build("assets/my-component.xml", {startValue: 10}))
183 | class MyComponent extends HBox {
184 | ...
185 | }
186 | ```
187 |
188 | Though not hugely useful here its important to note that this can be used in various ways, for example as a way to create generic container layouts with different content (using the `` node, eg:
189 |
190 | ```xml
191 |
192 |
193 |
194 |
195 | ```
196 |
197 | This is now a generic container that can have its title and content specified by different classes at compile time, for example:
198 |
199 | ```haxe
200 | @:build(haxe.ui.ComponentBuilder.build("container.xml", {title: "container 1", content: "container1.xml"}))
201 | class Container1 extends VBox {
202 | ...
203 | }
204 |
205 | @:build(haxe.ui.ComponentBuilder.build("container.xml", {title: "container 2", content: "container2.xml"}))
206 | class Container2 extends VBox {
207 | ...
208 | }
209 |
210 | ```
211 |
212 | ## Using xml metadata
213 |
214 | Using xml metadata is very similar to using external xml files, with the exception that the xml source is specified using haxe metadata rather than an a file. This is useful for testing and small components but may become unwieldy when creating large custom components (separation of UI and logic is generally better). Using xml metadata our custom component would look like:
215 |
216 | ```haxe
217 | @:xml('
218 |
219 |
220 |
221 |
222 |
223 | ')
224 | class MyComponent extends HBox {
225 | ...
226 | }
227 | ```
228 |
229 | ## Using an xml file
230 |
231 | The final way to create custom components is to use _only_ and xml file, that is to say, no haxe code at all. This may or may not be an appropriate option, especially depending on how much logic the custom component performs (logic will be in the xml file as script and thus doesnt separate nicely from UI):
232 |
233 | ```xml
234 |
235 |
241 |
242 |
243 |
244 |
245 |
246 | ```
247 |
248 | In order to use this xml file you must allow HaxeUI to know about it, this can be done via `module.xml´ similar to the following:
249 |
250 | ```xml
251 |
252 |
253 |
254 |
257 |
258 |
259 | ```
260 |
261 | This component class will now be available using both code and markup, when using via code it would be `custom.MyComponent` and when using via markup with would simply be ``
262 |
263 | More information about this, and modules in general, can be found in the "Modules" sections
264 |
265 |
266 |
267 | ## Useful metadata
268 |
269 | ### @:composite
270 |
271 | Sometimes you need to create a component that works both in native and composite.
272 |
273 | In this case you use the `composite` metadata, to indicate which classes will be used only for composites
274 |
275 |
276 |
277 | ```haxe
278 | @:composite(ButtonEvents, ButtonBuilder, ButtonLayout)
279 | class Button extends InteractiveComponent implements ICompositeInteractiveComponent {
280 | // this part will work both in native and composite backends
281 | }
282 |
283 | class ButtonEvents extends haxe.ui.events.Events {
284 | // this class won't be used in native components
285 | // where you register events
286 | // you can access it with component._internalEvents
287 | }
288 |
289 | class ButtonBuilder extends CompositeBuilder {
290 | // this class won't be used in native components
291 | // how you create the component, how you add/remove children components
292 | // you can access it with component._compositeBuilder
293 | }
294 |
295 | class ButtonLayout extends DefaultLayout {
296 | // this class won't be used in native components
297 | // how you reposition children
298 | // you can access it with component._defaultLayout
299 | }
300 | ```
301 |
302 | `@:composite(ButtonEvents, ButtonBuilder, ButtonLayout) `
303 |
304 | Translates to
305 |
306 | ```haxe
307 | function registerComposite() {
308 | super.registerComposite();
309 | this._internalEventsClass = haxe.ui.components.ButtonEvents;
310 | this._compositeBuilderClass = haxe.ui.components.ButtonBuilder;
311 | this._defaultLayoutClass = haxe.ui.components.ButtonLayout;
312 | }
313 | ```
314 |
315 |
316 |
317 |
318 |
319 | ### @:clonable
320 |
321 | When the component is cloned, it also clones the value of the property
322 |
323 | It extremely useful if you use the component in an item renderer
324 |
325 | ### @:value(...)
326 |
327 | Binds the value property to another property/variable
328 |
329 | ```haxe
330 | @:clonable @:behaviour(SelectedBehaviour) public var selected:Bool;
331 | @:clonable @:value(selected) public var value:Dynamic;
332 | ```
333 |
334 | translates to
335 |
336 | ```haxe
337 | function get_value() {
338 | return this.get_selected();
339 | }
340 |
341 | function set_value(value:Dynamic) {
342 | {
343 | var _g = Type.typeof(value);
344 | switch ((enumIndex _g)) {
345 | case 1, 2: this.set_selected(value == 1);
346 | case 6: if ((_g[0] == String)) this.set_selected(value == "true" || value == "1") else this.set_selected(value);
347 | case 7: if ((_g[0] == haxe.ui.util.VariantType)) {
348 | var v = value;
349 | this.set_selected(@:implicitCast haxe.ui.util._Variant.Variant_Impl_.toBool(v));
350 | } else this.set_selected(value);
351 | default: this.set_selected(value)
352 | };
353 | };
354 | return value;
355 | }
356 | ```
357 |
358 |
359 |
360 | ### @:behaviour
361 |
362 | Behaviour is a same a get/set propery, except that
363 |
364 | - it is used when the property has an influence on the visual of the component
365 |
366 | it handles the validation/invalidation of the component
367 |
368 | - you can easily extend different type of behaviours
369 |
370 | - the behaviour won't be used in the native backend except if you replace it with another
371 |
372 | The behaviour of the class can be changed for a native backend
373 |
374 | ```xml
375 |
376 |
377 |
378 |
379 |
380 | ```
381 |
382 |
383 |
384 | ### @:call(...)
385 |
386 | Call meta is the same @:behaviour except that it works for functions
387 |
388 | ```haxe
389 | @:call(ClearNodes) public function clearNodes():Void;
390 |
391 | @:dox(hide) @:noCompletion
392 | private class ClearNodes extends Behaviour {
393 | public override function call(param:Any = null):Variant {
394 | var treeview:TreeView = cast(_component, TreeView);
395 | treeview.selectedNode = null;
396 | var nodes = treeview.findComponents(TreeViewNode, 3);
397 | for (n in nodes) {
398 | treeview.removeComponent(n);
399 | }
400 | return null;
401 | }
402 | }
403 | ```
404 |
405 | It can be changed for a native backend
406 |
407 | ```xml
408 |
409 |
410 |
411 | ```
412 |
413 |
414 |
415 | ### @:event
416 |
417 | With `@:event` you can easily add an easy to set var, which works the same as `onChange`, `onClick`, etc
418 |
419 | ```haxe
420 | @:event(ItemEvent.COMPONENT_EVENT) public var onComponentEvent:ItemEvent->Void;
421 | ```
422 |
423 | is transformed into
424 |
425 | ```haxe
426 | @:noCompletion
427 | var _internal__onComponentEvent:haxe.ui.events.ItemEvent -> Void;
428 |
429 | @:dox(group = "Event related properties and methods")
430 | public var onComponentEvent(null,set):haxe.ui.events.ItemEvent -> Void;
431 |
432 | function set_onComponentEvent(value:haxe.ui.events.ItemEvent -> Void) {
433 | if ((this._internal__onComponentEvent != null)) {
434 | this.unregisterEvent(haxe.ui.events.ItemEvent.COMPONENT_EVENT, this._internal__onComponentEvent);
435 | this._internal__onComponentEvent = null;
436 | };
437 | if ((value != null)) {
438 | this._internal__onComponentEvent = value;
439 | this.registerEvent(haxe.ui.events.ItemEvent.COMPONENT_EVENT, value);
440 | };
441 | return value;
442 | }
443 | ```
444 |
445 |
446 |
447 | ### @:style
448 |
449 | Using style enable to easily get and set styles. It will also manage invalidation.
450 |
451 | `@:style`
452 |
453 | `@:style(layout) ` will invalidate the layout
454 |
455 | `@:style(layoutparent)` will invalidate the layoutparent
456 |
457 |
458 |
459 | ```haxe
460 | @:style(layout) public var textAlign:String;
461 | ```
462 |
463 | will transform to
464 |
465 | ```haxe
466 | @:style @:keep @:dox(group = "Style properties")
467 | public var textAlign(get,set):String;
468 |
469 | function get_textAlign() {
470 | if ((this.get_customStyle().textAlign != null)) return this.get_customStyle().textAlign;
471 | if ((this.get_style() == null || this.get_style().textAlign == null)) return null;
472 | return this.get_style().textAlign;
473 | }
474 |
475 | function set_textAlign(value:String) {
476 | if ((this.get_customStyle().textAlign == value)) return value;
477 | if ((this._style == null)) this._style = new haxe.ui.styles.Style(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
478 | if ((value == null)) this.get_customStyle().textAlign = null else this.get_customStyle().textAlign = value;
479 | this.invalidateComponent(cast "style", false);
480 | /** this part is added if you use @:style(layout) **/
481 | if ((! (this._layout == null || this._layoutLocked == true))) this.invalidateComponent(cast "layout", false);
482 | /** this part is added if you use @:style(parentLayout) **/
483 | if ((this.get_parentComponent() != null)) {
484 | var _this = this.get_parentComponent();
485 | if ((! (_this._layout == null || _this._layoutLocked == true))) _this.invalidateComponent(cast "layout", false);
486 | };
487 | return value;
488 | }
489 | ```
490 |
--------------------------------------------------------------------------------