packages feed

tinytools-vty-0.1.0.0: src/Potato/Reflex/Vty/Widget/Menu.hs

-- TODO FINISH INCOMPLETE
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE RecursiveDo     #-}

module Potato.Reflex.Vty.Widget.Menu (
  holdMenuWidget
) where

import           Relude

import           Potato.Reflex.Vty.Helpers
import           Potato.Reflex.Vty.Widget

import qualified Graphics.Vty.Input.Events as V
import           Reflex
import           Reflex.Network
import           Reflex.Potato.Helpers
import           Reflex.Vty


import           Data.Default
import qualified Data.Map as Map
import qualified Data.Text as T
import Data.Tree

type Shortcut = ()

data MenuTreeNode k = MenuTreeNode {
  _menuTreeNode_key :: k -- MUST BE UNIQUE
  , _menuTreeNode_label :: Text
  , _menuTreeNode_shortcut :: Maybe Shortcut
} deriving (Eq, Show)

data MenuWidgetConfig t k = MenuWidgetConfig {
  _menuWidgetConfig_menus :: Dynamic t ([Tree (MenuTreeNode k)])
}

data MenuWidget t k = MenuWidget {
  _menuWidget_activated :: Event t k
  , _menuWidget_capturedInput :: Event t ()
}

indexedMerge :: (Reflex t) => [Event t a] -> Event t (Int,a)
indexedMerge evs = leftmost . fmap (\(i,ev)-> fmap (i,) ev) . zip [0..] $ evs

type Pos = (Int,Int)

type MenuFocus k = [(k, Int, Pos)]

holdMenuWidget = undefined

{-
holdMenuWidget ::
  forall t m k. (MonadWidget t m)
  => MenuWidgetConfig t k
  -> m (MenuWidget t k)
holdMenuWidget MenuWidgetConfig {..} = mdo
  let
    makeMenuWidget :: [Tree (MenuTreeNode k)] -> m ()
    makeMenuWidget roots = do
      -- TODO
      -- if line down to currently opened menu still exists, keep focus (I guess to do this really right, you should track index as well so there's no menu jump glitcehs)

      -- setup shortcut map
      let
        shortcutfmapfn MenuTreeNode {..} = case _menuTreeNode_shortcut of
          Nothing -> Nothing
          Just x -> Just (x, _menuTreeNode_key)
        rootMaybeShortcuts = fmap (fmap shortcutfmapfn) roots
        shortcuts = catMaybes . join . fmap flatten $ rootMaybeShortcuts
        shortcutMap :: Behavior t (Map.Map Shortcut k) = constant $ Map.fromList $ shortcuts

      -- render the first layer at top row
      topLayerOut <- beginLayout $ row $
        forM roots $ \(Node MenuTreeNode {..} _) -> do
          let l = T.length _menuTreeNode_label
          (tile . fixed) (constDyn $ l + 1) $ do
            -- TODO highlight if selected in focusDyn
            text (constant _menuTreeNode_label)
            click <- mouseDown V.BLeft
            return (l+1, click $> _menuTreeNode_key)
      let
        topOffsets = scanl (+) 0 $ fmap fst topLayerOut
        -- (index, xoffset)
        topEv :: Event t (Int, Int) = indexedMerge $ zipWith (\offx ev -> fmap (,offx) ev) topOffsets $ fmap snd topLayerOut

        rootSetFocusEv = ffor topEv $ \(idx,(k,xoff)) -> [(k,idx,(xoff,1))]

        childWidgetFn [] = return never
        childWidgetFn ((k,idx,(xoff,yoff)):xs) = do
          forM
          selfClickEv
          childClickEv <- childWidgetFn xs
          return $ leftmost [selfClickEv, childClickEv]

      -- TODO list to changes in focus Dyn and render each following layer
      childMenusDyn = ffor (fmap tail focusDyn) $ childWidgetFn


      focusDyn :: Dynamic t (MenuFocus k) <- undefined
      return ()


  return MenuWidget {
      _menuWidget_activated = never
      , _menuWidget_capturedInput = never
    }
-}