packages feed

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))