Commits: 3
Make sliders stepped in Transformations example
Also other minor tweaks.
index 744c43a..0d66cf5 100644
--- a/src/Transformations.elm
+++ b/src/Transformations.elm
@@ -51,7 +51,11 @@ type Msg
=
=init : Flags -> ( Model, Cmd Msg )
=init () =
- ( Array.empty
+ ( Array.fromList
+ [ Translate 0 0
+ , Rotate 0
+ , Scale 1 1
+ ]
= , Cmd.none
= )
=
@@ -69,9 +73,17 @@ view model =
= , Element.spacing 20
= ]
= [ Element.el
- [ Element.width Element.fill ]
+ [ Element.width Element.fill
+ ]
= (Element.html element)
- , transformationsUI transformations
+ , Element.row [ Element.width Element.fill ]
+ [ Element.el
+ [ Background.color (Element.rgb 1 0.8 0.8)
+ , Element.padding 10
+ , Element.width Element.fill
+ ]
+ (transformationsUI transformations)
+ ]
= ]
=
= shape =
@@ -111,7 +123,8 @@ transformationsUI : List Transformation -> Element Msg
=transformationsUI transformations =
= let
= addButtons =
- [ Input.button []
+ [ Element.text "Add transformation: "
+ , Input.button []
= { onPress = Just (AddTransformation (Translate 0 0))
= , label = Element.text "Translate"
= }
@@ -176,7 +189,7 @@ transformationUI index transformation =
= , max = 10
= , value = horizontal
= , thumb = Input.defaultThumb
- , step = Nothing
+ , step = Just 0.1
= }
= , Input.slider
= [ Element.behindContent sliderBackground
@@ -189,7 +202,7 @@ transformationUI index transformation =
= , max = 10
= , value = vertical
= , thumb = Input.defaultThumb
- , step = Nothing
+ , step = Just 0.1
= }
= ]
=
@@ -205,7 +218,7 @@ transformationUI index transformation =
= , max = 100
= , value = x
= , thumb = Input.defaultThumb
- , step = Nothing
+ , step = Just 1
= }
= , Input.slider
= [ Element.behindContent sliderBackground
@@ -218,7 +231,7 @@ transformationUI index transformation =
= , max = 100
= , value = y
= , thumb = Input.defaultThumb
- , step = Nothing
+ , step = Just 1
= }
= ]
=
@@ -234,13 +247,14 @@ transformationUI index transformation =
= , max = 360
= , value = angle
= , thumb = Input.defaultThumb
- , step = Nothing
+ , step = Just 1
= }
= ]
= in
= Element.column
= [ Element.width Element.fill
- , Background.color (Element.rgb 0.9 0.9 0.9)
+ , Border.color (Element.rgb 0.9 0.9 0.9)
+ , Border.width 3
= , Element.padding 5
= , Element.spacing 20
= ]Implement NestedTransformations example
index d17943a..6cfda8a 100644
--- a/elm.json
+++ b/elm.json
@@ -11,11 +11,13 @@
= "elm/html": "1.0.0",
= "elm/json": "1.0.0",
= "elm/svg": "1.0.1",
+ "elm-community/basics-extra": "4.0.0",
= "elm-community/list-extra": "8.1.0",
= "elm-explorations/markdown": "1.0.0",
= "ianmackenzie/elm-geometry": "1.2.1",
= "ianmackenzie/elm-geometry-svg": "1.0.2",
- "mdgriffith/elm-ui": "1.1.0"
+ "mdgriffith/elm-ui": "1.1.0",
+ "turboMaCk/any-dict": "1.0.1"
= },
= "indirect": {
= "elm/time": "1.0.0",new file mode 100644
index 0000000..30da4f4
--- /dev/null
+++ b/src/NestedTransformations.elm
@@ -0,0 +1,437 @@
+module Transformations exposing (main)
+
+import Array exposing (Array)
+import Basics.Extra exposing (..)
+import Browser
+import Browser.Events
+import CartesianPlane
+import Dict.Any as Dict exposing (AnyDict)
+import Element exposing (Element)
+import Element.Background as Background
+import Element.Border as Border
+import Element.Input as Input
+import Geometry.Svg
+import Html exposing (Html)
+import Json.Decode exposing (Decoder)
+import LineSegment2d
+import List.Extra as List
+import Point2d
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+main =
+ Browser.element
+ { init = init
+ , view = view
+ , update = update
+ , subscriptions = subscriptions
+ }
+
+
+type alias Flags =
+ ()
+
+
+type alias Model =
+ AnyDict String Group (Array Transformation)
+
+
+type Transformation
+ = Identity
+ | Scale Float Float
+ | Translate Float Float
+ | Rotate Float
+
+
+type Group
+ = Pink
+ | Green
+
+
+type Msg
+ = Msg Group GroupMsg
+
+
+type GroupMsg
+ = AddTransformation Transformation
+ | DeleteTransformation Int
+ | SetTransformation Int Transformation
+
+
+init : Flags -> ( Model, Cmd Msg )
+init () =
+ ( Dict.empty Debug.toString
+ |> Dict.insert Pink
+ (Array.fromList
+ [ Translate 0 0
+ , Rotate 0
+ , Scale 1 1
+ ]
+ )
+ |> Dict.insert Green
+ (Array.fromList
+ [ Translate 0 0
+ , Rotate 0
+ , Scale 1 1
+ ]
+ )
+ , Cmd.none
+ )
+
+
+view : Model -> Html Msg
+view model =
+ let
+ wrapper element =
+ Element.column
+ [ Element.width (Element.maximum 600 Element.fill)
+ , Element.centerX
+ , Element.spacing 20
+ ]
+ [ Element.el
+ [ Element.width Element.fill
+ ]
+ (Element.html element)
+ , Element.row [ Element.width Element.fill ]
+ (model
+ |> Dict.toList
+ |> List.map (uncurry controls)
+ )
+ ]
+
+ controls : Group -> Array Transformation -> Element Msg
+ controls group transformations =
+ Element.el
+ [ Background.color (toColor group)
+ , Element.padding 10
+ , Element.width Element.fill
+ ]
+ (transformations
+ |> Array.toList
+ |> transformationsUI
+ |> Element.map (Msg group)
+ )
+
+ shape =
+ Dict.foldr
+ nestTransformationsGroup
+ (g [] [])
+ model
+
+ nestTransformationsGroup : Group -> Array Transformation -> Svg Msg -> Svg Msg
+ nestTransformationsGroup group transformations item =
+ let
+ transformation =
+ transformations |> Array.toList |> apply
+
+ color =
+ group
+ |> Debug.toString
+ |> String.toLower
+ in
+ g [ transform transformation ]
+ [ line
+ [ x1 "0"
+ , x2 "100"
+ , y1 "0"
+ , y2 "0"
+ , stroke color
+ , strokeWidth "1"
+ ]
+ []
+ , circle [ cx "0", cy "0", r "2", fill color ] []
+ , item
+ ]
+ in
+ shape
+ |> List.singleton
+ |> CartesianPlane.graph 300
+ |> wrapper
+ |> Element.layout
+ [ Element.height Element.fill
+ , Element.width Element.fill
+ ]
+
+
+transformationsUI : List Transformation -> Element GroupMsg
+transformationsUI transformations =
+ let
+ addButtons =
+ [ Element.text "Add transformation: "
+ , Input.button []
+ { onPress = Just (AddTransformation (Translate 0 0))
+ , label = Element.text "Translate"
+ }
+ , Input.button []
+ { onPress = Just (AddTransformation (Scale 1 1))
+ , label = Element.text "Scale"
+ }
+ , Input.button []
+ { onPress = Just (AddTransformation (Rotate 0))
+ , label = Element.text "Rotate"
+ }
+ ]
+
+ currentTrasformations =
+ transformations
+ |> List.indexedMap transformationUI
+ in
+ Element.column
+ [ Element.width Element.fill
+ , Element.spacing 10
+ ]
+ [ Element.row
+ [ Element.width Element.fill
+ , Element.spacing 10
+ ]
+ addButtons
+ , Element.column
+ [ Element.width Element.fill
+ , Element.spacing 10
+ ]
+ currentTrasformations
+ ]
+
+
+transformationUI : Int -> Transformation -> Element GroupMsg
+transformationUI index transformation =
+ let
+ sliderBackground =
+ Element.el
+ [ Element.width Element.fill
+ , Element.height (Element.px 2)
+ , Element.centerY
+ , Background.color <| Element.rgb 0.7 0.7 0.7
+ , Border.rounded 2
+ ]
+ Element.none
+
+ controls =
+ case transformation of
+ Identity ->
+ [ Element.text <| Debug.toString transformation ]
+
+ Scale horizontal vertical ->
+ [ Input.slider
+ [ Element.behindContent sliderBackground
+ ]
+ { onChange =
+ \x ->
+ SetTransformation index (Scale x vertical)
+ , label = Input.labelLeft [] (Element.text "horizontal")
+ , min = 0
+ , max = 10
+ , value = horizontal
+ , thumb = Input.defaultThumb
+ , step = Just 0.1
+ }
+ , Input.slider
+ [ Element.behindContent sliderBackground
+ ]
+ { onChange =
+ \y ->
+ SetTransformation index (Scale horizontal y)
+ , label = Input.labelLeft [] (Element.text "vertical")
+ , min = 0
+ , max = 10
+ , value = vertical
+ , thumb = Input.defaultThumb
+ , step = Just 0.1
+ }
+ ]
+
+ Translate x y ->
+ [ Input.slider
+ [ Element.behindContent sliderBackground
+ ]
+ { onChange =
+ \value ->
+ SetTransformation index (Translate value y)
+ , label = Input.labelLeft [] (Element.text "x")
+ , min = -100
+ , max = 100
+ , value = x
+ , thumb = Input.defaultThumb
+ , step = Just 1
+ }
+ , Input.slider
+ [ Element.behindContent sliderBackground
+ ]
+ { onChange =
+ \value ->
+ SetTransformation index (Translate x value)
+ , label = Input.labelLeft [] (Element.text "y")
+ , min = -100
+ , max = 100
+ , value = y
+ , thumb = Input.defaultThumb
+ , step = Just 1
+ }
+ ]
+
+ Rotate angle ->
+ [ Input.slider
+ [ Element.behindContent sliderBackground
+ ]
+ { onChange =
+ \value ->
+ SetTransformation index (Rotate value)
+ , label = Input.labelLeft [] (Element.text "angle")
+ , min = -360
+ , max = 360
+ , value = angle
+ , thumb = Input.defaultThumb
+ , step = Just 1
+ }
+ ]
+ in
+ Element.column
+ [ Element.width Element.fill
+ , Border.color (Element.rgb 0.9 0.9 0.9)
+ , Border.width 3
+ , Element.padding 5
+ , Element.spacing 20
+ ]
+ [ Element.row [ Element.width Element.fill ]
+ [ transformation
+ |> List.singleton
+ |> apply
+ |> Element.text
+ |> Element.el [ Element.width Element.fill ]
+ , Input.button []
+ { onPress = Just (DeleteTransformation index)
+ , label = Element.text "X"
+ }
+ ]
+ , Element.column
+ [ Element.width Element.fill
+ , Element.spacing 20
+ ]
+ controls
+ ]
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update (Msg group msg) model =
+ let
+ transformations =
+ model
+ |> Dict.get group
+ |> Maybe.withDefault Array.empty
+ |> (\current ->
+ case msg of
+ AddTransformation transformation ->
+ Array.push transformation current
+
+ DeleteTransformation index ->
+ arrayDelete index current
+
+ SetTransformation index transformation ->
+ Array.set index transformation current
+ )
+
+ arrayDelete index array =
+ let
+ end =
+ Array.length array
+
+ front =
+ Array.slice 0 index array
+
+ back =
+ Array.slice (index + 1) end array
+ in
+ Array.append front back
+ in
+ ( Dict.insert group transformations model
+ , Cmd.none
+ )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+ Sub.none
+
+
+apply : List Transformation -> String
+apply transformations =
+ let
+ toString : Transformation -> String
+ toString transformation =
+ case transformation of
+ Identity ->
+ ""
+
+ Scale x y ->
+ "scale("
+ ++ String.fromFloat x
+ ++ ", "
+ ++ String.fromFloat y
+ ++ ")"
+
+ Translate x y ->
+ "translate("
+ ++ String.fromFloat x
+ ++ ", "
+ ++ String.fromFloat y
+ ++ ")"
+
+ Rotate angle ->
+ "rotate("
+ ++ String.fromFloat angle
+ ++ ")"
+ in
+ transformations
+ |> List.map toString
+ |> String.join " "
+
+
+toColor : Group -> Element.Color
+toColor group =
+ case group of
+ Pink ->
+ Element.rgb 1 0.73 0.8
+
+ Green ->
+ Element.rgb 0.0 0.5 0.0
+
+
+grid : List (Svg.Attribute msg) -> Float -> Float -> Svg msg
+grid attributes unit size =
+ let
+ positiveValues =
+ size
+ / 2
+ |> floor
+ |> List.range 1
+ |> List.map toFloat
+ |> List.map ((*) unit)
+
+ negativeValues =
+ positiveValues
+ |> List.map negate
+
+ max =
+ unit * size / 2
+
+ min =
+ negate max
+ in
+ ((positiveValues ++ negativeValues)
+ |> List.map
+ (\value ->
+ [ ( Point2d.fromCoordinates ( value, min )
+ , Point2d.fromCoordinates ( value, max )
+ )
+ , ( Point2d.fromCoordinates ( min, value )
+ , Point2d.fromCoordinates ( max, value )
+ )
+ ]
+ )
+ |> List.concat
+ |> List.map LineSegment2d.fromEndpoints
+ |> List.map (Geometry.Svg.lineSegment2d attributes)
+ )
+ |> (::) (CartesianPlane.axes attributes (size * unit))
+ |> g []Reimplement Main with Elm Markup, nest a simple counter program
The idea is that Main will be our website and all the example programs will be nested in it.
index 6cfda8a..d305cfa 100644
--- a/elm.json
+++ b/elm.json
@@ -13,13 +13,16 @@
= "elm/svg": "1.0.1",
= "elm-community/basics-extra": "4.0.0",
= "elm-community/list-extra": "8.1.0",
+ "elm-community/result-extra": "2.2.1",
= "elm-explorations/markdown": "1.0.0",
= "ianmackenzie/elm-geometry": "1.2.1",
= "ianmackenzie/elm-geometry-svg": "1.0.2",
+ "mdgriffith/elm-markup": "1.0.0",
= "mdgriffith/elm-ui": "1.1.0",
= "turboMaCk/any-dict": "1.0.1"
= },
= "indirect": {
+ "elm/parser": "1.1.0",
= "elm/time": "1.0.0",
= "elm/url": "1.0.0",
= "elm/virtual-dom": "1.0.2",new file mode 100644
index 0000000..0f0689c
--- /dev/null
+++ b/src/Counter.elm
@@ -0,0 +1,71 @@
+module Counter exposing
+ ( Model
+ , Msg
+ , init
+ , main
+ , ui
+ , update
+ )
+
+import Browser
+import Element exposing (Element)
+import Element.Border as Border
+import Element.Input as Input
+import Html exposing (Html)
+
+
+main =
+ Browser.sandbox
+ { init = init
+ , view = view
+ , update = update
+ }
+
+
+type alias Model =
+ Int
+
+
+type Msg
+ = Increment
+ | Decrement
+
+
+init =
+ 0
+
+
+view : Model -> Html Msg
+view model =
+ model
+ |> ui
+ |> Element.layout []
+
+
+ui : Model -> Element Msg
+ui model =
+ Element.row
+ [ Element.padding 10
+ , Element.spacing 10
+ ]
+ [ Input.button []
+ { onPress = Just Decrement
+ , label = Element.text "-"
+ }
+ , model
+ |> String.fromInt
+ |> Element.text
+ , Input.button []
+ { onPress = Just Increment
+ , label = Element.text "+"
+ }
+ ]
+
+
+update msg model =
+ case msg of
+ Increment ->
+ model + 1
+
+ Decrement ->
+ model - 1index f18bc73..d1066f3 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,578 +1,134 @@
=module Main exposing (main)
=
-import Browser exposing (Document)
-import Browser.Events
-import CartesianCoordinates
-import Dict
-import Element
-import Element.Font as Font
-import Element.Keyed
-import Html
-import Html.Attributes
-import Json.Decode as Decode exposing (Decoder)
-import PolarCoordinates
-import Presentation exposing (Slide, markdown)
+import Browser
+import Counter
+import Element exposing (Element)
+import Element.Border as Border
+import Element.Input as Input
+import Html exposing (Html)
+import Mark
+import Mark.Custom
+import Result.Extra as Result
=
=
=main =
- Browser.document
+ Browser.sandbox
= { init = init
= , view = view
= , update = update
- , subscriptions = subscriptions
= }
=
=
-type alias Flags =
- ()
-
-
=type alias Model =
- { currentSlide : Int
-
- -- Nested programs
- , cartesianCoordinates : CartesianCoordinates.Model
- , polarCoordinates : PolarCoordinates.Model
- }
+ { counter : Counter.Model }
=
=
=type Msg
- = Next
- | Previous
- -- Nested programs
- | CartesianCoordinatesMsg CartesianCoordinates.Msg
- | PolarCoordinatesMsg PolarCoordinates.Msg
+ = CounterMsg Counter.Msg
=
=
-init : Flags -> ( Model, Cmd Msg )
-init flags =
- let
- ( cartesianCoordinatesModel, cartesianCoordinatesCmd ) =
- CartesianCoordinates.init ()
+init =
+ { counter = Counter.init
+ }
=
- ( polarCoordinatesModel, polarCoordinatesCmd ) =
- PolarCoordinates.init ()
- in
- ( { currentSlide = 0
- , cartesianCoordinates = cartesianCoordinatesModel
- , polarCoordinates = polarCoordinatesModel
- }
- , Cmd.batch
- [ Cmd.map CartesianCoordinatesMsg cartesianCoordinatesCmd
- , Cmd.map PolarCoordinatesMsg polarCoordinatesCmd
- ]
- )
-
-
-view : Model -> Document Msg
+
+view : Model -> Html Msg
=view model =
- { title = "FP-Art!"
- , body =
- [ Element.layout
- [ Element.width Element.fill
- , Element.height Element.fill
- ]
- <|
- Element.column
- [ Element.centerX
- , Font.center
- , Element.height Element.fill
- , Element.width (Element.maximum 800 Element.fill)
- ]
- [ slides model
- |> Dict.get model.currentSlide
- |> Maybe.map
- (Element.column
- [ Element.width Element.fill
- , Element.centerY
- ]
- )
- |> Maybe.withDefault (Element.text "404: Slide not found")
- ]
- ]
- }
+ content
+ |> Mark.parseWith options
+ |> Result.mapError Debug.toString
+ |> Result.map (\fn -> fn model)
+ |> Result.extract Element.text
+ |> Element.layout []
=
=
-update : Msg -> Model -> ( Model, Cmd Msg )
=update msg model =
= case msg of
- Next ->
- ( { model
- | currentSlide =
- min (Dict.size (slides model) - 1) (model.currentSlide + 1)
- }
- , Cmd.none
- )
-
- Previous ->
- ( { model
- | currentSlide =
- max 0 (model.currentSlide - 1)
- }
- , Cmd.none
- )
-
- -- Nested programs
- CartesianCoordinatesMsg msg_ ->
- let
- ( model_, cmd_ ) =
- CartesianCoordinates.update msg_ model.cartesianCoordinates
- in
- ( { model | cartesianCoordinates = model_ }
- , Cmd.map CartesianCoordinatesMsg cmd_
- )
-
- PolarCoordinatesMsg msg_ ->
- let
- ( model_, cmd_ ) =
- PolarCoordinates.update msg_ model.polarCoordinates
- in
- ( { model | polarCoordinates = model_ }
- , Cmd.map PolarCoordinatesMsg cmd_
- )
-
-
-subscriptions model =
- let
- handleKeyPress : Decoder Msg
- handleKeyPress =
- Decode.field "key" Decode.string
- |> Decode.andThen
- (\key ->
- case Debug.log "Key" key of
- "ArrowLeft" ->
- Decode.succeed Previous
-
- "ArrowRight" ->
- Decode.succeed Next
-
- "a" ->
- Decode.succeed Previous
-
- "d" ->
- Decode.succeed Next
-
- _ ->
- Decode.fail "Unsupported key"
- )
- in
- Browser.Events.onKeyPress handleKeyPress
-
-
-slides model =
- Dict.fromList <|
- List.indexedMap Tuple.pair <|
- [ markdown """
- # Software Garden
- ## A functional programming workshop
- ### for non-programmers
- """
- ]
- :: [ markdown """
- ## Setup
- """
- ]
- :: [ markdown """
- > This setup instructions are based on an assumption that you are using a Mac.
- >
- > If you are using Linux or BSD, then you probably know how to install stuff.
- >
- > If you are using anything else, then... well, good luck.
- >
- > The rest of the instructions should work with any platform.
-
- """ ]
- :: [ markdown """
-
- We will need:
-
- - a text editor (I use [Atom][])
- - and the [Elm programming language][]
-
- [Atom]: https://atom.io/
- [Elm programming language]: https://elm-lang.org/
-
- """
- ]
- :: [ markdown """
- ### Elm Installation
- """
- ]
- :: [ markdown """
- To install the Elm programming language, go to the [website][Elm] and follow the installation instructions.
-
- [Elm]: http://elm-lang.org/
- """
- ]
- :: [ markdown """
- Some of the tools we use with Elm require Node.js.
-
- Go to the [Node.js website][Node.js] and install the current version (the green button on the right).
-
- [Node.js]: https://nodejs.org/en/
- """
- ]
- :: [ markdown """
- We will need to use the terminal a little bit.
-
- # :fa-terminal:
-
- Don't be scared. It's easy :)
-
- <!-- slide data-background-image="images/mac-launchpad-terminal.png" data-background-size="cover" data-background-position="top center"-->
-
- > <p style="color: white">In Launchpad find a program called <code>terminal</code> and start it.</p>
-
- """
- ]
- :: [ markdown """
- You should see a window like this
- """
- , Html.img
- [ Html.Attributes.alt "Mac Terminal app window"
- , Html.Attributes.src "../assets/mac-terminal-window.png"
- ]
- []
- |> Element.html
- |> Element.el
- [ Element.height Element.fill
- , Element.width Element.fill
- ]
- , markdown """
- Here is some more markdown.
- """
- ]
- :: [ markdown """
-
- Now we are going to install few things.
-
- - Homebrew (to install other things)
- - Elm programming language
- - Atom editor
-
- """
- ]
- :: [ markdown """
-
- ### Install Homebrew
-
- Follow instructions on the [Homebrew website](https://brew.sh/) by typing the following in the terminal (you probably want to copy and paste it):
-
- ```sh
- /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- ```
-
- <small>
- Make sure that the command is exactly like the one above, including the `/` character at the beginning, the quotes and parentheses.
-
- It will ask you to confirm several actions and ask for your password. It may take few minutes to finish, so get your coffee
- </small>
-
- :fa-coffee:
-
- Once it's done you should see a command prompt like that:
-
- ```
- ~ your-name$
- ```
-
-
- """
- ]
- :: [ markdown """
-
- ### Install the Elm programming language
-
- <small>Once we have Homebrew installed, we can use it to install the language.</small>
-
- Type the following in the terminal.
-
- ```sh
- brew install node elm
- ```
-
- and check if it works by typing:
-
- ```
- elm repl
- ```
-
- """
- ]
- :: [ markdown """
-
- Note that the command line changes. You should see something like that
-
- ```
- ---- Elm 0.19.0 ----------------------------------------------------------------
- Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
- --------------------------------------------------------------------------------
- >
- ```
-
- It's the Elm REPL
-
- <small>Read - Evaluate - Print Loop</small>
-
- *[REPL]: Read - Evaluate - Print Loop.
-
- """
- ]
- :: [ markdown """
-
- Inside the REPL type
-
- ```
- 2 + 2
- ```
-
- And expect to see
-
- ```
- ---- Elm 0.19.0 ----------------------------------------------------------------
- Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
- --------------------------------------------------------------------------------
- > 2 + 2
- 4 : number
- >
- ```
-
- Easy, huh?
-
- """
- ]
- :: [ markdown """
-
- We will learn more about REPL later. For now type `:exit` to close it.
+ CounterMsg m ->
+ { model | counter = Counter.update m model.counter }
=
- The command line should look like before again.
=
- """
- ]
- :: [ markdown """
+type alias Styling =
+ Mark.Styling Msg
=
- ### Install Atom text editor
=
- Computer programs are represented as text, so the text editor is the most fundamental tool of a programmer. There is a lot of good text editors, but to get you started, we will use [Atom] here.
+type alias Options =
+ Mark.Options Model Styling Msg
=
- """
- ]
- :: [ markdown """
=
- Type following in the terminal:
-
- ```
- brew cask install atom
- ```
-
- And start it with:
-
- ```sh
- atom
- ```
-
- """
- ]
- :: [ markdown """
-
- One last thing we need is Elm support for Atom editor. You can install it by typing in the terminal:
-
- ```
- apm install language-elm
- ```
-
- <small>APM is the Atom Package Manager, but don't pay much attention to it. We won't be using it again.</small>
-
- """
- ]
- :: [ markdown """
-
- **We are all set!**
-
- :smile:
-
- """
- ]
- :: [ markdown """
-
-
- # First program!
-
- """
- ]
- :: [ markdown """
-
- As mentioned before, programs are represented as text (called *the source code*).
-
- The source code is stored in files
-
- :fa-file:
-
- and files are organized in directories
-
- :fa-folder:
-
- """
- ]
- :: [ markdown """
-
- So the first step is to create a directory for our new program. Let's call it `fpart`.
-
- In the terminal type
-
- ```sh
- mkdir fpart/
- ```
-
- and then
-
- ```
- cd fpart/
- ```
-
- <small>This creates a new directory and makes it the current one. Again, don't worry about the details.</small>
-
- """
- ]
- :: [ markdown """
-
- To easily create a new program, we can type
-
- ```
- elm init
- ```
-
- """
- ]
- :: [ markdown """
-
- Then to create a file with source code, type
-
- ```
- atom src/Main.elm
- ```
-
- <small>This command should open a new Atom window with empty text file.</small>
-
- """
- ]
- :: [ markdown """
-
- ### `main.elm`
-
- ```elm
- module Main exposing (main)
-
- import Html
-
-
- main =
- Html.text "Hello, Tree!"
- ```
-
- <small>Type the above in the editor and save the file</small>
-
- """
- ]
- :: [ markdown """
-
- To see the program running type following in the terminal
-
- ```sh
- elm reactor
- ```
-
- <small>This command starts the Elm reactor, which will let you run your program in the web browser. Note that it won't give you the command line back - it will run as long as you don't stop it.</small>
-
- """
- ]
- :: [ markdown """
-
- # Voila!
-
- <small>Open following address in the web browser</small>
-
- http://localhost:8000/src/Main.elm
+options : Options
+options =
+ let
+ default =
+ Mark.default
+
+ counterBlock : Mark.Custom.Block Model Styling Msg
+ counterBlock =
+ Mark.Custom.block "counter" counterView
+
+ counterView : Styling -> Model -> Element Msg
+ counterView style model =
+ model.counter
+ |> Counter.ui
+ |> Element.el
+ [ Element.centerX
+ ]
+ |> Element.el
+ [ Element.centerX
+ , Border.color (Element.rgb 1 0.6 0.6)
+ , Border.rounded 5
+ , Border.width 2
+ ]
+ |> Element.map CounterMsg
+ in
+ { default
+ | blocks =
+ counterBlock :: Mark.defaultBlocks
+ }
=
- <small>Note that the same address was printed by Elm reactor</small>
=
- """
- ]
- :: [ markdown """
+content =
+ """
+| header
+ To do:
=
- # Let's make a dot!
- # :fa-circle:
+Steps to reproduce the tree:
=
- """
- ]
- :: [ markdown """
+Make a dot
=
- We are going to use a technology called SVG
+ Centered (Elm UI, viewBox, cartesian coordinates)
=
- <small>Scalable Vector Graphics</small>
+Make a line
=
+ Play with transformations (union types)
=
- *[SVG]: Scalable Vector Graphics
+Gradients
=
- """
- ]
- :: [ markdown """
+Multiple lines
=
- Let's install an Elm package to help us work with SVG.
+ Rosettes (different kinds)
=
- Stop the Reactor running in terminal by pressing
+Groups and transformations
=
- `CTRL-C`
+ Spiral (recursion)
=
- and type the following
+Tree
=
- ```
- elm install elm/svg
- ```
=
- Then start the reactor again
+| header
+ Before the course begins
=
- ```
- elm reactor
- ```
+Setup the development environment
=
- <small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
+| list
+ - Elm
+ - Node.js
=
- """
- ]
- :: [ markdown """
=
- <iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
- </iframe>
+| counter
=
- """
- ]
- :: [ markdown """
- Move sliders to change the `x` and `y` coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down should it go.
- """
- , model.cartesianCoordinates
- |> CartesianCoordinates.ui
- |> Element.map CartesianCoordinatesMsg
- |> Element.el
- [ Element.centerX
- , Element.width (Element.maximum 600 Element.fill)
- ]
- ]
- :: [ markdown """
- Move sliders to change the `angle` and `length` properties of the line connecting the dot and origin. The x and y coordinates will be calculated like this:
+Last sentence
=
- ```
- x = cos(angle) * length
+| counter
=
- y = sin(angle) * length
- ```
- """
- , model.polarCoordinates
- |> PolarCoordinates.ui
- |> Element.map PolarCoordinatesMsg
- |> Element.el
- [ Element.centerX
- , Element.width (Element.maximum 600 Element.fill)
- ]
- ]
- :: []
+"""