Solution - Contextmenu

The exercise is to add the ability to remove a shape via the context menu. Let's add a Msg for it:

module Msg
-- ...
type Msg
    = -- ...
    | RemoveShape Int

And handle it in the update

module Update exposing (update)
-- ...
update : Msg -> Model -> ( Model, Cmd Msg )
update msg ({ mouse } as model) =
    case msg of
        -- ...
        RemoveShape shapeId ->
            ( model |> removeShape shapeId
            , Cmd.none
            )
                |> andSendShapes
-- ...
removeShape : Int -> Model -> Model
removeShape shapeId model =
    let
        nextShapes : Dict Int Shape
        nextShapes =
            model.shapes
                |> Dict.remove shapeId
    in
        { model | shapes = nextShapes }

Then we just need to add a new entry to the context menu:

module View exposing (view)
-- ...
import Msg
    exposing
        ( Msg
            ( -- ...
            , RemoveShape
            )
        , -- ...
        )
-- ...
toItemGroups : Int -> List (List ( ContextMenu.Item, Msg ))
toItemGroups shapeId =
    [ [ ( ContextMenu.item "Select", SelectShape shapeId )
      , ( ContextMenu.item "Remove", RemoveShape shapeId )
      ]
    ]

And that's it! So it took a bit of work to add context menus but now they're very easy to work with. It's also probably worthwhile to add context menus to the other shapes, but I didn't want to spend time on it for now.

Preparatory Readings

This week we're going to have a look at elm-native-ui. This is a tool to bridge the gap between React Native and Elm, allowing you to build native, cross-platform apps in your favorite language. In order to work with it, you'll want to have the following installed:

  • Android Studio or XCode, depending on the platform you want to focus on.
  • React Native CLI

Go ahead and install those, and we'll look at getting started in the next episode. See you soon!

Resources