@@ -26,7 +26,7 @@ Details can be found in
2626
2727# Subtypes
2828
29- All subtypes must contain the fields `pagesize::Int` and
29+ All subtypes must be mutable, and must contain the fields `pagesize::Int` and
3030`pageoffset::Int`. They must also implement the following functions.
3131
3232## Necessary Functions
@@ -36,7 +36,9 @@ These functions must be implemented for all subtypes of AbstractMenu.
3636 - `pick(m::AbstractMenu, cursor::Int)`
3737 - `cancel(m::AbstractMenu)`
3838 - `options(m::AbstractMenu)`
39- - `writeline(buf::IOBuffer, m::AbstractMenu, idx::Int, showcursor::Bool)`
39+ - `writeline(buf::IOBuffer, m::AbstractMenu, idx::Int, cursor)`
40+
41+ If `m` does not have a field called `selected`, then you must also implement `selected(m)`.
4042
4143## Optional Functions
4244
@@ -45,7 +47,8 @@ subtypes.
4547
4648 - `header(m::AbstractMenu)`
4749 - `keypress(m::AbstractMenu, i::UInt32)`
48- - `noptions(m::AbstractMenu)`
50+ - `numoptions(m::AbstractMenu)`
51+ - `selected(m::AbstractMenu)`
4952
5053"""
5154abstract type AbstractMenu end
@@ -78,28 +81,35 @@ cancel(m::AbstractMenu) = error("unimplemented")
7881
7982Return a list of strings to be displayed as options in the current page.
8083
81- Alternatively, implement `noptions `, in which case `options` is not needed.
84+ Alternatively, implement `numoptions `, in which case `options` is not needed.
8285"""
8386options (m:: AbstractMenu ) = error (" unimplemented" )
8487
8588"""
86- writeline(buf::IOBuffer, m::AbstractMenu, idx::Int, cursor::Union{Char,Nothing} )
89+ writeline(buf::IOBuffer, m::AbstractMenu, idx::Int, cursor::Bool, indicators::Indicators )
8790
88- Write the option at index `idx` to the buffer. If `isa(cursor, Char)`, it should be printed.
91+ Write the option at index `idx` to the buffer. If `indicators !== nothing`, the current line
92+ corresponds to the cursor position. The method is responsible for displaying visual indicator(s)
93+ about the state of this menu item; the configured characters are returned in `indicators`
94+ in fields with the following names:
95+ `cursor::Char`: the character used to indicate the cursor position
96+ `checked::String`: a string used to indicate this option has been marked
97+ `unchecked::String`: a string used to indicate this option has not been marked
98+ The latter two are relevant only for menus that support multiple selection.
8999
90100!!! compat "Julia 1.6"
91101 `writeline` requires Julia 1.6 or higher.
92102
93103 On older versions of Julia, this was
94104 `writeLine(buf::IOBuffer, m::AbstractMenu, idx, cursor::Bool)`
95- and if `cursor` is `true`, the cursor obtained from `TerminalMenus.CONFIG[:cursor] `
96- should be printed .
105+ and the indicators can be obtained from `TerminalMenus.CONFIG`, a Dict indexed by `Symbol `
106+ keys with the same names as the fields of `indicators` .
97107
98108 This older function is supported on all Julia 1.x versions but will be dropped in Julia 2.0.
99109"""
100- function writeline (buf:: IOBuffer , m:: AbstractMenu , idx:: Int , cursor:: Union{Char,Nothing} )
110+ function writeline (buf:: IOBuffer , m:: AbstractMenu , idx:: Int , cursor:: Bool , indicators )
101111 # error("unimplemented") # TODO : use this in Julia 2.0
102- writeLine (buf, m, idx, isa ( cursor, Char) )
112+ writeLine (buf, m, idx, cursor)
103113end
104114
105115
111121 header(m::AbstractMenu)
112122
113123Displays the header above the menu when it is rendered to the screen.
124+ Defaults to "".
114125"""
115126header (m:: AbstractMenu ) = " "
116127
@@ -119,22 +130,31 @@ header(m::AbstractMenu) = ""
119130
120131Send any non-standard keypress event to this function.
121132If `true` is returned, `request()` will exit.
133+ Defaults to `false`.
122134"""
123135keypress (m:: AbstractMenu , i:: UInt32 ) = false
124136
125137"""
126- noptions (m::AbstractMenu)
138+ numoptions (m::AbstractMenu)
127139
128140Return the number of options in menu `m`. Defaults to `length(options(m))`.
129141"""
130- noptions (m:: AbstractMenu ) = length (options (m))
142+ numoptions (m:: AbstractMenu ) = length (options (m))
131143
144+ """
145+ selected(m::AbstractMenu)
146+
147+ Return information about the user-selected option. Defaults to `m.selected`.
148+ """
149+ selected (m:: AbstractMenu ) = m. selected
132150
133151"""
134152 request(m::AbstractMenu; cursor=1)
135153
136- Display the menu and enter interactive mode. Returns `m.selected` which
137- varies based on menu type.
154+ Display the menu and enter interactive mode. `cursor` indicates the initial item
155+ for the cursor.
156+
157+ Returns `selected(m)` which varies based on menu type.
138158"""
139159request (m:: AbstractMenu ; kwargs... ) = request (terminal, m; kwargs... )
140160
@@ -147,7 +167,7 @@ function request(term::REPL.Terminals.TTYTerminal, m::AbstractMenu; cursor::Int=
147167 raw_mode_enabled = REPL. Terminals. raw! (term, true )
148168 raw_mode_enabled && print (term. out_stream, " \x 1b[?25l" ) # hide the cursor
149169
150- lastoption = noptions (m)
170+ lastoption = numoptions (m)
151171 try
152172 while true
153173 c = readkey (term. in_stream)
@@ -223,7 +243,7 @@ function request(term::REPL.Terminals.TTYTerminal, m::AbstractMenu; cursor::Int=
223243 end
224244 println (term. out_stream)
225245
226- return m . selected
246+ return selected (m)
227247end
228248
229249
@@ -255,6 +275,7 @@ function printmenu(out, m::AbstractMenu, cursor::Int; init::Bool=false)
255275 CONFIG[:suppress_output ] && return
256276
257277 buf = IOBuffer ()
278+ indicators = Indicators ()
258279
259280 lines = m. pagesize- 1
260281
@@ -274,13 +295,13 @@ function printmenu(out, m::AbstractMenu, cursor::Int; init::Bool=false)
274295
275296 if i == firstline && m. pageoffset > 0
276297 print (buf, CONFIG[:up_arrow ])
277- elseif i == lastline && i != noptions (m)
298+ elseif i == lastline && i != numoptions (m)
278299 print (buf, CONFIG[:down_arrow ])
279300 else
280301 print (buf, " " )
281302 end
282303
283- writeline (buf, m, i, i == cursor ? CONFIG[ :cursor ] : nothing )
304+ writeline (buf, m, i, i == cursor, indicators )
284305
285306 i != lastline && print (buf, " \r\n " )
286307 end
0 commit comments