| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Termtab.UI.Types
Description
The editor's state (AppState) and the pure functions that transform
it: cursor navigation (move*/goTo*), zoom, and display-mode
cycling. Kept separate from Termtab.UI.Editing (which mutates the
Song itself) and from Termtab.UI.Keybindings (which decides which
of these functions a keypress calls) — this module only knows how to
move the cursor and answer questions about where it is, not how to edit
notes.
Synopsis
- data AppState = AppState {
- asSong :: Song
- asFilePath :: Maybe FilePath
- asCurrentMeasure :: MeasureIndex
- asCurrentBeat :: BeatIndex
- asCurrentTrack :: TrackIndex
- asCurrentString :: StringIndex
- asInputMode :: InputMode
- asDisplayModes :: Map TrackIndex DisplayMode
- asZoom :: Int
- asMessage :: Maybe String
- asPlaybackStatus :: PlaybackStatus
- asPlayheadMeasure :: Maybe MeasureIndex
- asPlayheadBeat :: Maybe BeatIndex
- asPlaybackEnv :: Maybe PlaybackEnv
- asBChan :: BChan AppEvent
- asUndoStack :: [Song]
- asRedoStack :: [Song]
- asFretEntry :: Maybe FretNumber
- asSelectionStart :: Maybe (MeasureIndex, BeatIndex)
- asProtocol :: GraphicsProtocol
- asGlyphFont :: Maybe GlyphFont
- asInkColor :: PixelRGBA8
- asNotationSigs :: Map TrackIndex String
- data DisplayMode
- data InputMode
- data ResourceName
- data AppEvent
- initAppState :: Maybe FilePath -> Song -> BChan AppEvent -> AppState
- moveBeatRight :: AppState -> AppState
- moveBeatLeft :: AppState -> AppState
- moveMeasureForward :: AppState -> AppState
- moveMeasureBack :: AppState -> AppState
- moveStringUp :: AppState -> AppState
- moveStringDown :: AppState -> AppState
- goToStart :: AppState -> AppState
- goToEnd :: AppState -> AppState
- goToMeasureStart :: AppState -> AppState
- goToMeasureEnd :: AppState -> AppState
- goToFirstString :: AppState -> AppState
- goToLastString :: AppState -> AppState
- cycleDisplayMode :: AppState -> AppState
- zoomIn :: AppState -> AppState
- zoomOut :: AppState -> AppState
- currentTrack :: AppState -> Maybe Track
- currentMeasure :: AppState -> Maybe Measure
- currentMeasureBeatCount :: AppState -> Int
- atLastBeat :: AppState -> Bool
- atLastMeasure :: AppState -> Bool
- atFirstBeat :: AppState -> Bool
- atFirstMeasure :: AppState -> Bool
- isMeasureEmpty :: MeasureIndex -> AppState -> Bool
- isTrailingEmpty :: MeasureIndex -> AppState -> Bool
- beatsForTrackMeasure :: Track -> MeasureIndex -> [Beat]
- stringCountForTrack :: Track -> Int
- measureCount :: AppState -> Int
Documentation
The entire mutable state of the running editor: the document itself
(asSong) plus cursor position, input mode, undo/redo history,
playback status, and resolved graphics capabilities. This is the sole
state threaded through Brick's event loop — every keybinding and
rendering function takes and/or produces one of these.
Constructors
data DisplayMode Source #
What a single track's viewport renders: ASCII tab, the rasterized
Bravura staff notation, or both stacked. Stored per-track in
asDisplayModes since a mixed Standard + Guitar song may want
different modes per track (see initAppState's defaultModeFor).
Constructors
| TabOnly | |
| NotationOnly | |
| TabAndNotation |
Instances
| Show DisplayMode Source # | |
Defined in Termtab.UI.Types Methods showsPrec :: Int -> DisplayMode -> ShowS # show :: DisplayMode -> String # showList :: [DisplayMode] -> ShowS # | |
| Eq DisplayMode Source # | |
Defined in Termtab.UI.Types | |
Which set of keybindings Termtab.UI.Keybindings is currently
interpreting input as. CommandMode carries the command line typed so
far; MenuMode carries the path of menu keys pressed so far ([] is
the root menu, ["s"] is the subdivide submenu, etc), since menus
nest.
Constructors
| NormalMode | |
| CommandMode String | |
| GoToMode | |
| VisualMode | |
| MenuMode [String] |
data ResourceName Source #
Brick widget-name identifiers, used to address specific viewports/
regions for scrolling and extent lookups (e.g. lookupExtent).
Constructors
| TrackViewport TrackIndex | |
| StatusBarResource | |
| CommandLineResource | |
| NotationRegion TrackIndex |
Instances
| Show ResourceName Source # | |
Defined in Termtab.UI.Types Methods showsPrec :: Int -> ResourceName -> ShowS # show :: ResourceName -> String # showList :: [ResourceName] -> ShowS # | |
| Eq ResourceName Source # | |
Defined in Termtab.UI.Types | |
| Ord ResourceName Source # | |
Defined in Termtab.UI.Types Methods compare :: ResourceName -> ResourceName -> Ordering # (<) :: ResourceName -> ResourceName -> Bool # (<=) :: ResourceName -> ResourceName -> Bool # (>) :: ResourceName -> ResourceName -> Bool # (>=) :: ResourceName -> ResourceName -> Bool # max :: ResourceName -> ResourceName -> ResourceName # min :: ResourceName -> ResourceName -> ResourceName # | |
Custom Brick events delivered through asBChan. PlaybackTick drives
UI redraws while a song plays; GraphicsRefresh is posted once at
startup to (re-)blit notation images after the terminal has reported
real widget extents (which aren't known on the very first frame).
Constructors
| PlaybackTick | |
| GraphicsRefresh |
Instances
initAppState :: Maybe FilePath -> Song -> BChan AppEvent -> AppState Source #
Build the starting AppState for song (loaded from mPath, or
Nothing for a brand-new document), with the cursor at measure 0 beat 0,
no undo history, and a per-track default DisplayMode (fretted
instruments start as TabAndNotation, Standard tracks as
NotationOnly since they have no tab to show). Graphics fields
(asProtocol, asGlyphFont, etc) start at their no-graphics defaults —
the caller resolves and fills those in separately once terminal
capabilities are detected.
moveBeatRight :: AppState -> AppState Source #
Move the cursor one beat right, wrapping to beat 0 of the next measure if already at the last beat (unless already in the last measure, in which case the cursor doesn't move here — auto-creating a new measure at the end is handled by the caller in Termtab.UI.Keybindings, not by this pure navigation function).
moveBeatLeft :: AppState -> AppState Source #
Move the cursor one beat left, wrapping to the last beat of the
previous measure if already at beat 0 (computed by temporarily moving
the cursor there and re-running currentMeasureBeatCount, since that
count depends on which measure/track is current).
moveMeasureForward :: AppState -> AppState Source #
Jump the cursor to beat 0 of the next measure, clamped at the last measure (does not wrap or auto-create).
moveMeasureBack :: AppState -> AppState Source #
Jump the cursor to beat 0 of the previous measure, clamped at measure 0.
moveStringUp :: AppState -> AppState Source #
Move the cursor's string index up (toward index 0), clamped there.
moveStringDown :: AppState -> AppState Source #
Move the cursor's string index down, clamped to the current track's
last string (0 for a Standard track, since it has no strings).
goToEnd :: AppState -> AppState Source #
Jump the cursor to the last beat of the last measure, per that
measure's own time signature (not currentMeasureBeatCount, which
would also account for empty padding slots — this uses the raw
numerator instead).
goToMeasureStart :: AppState -> AppState Source #
Jump to beat 0 of the current measure.
goToMeasureEnd :: AppState -> AppState Source #
Jump to the last beat of the current measure, per its time signature
numerator (see goToEnd for the same caveat about padding slots).
goToFirstString :: AppState -> AppState Source #
Jump the cursor to string index 0.
goToLastString :: AppState -> AppState Source #
Jump the cursor to the current track's last string.
cycleDisplayMode :: AppState -> AppState Source #
Advance the current track's DisplayMode to the next in the cycle
TabOnly -> NotationOnly -> TabAndNotation -> TabOnly.
currentTrack :: AppState -> Maybe Track Source #
The Track at asCurrentTrack, or Nothing if the cursor's track
index is out of range (e.g. the last track was just deleted).
currentMeasure :: AppState -> Maybe Measure Source #
The Measure at asCurrentMeasure, or Nothing if out of range.
currentMeasureBeatCount :: AppState -> Int Source #
Number of navigable beats in the current measure. Accounts for actual beats plus empty slots that fill the remaining duration from the time signature.
atLastBeat :: AppState -> Bool Source #
Are we at the last beat of the current measure?
atLastMeasure :: AppState -> Bool Source #
Are we at the last measure?
atFirstBeat :: AppState -> Bool Source #
Are we at the first beat of the current measure?
atFirstMeasure :: AppState -> Bool Source #
Are we at the first measure?
isMeasureEmpty :: MeasureIndex -> AppState -> Bool Source #
A measure is empty if no track has any notes in it. Empty beat lists or beats with no notes all count as empty.
isTrailingEmpty :: MeasureIndex -> AppState -> Bool Source #
A measure is trailing-empty if it and all measures after it are empty. Only trailing-empty measures should be auto-deleted on backward navigation.
beatsForTrackMeasure :: Track -> MeasureIndex -> [Beat] Source #
The beats a track has for one measure, or [] if it has none there.
stringCountForTrack :: Track -> Int Source #
Number of fretboard strings for a track, or 0 for a Standard
(non-fretted) instrument.
measureCount :: AppState -> Int Source #
Total number of measures in the current song.