aboutsummaryrefslogtreecommitdiff
path: root/src/client/elm/Tooltip.elm
blob: 4f70cdad3b90605bdb3868d2a8b30a29706675b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module Tooltip exposing
  ( Msg(..)
  , Model
  , init
  , subscription
  , update
  , view
  , show
  )

import Platform.Cmd

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)

import Mouse exposing (Position)
import Window exposing (Size)

type Msg =
  UpdateMousePosition Position
  | UpdateWindowSize Size
  | ShowMessage String
  | HideMessage

type alias Model =
  { mousePosition : Maybe Position
  , windowSize : Size
  , message : Maybe String
  }

init : Int -> Int -> Model
init width height =
  { mousePosition = Nothing
  , windowSize =
      { width = width
      , height = height
      }
  , message = Nothing
  }

subscription : Sub Msg
subscription =
  Sub.batch
    [ Mouse.moves UpdateMousePosition
    , Window.resizes UpdateWindowSize
    ]

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    UpdateMousePosition position ->
      ( { model | mousePosition = Just position }
      , Cmd.none
      )

    UpdateWindowSize size ->
      ( { model | windowSize = size }
      , Cmd.none
      )

    ShowMessage message ->
      ( { model | message = Just message }
      , Cmd.none
      )

    HideMessage ->
      ( { model | message = Nothing }
      , Cmd.none
      )

view : Model -> Html Msg
view { mousePosition, windowSize, message } =
  case (mousePosition, message) of
    (Just pos, Just msg) ->
      div
        [ class "tooltip"
        , style
            [ ("position", "absolute")
            , horizontalPosition windowSize pos
            , ("top", px <| pos.y + 15)
            ]
        ]
        [ text msg ]
    _ ->
      text ""

horizontalPosition : Size -> Position -> (String, String)
horizontalPosition size position =
  if isLeft size position
    then ("left", px <| position.x + 5)
    else ("right", px <| size.width - position.x)

verticalPosition : Size -> Position -> (String, String)
verticalPosition size position =
  if isTop size position
    then ("top", px <| position.y + 20)
    else ("bottom", px <| size.height - position.y + 15)

px : Int -> String
px n = (toString n) ++ "px"

isLeft : Size -> Position -> Bool
isLeft { width } { x } = x < width // 2

isTop : Size -> Position -> Bool
isTop { height } { y } = y < height // 2

show : (Msg -> msg) -> String -> List (Attribute msg)
show mapMsg message =
  [ onMouseEnter <| mapMsg <| ShowMessage message
  , onMouseLeave <| mapMsg <| HideMessage
  ]