{-|
Module      : Monomer.Core.WidgetTypes
Copyright   : (c) 2018 Francisco Vallarino
License     : BSD-3-Clause (see the LICENSE file)
Maintainer  : fjvallarino@gmail.com
Stability   : experimental
Portability : non-portable

Basic types and definitions for Widgets.
-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}

module Monomer.Core.WidgetTypes where

import Control.Concurrent (MVar)
import Control.Lens (ALens')
import Data.ByteString.Lazy (ByteString)
import Data.Default
import Data.Map.Strict (Map)
import Data.Sequence (Seq)
import Data.String (IsString(..))
import Data.Text (Text)
import Data.Typeable (Typeable, typeOf)
import GHC.Generics

import qualified Data.Text as T

import Monomer.Common
import Monomer.Core.StyleTypes
import Monomer.Core.ThemeTypes
import Monomer.Event.Types
import Monomer.Graphics.Types

-- | Time ellapsed since startup
type Timestamp = Int

-- | Type constraints for a valid model
type WidgetModel s = Typeable s
-- | Type constraints for a valid event
type WidgetEvent e = Typeable e

{-|
Map of WidgetKeys to WidgetNodes. This association is valid only in the context
of a Composite, with visibility of keys restricted to its scope. WidgetKeys
inside nested Composites are /not/ visible.
-}
type WidgetKeyMap s e = Map WidgetKey (WidgetNode s e)

-- | Direction of focus movement.
data FocusDirection
  = FocusFwd  -- ^ Focus moving forward (usually left to right, top to bottom).
  | FocusBwd  -- ^ Focus moving backward (usually right to left, top to bottom).
  deriving (FocusDirection -> FocusDirection -> Bool
(FocusDirection -> FocusDirection -> Bool)
-> (FocusDirection -> FocusDirection -> Bool) -> Eq FocusDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FocusDirection -> FocusDirection -> Bool
$c/= :: FocusDirection -> FocusDirection -> Bool
== :: FocusDirection -> FocusDirection -> Bool
$c== :: FocusDirection -> FocusDirection -> Bool
Eq, Int -> FocusDirection -> ShowS
[FocusDirection] -> ShowS
FocusDirection -> String
(Int -> FocusDirection -> ShowS)
-> (FocusDirection -> String)
-> ([FocusDirection] -> ShowS)
-> Show FocusDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FocusDirection] -> ShowS
$cshowList :: [FocusDirection] -> ShowS
show :: FocusDirection -> String
$cshow :: FocusDirection -> String
showsPrec :: Int -> FocusDirection -> ShowS
$cshowsPrec :: Int -> FocusDirection -> ShowS
Show)

-- | "WidgetRequest" specific for window related operations.
data WindowRequest
  = WindowSetTitle Text  -- ^ Sets the title of the window to the given text.
  | WindowSetFullScreen  -- ^ Switches to fullscreen mode.
  | WindowMaximize       -- ^ Maximizes the window.
  | WindowMinimize       -- ^ Minimizes the window.
  | WindowRestore        -- ^ Restores the window to its previous normal size.
  | WindowBringToFront   -- ^ Brings the window to the foreground.
  deriving (WindowRequest -> WindowRequest -> Bool
(WindowRequest -> WindowRequest -> Bool)
-> (WindowRequest -> WindowRequest -> Bool) -> Eq WindowRequest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WindowRequest -> WindowRequest -> Bool
$c/= :: WindowRequest -> WindowRequest -> Bool
== :: WindowRequest -> WindowRequest -> Bool
$c== :: WindowRequest -> WindowRequest -> Bool
Eq, Int -> WindowRequest -> ShowS
[WindowRequest] -> ShowS
WindowRequest -> String
(Int -> WindowRequest -> ShowS)
-> (WindowRequest -> String)
-> ([WindowRequest] -> ShowS)
-> Show WindowRequest
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WindowRequest] -> ShowS
$cshowList :: [WindowRequest] -> ShowS
show :: WindowRequest -> String
$cshow :: WindowRequest -> String
showsPrec :: Int -> WindowRequest -> ShowS
$cshowsPrec :: Int -> WindowRequest -> ShowS
Show)

-- | Type of a widget. Used during the merge process.
newtype WidgetType
  = WidgetType Text
  deriving (WidgetType -> WidgetType -> Bool
(WidgetType -> WidgetType -> Bool)
-> (WidgetType -> WidgetType -> Bool) -> Eq WidgetType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WidgetType -> WidgetType -> Bool
$c/= :: WidgetType -> WidgetType -> Bool
== :: WidgetType -> WidgetType -> Bool
$c== :: WidgetType -> WidgetType -> Bool
Eq, Int -> WidgetType -> ShowS
[WidgetType] -> ShowS
WidgetType -> String
(Int -> WidgetType -> ShowS)
-> (WidgetType -> String)
-> ([WidgetType] -> ShowS)
-> Show WidgetType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WidgetType] -> ShowS
$cshowList :: [WidgetType] -> ShowS
show :: WidgetType -> String
$cshow :: WidgetType -> String
showsPrec :: Int -> WidgetType -> ShowS
$cshowsPrec :: Int -> WidgetType -> ShowS
Show, (forall x. WidgetType -> Rep WidgetType x)
-> (forall x. Rep WidgetType x -> WidgetType) -> Generic WidgetType
forall x. Rep WidgetType x -> WidgetType
forall x. WidgetType -> Rep WidgetType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WidgetType x -> WidgetType
$cfrom :: forall x. WidgetType -> Rep WidgetType x
Generic)

instance IsString WidgetType where
  fromString :: String -> WidgetType
fromString = Text -> WidgetType
WidgetType (Text -> WidgetType) -> (String -> Text) -> String -> WidgetType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

