You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pressing "tab" will switch focus from someWidget<n> to someWidget<n+1 mod 6> and switch focus between row1 and row2 as necessary
However, instead we have:
pressing "tab" will focus row2 and someWidget2
in addition, pressing tab again will focus row1 and someWidget2
Challenges
Broadly speaking, Layout alternates between Layout and VtyWidget and we need to pass data across this boundary in order for tabbing to work as desired.
Using the existing Layout module as a starting point, there are 2 major challenges to support the desired behavior outlined above:
runLayout needs to be aware of nested layout nodes in order to focus the correct tile
tile needs to be aware of when a particular nested node index should be focus
Solution
is addressed by introducing the new class below. NOTE, LayoutTree is discussed later.
class IsLayoutReturn t b a where
getLayoutResult :: b -> a
getLayoutNumChildren :: b -> Int
getLayoutFocussedDyn :: b -> Dynamic t (Maybe Int)
getLayoutTree :: b -> LayoutTree t
instance IsLayoutReturn t (LayouTree t, Dynamic t (Maybe Int), Int, a) a where
getLayoutResult (_,_,_,a) = a
getLayoutNumChildren (_,_,d,_) = d
getLayoutFocussedDyn (_,d,_,_) = d
getLayoutTree (tree,_,_,_) = tree
instance Reflex t => IsLayoutReturn t a a where
getLayoutResult = id
getLayoutNumChildren _ = 1
getLayoutFocussedDyn _ = constDyn Nothing
getLayoutTree _ = emptyLayoutTree
is address by wrapping the VtyWidget monad with additional contextual information
class IsLayoutVtyWidget l t (m :: * -> *) where
runIsLayoutVtyWidget :: l t m a -> Event t (Maybe Int) -> VtyWidget t m a
newtype LayoutVtyWidget t m a = LayoutVtyWidget {
unLayoutVtyWidget :: ReaderT (Event t (Maybe Int)) (VtyWidget t m) a
} deriving (...)
instance MonadTrans (LayoutVtyWidget t) where
lift x = LayoutVtyWidget $ lift $ lift x
instance IsLayoutVtyWidget VtyWidget t m where
runIsLayoutVtyWidget w _ = w
instance IsLayoutVtyWidget LayoutVtyWidget t m where
runIsLayoutVtyWidget = runReaderT . unLayoutVtyWidget
Note that since we have instance LayoutReturn t a a in 1. and instance IsLayoutVtyWidget VtyWidget t m in 2. they work with both layout and non-layout nodes.
Interface Changes
Since focus events now come from the top level layout node, a new method is needed:
Unfortunately, the interface is not seamless in the case of 1. as the desired monadic return value type is ambiguous as we have both
IsLayoutReturn t (LayoutTree t, Dynamic t (Maybe Int), Int, a) a IsLayoutReturn t (LayoutTree t, Dynamic t (Maybe Int), Int, a) (LayoutTree t, Dynamic t (Maybe Int), Int, a)
So we introduce new variants fixedD and stretchD that make the type deductions above explicit.
Testing
LayoutTree is an optional returned object of type Dynamic t (Tree Region) objects of all the children. The intent is to use for automated testing (e.g. get me the absolute coordinates of (5,7) in relative coordinates of the third node of the second node of some LayoutTree). You can see an example of this here. I imagine it might be useful in non-testing scenarios as well.
Code
I've opened up the following draft PR that implements most of the above for discussion.
The text was updated successfully, but these errors were encountered:
TLDR; see draft PR
Problem Outline
Tab navigation in the current Layout system does not work when Layouts are nested
For example:
assume
row1
+someWidget1
are in focusThe desired behavior is:
row1
andsomeWidget2
someWidget<n>
tosomeWidget<n+1 mod 6>
and switch focus betweenrow1
androw2
as necessaryHowever, instead we have:
row2
andsomeWidget2
tab
again will focusrow1
andsomeWidget2
Challenges
Broadly speaking, Layout alternates between Layout and VtyWidget and we need to pass data across this boundary in order for tabbing to work as desired.
Using the existing
Layout
module as a starting point, there are 2 major challenges to support the desired behavior outlined above:runLayout
needs to be aware of nested layout nodes in order to focus the correct tiletile
needs to be aware of when a particular nested node index should be focusSolution
LayoutTree
is discussed later.Note that since we have
instance LayoutReturn t a a
in 1. andinstance IsLayoutVtyWidget VtyWidget t m
in 2. they work with both layout and non-layout nodes.Interface Changes
Since focus events now come from the top level layout node, a new method is needed:
Unfortunately, the interface is not seamless in the case of 1. as the desired monadic return value type is ambiguous as we have both
IsLayoutReturn t (LayoutTree t, Dynamic t (Maybe Int), Int, a) a
IsLayoutReturn t (LayoutTree t, Dynamic t (Maybe Int), Int, a) (LayoutTree t, Dynamic t (Maybe Int), Int, a)
So we introduce new variants
fixedD
andstretchD
that make the type deductions above explicit.Testing
LayoutTree
is an optional returned object of typeDynamic t (Tree Region)
objects of all the children. The intent is to use for automated testing (e.g. get me the absolute coordinates of (5,7) in relative coordinates of the third node of the second node of someLayoutTree
). You can see an example of this here. I imagine it might be useful in non-testing scenarios as well.Code
I've opened up the following draft PR that implements most of the above for discussion.
The text was updated successfully, but these errors were encountered: