Skip to content

Commit 03bae3b

Browse files
authored
Merge pull request #56 from boydm/boyd
Fill in guides / documentation, improve some tests.
2 parents 5c374ab + c6a6d6a commit 03bae3b

15 files changed

+636
-146
lines changed

guides/getting_started.md

Lines changed: 4 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,8 @@
11
# Getting Started
22

3-
This guide will walk you through installing the OpenGL related dependencies,
3+
This guide will walk you through installing the new project generator,
44
then building your first Scenic application.
55

6-
## Install Dependencies
7-
8-
The design of Scenic goes to great lengths to minimize its dependencies to just
9-
the minimum. Namely, it needs Erlang/Elixir and OpenGL.
10-
11-
Rendering your application into a window on your local computer (MacOS, Ubuntu
12-
and others) is done by the `scenic_driver_glfw` driver. It uses the GLFW and
13-
GLEW libraries to connect to OpenGL.
14-
15-
The instructions below assume you have already installed Elixir/Erlang. If you
16-
need to install Elixir/Erlang there are instructions on the [elixir-lang
17-
website](https://elixir-lang.org/install.html).
18-
19-
### Installing on MacOS
20-
21-
The easiest way to install on MacOS is to use Homebrew. Just run the following
22-
in a terminal:
23-
24-
```bash
25-
brew update
26-
brew install glfw3 glew pkg-config
27-
```
28-
29-
Once these components have been installed, you should be able to build the
30-
`scenic_driver_glfw` driver.
31-
32-
### Installing on Ubuntu 16
33-
34-
The easiest way to install on Ubuntu is to use apt-get. Just run the following:
35-
36-
```bash
37-
sudo apt-get update
38-
sudo apt-get install pkgconf libglfw3 libglfw3-dev libglew1.13 libglew-dev
39-
```
40-
41-
Once these components have been installed, you should be able to build the
42-
`scenic_driver_glfw` driver.
43-
44-
### Installing on Ubuntu 18
45-
46-
The easiest way to install on Ubuntu is to use apt-get. Just run the following:
47-
48-
```bash
49-
sudo apt-get update
50-
sudo apt-get install pkgconf libglfw3 libglfw3-dev libglew2.0 libglew-dev
51-
```
52-
53-
Once these components have been installed, you should be able to build the
54-
`scenic_driver_glfw` driver.
55-
56-
### Installing on Fedora
57-
58-
The easiest way to install on Fedora is to use dnf. Just run the following:
59-
60-
```
61-
dnf install glfw glfw-devel pkgconf glew glew-devel
62-
```
63-
64-
Once these components have been installed, you should be able to build the `scenic_driver_glfw` driver.
65-
66-
### Installing on Archlinux
67-
68-
The easiest way to install on Archlinux is to use pacman. Just run the following:
69-
70-
```bash
71-
sudo pacman -S glfw-x11 glew
72-
```
73-
74-
If you're using wayland, you'll probably need `glfw-wayland` instead of `glfw-x11` and `glew-wayland` instead of `glew`
75-
766
## Install `scenic.new`
777

788
The Scenic Archive is the home of the `scenic.new` mix task, which layout a
@@ -151,7 +81,7 @@ process, its size, the default scene and start one or more drivers.
15181
See the documentation for [ViewPort Configuration](Scenic.ViewPort.Config.html)
15282
to learn more about how to set the options on a viewport.
15383

154-
Note that all the drivers are in seperate Hex packages as you should choose the
84+
Note that all the drivers are in separate Hex packages as you should choose the
15585
correct one for your application. For example, the `Scenic.Driver.Glfw` driver
15686
draws your scenes into a window under MacOS and Ubuntu. It should work on other
15787
OS's as well, such as other flavors of Unix or Windows, but I haven't worked on
@@ -185,7 +115,7 @@ Scene | Description
185115
Splash | The Splash scene is configured to run when the app is started in the `config/config.exs` file. It runs a simple animation, then transitions to the Sensor scene. It also shows how intercept basic user input to exit the scene early.
186116
Sensor | The Sensor scene depicts a simulated temperature sensor. The sensor is always running and updates its data through the `Scenic.SensorPubSub` server.
187117
Primitives | The Primitives scenes displays an overview of the basic primitive types and some of the styles that can be applied to them.
188-
Components | The Components scene shows the basic components that come with Scenic. The crash button will cause a match error that will crash the scene, showing how the supervison tree restarts the scene. It also shows how to receive events from components.
118+
Components | The Components scene shows the basic components that come with Scenic. The crash button will cause a match error that will crash the scene, showing how the supervision tree restarts the scene. It also shows how to receive events from components.
189119

190120
Component | Description
191121
--------- | -----------
@@ -198,6 +128,6 @@ Scenic.SensorPubSub service.
198128

199129
## What to read next?
200130

201-
Next, you should read about the [structure of a scene](scene_structure.html).
131+
Next, you should read about the [structure of a scene](overview_scene.html).
202132
This will explain the parts of a scene, how to send and receive messages and how
203133
to push the graph to the ViewPort.

guides/install_dependencies.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Install Dependencies
2+
3+
The design of Scenic goes to great lengths to minimize its dependencies to just
4+
the minimum. Namely, it needs Erlang/Elixir and OpenGL.
5+
6+
Rendering your application into a window on your local computer (MacOS, Ubuntu
7+
and others) is done by the `scenic_driver_glfw` driver. It uses the GLFW and
8+
GLEW libraries to connect to OpenGL.
9+
10+
The instructions below assume you have already installed Elixir/Erlang. If you
11+
need to install Elixir/Erlang there are instructions on the [elixir-lang
12+
website](https://elixir-lang.org/install.html).
13+
14+
### Installing on MacOS
15+
16+
The easiest way to install on MacOS is to use Homebrew. Just run the following
17+
in a terminal:
18+
19+
```bash
20+
brew update
21+
brew install glfw3 glew pkg-config
22+
```
23+
24+
Once these components have been installed, you should be able to build the
25+
`scenic_driver_glfw` driver.
26+
27+
### Installing on Ubuntu 16
28+
29+
The easiest way to install on Ubuntu is to use apt-get. Just run the following:
30+
31+
```bash
32+
sudo apt-get update
33+
sudo apt-get install pkgconf libglfw3 libglfw3-dev libglew1.13 libglew-dev
34+
```
35+
36+
Once these components have been installed, you should be able to build the
37+
`scenic_driver_glfw` driver.
38+
39+
### Installing on Ubuntu 18
40+
41+
The easiest way to install on Ubuntu is to use apt-get. Just run the following:
42+
43+
```bash
44+
sudo apt-get update
45+
sudo apt-get install pkgconf libglfw3 libglfw3-dev libglew2.0 libglew-dev
46+
```
47+
48+
Once these components have been installed, you should be able to build the
49+
`scenic_driver_glfw` driver.
50+
51+
### Installing on Fedora
52+
53+
The easiest way to install on Fedora is to use dnf. Just run the following:
54+
55+
```
56+
dnf install glfw glfw-devel pkgconf glew glew-devel
57+
```
58+
59+
Once these components have been installed, you should be able to build the `scenic_driver_glfw` driver.
60+
61+
### Installing on Archlinux
62+
63+
The easiest way to install on Archlinux is to use pacman. Just run the following:
64+
65+
```bash
66+
sudo pacman -S glfw-x11 glew
67+
```
68+
69+
If you're using wayland, you'll probably need `glfw-wayland` instead of `glfw-x11` and `glew-wayland` instead of `glew`

guides/overview_general.md

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ be used to build portable applications.
2525

2626
- **Remotable:** Scenic devices know how to run themselves, but can still be
2727
accessed remotely. Remote traffic attempts to be as small so it can be used
28-
over the internet, cellular modems, Bluetooth, etc.
28+
over the Internet, cellular modems, Bluetooth, etc.
2929

3030
- **Reusable:** Collections of UI can be packaged up for reuse with, and across
3131
applications. I expect to see Hex packages of controls, graphs, and more
@@ -36,7 +36,7 @@ be used to build portable applications.
3636
simple.
3737

3838
- **Secure:** Scenic is designed with an eye towards security. For now, the main
39-
effort is to keep it simple. No browser, javascript, and other complexity
39+
effort is to keep it simple. No browser, Javascript, and other complexity
4040
presenting vulnerabilities. There will be much more to say about security
4141
later.
4242

@@ -57,25 +57,17 @@ be used to build portable applications.
5757

5858
Scenic is built as a three-layer architectural cake.
5959

60-
### Scene Layer
60+
### [Scene Layer](overview_scene.html)
6161

62-
At the top is the **Scene Layer**, which encapsulates all application business
63-
logic. The developer will do most of their Scenic work in the Scene layer.
62+
At the top is the [**Scene Layer**](overview_scene.html), which encapsulates all application business logic. The developer will do most of their Scenic work in the Scene layer.
6463

65-
### ViewPort Layer
64+
### [ViewPort Layer](overview_viewport.html)
6665

67-
In the middle is the **ViewPort Layer**, which acts as a bridge between the
68-
Scenes and the Drivers. The ViewPort controls the scene lifecycle (More on that
69-
in [Scene Overview](overview_scene.html)), sends graphs down to the drivers, and
70-
routes user input up to the correct scene.
66+
In the middle is the [**ViewPort Layer**](overview_viewport.html), which acts as a bridge between the Scenes and the Drivers. The ViewPort controls the scene life-cycle (More on that in [Scene Overview](overview_scene.html)), sends graphs down to the drivers, and routes user input up to the correct scene.
7167

72-
### Driver layer
68+
### [Driver layer](overview_driver.html)
7369

74-
At the bottom is the **Driver layer**, which is where knowledge of the graphics
75-
hardware and/or remote configuration lives. Drivers draw everything on the
76-
screen and originate the raw user input. Developers can write their own drivers,
77-
but that will be rare if at all. Dealing with Sensors and other hardware is a
78-
different problem space.
70+
At the bottom is the [**Driver layer**](overview_driver.html), which is where knowledge of the graphics hardware and/or remote configuration lives. Drivers draw everything on the screen and originate the raw user input. Developers can write their own drivers, but that will be rare if at all. Dealing with Sensors and other hardware is a different problem space.
7971

8072
## Mental Model
8173

@@ -126,7 +118,7 @@ that manage them for you.
126118
### ViewPort
127119

128120
A ViewPort is a sort of like a tab in your browser. It manages the scene
129-
lifecycle, routes graphs to the drivers, and input back up to the scenes. If you
121+
life-cycle, routes graphs to the drivers, and input back up to the scenes. If you
130122
want two windows in your app, you need to start two ViewPorts.
131123

132124
### Driver

guides/overview_graph.md

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,94 @@
11
# Graph Overview
22

3-
Give an overview of a graph here
3+
The most important state a Scene is responsible for is its Graph. The Graph
4+
defines what is to be drawn to the screen, any referenced components, and the
5+
overall draw order. When a Scene decides the graph is ready to be drawn to the
6+
screen, it pushes it to the Viewport.
47

5-
Coming soon
8+
Graphs are made out of a handful of primitives, each of which knows how to draw
9+
one thing. When multiple primitives are put together, almost any standard UI can be drawn.
610

7-
## Positions, rotation, scale and more
11+
For example, the graph below shows the words "Hello World" around them.
812

9-
A major mental model difference between Scenic and everything web is how things
10-
are positioned on the screen. In this case, Scenic is built like a game.
13+
@graph Graph.build(font: :roboto, font_size: 24)
14+
|> text("Hello World", text_align: center, translate: {300, 300})
15+
|> circle(100, stroke: {2, :green} translate: {300, 300})
1116

12-
Scenic is aimed at fixed-screen devices and apps that control their own layout.
13-
On the web, there is no guarantee what size screen or window the client will
14-
use, so it relies on dynamic layout that is computed on the client.
17+
In the example above, the first line creates a new graph and assigns two font styles to its root. The next two lines form a pipeline that adds primitives to the root
18+
node of the new graph. Each of these primitives also assigns styles.
1519

16-
Scenic does not have an auto-layout engine. Instead, everything rendered on the
17-
screen is positioned with transform matrices, just like a game.
20+
## Primitives
1821

19-
**Don’t worry!** You will not need to look at any matrices unless you want to
20-
get fancy.
22+
There is a fixed set of primitives that Scenic knows how to draw. These form the base set of things that you can do. While they seem simple, when combined you draw pretty much any 2D UI that you need.
2123

22-
To move something on the screen, just add one of the transform options. Like
23-
this
24+
[Read more about the primitives here.](overview_primitives.html)
25+
26+
In general, each primitive renders one thing to the screen. The Group primitive is
27+
sort of like a `<div>` tag in html in that it creates a new node in the graph hierarchy that more primitives can be organized beneath.
28+
29+
Each primitive can also be assigned styles and transforms, which affect how (or whether) they are drawn and where.
30+
31+
## Styles
32+
33+
In addition to the fixed set of primitives, there is also a fixed set of primitive styles. (Some components support more styles, but they really get boiled down to the primitive styles when it is time to render)
34+
35+
[Read more about the styles here.](overview_styles.html)
36+
37+
Styles are inherited down the graph hierarchy. This means that if you set a style on the root of a graph, or in a group, then any primitives below that node inherit those styles without needing to explicitly set them on every single primitive.
38+
39+
For example, in the following graph, the font and font_size styles are set at the root. Both text primitives inherit those values, although the second one overrides the size with something bigger.
40+
41+
@graph Graph.build(font: :roboto, font_size: 24)
42+
|> text("Hello World", translate: {300, 300})
43+
|> text("Bigger Hello", font_size: 40, translate: {400, 300})
44+
45+
46+
## Transforms
47+
48+
The final type of primitive control is transforms. Unlike html, which uses auto-layout to position items on the screen, Scenic moves primitives around using matrix transforms. This is common in video games and provides powerful control of your primitives.
49+
50+
A [matrix](https://en.wikipedia.org/wiki/Matrix_(mathematics)) is an array of numbers that can be used to change the positions, rotations, scale and more of locations.
51+
52+
**Don’t worry!** You will not need to look at any matrices unless you want to get fancy. In Scenic, you will rarely (if ever) create matrices on your own (you can if you know what you are doing!), and will instead use the transform helpers.
53+
54+
[You can read about the transform types here.](overview_transforms.html)
55+
56+
Transforms are inherited down the graph hierarchy. This means that if you place a rotation transform at the root of a graph, then all the primitives will be rotated around a common point.
57+
58+
If you want to zoom in, scroll, or rotate a UI, or just pieces of the UI, you can do that very easily by applying transforms.
59+
60+
In the example below, the first text line is translated, and the second is scaled bigger, and the whole graph rotated 0.4 radians.
61+
62+
@graph Graph.build(font: :roboto, font_size: 24, rotate: 0.4)
63+
|> text("Hello World", translate: {300, 300})
64+
|> text("Bigger Hello", font_size: 40, scale: 1.5)
65+
66+
67+
## Modifying a graph
68+
69+
Scenic was written specifically for Erlang/Elixir, which is a functional programming model with immutable data.
70+
71+
As such, once you make a graph, it stays in memory unchanged - until you change it via `Graph.modify/3`. Technically you never change it (that's the immutable part), instead Graph.modify returns a new graph with different data in it.
72+
73+
[Graph.modify/3](Scenic.Graph.html#modify/3) is the single Graph function that you will use the most.
74+
75+
For example, lets go back to our graph with the two text items in it.
76+
77+
@graph Graph.build(font: :roboto, font_size: 24, rotate: 0.4)
78+
|> text("Hello World", translate: {300, 300}, id: :small_text)
79+
|> text("Bigger Hello", font_size: 40, scale: 1.5, id: :big_text)
80+
81+
This time, we've assigned ids to both of the text primitives. This makes it easy to find and modify that primitive in the graph.
82+
83+
graph =
84+
@graph
85+
|> Graph.modify( :small_text, &text(&1, "Smaller Hello", font_size: 16))
86+
|> Graph.modify( :big_text, &text(&1, "Bigger Hello", font_size: 60))
87+
|> push_graph()
88+
89+
Notice that the graph is modified multiple times in the pipeline. The `push_graph/1` function is relatively heavy when the graph references other scenes. The recommended pattern is to make multiple changes to the graph and then push once at the end.
90+
91+
92+
## What to read next?
93+
94+
If you are exploring Scenic, then you should read the [Primitives Overview](overview_primitives.html) next.

0 commit comments

Comments
 (0)