{-|
Widgets can receive/report data using lenses or direct values. Reporting
WidgetValue requires user events (in general, an onChange event).
-}
data WidgetData s a
  = WidgetValue a            -- ^ A direct value.
  | WidgetLens (ALens' s a)  -- ^ A lens into the parent model.

{-|
Widgets instances have an associated path from the root, which is unique at a
specific point in time. This path may change, since widgets could be added
before or after it (for example, a widget is added to the beginning of a list).
WidgetIds are used by the runtime to create an association from a unique
identifier to the current valid path of an instance; this unique identifier, the
WidgetId, is the result of combining the timestamp when the instance was created
and its path at that time.

Several WidgetRequests rely on this to find the destination of asynchronous
requests (tasks, clipboard, etc).
-}
data WidgetId = WidgetId {
  WidgetId -> Int
_widTs :: Int,    -- ^ The timestamp when the instance was created.
  WidgetId -> Path
_widPath :: Path  -- ^ The path at creation time.
} deriving (WidgetId -> WidgetId -> Bool
(WidgetId -> WidgetId -> Bool)
-> (WidgetId -> WidgetId -> Bool) -> Eq WidgetId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WidgetId -> WidgetId -> Bool
$c/= :: WidgetId -> WidgetId -> Bool
== :: WidgetId -> WidgetId -> Bool
$c== :: WidgetId -> WidgetId -> Bool
Eq, Int -> WidgetId -> ShowS
[WidgetId] -> ShowS
WidgetId -> String
(Int -> WidgetId -> ShowS)
-> (WidgetId -> String) -> ([WidgetId] -> ShowS) -> Show WidgetId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WidgetId] -> ShowS
$cshowList :: [WidgetId] -> ShowS
show :: WidgetId -> String
$cshow :: WidgetId -> String
showsPrec :: Int -> WidgetId -> ShowS
$cshowsPrec :: Int -> WidgetId -> ShowS
Show, Eq WidgetId
Eq WidgetId
-> (WidgetId -> WidgetId -> Ordering)
-> (WidgetId -> WidgetId -> Bool)
-> (WidgetId -> WidgetId -> Bool)
-> (WidgetId -> WidgetId -> Bool)
-> (WidgetId -> WidgetId -> Bool)
-> (WidgetId -> WidgetId -> WidgetId)
-> (WidgetId -> WidgetId -> WidgetId)
-> Ord WidgetId
WidgetId -> WidgetId -> Bool
WidgetId -> WidgetId -> Ordering
WidgetId -> WidgetId -> WidgetId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: WidgetId -> WidgetId -> WidgetId
$cmin :: WidgetId -> WidgetId -> WidgetId
max :: WidgetId -> WidgetId -> WidgetId
$cmax :: WidgetId -> WidgetId -> WidgetId
>= :: WidgetId -> WidgetId -> Bool
$c>= :: WidgetId -> WidgetId -> Bool
> :: WidgetId -> WidgetId -> Bool
$c> :: WidgetId -> WidgetId -> Bool
<= :: WidgetId -> WidgetId -> Bool
$c<= :: WidgetId -> WidgetId -> Bool
< :: WidgetId -> WidgetId -> Bool
$c< :: WidgetId -> WidgetId -> Bool
compare :: WidgetId -> WidgetId -> Ordering
$ccompare :: WidgetId -> WidgetId -> Ordering
$cp1Ord :: Eq WidgetId
Ord, (forall x. WidgetId -> Rep WidgetId x)
-> (forall x. Rep WidgetId x -> WidgetId) -> Generic WidgetId
forall x. Rep WidgetId x -> WidgetId
forall x. WidgetId -> Rep WidgetId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WidgetId x -> WidgetId
$cfrom :: forall x. WidgetId -> Rep WidgetId x
Generic)

instance Default WidgetId where
  def :: WidgetId
def = Int -> Path -> WidgetId
WidgetId Int
0 Path
emptyPath

{-|
During the merge process, widgets are matched based on WidgetType and WidgetKey.
By default an instance's key is null, which means any matching type will be
valid for merging. If you have items that can be reordered, using a key makes
sure merge picks the correct instance for merging. Keys should be unique within
the context of a Composite. Duplicate key behavior is undefined.
-}
newtype WidgetKey
  = WidgetKey Text
  deriving (WidgetKey -> WidgetKey -> Bool
(WidgetKey -> WidgetKey -> Bool)
-> (WidgetKey -> WidgetKey -> Bool) -> Eq WidgetKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WidgetKey -> WidgetKey -> Bool
$c/= :: WidgetKey -> WidgetKey -> Bool
== :: WidgetKey -> WidgetKey -> Bool
$c== :: WidgetKey -> WidgetKey -> Bool
Eq, Int -> WidgetKey -> ShowS
[WidgetKey] -> ShowS
WidgetKey -> String
(Int -> WidgetKey -> ShowS)
-> (WidgetKey -> String)
-> ([WidgetKey] -> ShowS)
-> Show WidgetKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WidgetKey] -> ShowS
$cshowList :: [WidgetKey] -> ShowS
show :: WidgetKey -> String
$cshow :: WidgetKey -> String
showsPrec :: Int -> WidgetKey -> ShowS
$cshowsPrec :: Int -> WidgetKey -> ShowS
Show, Eq WidgetKey
Eq WidgetKey
-> (WidgetKey -> WidgetKey -> Ordering)
-> (WidgetKey -> WidgetKey -> Bool)
-> (WidgetKey -> WidgetKey -> Bool)
-> (WidgetKey -> WidgetKey -> Bool)
-> (WidgetKey -> WidgetKey -> Bool)
-> (WidgetKey -> WidgetKey -> WidgetKey)
-> (WidgetKey -> WidgetKey -> WidgetKey)
-> Ord WidgetKey
WidgetKey -> WidgetKey -> Bool
WidgetKey -> WidgetKey -> Ordering
WidgetKey -> WidgetKey -> WidgetKey
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: WidgetKey -> WidgetKey -> WidgetKey
$cmin :: WidgetKey -> WidgetKey -> WidgetKey
max :: WidgetKey -> WidgetKey -> WidgetKey
$cmax :: WidgetKey -> WidgetKey -> WidgetKey
>= :: WidgetKey -> WidgetKey -> Bool
$c>= :: WidgetKey -> WidgetKey -> Bool
> :: WidgetKey -> WidgetKey -> Bool
$c> :: WidgetKey -> WidgetKey -> Bool
<= :: WidgetKey -> WidgetKey -> Bool
$c<= :: WidgetKey -> WidgetKey -> Bool
< :: WidgetKey -> WidgetKey -> Bool
$c< :: WidgetKey -> WidgetKey -> Bool
compare :: WidgetKey -> WidgetKey -> Ordering
$ccompare :: WidgetKey -> WidgetKey -> Ordering
$cp1Ord :: Eq WidgetKey
Ord, (forall x. WidgetKey -> Rep WidgetKey x)
-> (forall x. Rep WidgetKey x -> WidgetKey) -> Generic WidgetKey
forall x. Rep WidgetKey x -> WidgetKey
forall x. WidgetKey -> Rep WidgetKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WidgetKey x -> WidgetKey
$cfrom :: forall x. WidgetKey -> Rep WidgetKey x
Generic)

