Skip to content

Commit

Permalink
navigable table
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Sep 9, 2024
1 parent 4721f90 commit 76277e2
Show file tree
Hide file tree
Showing 28 changed files with 626 additions and 307 deletions.
2 changes: 2 additions & 0 deletions .hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- {name: Data.List.head, within: []}
- {name: Prelude.head, within: [Swarm.Web.Tournament.Database.Query]}
- {name: Prelude.tail, within: []}
- {name: Prelude.maximum, within: [Swarm.Util]}
- {name: Prelude.minimum, within: []}
- {name: Prelude.!!, within: [Swarm.Util.indexWrapNonEmpty, TestEval]}
- {name: undefined, within: [Swarm.Language.Key, TestUtil]}
- {name: fromJust, within: []}
Expand Down
1 change: 1 addition & 0 deletions app/game/Swarm/App.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import Swarm.Language.Pretty (prettyText)
import Swarm.Log (LogSource (SystemLog), Severity (..))
import Swarm.TUI.Controller
import Swarm.TUI.Model
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.StateUpdate
import Swarm.TUI.Model.UI (uiAttrMap)
import Swarm.TUI.View
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-doc/Swarm/Doc/Wiki/Cheatsheet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ listToRow mw xs = wrap '|' . T.intercalate "|" $ zipWith format mw xs
format w x = wrap ' ' x <> T.replicate (w - T.length x) " "

maxWidths :: [[Text]] -> [Int]
maxWidths = map (maximum . map T.length) . transpose
maxWidths = map (maximum0 . map T.length) . transpose

Check failure on line 102 in src/swarm-doc/Swarm/Doc/Wiki/Cheatsheet.hs

View workflow job for this annotation

GitHub Actions / Haskell-CI - windows-latest - ghc-9.8.2

Variable not in scope: maximum0 :: [Int] -> Int

-- ** COMMANDS

Expand Down
13 changes: 13 additions & 0 deletions src/swarm-topography/Swarm/Game/Universe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Control.Lens (makeLenses, view)
import Data.Function (on)
import Data.Int (Int32)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Yaml (FromJSON, ToJSON, Value (Object), parseJSON, withText, (.:))
import GHC.Generics (Generic)
import Linear (V2 (..))
Expand Down Expand Up @@ -82,3 +83,15 @@ defaultCosmicLocation = Cosmic DefaultRootSubworld origin

offsetBy :: Cosmic Location -> V2 Int32 -> Cosmic Location
offsetBy loc v = fmap (.+^ v) loc

locationToString :: Location -> String
locationToString (Location x y) =
unwords $ map show [x, y]

renderCoordsString :: Cosmic Location -> String
renderCoordsString (Cosmic sw coords) =
unwords $ locationToString coords : suffix
where
suffix = case sw of
DefaultRootSubworld -> []
SubworldName swName -> ["in", T.unpack swName]
7 changes: 7 additions & 0 deletions src/swarm-tui/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Brick.Widgets.Dialog
import Brick.Widgets.Edit (Editor, applyEdit, handleEditorEvent)
import Brick.Widgets.List (handleListEvent)
import Brick.Widgets.List qualified as BL
import Brick.Widgets.TabularList.Mixed
import Control.Applicative (pure)
import Control.Category ((>>>))
import Control.Lens as Lens
Expand Down Expand Up @@ -101,6 +102,7 @@ import Swarm.TUI.Model.Name
import Swarm.TUI.Model.Repl
import Swarm.TUI.Model.StateUpdate
import Swarm.TUI.Model.UI
import Swarm.TUI.View.RobotDisplay
import Swarm.Util hiding (both, (<<.=))

