Skip to content

core.ui.choicebox

This module provides a single-choice list box component for the terminal UI system.

TIP

To use this module, you need to import it first: import("core.ui.choicebox")

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:

  • Single selection support (uses (X) to mark selected item, ( ) for unselected items)
  • Keyboard navigation (Up/Down, PageUp/PageDown)
  • Scroll support (when the number of options exceeds the visible area)
  • Automatic resize handling
  • Event callbacks (on_load, on_scrolled, on_selected)

choicebox:new

  • Create a new single-choice list box instance

Function Prototype

API

lua
choicebox:new(name: <string>, bounds: <rect>)

Parameter Description

ParameterDescription
nameRequired. List box name string
boundsRequired. List box bounds rectangle

Return Value

TypeDescription
choiceboxReturns a single-choice list box instance

Usage

Create a single-choice list box:

lua
import("core.ui.choicebox")
import("core.ui.rect")

local choicebox = choicebox:new("my_choice", rect{10, 5, 30, 10})

choicebox:load

  • Load option values into the list box

Function Prototype

API

lua
choicebox:load(values: <table>, selected?: <number>)

Parameter Description

ParameterDescription
valuesRequired. Array of option values
selectedOptional. Index of the default selected item (1-based), defaults to 1

Return Value

No return value

Usage

Load options and set the default selected item:

lua
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.

choicebox:scrollable

  • Check if the list box is scrollable

Function Prototype

API

lua
choicebox:scrollable()

Parameter Description

No parameters

Return Value

TypeDescription
booleanReturns true when the number of options exceeds the visible height, otherwise returns false

Usage

Check if scrolling is needed:

lua
if choicebox:scrollable() then
    print("Many options available, can scroll to view")
end

choicebox:scroll

  • Scroll the list box content

Function Prototype

API

lua
choicebox:scroll(count: <number>)

Parameter Description

ParameterDescription
countRequired. Number of lines to scroll, positive for down, negative for up

Return Value

No return value

Usage

Scroll the list box content:

lua
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).

choicebox:on_event

  • Handle keyboard events

Function Prototype

API

lua
choicebox:on_event(e: <event>)

Parameter Description

ParameterDescription
eRequired. Event object

Return Value

TypeDescription
booleanReturns true if the event was handled, otherwise returns false

Usage

The list box automatically handles the following keyboard events:

  • Up: Navigate up, automatically scrolls up one page when reaching the top
  • Down: Navigate down, automatically scrolls down one page when reaching the bottom
  • PageUp: Scroll up one page
  • PageDown: Scroll down one page
  • Enter or Space: Select the current item

When 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:

lua
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

choicebox:on_resize

  • Handle list box resize

Function Prototype

API

lua
choicebox:on_resize()

Parameter Description

No parameters

Return Value

No return value

Usage

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:

lua
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