instance IsString WidgetKey where
  fromString :: String -> WidgetKey
fromString = Text -> WidgetKey
WidgetKey (Text -> WidgetKey) -> (String -> Text) -> String -> WidgetKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

{-|
Wrapper of a Typeable instance representing the state of a widget. The widget is
in charge of casting to the correct type.
-}
data WidgetState
  = forall i . WidgetModel i => WidgetState i

instance Show WidgetState where
  show :: WidgetState -> String
show (WidgetState i
state) = String
"WidgetState: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show (i -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf i
state)

{-|
Wrapper of a Typeable instance representing shared data between widgets. Used,
for example, by image widget to avoid loading the same image multiple times. The
widget is in charge of casting to the correct type.
-}
data WidgetShared
  = forall i . Typeable i => WidgetShared i

instance Show WidgetShared where
  show :: WidgetShared -> String
show (WidgetShared i
shared) = String
"WidgetShared: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show (i -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf i
shared)

{-|
WidgetRequests are the way a widget can perform side effects, such as changing
cursor icons, get/set the clipboard and perform asynchronous tasks. These
requests are included as part of a WidgetResult in different points in the
lifecycle of a widget.
-}
data WidgetRequest s e
  -- | Ignore events generated by the parent. Could be used to consume the tab
  --   key and avoid having the focus move to the next widget.
  = IgnoreParentEvents
  -- | Ignore children events. Scroll relies on this to handle click/wheel.
  | IgnoreChildrenEvents
  -- | The widget content changed and requires a different size. Processed at
  --   the end of the cycle, since several widgets may request it.
  | ResizeWidgets WidgetId
  -- | The widget content changed and requires a different size. Processed
  --   immediately. Avoid if possible, since it can affect performance.
  | ResizeWidgetsImmediate WidgetId
  -- | Moves the focus, optionally indicating a starting widgetId.
  | MoveFocus (Maybe WidgetId) FocusDirection
  -- | Sets the focus to the given widgetId.
  | SetFocus WidgetId
  -- | Requests the clipboard contents. It will be received as a SystemEvent.
  | GetClipboard WidgetId
  -- | Sets the clipboard to the given ClipboardData.
  | SetClipboard ClipboardData
  -- | Sets the viewport that should be remain visible when an on-screen
  --   keyboard is displayed. Required for mobile.
  | StartTextInput Rect
  -- | Resets the keyboard viewport,
  | StopTextInput
  -- | Sets a widget as the base target of future events. This is used by the
  --   dropdown component to handle list events; this list, acting as an
  --   overlay, is displayed on top of all other widgets. Tooltip uses it too.
  --   every other widget).
  | SetOverlay WidgetId Path
  -- | Removes the existing overlay.
  | ResetOverlay WidgetId
  -- | Sets the current active cursor icon. This acts as a stack, and resetting
  --   a widgetId means going back to the cursor set immediately before.
  | SetCursorIcon WidgetId CursorIcon
  -- | Removes a cursor icon from the stack. Duplicate requests are ignored.
  | ResetCursorIcon WidgetId
  -- | Sets the current item being dragged and the message it carries. This
  --   message can be used by targets to check if they accept it or not.
  | StartDrag WidgetId Path WidgetDragMsg
  -- | Cancels the current dragging process.
  | StopDrag WidgetId
  -- | Requests rendering a single frame. Rendering is not done at a fixed rate,
  --   in order to reduce CPU usage. Widgets are responsible for requesting
  --   rendering at points of interest. Mouse (except mouse move) and keyboard
  --   events automatically generate render requests, but the result of a
  --   WidgetTask or WidgetProducer does not.
  | RenderOnce
  -- | Useful if a widget requires periodic rendering. An optional maximum
  --   number of frames can be provided.
  | RenderEvery WidgetId Int (Maybe Int)
  -- | Stops a previous periodic rendering request.
  | RenderStop WidgetId
  {-|
  Requests an image to be removed from the Renderer. In general, used by the
  dispose function.
  -}
  | RemoveRendererImage Text
  -- | Requests to exit the application. Can also be used to cancel a previous
  --   request (or a window close).
  | ExitApplication Bool
  -- | Performs a "WindowRequest".
  | UpdateWindow WindowRequest
  -- | Request a model update. This usually involves lenses and "widgetDataSet".
  | UpdateModel (s -> s)
  -- | Updates the path of a given widget. Both "Monomer.Widgets.Single" and
  --   "Monomer.Widgets.Container" handle this automatically.
  | SetWidgetPath WidgetId Path
  -- | Clears an association between widgetId and path.
  | ResetWidgetPath WidgetId
  -- | Raises a user event, which usually will be processed in handleEvent by a
  --   "Monomer.Widgets.Composite" instance.
  | WidgetEvent e => RaiseEvent e
  -- | Sends a message to the given widgetId. If the target does not expect the
  --   message's type, it will be ignored.
  | forall i . Typeable i => SendMessage WidgetId i
  -- | Runs an asynchronous tasks. It is mandatory to return a message that will
  --   be sent to the task owner (this is the only way to feed data back).
  | forall i . Typeable i => RunTask WidgetId Path (IO i)
  -- | Similar to RunTask, but can generate unlimited messages. This is useful
  --   for WebSockets and similar data sources. It receives a function that
  --   can be used to send messages back to the producer owner.
  | forall i . Typeable i => RunProducer WidgetId Path ((i -> IO ()) -> IO ())

instance Eq e => Eq (WidgetRequest s e) where
  WidgetRequest s e
IgnoreParentEvents == :: WidgetRequest s e -> WidgetRequest s e -> Bool
== WidgetRequest s e
IgnoreParentEvents = Bool
True
  WidgetRequest s e
IgnoreChildrenEvents == WidgetRequest s e
IgnoreChildrenEvents = Bool
True
  ResizeWidgets WidgetId