-- ~~~~ Note [liftA2 re-export from Prelude]
Expand Down Expand Up @@ -418,6 +420,11 @@ handleModalEvent = \case
refreshList $ uiState . uiGameplay . uiDialogs . uiStructure . structurePanelListWidget
StructureSummary -> handleInfoPanelEvent modalScroll (VtyEvent ev)
_ -> handleInfoPanelEvent modalScroll (VtyEvent ev)
Just RobotsModal -> case ev of
V.EvKey (V.KChar '\t') [] -> uiState . uiGameplay . uiDialogs . uiRobot . robotsDisplayMode %= cycleEnum
_ ->
Brick.zoom (uiState . uiGameplay . uiDialogs . uiRobot . robotListContent . libList) $
handleMixedListEvent ev
_ -> handleInfoPanelEvent modalScroll (VtyEvent ev)
where
refreshGoalList lw = nestEventM' lw $ handleListEventWithSeparators ev shouldSkipSelection
Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import Swarm.TUI.Controller.EventHandlers.Robot (handleRobotPanelEvent, robotEve
import Swarm.TUI.Controller.EventHandlers.World (worldEventHandlers)
import Swarm.TUI.Model
import Swarm.TUI.Model.Event (SwarmEvent, swarmEvents)
import Swarm.TUI.Model.Name
import Swarm.Util (parens, squote)

-- ~~~~ Note [how Swarm event handlers work]
Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers/Frame.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Swarm.TUI.Controller.UpdateUI
import Swarm.TUI.Controller.Util
import Swarm.TUI.Model
import Swarm.TUI.Model.Achievements (popupAchievement)
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.UI
import System.Clock

Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Swarm.TUI.Model
import Swarm.TUI.Model.DebugOption (DebugOption (ToggleCreative, ToggleWorldEditor))
import Swarm.TUI.Model.Dialog.Goal
import Swarm.TUI.Model.Event (MainEvent (..), SwarmEvent (..))
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.UI
import System.Clock (Clock (..), TimeSpec (..), getTime)

Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers/REPL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Swarm.Game.State.Substate
import Swarm.TUI.Controller.Util
import Swarm.TUI.Model
import Swarm.TUI.Model.Event
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.Repl
import Swarm.TUI.Model.UI

Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers/Robot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import Swarm.TUI.Inventory.Sorting (cycleSortDirection, cycleSortOrder)
import Swarm.TUI.List
import Swarm.TUI.Model
import Swarm.TUI.Model.Event
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.UI
import Swarm.TUI.View.Util (generateModal)

Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Controller/EventHandlers/World.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Swarm.Language.Syntax.Direction (Direction (..), directionSyntax)
import Swarm.TUI.Controller.Util
import Swarm.TUI.Model
import Swarm.TUI.Model.Event
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.UI

-- | Handle a user input event in the world view panel.
Expand Down
28 changes: 28 additions & 0 deletions src/swarm-tui/Swarm/TUI/Controller/UpdateUI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import Brick hiding (Direction, Location)
import Brick.Focus

-- See Note [liftA2 re-export from Prelude]

import Brick.Widgets.List qualified as BL
import Brick.Widgets.TabularList.Mixed (MixedTabularList (..))
import Control.Applicative (liftA2, pure)
import Control.Lens as Lens
import Control.Monad (unless, when)
Expand Down Expand Up @@ -43,6 +45,8 @@ import Swarm.TUI.Model.Name
import Swarm.TUI.Model.Repl
import Swarm.TUI.Model.UI
import Swarm.TUI.View.Objective qualified as GR
import Swarm.TUI.View.Robot
import Swarm.TUI.View.RobotDisplay (libList, robID, robotListContent)
import Witch (into)
import Prelude hiding (Applicative (..))

Expand Down Expand Up @@ -165,6 +169,8 @@ updateUI = do

newPopups <- generateNotificationPopups

doRobotListUpdate g

let redraw =
g ^. needsRedraw
|| inventoryUpdated
Expand All @@ -174,6 +180,28 @@ updateUI = do
|| newPopups
pure redraw

doRobotListUpdate :: GameState -> EventM Name AppState ()
doRobotListUpdate g = do
gp <- use $ uiState . uiGameplay
dOps <- use $ uiState . uiDebugOptions

let rd =
mkRobotDisplay
( RobotRenderingContext
{ _mygs = g
, _gameplay = gp
, _timing = gp ^. uiTiming
, _uiDbg = dOps
}
)

let MixedTabularList oldList _ _ = gp ^. uiDialogs . uiRobot . robotListContent . libList
maybeOldSelectedRID = robID . snd <$> BL.listSelectedElement oldList
rd' = case maybeOldSelectedRID of
Nothing -> rd
Just oldSelectedRID -> rd & libList %~ (\(MixedTabularList ls a b) -> MixedTabularList (BL.listFindBy ((== oldSelectedRID) . robID) ls) a b)
uiState . uiGameplay . uiDialogs . uiRobot . robotListContent .= rd'

-- | Either pops up the updated Goals modal
-- or pops up the Congratulations (Win) modal, or pops
-- up the Condolences (Lose) modal.
Expand Down
3 changes: 1 addition & 2 deletions src/swarm-tui/Swarm/TUI/Controller/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ import Swarm.Language.Capability (Capability (CDebug))
import Swarm.Language.Syntax hiding (Key)
import Swarm.TUI.Model (
AppState,
FocusablePanel,
ModalType (..),
Name (..),
gameState,
modalScroll,
uiState,
)
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.Repl (REPLHistItem, REPLPrompt, REPLState, addREPLItem, replHistory, replPromptText, replPromptType)
import Swarm.TUI.Model.UI
import Swarm.TUI.View.Util (generateModal)
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-tui/Swarm/TUI/Editor/Masking.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Swarm.Game.Universe
import Swarm.Game.World.Coords
import Swarm.TUI.Editor.Model
import Swarm.TUI.Editor.Util qualified as EU
import Swarm.TUI.Model.UI
import Swarm.TUI.Model.UI.Gameplay

shouldHideWorldCell :: UIGameplay -> Coords -> Bool
shouldHideWorldCell ui coords =
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-tui/Swarm/TUI/Editor/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ drawWorldEditor toplevelFocusRing uis =
L.intersperse
"@"
[ EA.renderRectDimensions rectArea
, VU.locationToString upperLeftLoc
, locationToString upperLeftLoc
]
where
upperLeftLoc = coordsToLoc upperLeftCoord
Expand Down
1 change: 0 additions & 1 deletion src/swarm-tui/Swarm/TUI/Model.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module Swarm.TUI.Model (
-- $uilabel
AppEvent (..),
FocusablePanel (..),
Name (..),

-- ** Web command
WebCommand (..),
Expand Down
1 change: 1 addition & 0 deletions src/swarm-tui/Swarm/TUI/Model/KeyBindings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Swarm.Language.Pretty (prettyText)
import Swarm.TUI.Controller.EventHandlers
import Swarm.TUI.Model
import Swarm.TUI.Model.Event (SwarmEvent, defaultSwarmBindings, swarmEvents)
import Swarm.TUI.Model.Name

-- See Note [how Swarm event handlers work]

Expand Down
2 changes: 2 additions & 0 deletions src/swarm-tui/Swarm/TUI/Model/Name.hs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ data Name
StructureWidgets StructureWidget
| -- | The list of scenario choices.
ScenarioList
| -- | The robots list
RobotsList
| -- | The scrollable viewport for the info panel.
InfoViewport
| -- | The scrollable viewport for any modal dialog.
Expand Down
Loading

0 comments on commit 76277e2

Please sign in to comment.