Skip to content

About

A lightweight Lua library for creating, managing, and navigating interactive dialogs in SA:MP

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

easy-dialog v1.5

A lightweight Lua library for building and managing interactive dialogs in SA:MP. Provides object-oriented APIs to create dialogs, handle navigation, and manage user input in a modular way.

Contents


Requirements


Installation

  1. Download or clone this repository.
  2. Rename easy_dialog-main folder to easy_dialog.
  3. Place it into your lib/ directory (MoonLoader folder).
  4. Require it in your script:
local easy_dialog = require 'easy_dialog'
local Dialog = easy_dialog.Dialog

Quick Start

local d = Dialog.new()
    :setCaption("Hello")
    :setStyle("msgbox")
    :setContent("Welcome to easy-dialog!")
    :setButtons("OK", "")
    :setOnResponse(function(self, button)
        if button == 1 then
            print("Dialog confirmed")
        end
    end)

easy_dialog.init()
easy_dialog.register("welcome", d)
easy_dialog.start("welcome")

Core Concepts

Dialog Object

Each dialog is an independent object with its own state, callbacks, and configuration. Dialogs are registered by name and navigated via a stack-based system.

Navigation Stack

Dialogs maintain a navigation history (stack). Use start() to begin a new root flow, go() to push dialogs onto the stack, back() to return, and home() to jump to the root.

Callback Pattern

All callbacks receive self as the first argument. Return values from child dialogs are passed to the parent's onProcessResult callback.


Library API

Initialization

Function Description
easy_dialog.init() Starts the internal handler loop. Call once before showing any dialogs.
easy_dialog.stop() Stops the handler and clears all registered dialogs.

Registration & Navigation

Function Description
easy_dialog.register(name, dialog) Registers a dialog with a unique string key.
easy_dialog.start(name, data?) Opens a dialog as root. Clears the navigation stack.
easy_dialog.go(name, data?) Navigates to a dialog. Behavior depends on its LaunchMode.
easy_dialog.back() Returns to the previous dialog in the stack.
easy_dialog.home() Returns to the root/first dialog in the stack.
easy_dialog.done(result?) Closes current dialog and passes result to parent's onProcessResult.
easy_dialog.show(dialog, isTemporary?, resetPagination?) Directly shows any dialog object.

Quick Helpers

Function Description
easy_dialog.alert(caption, text, onOK?) Shows a modal message box.
easy_dialog.confirm(caption, text, onConfirm) Shows OK/Cancel confirmation. onConfirm(true) if OK pressed.
easy_dialog.prompt(caption, text, onInput) Shows input dialog. onInput receives user's text.

Dialog API

Creation

local d = Dialog.new()          -- create new dialog
local d = Dialog()              -- equivalent shorthand

Setters (all chainable)

Method Description
:setId(id) Set custom SAMP dialog ID. IDs 15000-32767 are reserved for auto-allocation.
:setCaption(text) Set dialog title. Accepts a string or a function returning a string.
:setStyle(style) Dialog style. One of: msgbox, input, list, password, tablist, tablist_headers.
:setButtons(okText, cancelText) Set button labels. Cancel text can be empty for single-button dialogs.
:setContent(text) Set static text content. For non-list styles.
:setItems(items) Set list items. Accepts a table or a function returning a table.
:setHeaders(headers) Set tablist column headers. Table of strings.
:setItemsPerPage(count) Enable pagination. Set to 0 to disable.
:setLaunchMode(mode) Set navigation behavior. See Navigation.

Callbacks Setters

Method Description
:setOnResponse(fn) Main response handler.
:setOnShow(fn) Called when dialog becomes visible.
:setOnUpdate(fn) Called every frame while dialog is active.
:setOnStart(fn) Called when dialog is first shown via start() or go().
:setOnProcessResult(fn) Called when returning from a child dialog via done().

Other Methods

Method Description
:update() Force re-render the dialog (e.g., after changing items).
:close(button?) Close the dialog programmatically. 0 = left button, 1 = right button (default).
d() Shortcut: equivalent to Engine.show(d).

Callbacks Reference

:setOnStart(fn(self, data))

Fires once when a dialog is first displayed via start() or go(). The data parameter is passed from those functions.

:setOnStart(function(self, data)
    self.currentData = data
    print("Started with data:", data)
end)

:setOnShow(fn(self))

Fires every time the dialog is shown (including page navigation).

:setOnShow(function(self)
    print("Dialog shown:", self.caption)
end)

:setOnUpdate(fn(self, deltaTime))

Fires every frame while the dialog is active. Useful for animations or real-time updates.

:setOnUpdate(function(self, dt)
    self.animationTime = (self.animationTime or 0) + dt
end)

:setOnResponse(fn(self, button, index, input, item))

Fires when the user responds to the dialog.

Parameter Type Description
self Dialog The dialog instance.
button number 1 for left button (OK/Select), 0 for right button (Cancel/Close).
index number Selected list item index (1-based), or -1 for non-list styles.
input string User's text input (for input and password styles).
item any The actual list item value at index (resolves function items automatically).
:setOnResponse(function(self, button, index, input, item)
    if button == 1 then
        if self.dialog_style == "input" then
            print("User typed:", input)
        else
            print("Selected item #" .. index .. ":", item)
        end
    end
end)