w1 == ResizeWidgets WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  ResizeWidgetsImmediate WidgetId
w1 == ResizeWidgetsImmediate WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  MoveFocus Maybe WidgetId
w1 FocusDirection
fd1 == MoveFocus Maybe WidgetId
w2 FocusDirection
fd2 = (Maybe WidgetId
w1, FocusDirection
fd1) (Maybe WidgetId, FocusDirection)
-> (Maybe WidgetId, FocusDirection) -> Bool
forall a. Eq a => a -> a -> Bool
== (Maybe WidgetId
w2, FocusDirection
fd2)
  SetFocus WidgetId
w1 == SetFocus WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  GetClipboard WidgetId
w1 == GetClipboard WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  SetClipboard ClipboardData
c1 == SetClipboard ClipboardData
c2 = ClipboardData
c1 ClipboardData -> ClipboardData -> Bool
forall a. Eq a => a -> a -> Bool
== ClipboardData
c2
  StartTextInput Rect
r1 == StartTextInput Rect
r2 = Rect
r1 Rect -> Rect -> Bool
forall a. Eq a => a -> a -> Bool
== Rect
r2
  WidgetRequest s e
StopTextInput == WidgetRequest s e
StopTextInput = Bool
True
  SetOverlay WidgetId
w1 Path
p1 == SetOverlay WidgetId
w2 Path
p2 = (WidgetId
w1, Path
p1) (WidgetId, Path) -> (WidgetId, Path) -> Bool
forall a. Eq a => a -> a -> Bool
== (WidgetId
w2, Path
p2)
  ResetOverlay WidgetId
w1 == ResetOverlay WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  SetCursorIcon WidgetId
w1 CursorIcon
c1 == SetCursorIcon WidgetId
w2 CursorIcon
c2 = (WidgetId
w1, CursorIcon
c1) (WidgetId, CursorIcon) -> (WidgetId, CursorIcon) -> Bool
forall a. Eq a => a -> a -> Bool
== (WidgetId
w2, CursorIcon
c2)
  ResetCursorIcon WidgetId
w1 == ResetCursorIcon WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  StartDrag WidgetId
w1 Path
p1 WidgetDragMsg
m1 == StartDrag WidgetId
w2 Path
p2 WidgetDragMsg
m2 = (WidgetId
w1, Path
p1, WidgetDragMsg
m1) (WidgetId, Path, WidgetDragMsg)
-> (WidgetId, Path, WidgetDragMsg) -> Bool
forall a. Eq a => a -> a -> Bool
== (WidgetId
w2, Path
p2, WidgetDragMsg
m2)
  StopDrag WidgetId
w1 == StopDrag WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  WidgetRequest s e
RenderOnce == WidgetRequest s e
RenderOnce = Bool
True
  RenderEvery WidgetId
p1 Int
c1 Maybe Int
r1 == RenderEvery WidgetId
p2 Int
c2 Maybe Int
r2 = (WidgetId
p1, Int
c1, Maybe Int
r1) (WidgetId, Int, Maybe Int) -> (WidgetId, Int, Maybe Int) -> Bool
forall a. Eq a => a -> a -> Bool
== (WidgetId
p2, Int
c2, Maybe Int
r2)
  RenderStop WidgetId
p1 == RenderStop WidgetId
p2 = WidgetId
p1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
p2
  ExitApplication Bool
e1 == ExitApplication Bool
e2 = Bool
e1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
e2
  UpdateWindow WindowRequest
w1 == UpdateWindow WindowRequest
w2 = WindowRequest
w1 WindowRequest -> WindowRequest -> Bool
forall a. Eq a => a -> a -> Bool
== WindowRequest
w2
  SetWidgetPath WidgetId
w1 Path
p1 == SetWidgetPath WidgetId
w2 Path
p2 = (WidgetId
w1, Path
p1) (WidgetId, Path) -> (WidgetId, Path) -> Bool
forall a. Eq a => a -> a -> Bool
== (WidgetId
w2, Path
p2)
  ResetWidgetPath WidgetId
w1 == ResetWidgetPath WidgetId
w2 = WidgetId
w1 WidgetId -> WidgetId -> Bool
forall a. Eq a => a -> a -> Bool
== WidgetId
w2
  RaiseEvent e
e1 == RaiseEvent e
e2 = e
e1 e -> e -> Bool
forall a. Eq a => a -> a -> Bool
== e
e2
  WidgetRequest s e
_ == WidgetRequest s e
_ = Bool
False

{-|
Result of widget operations (init, merge, handleEvent, etc). The node is
mandatory. The "resultNode", "resultEvts", "resultReqs" and "resultReqsEvts"
helper functions can also be used.

In general a result starts in a child widget, but parent widgets can append
requets or new versions of themselves.
-}
data WidgetResult s e = WidgetResult {
  WidgetResult s e -> WidgetNode s e
_wrNode :: WidgetNode s e,              -- ^ The updated widget node.
  WidgetResult s e -> Seq (WidgetRequest s e)
_wrRequests :: Seq (WidgetRequest s e)  -- ^ The widget requests.
}

-- This instance is lawless (there is not an empty widget): use with caution
instance Semigroup (WidgetResult s e) where
  WidgetResult s e
er1 <> :: WidgetResult s e -> WidgetResult s e -> WidgetResult s e
<> WidgetResult s e
er2 = WidgetResult :: forall s e.
WidgetNode s e -> Seq (WidgetRequest s e) -> WidgetResult s e
WidgetResult {
    _wrNode :: WidgetNode s e
_wrNode = WidgetResult s e -> WidgetNode s e
forall s e. WidgetResult s e -> WidgetNode s e
_wrNode WidgetResult s e
er2,
    _wrRequests :: Seq (WidgetRequest s e)
_wrRequests = WidgetResult s e -> Seq (WidgetRequest s e)
forall s e. WidgetResult s e -> Seq (WidgetRequest s e)
_wrRequests WidgetResult s e
er1 Seq (WidgetRequest s e)
-> Seq (WidgetRequest s e) -> Seq (WidgetRequest s e)
forall a. Semigroup a => a -> a -> a
<> WidgetResult s e -> Seq (WidgetRequest s e)
forall s e. WidgetResult s e -> Seq (WidgetRequest s e)
_wrRequests WidgetResult s e
er2
  }

-- | Used to indicate active layout direction. Some widgets, such as spacer,
--   can use it to adapt themselves.
data LayoutDirection
  = LayoutNone
  | LayoutHorizontal
  | LayoutVertical
  deriving (LayoutDirection -> LayoutDirection -> Bool
(LayoutDirection -> LayoutDirection -> Bool)
-> (LayoutDirection -> LayoutDirection -> Bool)
-> Eq LayoutDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LayoutDirection -> LayoutDirection -> Bool
$c/= :: LayoutDirection -> LayoutDirection -> Bool
== :: LayoutDirection -> LayoutDirection -> Bool
$c== :: LayoutDirection -> LayoutDirection -> Bool
Eq, Int -> LayoutDirection -> ShowS
[LayoutDirection] -> ShowS
LayoutDirection -> String
(Int -> LayoutDirection -> ShowS)
-> (LayoutDirection -> String)
-> ([LayoutDirection] -> ShowS)
-> Show LayoutDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LayoutDirection] -> ShowS
$cshowList :: [LayoutDirection] -> ShowS
show :: LayoutDirection -> String
$cshow :: LayoutDirection -> String
showsPrec :: Int -> LayoutDirection -> ShowS
$cshowsPrec :: Int -> LayoutDirection -> ShowS
Show, (forall x. LayoutDirection -> Rep LayoutDirection x)
-> (forall x. Rep LayoutDirection x -> LayoutDirection)
-> Generic LayoutDirection
forall x. Rep LayoutDirection x -> LayoutDirection
forall x. LayoutDirection -> Rep LayoutDirection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LayoutDirection x -> LayoutDirection
$cfrom :: forall x. LayoutDirection -> Rep LayoutDirection x
Generic)

-- | The widget environment. This includes system information, active viewport,
--   and input status among other things.
data WidgetEnv s e = WidgetEnv {
  -- | The OS of the host.
  WidgetEnv s e -> Text
_weOs :: Text,
  -- | Provides helper funtions for calculating text size.
  WidgetEnv s e -> FontManager
_weFontManager :: FontManager,
  -- | Returns the information of a node given a path from root, if any.
  WidgetEnv s e -> Path -> Maybe WidgetNodeInfo
_weFindByPath :: Path -> Maybe WidgetNodeInfo,
  -- | The mouse button that is considered main.
  WidgetEnv s e -> Button
_weMainButton :: Button,
  -- | The mouse button that is considered as secondary or context button.
  WidgetEnv s e -> Button
_weContextButton :: Button,
  -- | The active theme. Some widgets derive their base style from this.
  WidgetEnv s e -> Theme
_weTheme :: Theme,
  -- | The main window size.
  WidgetEnv s e -> Size
_weWindowSize :: Size,
  -- | The active map of shared data.
  WidgetEnv s e -> MVar (Map Text WidgetShared)
_weWidgetShared :: MVar (Map Text WidgetShared),
  -- | The active map of WidgetKey -> WidgetNode, if any.
  WidgetEnv s e -> WidgetKeyMap s e
_weWidgetKeyMap :: WidgetKeyMap s e,
  -- | The currently hovered path, if any.
  WidgetEnv s e -> Maybe Path
_weHoveredPath :: Maybe Path,
  -- | The currently focused path. There's always one, even if it's empty.
  WidgetEnv s e -> Path
_weFocusedPath :: Path,
  -- | The current overlay path, if any.
  WidgetEnv s e -> Maybe Path
_weOverlayPath :: Maybe Path,
  -- | The current drag message and source path, if any is active.
  WidgetEnv s e -> Maybe (Path, WidgetDragMsg)
_weDragStatus :: Maybe (Path, WidgetDragMsg),
  -- | Indicates the path and position where the main button was pressed.
  WidgetEnv s e -> Maybe (Path, Point)
_weMainBtnPress :: Maybe (Path, Point),
  -- | The current active cursor, and the path that set it.
  WidgetEnv s e -> Maybe (Path, CursorIcon)
_weCursor :: Maybe (Path, CursorIcon),
  -- | The current user model.
  WidgetEnv s e -> s
_weModel :: s,
  -- | The input status, mainly mouse and keyboard.
  WidgetEnv s e -> InputStatus
_weInputStatus :: InputStatus,
  -- | The timestamp when this cycle started.
  WidgetEnv s e -> Int
_weTimestamp :: Timestamp,
  {-|
  Whether the theme changed in this cycle. Should be considered when a widget
  avoids merging as optimization, as the styles may have changed.
  -}
  WidgetEnv s e -> Bool
_weThemeChanged :: Bool,
  -- | Indicates whether the current widget is in a top layer (zstack).
  WidgetEnv s e -> Point -> Bool
_weInTopLayer :: Point -> Bool,
  -- | The current layout direction.
  WidgetEnv s e -> LayoutDirection
_weLayoutDirection :: LayoutDirection,
  {-|
  The active viewport.  This may be smaller than the widget's viewport, if it's
  currently inside a scroll or similar.
  -}
  WidgetEnv s e -> Rect
_weViewport :: Rect,
  -- | The current accumulated offset. This can be affected by scroll.
  WidgetEnv s e -> Point
_weOffset :: Point
}

-- | Complementary information to a Widget, forming a node in the widget tree.
data WidgetNodeInfo =
  WidgetNodeInfo {
    -- | Type of the widget.
    WidgetNodeInfo -> WidgetType
_wniWidgetType :: !WidgetType,
    -- | The identifier at creation time of the widget (runtime generated).
    WidgetNodeInfo -> WidgetId
_wniWidgetId :: !WidgetId,
    -- | Key/Identifier of the widget (user provided). Used for merging.
    WidgetNodeInfo -> Maybe WidgetKey
_wniKey :: Maybe WidgetKey,
    -- | The path of the instance in the widget tree, as a set of indexes.
    WidgetNodeInfo -> Path
_wniPath :: !Path,
    -- | The requested width for the widget. The one in style takes precedence.
    WidgetNodeInfo -> SizeReq
_wniSizeReqW :: !SizeReq,
    -- | The requested height for the widget. The one in style takes precedence.
    WidgetNodeInfo -> SizeReq
_wniSizeReqH :: !SizeReq,
    -- | Indicates if the widget is enabled for user interaction.
    WidgetNodeInfo -> Bool
_wniEnabled :: !Bool,
    -- | Indicates if the widget is visible.
    WidgetNodeInfo -> Bool
_wniVisible :: !Bool,
    -- | Indicates whether the widget can receive focus.
    WidgetNodeInfo -> Bool
_wniFocusable :: !Bool,
    {-|
    The area of the window where the widget can draw. Could be out of bounds or
    partially invisible if inside a scroll. The viewport on 'WidgetEnv' defines
    what is currently visible.
    -}
    WidgetNodeInfo -> Rect
_wniViewport :: !Rect,
    -- | Style attributes of the widget instance.
    WidgetNodeInfo -> Style
_wniStyle :: Style
  } deriving (WidgetNodeInfo -> WidgetNodeInfo -> Bool
(WidgetNodeInfo -> WidgetNodeInfo -> Bool)
-> (WidgetNodeInfo -> WidgetNodeInfo -> Bool) -> Eq WidgetNodeInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WidgetNodeInfo -> WidgetNodeInfo -> Bool
$c/= :: WidgetNodeInfo -> WidgetNodeInfo -> Bool
== :: WidgetNodeInfo -> WidgetNodeInfo -> Bool
$c== :: WidgetNodeInfo -> WidgetNodeInfo -> Bool
Eq, Int -> WidgetNodeInfo -> ShowS
[WidgetNodeInfo] -> ShowS
WidgetNodeInfo -> String
(Int -> WidgetNodeInfo -> ShowS)
-> (WidgetNodeInfo -> String)
-> ([WidgetNodeInfo] -> ShowS)
-> Show WidgetNodeInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WidgetNodeInfo] -> ShowS
$cshowList :: [WidgetNodeInfo] -> ShowS
show :: WidgetNodeInfo -> String
$cshow :: WidgetNodeInfo -> String
showsPrec :: Int -> WidgetNodeInfo -> ShowS
$cshowsPrec :: Int -> WidgetNodeInfo -> ShowS
Show, (forall x. WidgetNodeInfo -> Rep WidgetNodeInfo x)
-> (forall x. Rep WidgetNodeInfo x -> WidgetNodeInfo)
-> Generic WidgetNodeInfo
forall x. Rep WidgetNodeInfo x -> WidgetNodeInfo
forall x. WidgetNodeInfo -> Rep WidgetNodeInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WidgetNodeInfo x -> WidgetNodeInfo
$cfrom :: forall x. WidgetNodeInfo -> Rep WidgetNodeInfo x
Generic)

instance Default WidgetNodeInfo where
  def :: WidgetNodeInfo
def = WidgetNodeInfo :: WidgetType
-> WidgetId
-> Maybe WidgetKey
-> Path
-> SizeReq
-> SizeReq
-> Bool
-> Bool
-> Bool
-> Rect
-> Style
-> WidgetNodeInfo
WidgetNodeInfo {
    _wniWidgetType :: WidgetType
_wniWidgetType = Text -> WidgetType
WidgetType (String -> Text
T.pack String
""),
    _wniWidgetId :: WidgetId
_wniWidgetId = WidgetId
forall a. Default a => a
def,
    _wniKey :: Maybe WidgetKey
_wniKey = Maybe WidgetKey
forall a. Maybe a
Nothing,
    _wniPath :: Path
_wniPath = Path
emptyPath,
    _wniSizeReqW :: SizeReq
_wniSizeReqW = SizeReq
forall a. Default a => a
def,
    _wniSizeReqH :: SizeReq
_wniSizeReqH = SizeReq
forall a. Default a => a
def,
    _wniEnabled :: Bool
_wniEnabled = Bool
True,
    _wniVisible :: Bool
_wniVisible = Bool
True,
    _wniFocusable :: Bool
_wniFocusable = Bool
False,
    _wniViewport :: Rect
_wniViewport = Rect
forall a. Default a => a
def,
    _wniStyle :: Style
_wniStyle = Style
forall a. Default a => a
def
  }

-- | An instance of the widget in the widget tree.
data WidgetNode s e = WidgetNode {
  -- | The actual widget.
  WidgetNode s e -> Widget s e
_wnWidget :: Widget s e,
  -- | Information about the instance.
  WidgetNode s e -> WidgetNodeInfo
_wnInfo :: WidgetNodeInfo,
  -- | The children widgets, if any.
  WidgetNode s e -> Seq (WidgetNode s e)
_wnChildren :: Seq (WidgetNode s e)
}

{-|
An instance of the widget in the widget tree, without specific type information.
This allows querying for widgets that may be nested in Composites, which are not
visible as a regular "WidgetNode" because of possible type mismatches (see
"WidgetKeyMap").
-}
data WidgetInstanceNode = WidgetInstanceNode {
  -- | Information about the instance.
  WidgetInstanceNode -> WidgetNodeInfo
_winInfo :: WidgetNodeInfo,
  -- | The widget state, if any.
  WidgetInstanceNode -> Maybe WidgetState
_winState :: Maybe WidgetState,
  -- | The children widget, if any.
  WidgetInstanceNode -> Seq WidgetInstanceNode
_winChildren :: Seq WidgetInstanceNode
} deriving (Int -> WidgetInstanceNode -> ShowS
[WidgetInstanceNode] -> ShowS
WidgetInstanceNode -> String
(Int -> WidgetInstanceNode -> ShowS)
-> (WidgetInstanceNode -> String)
-> ([WidgetInstanceNode] -> ShowS)
-> Show WidgetInstanceNode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WidgetInstanceNode] -> ShowS
$cshowList :: [WidgetInstanceNode] -> ShowS
show :: WidgetInstanceNode -> String
$cshow :: WidgetInstanceNode -> String
showsPrec :: Int -> WidgetInstanceNode -> ShowS
$cshowsPrec :: Int -> WidgetInstanceNode -> ShowS
Show, (forall x. WidgetInstanceNode -> Rep WidgetInstanceNode x)
-> (forall x. Rep WidgetInstanceNode x -> WidgetInstanceNode)
-> Generic WidgetInstanceNode
forall x. Rep WidgetInstanceNode x -> WidgetInstanceNode
forall x. WidgetInstanceNode -> Rep WidgetInstanceNode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WidgetInstanceNode x -> WidgetInstanceNode
$cfrom :: forall x. WidgetInstanceNode -> Rep WidgetInstanceNode x
Generic)

{-|
Main widget type. This is the type all widgets implement. In general it's not
needed to implement this type directly, and it's easier to use
"Monomer.Widgets.Container" for widgets with children elements and
"Monomer.Widgets.Single" for widgets without children.
-}
data Widget s e =
  Widget {
    {-|
    Initializes the given node. This could include rebuilding the widget in
    case internal state needs to use model/environment information, generate
    user events or make requests to the runtime.

    Arguments:

    - The widget environment.
    - The widget node.

    Returns:

    - The result of the init operation.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> WidgetResult s e
widgetInit
      :: WidgetEnv s e
      -> WidgetNode s e
      -> WidgetResult s e,
    {-|
    Merges the current node with the node it matched with during the merge
    process. Receives the newly created node (whose *init* function is not
    called), the previous node and the state extracted from that node. This
    process is widget dependent, and may use or ignore the previous state
    depending on newly available information.

    In general, you want to at least keep the previous state unless the widget
    is stateless or only consumes model/environment information.

    Arguments:

    - The widget environment.
    - The widget node.
    - The previous widget node.

    Returns:

    - The result of the merge operation.
    -}
    Widget s e
-> WidgetEnv s e
-> WidgetNode s e
-> WidgetNode s e
-> WidgetResult s e
widgetMerge
      :: WidgetEnv s e
      -> WidgetNode s e
      -> WidgetNode s e
      -> WidgetResult s e,
    {-|
    Disposes the current node. Only used by widgets which allocate resources
    during /init/ or /merge/, and will usually involve requests to the runtime.

    Arguments:

    - The widget environment.
    - The widget node.

    Returns:

    - The result of the dispose operation.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> WidgetResult s e
widgetDispose
      :: WidgetEnv s e
      -> WidgetNode s e
      -> WidgetResult s e,
    {-|
    Returns the current internal state, which can later be used when during the
    merge process.

    Arguments:

    - The widget environment.
    - The widget node.

    Returns:

    - The internal state, if any.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> Maybe WidgetState
widgetGetState
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Maybe WidgetState,
    {-|
    Returns information about the instance and its children.

    Arguments:

    - The widget environment.
    - The widget node.

    Returns:

    - The untyped node information.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> WidgetInstanceNode
widgetGetInstanceTree
      :: WidgetEnv s e
      -> WidgetNode s e
      -> WidgetInstanceNode,
    {-|
    Returns the next focusable node. What next/previous is, depends on how the
    widget works. Moving left to right, top to bottom is usually considered
    forward.

    Arguments:

    - The widget environment.
    - The widget node.
    - The direction in which focus is moving.
    - The path to start the search from.

    Returns:

    - The next focusable node info.
    -}
    Widget s e
-> WidgetEnv s e
-> WidgetNode s e
-> FocusDirection
-> Path
-> Maybe WidgetNodeInfo
widgetFindNextFocus
      :: WidgetEnv s e
      -> WidgetNode s e
      -> FocusDirection
      -> Path
      -> Maybe WidgetNodeInfo,
    {-|
    Returns the currently hovered widget, if any.

    Arguments:

    - The widget environment.
    - The widget node.
    - The path to start the search from.
    - The point to test for.

    Returns:

    - The hovered child index, if any.
    -}
    Widget s e
-> WidgetEnv s e
-> WidgetNode s e
-> Path
-> Point
-> Maybe WidgetNodeInfo
widgetFindByPoint
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Path
      -> Point
      -> Maybe WidgetNodeInfo,
    {-|
    Returns the widget matching the given path, plus all its parents.

    Arguments:

    - The widget environment.
    - The widget node.
    - The path to search for.

    Returns:

    - The sequence of widgets up to path, ordered from root to target.
    -}
    Widget s e
-> WidgetEnv s e -> WidgetNode s e -> Path -> Seq WidgetNodeInfo
widgetFindBranchByPath
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Path
      -> Seq WidgetNodeInfo,
    {-|
    Receives a System event and, optionally, returns a result. This can include
    an updated version of the widget (in case it has internal state), user
    events or requests to the runtime.

    Arguments:

    - The widget environment.
    - The widget node.
    - The target path of the event.
    - The SystemEvent to handle.

    Returns:

    - The result of handling the event, if any.
    -}
    Widget s e
-> WidgetEnv s e
-> WidgetNode s e
-> Path
-> SystemEvent
-> Maybe (WidgetResult s e)
widgetHandleEvent
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Path
      -> SystemEvent
      -> Maybe (WidgetResult s e),
    {-|
    Receives a message and, optionally, returns a result. This can include an
    updated version of the widget (in case it has internal state), user events
    or requests to the runtime. There is no validation regarding the message
    type, and the widget should take care of _casting_ to the correct type using
    "Data.Typeable.cast"

    Arguments:

    - The widget environment.
    - The widget node.
    - The target path of the message.
    - The message to handle.

    Returns:

    - The result of handling the message, if any.
    -}
    Widget s e
-> forall i.
   Typeable i =>
   WidgetEnv s e
   -> WidgetNode s e -> Path -> i -> Maybe (WidgetResult s e)
widgetHandleMessage
      :: forall i . Typeable i
      => WidgetEnv s e
      -> WidgetNode s e
      -> Path
      -> i
      -> Maybe (WidgetResult s e),
    {-|
    Returns the preferred size for the widget.

    Arguments:

    - The widget environment.
    - The widget node.

    Returns:

    - The horizontal and vertical requirements.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> (SizeReq, SizeReq)
widgetGetSizeReq
      :: WidgetEnv s e
      -> WidgetNode s e
      -> (SizeReq, SizeReq),
    {-|
    Resizes the widget to the provided size.

    Arguments:

    - The widget environment.
    - The widget node.
    - The new viewport.
    - Helper to checks if a given path, or its children, requested resize.

    Returns:

    - The result of resizing the widget.
    -}
    Widget s e
-> WidgetEnv s e
-> WidgetNode s e
-> Rect
-> (Path -> Bool)
-> WidgetResult s e
widgetResize
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Rect
      -> (Path -> Bool)
      -> WidgetResult s e,
    {-|
    Renders the widget's content using the given Renderer.

    Arguments:

    - The widget environment.
    - The widget node.
    - The renderer, providing low level drawing functions.

    Returns:

    - The IO action with rendering instructions.
    -}
    Widget s e -> WidgetEnv s e -> WidgetNode s e -> Renderer -> IO ()
widgetRender
      :: WidgetEnv s e
      -> WidgetNode s e
      -> Renderer
      -> IO ()
  }

instance Show (WidgetRequest s e) where
  show :: WidgetRequest s e -> String
show WidgetRequest s e
IgnoreParentEvents = String
"IgnoreParentEvents"
  show WidgetRequest s e
IgnoreChildrenEvents = String
"IgnoreChildrenEvents"
  show (ResizeWidgets WidgetId
wid) = String
"ResizeWidgets: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (ResizeWidgetsImmediate WidgetId
wid) = String
"ResizeWidgetsImmediate: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (MoveFocus Maybe WidgetId
start FocusDirection
dir) = String
"MoveFocus: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Maybe WidgetId, FocusDirection) -> String
forall a. Show a => a -> String
show (Maybe WidgetId
start, FocusDirection
dir)
  show (SetFocus WidgetId
path) = String
"SetFocus: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
path
  show (GetClipboard WidgetId
wid) = String
"GetClipboard: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (SetClipboard ClipboardData
_) = String
"SetClipboard"
  show (StartTextInput Rect
rect) = String
"StartTextInput: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Rect -> String
forall a. Show a => a -> String
show Rect
rect
  show WidgetRequest s e
StopTextInput = String
"StopTextInput"
  show (SetOverlay WidgetId
wid Path
path) = String
"SetOverlay: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (WidgetId, Path) -> String
forall a. Show a => a -> String
show (WidgetId
wid, Path
path)
  show (ResetOverlay WidgetId
wid) = String
"ResetOverlay: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (SetCursorIcon WidgetId
wid CursorIcon
icon) = String
"SetCursorIcon: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (WidgetId, CursorIcon) -> String
forall a. Show a => a -> String
show (WidgetId
wid, CursorIcon
icon)
  show (ResetCursorIcon WidgetId
wid) = String
"ResetCursorIcon: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (StartDrag WidgetId
wid Path
path WidgetDragMsg
info) = String
"StartDrag: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (WidgetId, Path, WidgetDragMsg) -> String
forall a. Show a => a -> String
show (WidgetId
wid, Path
path, WidgetDragMsg
info)
  show (StopDrag WidgetId
wid) = String
"StopDrag: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show WidgetRequest s e
RenderOnce = String
"RenderOnce"
  show (RenderEvery WidgetId
wid Int
ms Maybe Int
repeat) = String
"RenderEvery: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (WidgetId, Int, Maybe Int) -> String
forall a. Show a => a -> String
show (WidgetId
wid, Int
ms, Maybe Int
repeat)
  show (RenderStop WidgetId
wid) = String
"RenderStop: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show (RemoveRendererImage Text
name) = String
"RemoveRendererImage: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
name
  show ExitApplication{} = String
