Commits: 4

Create a fancy coupon widget and use it for Utrecht test run on

We want the link to be more prominent.

index a010fa5..67672db 100644
--- a/content/index.txt
+++ b/content/index.txt
@@ -15,8 +15,11 @@ Hello! We are running a workshop that will give you a glimpse into the way softw
=
=During this *5 days workshop* (4 hours each day) you will learn to solve problems using a functional programming language. We think {Link|it's important|url=/motivation.html}. Upon completion of the course your name, photo and link to your website (or LinkedIn profile etc) will be posted here.  The price for participation is *500 €* (inc. 21% VAT).
=
-| Note
-    {Icon|name=gift} {Link|Special offer for University of Utrecht students|url=/test-run.html}.
+| Coupon
+    icon = gift
+    primary = True
+    text = Special offer for University of Utrecht students
+    href = /test-run.html
=
=Below is the material through which we will be going during the workshop. Only the first section is a required read before you come.
=
index 41c32c3..2eac9c4 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -827,6 +827,7 @@ document =
=            [ Mark.Custom.editor
=            , Mark.Custom.elmRepl
=            , Mark.Custom.note
+            , Mark.Custom.coupon
=            ]
=
=        special =
index 88c3af4..1e547c3 100644
--- a/src/Mark/Custom.elm
+++ b/src/Mark/Custom.elm
@@ -1,5 +1,6 @@
=module Mark.Custom exposing
=    ( colors
+    , coupon
=    , editor
=    , elmRepl
=    , emphasize
@@ -103,6 +104,100 @@ link =
=        (Mark.field "label" paragraph)
=
=
+coupon =
+    let
+        render :
+            { icon : String
+            , text : String
+            , primary : Bool
+            , href : String
+            }
+            -> model
+            -> Element msg
+        render config model =
+            { url = config.href
+            , label =
+                [ FeatherIcons.icons
+                    |> Dict.get config.icon
+                    |> Maybe.map (FeatherIcons.toHtml [])
+                    |> Maybe.map Element.html
+                    |> Maybe.map (Element.el [ Element.paddingXY 10 0 ])
+                    |> Maybe.withDefault Element.none
+                , config.text
+                    |> Element.text
+                ]
+                    |> Element.row
+                        [ Element.centerX
+                        ]
+            }
+                |> Element.link
+                    [ Element.paddingXY 0 20
+                    , Font.size 24
+                    , Font.bold
+                    , Background.color colors.white
+                    , Element.width Element.fill
+
+                    -- , Background.color colors.charcoal
+                    , Font.color
+                        (if config.primary then
+                            colors.green
+
+                         else
+                            colors.charcoal
+                        )
+                    , Border.rounded 9
+                    , Border.width 1
+                    , Border.color
+                        (if config.primary then
+                            colors.green
+
+                         else
+                            colors.charcoal
+                        )
+                    , Border.width 1
+                    , Border.dashed
+                    , Element.mouseOver
+                        [ Border.shadow
+                            { offset = ( 0, 2 )
+                            , size = 0
+                            , blur = 3
+                            , color = colors.charcoal
+                            }
+                        , Element.moveDown 5
+                        , Element.moveLeft 3
+                        , Element.rotate (degrees 1)
+                        ]
+                    ]
+                |> Element.el
+                    [ Background.color colors.gray
+                    , Border.innerShadow
+                        { offset = ( 0, 2 )
+                        , size = 1
+                        , blur = 3
+                        , color = colors.charcoal
+                        }
+                    , Border.rounded 10
+                    , Border.width 1
+                    , Border.color
+                        (if config.primary then
+                            colors.green
+
+                         else
+                            colors.charcoal
+                        )
+                    , Border.width 1
+                    , Border.dashed
+                    ]
+    in
+    Mark.record4 "Coupon"
+        (\icon_ text_ primary href -> { icon = icon_, text = text_, primary = primary, href = href })
+        (Mark.field "icon" Mark.string)
+        (Mark.field "text" Mark.string)
+        (Mark.field "primary" Mark.bool)
+        (Mark.field "href" Mark.string)
+        |> Mark.map render
+
+
=monospace : Mark.Block (model -> Element msg)
=monospace =
=    Mark.Default.monospace

Merge branch 'big-utrecht-button' into 'master'

Create a fancy coupon widget and use it for Utrecht test run

See merge request software-garden/software-garden.gitlab.io!29

Make AnimatedTree markup block customizable

It takes the same configuration as Tree block. The minimum and maximum age are hardcoded (0 - 6).

Also add a Subtitle block.

index 10a10f6..33c7a49 100644
--- a/content/day-5.txt
+++ b/content/day-5.txt
@@ -25,6 +25,38 @@ We have a nice picture of a tree, but ultimately it may have been easier to just
=
=| Window
=    | AnimatedTree
+        | Axiom
+            color = olive
+            rotation = -90
+            age = 8
+            growing = True
+
+        | Rule
+            parent = olive
+
+            children =
+                | Child
+                    color = olive
+                    rotation = 5.0
+
+                | Child
+                    color = maroon
+                    rotation = 40
+
+                | Child
+                    color = maroon
+                    rotation = -40
+
+        | Rule
+            parent = maroon
+            children =
+                | Child
+                    color = olive
+                    rotation = 20
+                | Child
+                    color = olive
+                    rotation = -20
+
=
=| Header
=    The Elm Architecture
index 67672db..7bae3a4 100644
--- a/content/index.txt
+++ b/content/index.txt
@@ -1,11 +1,42 @@
=| Title
=    Software Garden
=
-| Emphasize
-
-
+| Subtitle
=    A software development workshop for non-programmers
=
+| AnimatedTree
+    | Axiom
+        color = olive
+        rotation = -90
+        age = 8
+        growing = True
+
+    | Rule
+        parent = olive
+
+        children =
+            | Child
+                color = olive
+                rotation = 5.0
+
+            | Child
+                color = maroon
+                rotation = 40
+
+            | Child
+                color = maroon
+                rotation = -40
+
+    | Rule
+        parent = maroon
+        children =
+            | Child
+                color = olive
+                rotation = 20
+            | Child
+                color = olive
+                rotation = -20
+
=Hello! We are running a workshop that will give you a glimpse into the way software is created. Our workshop is intended for people with no prior experience in programming and doesn't require any technical knowledge. Everybody is welcome!
=
=| Emphasize
index fe2d90a..d13c1f8 100644
--- a/src/Examples/AnimatedTree.elm
+++ b/src/Examples/AnimatedTree.elm
@@ -27,12 +27,17 @@ main =
=        }
=
=
+minAge =
+    0
+
+
+maxAge =
+    6
+
+
=type alias Model =
=    { age : Float
-    , maxAge : Float
-    , minAge : Float
=    , play : Bool
-    , config : Examples.Tree.Config
=    }
=
=
@@ -43,27 +48,27 @@ type alias Flags =
=init : Flags -> ( Model, Cmd msg )
=init flags =
=    ( { age = 0.0
-      , maxAge = 6.0
-      , minAge = 0
=      , play = False
-      , config = Examples.Tree.defaults
=      }
=    , Cmd.none
=    )
=
=
-ui : Model -> Element Msg
-ui model =
+ui : Examples.Tree.Config -> Model -> Element Msg
+ui config model =
=    let
=        tree =
=            { config | axiom = { axiom | age = model.age } }
=
+        axiom =
+            config.axiom
+
=        controls =
=            Element.row
=                [ Element.spacing 12
=                ]
=                [ rewindButton
-                , if model.age == model.maxAge then
+                , if model.age == maxAge then
=                    resetButton
=
=                  else if model.play then
@@ -74,12 +79,6 @@ ui model =
=                , forwardButton
=                ]
=
-        config =
-            model.config
-
-        axiom =
-            config.axiom
-
=        playButton =
=            Input.button []
=                { onPress = Just Play
@@ -165,7 +164,7 @@ type Msg
=view : Model -> Html Msg
=view model =
=    model
-        |> ui
+        |> ui Examples.Tree.defaults
=        |> Element.layout
=            [ Element.width Element.fill
=            , Element.height Element.fill
@@ -190,30 +189,42 @@ update msg model =
=                progress =
=                    min 32 delta / 1000
=            in
-            ( { model | age = grow progress model }
+            ( { model
+                | age = grow progress model
+                , play = model.age < maxAge
+              }
=            , Cmd.none
=            )
=
=        Reset ->
-            ( { model | age = model.minAge }
+            ( { model
+                | age = minAge
+                , play = True
+              }
=            , Cmd.none
=            )
=
=        Rewind ->
-            ( { model | age = grow -0.2 model }
+            ( { model
+                | age = grow -0.2 model
+                , play = False
+              }
=            , Cmd.none
=            )
=
=        Forward ->
-            ( { model | age = grow 0.2 model }
+            ( { model
+                | age = grow 0.2 model
+                , play = False
+              }
=            , Cmd.none
=            )
=
=
=grow progress model =
=    (model.age + progress)
-        |> min model.maxAge
-        |> max model.minAge
+        |> min maxAge
+        |> max minAge
=
=
=subscriptions : Model -> Sub Msg
index 2eac9c4..70dd2ff 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -819,6 +819,7 @@ document =
=            , Mark.Custom.link
=            , Mark.Custom.monospace
=            , Mark.Custom.emphasize
+            , Mark.Custom.subtitle
=            , Mark.Custom.list
=            , Mark.Custom.image
=            ]
@@ -1140,19 +1141,49 @@ document =
=        animatedTree : Mark.Block (Examples.Model -> Element Msg)
=        animatedTree =
=            let
-                render : Examples.Model -> Element Msg
-                render model =
-                    Examples.AnimatedTree.ui model.animatedTree
+                render : Examples.Tree.Config -> Examples.Model -> Element Msg
+                render config model =
+                    model.animatedTree
+                        |> Examples.AnimatedTree.ui config
=                        |> Element.map Examples.AnimatedTreeMsg
=                        |> Element.map ExamplesMsg
+
+                axiom : Mark.Block Examples.Tree.Axiom
+                axiom =
+                    Mark.record4 "Axiom"
+                        Examples.Tree.Axiom
+                        (Mark.field "color" Mark.string)
+                        (Mark.field "rotation" Mark.float)
+                        (Mark.field "age" Mark.float)
+                        (Mark.field "growing" Mark.bool)
+
+                rules : Mark.Block (List Examples.Tree.Rule)
+                rules =
+                    Mark.manyOf [ rule ]
+
+                rule =
+                    Mark.record2 "Rule"
+                        Tuple.pair
+                        (Mark.field "parent" Mark.string)
+                        (Mark.field "children" (Mark.manyOf [ child ]))
+
+                parent =
+                    Mark.block "Parent" identity Mark.string
+
+                -- Mark.stub "Parent" "green"
+                child =
+                    Mark.record2 "Child"
+                        Examples.Tree.Segment
+                        (Mark.field "color" Mark.string)
+                        (Mark.field "rotation" Mark.float)
=            in
-            Mark.stub "AnimatedTree"
+            Mark.block "AnimatedTree"
=                render
+                (Mark.startWith Examples.Tree.Config
+                    axiom
+                    rules
+                )
=
-        -- Mark.Block Examples.Tree.Config
-        -- result = Examples.Tree.Config
-        -- start = Axiom
-        -- rest =  List Rule
=        viewBox : Mark.Block (Examples.Model -> Element Msg)
=        viewBox =
=            let
index 1e547c3..e17b54e 100644
--- a/src/Mark/Custom.elm
+++ b/src/Mark/Custom.elm
@@ -13,6 +13,7 @@ module Mark.Custom exposing
=    , note
=    , paragraph
=    , row
+    , subtitle
=    , text
=    , title
=    , window
@@ -484,6 +485,26 @@ emphasize =
=        (Mark.manyOf [ text ])
=
=
+subtitle =
+    let
+        render :
+            (model -> List (Element msg))
+            -> model
+            -> Element msg
+        render content model =
+            content model
+                |> Element.paragraph
+                    [ Font.center
+                    , Element.paddingXY 0 10
+                    , Element.width Element.fill
+                    , Element.spacing 10
+                    ]
+    in
+    Mark.block "Subtitle"
+        render
+        text
+
+
=image : Mark.Block (model -> Element msg)
=image =
=    Mark.Default.image

Give id attribute to each subtitle, so it can be linked directly

index 7bae3a4..eb4b093 100644
--- a/content/index.txt
+++ b/content/index.txt
@@ -80,7 +80,7 @@ Below is the material through which we will be going during the workshop. Only t
=    label = Day 5 - Let's Make the Tree Grow
=
=
-| Header
+| Subtitle
=    About us
=
=*Ted*: I'm going to be your teacher during the workshop. I've been working as a software developer for the best part of the last six years. Before that I've been a lawyer.
index e17b54e..075de33 100644
--- a/src/Mark/Custom.elm
+++ b/src/Mark/Custom.elm
@@ -488,21 +488,29 @@ emphasize =
=subtitle =
=    let
=        render :
-            (model -> List (Element msg))
+            String
=            -> model
=            -> Element msg
=        render content model =
-            content model
+            content
+                |> Element.text
+                |> List.singleton
=                |> Element.paragraph
=                    [ Font.center
=                    , Element.paddingXY 0 10
=                    , Element.width Element.fill
=                    , Element.spacing 10
+                    , content
+                        |> String.toLower
+                        |> String.words
+                        |> String.join "-"
+                        |> Html.Attributes.id
+                        |> Element.htmlAttribute
=                    ]
=    in
=    Mark.block "Subtitle"
=        render
-        text
+        Mark.string
=
=
=image : Mark.Block (model -> Element msg)