:setOnProcessResult(fn(self, result))

Fires when a child dialog calls done(result). Receives whatever value was passed to done().

:setOnProcessResult(function(self, result)
    print("Child returned:", result)
end)

Navigation

Launch Modes

Set via :setLaunchMode(mode):

Mode Value Behavior
STANDARD easy_dialog.LaunchMode.STANDARD Default. Pushes dialog onto stack.
ROOT easy_dialog.LaunchMode.ROOT Clears entire stack, making this dialog the new root.
SINGLE_TOP easy_dialog.LaunchMode.SINGLE_TOP If dialog is already in stack, returns to it instead of pushing a duplicate.

Navigation Flow Example

-- Main menu (root)
local main = Dialog.new()
    :setLaunchMode(easy_dialog.LaunchMode.ROOT)
    :setCaption("Main Menu")
    :setStyle("list")
    :setItems({"Settings", "About"})
    :setOnResponse(function(self, button, index)
        if button == 1 then
            if index == 1 then easy_dialog.go("settings")
            else                easy_dialog.go("about")
            end
        end
    end)

-- Settings submenu
local settings = Dialog.new()
    :setCaption("Settings")
    :setStyle("list")
    :setItems({"Audio", "Video"})
    :setOnResponse(function(self, button, index)
        if button == 0 then easy_dialog.back()
        elseif index == 1 then easy_dialog.go("audio")
        end
    end)

easy_dialog.register("main", main)
easy_dialog.register("settings", settings)
easy_dialog.start("main")

Pagination

For large lists, enable pagination with :setItemsPerPage(n) where n is items per page.

local d = Dialog.new()
    :setCaption("Player List")
    :setStyle("list")
    :setItems(playerNames)         -- can be a function
    :setItemsPerPage(10)           -- show 10 items per page
    :setButtons("Select", "Close")

The library automatically adds navigation rows (<< Prev page / Next page >>) and updates the caption to show Page X/Y.

Dynamic Content with Pagination

If items are provided as a function, the list updates automatically on each page change:

:setItems(function(self)
    return getOnlinePlayers()      -- called fresh each render
end)

Configuration

Customize default texts via easy_dialog.configure():

easy_dialog.configure({
    PAGINATION_TEXT  = "Page %d/%d",
    EMPTY_LIST_TEXT  = "{CCCCCC}Empty list.",
    PAGINATION_PREV  = "{BDBDBD}<< Previous",
    PAGINATION_NEXT  = "{BDBDBD}Next >>"
})

Performance

The library includes several optimizations for high-frequency operations:

  • Launch mode validation: Pre-computed lookup table for O(1) checks instead of iteration.
  • Style ID caching: Dialog style integer is computed once on setStyle() and reused.
  • Global variable caching: SA-MP functions are cached in local variables within the handler loop to avoid repeated global lookups.

Full Example

local easy_dialog = require 'easy_dialog'

-- Helper to create styled headers
local function header(text)
    return "{FFCC00}" .. text
end

-- About dialog
local about = Dialog.new()
    :setCaption("About")
    :setStyle("msgbox")
    :setContent("easy-dialog v1.5\nA lightweight dialog library for SA:MP.")
    :setButtons("Back", "")
    :setOnResponse(function(self, button)
        if button == 1 then easy_dialog.back() end
    end)

-- Settings dialog
local settings = Dialog.new()
    :setCaption("Settings")
    :setStyle("list")
    :setItems({"Audio", "Video", "Controls"})
    :setButtons("Select", "Back")
    :setOnResponse(function(self, button, index)
        if button == 0 then easy_dialog.back()
        elseif button == 1 and index == 1 then
            easy_dialog.alert("Audio", "Audio settings coming soon.")
        end
    end)
    :setOnProcessResult(function(self, result)
        print("Settings result:", result)
    end)

-- Main menu
local mainMenu = Dialog.new()
    :setLaunchMode(easy_dialog.LaunchMode.ROOT)
    :setCaption("Main Menu")
    :setStyle("tablist")
    :setHeaders({"Feature", "Description"})
    :setItems({
        {"Settings", "Configure options"},
        {"About", "Library information"},
    })
    :setButtons("OK", "Exit")
    :setOnResponse(function(self, button, index, _, item)
        if button == 0 then
            print("Exited menu")
            return
        end
        local choice = item[1]
        if choice == "Settings" then
            easy_dialog.go("settings")
        elseif choice == "About" then
            easy_dialog.go("about")
        end
    end)
    :setOnStart(function(self, data)
        print("Main menu started with data:", data)
    end)

-- Initialize and register
easy_dialog.init()
easy_dialog.register("main", mainMenu)
easy_dialog.register("settings", settings)
easy_dialog.register("about", about)

-- Start the application
easy_dialog.start("main", { version = "1.5" })

License

MIT. Free to use and modify.

About

A lightweight Lua library for creating, managing, and navigating interactive dialogs in SA:MP

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages