From af2459aedb97024a45ebf0c0f801a62cbf97b5f1 Mon Sep 17 00:00:00 2001 From: David North Date: Thu, 29 Oct 2020 19:59:23 +0000 Subject: [PATCH] Adds tooltip Tooltip is now available on menus. Fixes #39 --- VirtualGloomhavenBoard/Elm/src/Main.elm | 70 ++++++++++++++++--- .../wwwroot/scss/_tooltip.scss | 44 ++++++++++++ VirtualGloomhavenBoard/wwwroot/scss/main.scss | 1 + 3 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 VirtualGloomhavenBoard/wwwroot/scss/_tooltip.scss diff --git a/VirtualGloomhavenBoard/Elm/src/Main.elm b/VirtualGloomhavenBoard/Elm/src/Main.elm index a811062..5f666af 100644 --- a/VirtualGloomhavenBoard/Elm/src/Main.elm +++ b/VirtualGloomhavenBoard/Elm/src/Main.elm @@ -6,6 +6,7 @@ import Bitwise import BoardMapTile exposing (MapTileRef(..), refToString) import BoardOverlay exposing (BoardOverlay, BoardOverlayDirectionType(..), BoardOverlayType(..), ChestType(..), CorridorMaterial(..), DifficultTerrainSubType(..), DoorSubType(..), ObstacleSubType(..), TrapSubType(..), TreasureSubType(..), getBoardOverlayName) import Browser +import Browser.Dom as BrowserDom exposing (Error) import Browser.Events exposing (Visibility(..), onKeyDown, onKeyUp, onVisibilityChange) import Character exposing (CharacterClass(..), characterToString) import Dict @@ -15,7 +16,7 @@ import Game exposing (AIType(..), Cell, Game, GameState, Piece, PieceType(..), R import GameSync exposing (Msg(..), connectToServer, update) import Html exposing (a, div, footer, header, iframe, img, span, text) import Html.Attributes exposing (attribute, checked, class, href, id, maxlength, minlength, required, src, style, target, title, value) -import Html.Events exposing (onClick) +import Html.Events exposing (on, onClick) import Http exposing (Error) import Json.Decode as Decode import List exposing (all, any, filter, filterMap, head, map, member, reverse, sort, sortWith, take) @@ -52,6 +53,7 @@ type alias Model = , roomCodeSeed : Maybe Int , keysDown : List String , roomCodePassesServerCheck : Bool + , tooltipTarget : Maybe ( BrowserDom.Element, String ) } @@ -119,6 +121,9 @@ type Msg | Paste String | VisibilityChanged Visibility | PushGameState Bool + | InitTooltip String String + | SetTooltip String (Result BrowserDom.Error BrowserDom.Element) + | ResetTooltip | ExitFullscreen () | Reconnect | NoOp @@ -237,6 +242,7 @@ init ( oldState, maybeOverrides, seed ) = overrides.initRoomCodeSeed [] True + Nothing , Cmd.batch [ connectToServer , loadScenarioById @@ -888,6 +894,20 @@ update msg model = Visible -> ( model, Cmd.none ) + InitTooltip identifier text -> + ( model, Task.attempt (SetTooltip text) (BrowserDom.getElement identifier) ) + + SetTooltip text result -> + case result of + Ok element -> + ( { model | tooltipTarget = Just ( element, text ) }, Cmd.none ) + + Err _ -> + ( model, Cmd.none ) + + ResetTooltip -> + ( { model | tooltipTarget = Nothing }, Cmd.none ) + ExitFullscreen _ -> ( { model | fullscreen = False, currentClientSettings = Nothing }, Cmd.none ) @@ -1035,6 +1055,32 @@ view model = _ -> [ getDialogForAppMode model ] ) + ++ (case model.tooltipTarget of + Nothing -> + [] + + Just ( e, t ) -> + let + x = + (e.element.x + + e.element.width + |> String.fromFloat + ) + ++ "px" + + y = + (e.element.y + + (e.element.height / 4) + |> String.fromFloat + ) + ++ "px" + in + [ div [ class "tooltip-wrapper", style "left" x, style "top" y ] + [ div [ class "tooltip-text" ] + [ text t ] + ] + ] + ) ) @@ -1476,42 +1522,42 @@ getNavHtml model = [ Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode MovePiece ) |> Dom.addClass "move-piece" - |> Dom.addAttribute (title "Move Monsters or Players") + |> tooltipHtml "moveAction" "Move Monsters or Players" |> Dom.addClassConditional "active" (model.config.gameMode == MovePiece) |> Dom.appendText "Move Piece" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode KillPiece ) - |> Dom.addAttribute (title "Remove Monsters or Players") + |> tooltipHtml "removeAction" "Remove Monsters or Players" |> Dom.addClass "kill-piece" |> Dom.addClassConditional "active" (model.config.gameMode == KillPiece) |> Dom.appendText "Kill Piece" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode LootCell ) - |> Dom.addAttribute (title "Loot a tile") + |> tooltipHtml "lootAction" "Loot a tile" |> Dom.addClass "loot" |> Dom.addClassConditional "active" (model.config.gameMode == LootCell) |> Dom.appendText "Loot" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode MoveOverlay ) - |> Dom.addAttribute (title "Move Obstacles or Traps") + |> tooltipHtml "moveObstacleAction" "Move Obstacles or Traps" |> Dom.addClass "move-overlay" |> Dom.addClassConditional "active" (model.config.gameMode == MoveOverlay) |> Dom.appendText "Move Overlay" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode DestroyOverlay ) - |> Dom.addAttribute (title "Remove Obstacles or Traps") + |> tooltipHtml "removeObstacleAction" "Remove Obstacles or Traps" |> Dom.addClass "destroy-overlay" |> Dom.addClassConditional "active" (model.config.gameMode == DestroyOverlay) |> Dom.appendText "Destroy Overlay" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode RevealRoom ) - |> Dom.addAttribute (title "Open a door") + |> tooltipHtml "openDoorAction" "Open a door" |> Dom.addClass "reveal-room" |> Dom.addClassConditional "active" (model.config.gameMode == RevealRoom) |> Dom.appendText "Reveal Room" , Dom.element "li" |> Dom.addAction ( "click", ChangeGameMode AddPiece ) - |> Dom.addAttribute (title "Summon a piece to the board") + |> tooltipHtml "summonAction" "Summon a piece to the board" |> Dom.addClass "add-piece" |> Dom.addClassConditional "active" (model.config.gameMode == AddPiece) |> Dom.appendText "Add Piece" @@ -2176,6 +2222,14 @@ shortcutHtml keys element = element +tooltipHtml : String -> String -> Element Msg -> Element Msg +tooltipHtml identifier tooltip element = + element + |> Dom.setId identifier + |> Dom.addAction ( "pointerover", InitTooltip identifier tooltip ) + |> Dom.addAction ( "pointerout", ResetTooltip ) + + isValidScenario : String -> Bool isValidScenario scenarioId = case String.toInt scenarioId of diff --git a/VirtualGloomhavenBoard/wwwroot/scss/_tooltip.scss b/VirtualGloomhavenBoard/wwwroot/scss/_tooltip.scss new file mode 100644 index 0000000..14497df --- /dev/null +++ b/VirtualGloomhavenBoard/wwwroot/scss/_tooltip.scss @@ -0,0 +1,44 @@ +html { + .tooltip-wrapper { + position: absolute; + z-index: 1; + color: white; + background-color: rgba(0, 0, 0); + padding: 0.4rem; + margin-left: 1rem; + letter-spacing: 0.12rem; + transition: all 0.2s; + opacity: 0; + animation-duration: 0.5s; + animation-name: tooltipIn; + animation-fill-mode: both; + animation-delay: 0.75s; + + &:after { + width: 0.75rem; + height: 0.75rem; + content: ''; + display: block; + position: absolute; + left: -0.35rem; + transform: rotate(45deg); + z-index: 1; + background-color: rgba(0, 0, 0); + top: 0.7rem; + } + + .tooltip-text { + padding-left: 0.5rem; + } + } +} + +@keyframes tooltipIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} \ No newline at end of file diff --git a/VirtualGloomhavenBoard/wwwroot/scss/main.scss b/VirtualGloomhavenBoard/wwwroot/scss/main.scss index df7f848..318ce26 100644 --- a/VirtualGloomhavenBoard/wwwroot/scss/main.scss +++ b/VirtualGloomhavenBoard/wwwroot/scss/main.scss @@ -1,6 +1,7 @@ @use 'layout'; @use 'form'; @use 'modal'; +@use 'tooltip'; @use 'board'; @use 'screens';