This module provides a single-choice list box component for the terminal UI system.
::: tip TIP
To use this module, you need to import it first: import("core.ui.choicebox")
:::
::: tip NOTE
The UI module is primarily used for xmake's internal xmake f --menu menu-based visual configuration. It provides basic UI components that can also be used by users to implement their own terminal UIs.
:::
The choicebox module extends panel and provides a single-choice list box with:
(X) to mark selected item, ( ) for unselected items)::: tip API
choicebox:new(name: <string>, bounds: <rect>)
:::
| Parameter | Description |
|---|---|
| name | Required. List box name string |
| bounds | Required. List box bounds rectangle |
| Type | Description |
|---|---|
| choicebox | Returns a single-choice list box instance |
Create a single-choice list box:
import("core.ui.choicebox")
import("core.ui.rect")
local choicebox = choicebox:new("my_choice", rect{10, 5, 30, 10})
::: tip API
choicebox:load(values: <table>, selected?: <number>)
:::
| Parameter | Description |
|---|---|
| values | Required. Array of option values |
| selected | Optional. Index of the default selected item (1-based), defaults to 1 |
No return value
Load options and set the default selected item:
local values = {"Option 1", "Option 2", "Option 3", "Option 4"}
choicebox:load(values, 2) -- Default to the second item
After loading, the action.ac_on_load event is triggered.
::: tip API
choicebox:scrollable()
:::
No parameters
| Type | Description |
|---|---|
| boolean | Returns true when the number of options exceeds the visible height, otherwise returns false |
Check if scrolling is needed:
if choicebox:scrollable() then
print("Many options available, can scroll to view")
end
::: tip API
choicebox:scroll(count: <number>)
:::
| Parameter | Description |
|---|---|
| count | Required. Number of lines to scroll, positive for down, negative for up |
No return value
Scroll the list box content:
choicebox:scroll(1) -- Scroll down one line
choicebox:scroll(-1) -- Scroll up one line
choicebox:scroll(choicebox:height()) -- Scroll down one page
When scrolling, the action.ac_on_scrolled event is triggered, passing the current scroll position ratio (0.0-1.0).
::: tip API
choicebox:on_event(e: <event>)
:::
| Parameter | Description |
|---|---|
| e | Required. Event object |
| Type | Description |
|---|---|
| boolean | Returns true if the event was handled, otherwise returns false |
The list box automatically handles the following keyboard events:
Up: Navigate up, automatically scrolls up one page when reaching the topDown: Navigate down, automatically scrolls down one page when reaching the bottomPageUp: Scroll up one pagePageDown: Scroll down one pageEnter or Space: Select the current itemWhen an item is selected, the action.ac_on_selected event is triggered, passing the selected item's index and value.
Override this method to add custom event handling:
function my_choicebox:on_event(e)
if e.type == event.ev_keyboard and e.key_name == "Tab" then
-- Custom handling for Tab key
return true
end
return choicebox.on_event(self, e)
end
::: tip API
choicebox:on_resize()
:::
No parameters
No return value
This method is automatically called when the list box size changes. It relayouts the option items, only showing items within the currently visible range.
Here is a complete usage example:
import("core.ui.choicebox")
import("core.ui.rect")
import("core.ui.window")
import("core.ui.application")
import("core.ui.action")
local demo = application()
function demo:init()
application.init(self, "demo")
self:background_set("blue")
-- Create window
local win = window:new("main", rect{1, 1, self:width() - 1, self:height() - 1}, "Choice Box Demo")
-- Create single-choice list box
local choice = choicebox:new("choices", rect{5, 5, 40, 15})
-- Load option values
local options = {"gcc", "clang", "msvc", "mingw", "icc"}
choice:load(options, 1) -- Default to first item
-- Set selection event handler
choice:action_set(action.ac_on_selected, function (v, index, value)
print("Selected:", value, "(index:", index, ")")
end)
-- Set scroll event handler
choice:action_set(action.ac_on_scrolled, function (v, ratio)
print("Scroll position:", string.format("%.2f%%", ratio * 100))
end)
-- Add list box to window panel
local panel = win:panel()
panel:insert(choice)
-- Select the list box
panel:select(choice)
self:insert(win)
self._win = win
end
function demo:on_resize()
self._win:bounds_set(rect{1, 1, self:width() - 1, self:height() - 1})
application.on_resize(self)
end
function main(...)
demo:run(...)
end