moffy-samples-events-0.1.0.0: src/Control/Moffy/Samples/Followbox/Clickable.hs
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
{-# LANGUAGE DataKinds, TypeOperators #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Control.Moffy.Samples.Followbox.Clickable (
-- * Clickable
Clickable, view, click, clickable, clickableText,
-- * With Text Extents
WithTextExtents, withTextExtents, nextToText, translate,
-- * Temporary
FontName, FontSize
) where
import Prelude hiding (repeat)
import Control.Moffy (React, adjust, repeat, find, indexBy)
import Control.Moffy.Samples.Event.Mouse qualified as Mouse
import Control.Moffy.Samples.Event.CalcTextExtents (
TextExtents(..), FontName, FontSize, Rectangle(..),
CalcTextExtents, calcTextExtents )
import Data.Type.Set (pattern Nil, (:-), Singleton)
import qualified Data.Text as T
import Control.Moffy.Samples.Followbox.ViewType (View(..), blue, VText(..))
import Control.Moffy.Samples.Viewable.Basic (Position)
import Data.OneOfThem
import Data.Type.Flip ((<$%>))
import Data.Bool
---------------------------------------------------------------------------
-- * CLICKABLE
-- * WITH TEXT EXTENTS
---------------------------------------------------------------------------
-- CLICKABLE
---------------------------------------------------------------------------
-- data Clickable s = Clickable { view :: View, click :: React s (LoadDefaultWindow :- MouseEv) () }
data Clickable s = Clickable { view :: View, click :: React s MouseEv () }
type MouseEv = Mouse.Move :- Mouse.Down :- Mouse.Up :- 'Nil
clickable :: View -> Position -> Position -> Clickable s
clickable v (l, t) (r, b) = Clickable v
. adjust $ () <$ find isd (fst <$%> repeat Mouse.move `indexBy` repeat leftClick)
where isd (x, y) = l <= x && x <= r && t <= y && y <= b
clickOn :: Mouse.Button -> React s (Singleton Mouse.Down) ()
clickOn b0 = do
b <- Mouse.down
bool (clickOn b0) (pure ()) (b == b0)
leftClick :: React s (Singleton Mouse.Down) ()
leftClick = clickOn Mouse.ButtonPrimary
---------------------------------------------------------------------------
-- WITH TEXT EXTENTS
---------------------------------------------------------------------------
data WithTextExtents = WithTextExtents FontName FontSize T.Text TextExtents
clickableText :: Position -> WithTextExtents -> Clickable s
clickableText p@(x, y) (WithTextExtents fn fs txt xg) =
clickable (View [expand . Singleton $ Text' blue fn fs p txt]) (l, t) (l + gw, t + gh) where
(l, t) = (x + dx, y + dy)
[dx, dy, gw, gh] = ($ textExtentsInkRect xg) <$> [
rectangleLeft, rectangleTop, rectangleWidth, rectangleHeight ]
withTextExtents :: FontName -> FontSize -> T.Text ->
-- React s (LoadDefaultWindow :- CalcTextExtents :- 'Nil) WithTextExtents
React s (CalcTextExtents :- 'Nil) WithTextExtents
withTextExtents fn fs t = WithTextExtents fn fs t <$> calcTextExtents fn fs t
nextToText :: Position -> WithTextExtents -> Position
nextToText (x, y) (WithTextExtents _ _ _ xg) = (x + xo, y) where
[xo, _yo] = ($ xg) <$> [rectangleWidth . textExtentsLogicalRect, rectangleHeight . textExtentsLogicalRect]
translate :: Position -> WithTextExtents -> (Rational, Rational) -> Position
translate (x, y) (WithTextExtents _ (toRational -> fs) _ _) (dx, dy) =
(x + fromRational (fs * dx), y + fromRational (fs * dy))