"ExitApplication"
  show (UpdateWindow WindowRequest
req) = String
"UpdateWindow: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WindowRequest -> String
forall a. Show a => a -> String
show WindowRequest
req
  show UpdateModel{} = String
"UpdateModel"
  show (SetWidgetPath WidgetId
wid Path
path) = String
"SetWidgetPath: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (WidgetId, Path) -> String
forall a. Show a => a -> String
show (WidgetId
wid, Path
path)
  show (ResetWidgetPath WidgetId
wid) = String
"ResetWidgetPath: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetId -> String
forall a. Show a => a -> String
show WidgetId
wid
  show RaiseEvent{} = String
"RaiseEvent"
  show SendMessage{} = String
"SendMessage"
  show RunTask{} = String
"RunTask"
  show RunProducer{} = String
"RunProducer"

instance Show (WidgetResult s e) where
  show :: WidgetResult s e -> String
show WidgetResult s e
result = String
"WidgetResult "
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"{ _wrRequests: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Seq (WidgetRequest s e) -> String
forall a. Show a => a -> String
show (WidgetResult s e -> Seq (WidgetRequest s e)
forall s e. WidgetResult s e -> Seq (WidgetRequest s e)
_wrRequests WidgetResult s e
result)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", _wrNode: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetNode s e -> String
forall a. Show a => a -> String
show (WidgetResult s e -> WidgetNode s e
forall s e. WidgetResult s e -> WidgetNode s e
_wrNode WidgetResult s e
result)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" }"

instance Show (WidgetEnv s e) where
  show :: WidgetEnv s e -> String
show WidgetEnv s e
wenv = String
"WidgetEnv "
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"{ _weOs: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show (WidgetEnv s e -> Text
forall s e. WidgetEnv s e -> Text
_weOs WidgetEnv s e
wenv)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", _weWindowSize: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Size -> String
forall a. Show a => a -> String
show (WidgetEnv s e -> Size
forall s e. WidgetEnv s e -> Size
_weWindowSize WidgetEnv s e
wenv)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", _weFocusedPath: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path -> String
forall a. Show a => a -> String
show (WidgetEnv s e -> Path
forall s e. WidgetEnv s e -> Path
_weFocusedPath WidgetEnv s e
wenv)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", _weTimestamp: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (WidgetEnv s e -> Int
forall s e. WidgetEnv s e -> Int
_weTimestamp WidgetEnv s e
wenv)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" }"

instance Show (WidgetNode s e) where
  show :: WidgetNode s e -> String
show WidgetNode s e
node = String
"WidgetNode "
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"{ _wnInfo: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ WidgetNodeInfo -> String
forall a. Show a => a -> String
show (WidgetNode s e -> WidgetNodeInfo
forall s e. WidgetNode s e -> WidgetNodeInfo
_wnInfo WidgetNode s e
node)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", _wnChildren: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Seq (WidgetNode s e) -> String
forall a. Show a => a -> String
show (WidgetNode s e -> Seq (WidgetNode s e)
forall s e. WidgetNode s e -> Seq (WidgetNode s e)
_wnChildren WidgetNode s e
node)
    String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" }"