Skip to content

Commit c6eecc3

Browse files
committed
filling out the guides
1 parent 6043ad1 commit c6eecc3

10 files changed

+369
-136
lines changed

guides/getting_started.md

Lines changed: 1 addition & 71 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

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: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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 life-cycle (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

guides/overview_graph.md

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ For example, in the following graph, the font and font_size styles are set at th
4545

4646
## Transforms
4747

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 based transforms. This is common in video games and provides powerful control of your primitives.
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.
4949

5050
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.
5151

52-
In Scenic, you will only rarely create matrices on your own (you can if you know what you are doing!), and will instead use the very easy transform helpers.
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.
5353

5454
[You can read about the transform types here.](overview_transforms.html)
5555

@@ -84,30 +84,11 @@ This time, we've assigned ids to both of the text primitives. This makes it easy
8484
@graph
8585
|> Graph.modify( :small_text, &text(&1, "Smaller Hello", font_size: 16))
8686
|> Graph.modify( :big_text, &text(&1, "Bigger Hello", font_size: 60))
87+
|> push_graph()
8788

88-
Notice that the graph is modified multiple times in a pipeline.
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.
8990

9091

91-
## Graph Internals
92+
## What to read next?
9293

93-
94-
95-
Coming soon
96-
97-
## Positions, rotation, scale and more
98-
99-
A major mental model difference between Scenic and everything web is how things
100-
are positioned on the screen. In this case, Scenic is built like a game.
101-
102-
Scenic is aimed at fixed-screen devices and apps that control their own layout.
103-
On the web, there is no guarantee what size screen or window the client will
104-
use, so it relies on dynamic layout that is computed on the client.
105-
106-
Scenic does not have an auto-layout engine. Instead, everything rendered on the
107-
screen is positioned with transform matrices, just like a game.
108-
109-
**Don’t worry!** You will not need to look at any matrices unless you want to
110-
get fancy.
111-
112-
To move something on the screen, just add one of the transform options. Like
113-
this
94+
If you are exploring Scenic, then you should read the [Primitives Overview](overview_primitives.html) next.

guides/overview_primitives.md

Lines changed: 111 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,111 @@
1-
# Styles Overview
2-
3-
* [Arc](Scenic.Primitive.Arc)
4-
* [Circle](Scenic.Primitive.Circle)
5-
* [Ellipse](Scenic.Primitive.Ellipse)
6-
* [Group](Scenic.Primitive.Group)
7-
* [Line](Scenic.Primitive.Line)
8-
* [Path](Scenic.Primitive.Path)
9-
* [Quad](Scenic.Primitive.Quad)
10-
* [Rectangle](Scenic.Primitive.Rectangle)
11-
* [RoundedRectangle](Scenic.Primitive.RoundedRectangle)
12-
* [Scene Ref](Scenic.Primitive.SceneRef)
13-
* [Sector](Scenic.Primitive.Sector)
14-
* [Text](Scenic.Primitive.Text)
15-
* [Triangle](Scenic.Primitive.Triangle)
1+
# Primitives Overview
2+
3+
Primitives are the simplest thing that Scenic know how to draw to the screen. Everything that you see in a Scenic application is drawn by combining multiple primitives together to make complex UIs.
4+
5+
There is a fixed set of primitives. This simplifies the internals of Scenic, particularly when it comes to communicating to the drivers. New primitives may be added in the future, but those require serious thought and coordination.
6+
7+
* [`Arc`](Scenic.Primitive.Arc.html) draws an arc. This would be a line cut out of a part of the edge of a circle. If you want a shape that looks like a piece of pie, then you should use the [`Sector`](Scenic.Primitive.Sector.html).
8+
* [`Circle`](Scenic.Primitive.Circle.html) draws a circle.
9+
* [`Ellipse`](Scenic.Primitive.Ellipse.html) draws an ellipse.
10+
* [`Group`](Scenic.Primitive.Group.html) doesn't draw anything. Instead, it creates a node in the graph that you can insert more primitives into. Any styles or transforms you apply to the Group are inherited by all the primitives below it.
11+
* [`Line`](Scenic.Primitive.Line.html) draws a line.
12+
* [`Path`](Scenic.Primitive.Path.html) is sort of an escape valve for complex shapes not covered by the other primitives. You supply a list of instructions, such as :move_to, :line_to, :bezier_to, etc to generate a complex shape.
13+
* [`Quad`](Scenic.Primitive.Quad.html) draws polygon with four sides.
14+
* [`Rectangle`](Scenic.Primitive.Rectangle.html) draws a rectangle.
15+
* [`RoundedRectangle`](Scenic.Primitive.RoundedRectangle.html) draws a rectangle with the corners rounded by a given radius.
16+
* [`SceneRef`](Scenic.Primitive.SceneRef.html) doesn't draw anything by itself. Instead it points to another scene/graph and tells the driver to draw that here.
17+
* [`Sector`](Scenic.Primitive.Sector.html) draws a shape that looks like a piece of pie. If you want to stroke just the curved edge, then combine it with an [`Arc`](Scenic.Primitive.Arc.html).
18+
* [`Text`](Scenic.Primitive.Text.html) draws a string of text.
19+
* [`Triangle`](Scenic.Primitive.Triangle.html) draws a triangle.
20+
21+
## Using Primitives
22+
23+
The easiest way to insert primitives into your graph is to import the functions in `Scenic.Primitives` into your scene module. This adds a helper function for each primitive that you can use in a pipeline to build a graph.
24+
25+
defmodule MyApp.Scene.Example do
26+
use Scenic.Scene
27+
alias Scenic.Graph
28+
import Scenic.Primitives
29+
30+
@graph Graph.build(font: :roboto, font_size: 22)
31+
|> text("Hello World", text_align: :center, translate: {300, 350})
32+
|> circle(150, fill: :green, translate: {300, 350})
33+
34+
...
35+
36+
end
37+
38+
In the example above, the scene calls `import Scenic.Primitives`, which imports helpers for all the primitives. Since the graph only uses text and circle, you could save a tiny bit of memory by just importing what you need.
39+
40+
import Scenic.Primitives, only: [{:text,3}, {:circle, 3}]
41+
42+
Once the helpers are imported, you call each call appends a primitive to the graph.
43+
44+
## Styles
45+
46+
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)
47+
48+
[Read more about the styles here.](overview_styles.html)
49+
50+
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.
51+
52+
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.
53+
54+
@graph Graph.build(font: :roboto, font_size: 24)
55+
|> text("Hello World", translate: {300, 300})
56+
|> text("Bigger Hello", font_size: 40, translate: {400, 300})
57+
58+
59+
## Transforms
60+
61+
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 based transforms. This is common in video games and provides powerful control of your primitives.
62+
63+
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.
64+
65+
**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.
66+
67+
[You can read about the transform types here.](overview_transforms.html)
68+
69+
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.
70+
71+
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.
72+
73+
In the example below, the first text line is translated, and the second is scaled bigger, and the whole graph rotated 0.4 radians.
74+
75+
@graph Graph.build(font: :roboto, font_size: 24, rotate: 0.4)
76+
|> text("Hello World", translate: {300, 300})
77+
|> text("Bigger Hello", font_size: 40, scale: 1.5)
78+
79+
80+
## Modifying a Primitive
81+
82+
Scenic was written specifically for Erlang/Elixir, which is a functional programming model with immutable data.
83+
84+
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.
85+
86+
@graph Graph.build(font: :roboto, font_size: 24, rotate: 0.4)
87+
|> text("Hello World", translate: {300, 300}, id: :small_text)
88+
|> text("Bigger Hello", font_size: 40, scale: 1.5, id: :big_text)
89+
90+
In the above graph, we've assigned `:id` values to both primitives. This makes it easy to find and modify that primitive in the graph. `Graph.modify/3` is very fast at finding primitives marked with an `:id`. If you marked multiple primitives withe `id: :small_text`, then they would all be modified by the call to `Graph.modify/3`
91+
92+
graph =
93+
@graph
94+
|> Graph.modify( :small_text, &text(&1, "Smaller Hello", font_size: 16))
95+
|> Graph.modify( :big_text, &text(&1, "Bigger Hello", font_size: 60))
96+
|> push_graph()
97+
98+
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.
99+
100+
The last parameter to `Graph.modify/3` is a pointer to a function that receives a primitive and returns the the new primitive that should be inserted in its place.
101+
102+
The following is the same as one of the calls above, but in expanded form to make it easier to see what is going on
103+
104+
graph = Graph.modify( graph, :small_text, fn(primitive) ->
105+
text(primitive, "Smaller Hello", font_size: 16)
106+
end)
107+
108+
109+
## What to read next?
110+
111+
If you are exploring Scenic, then you should read the [Styles Overview](overview_styles.html) next.

0 commit comments

Comments
 (0)