Clickable Button Documentation?

Langues: JP EN DE FR
Yellow Box
3232 users online
Forum » Windower » Support » Clickable button documentation?
Clickable button documentation?
Offline
By LightningHelix 2026-05-04 07:24:13
Link | Citer | R
 
Incredibly broad question, but I couldn't think of anywhere better to ask. I'm wondering how exactly people create a clickable button via a lua addon, and whether there's any documentation about it.

Here's what I naively expected to work:
Code
_addon.name = 'testing'
_addon.author = 'me'
_addon.version = '0.0.1'
_addon.commands = {'testing'}

texts = require('texts') --to create the box
require('luau') --to make T{} work, I have no idea how to do box settings without this lol 

--on addon load, create box
windower.register_event('load', function (...)

  generate_text()

end)

--this SHOULD only fire on left click, but...
function left_click_function()
  windower.add_to_chat(216, 'Success!')
end


--generate the box on addon load
function generate_text()

  --define some text
  BOX_CONTENTS = '\\cs(0, 0, 0)' .. 'HELLO! I AM A BOX. ' .. '\\cr\n' .. '\\cr\n'

  --create the box
  ACTUAL_BOX = texts.new(windowSettings) 

  --put the text in the box
  ACTUAL_BOX:text(BOX_CONTENTS)

  --and make it all visible
  ACTUAL_BOX:visible(true)

  --now, I naively expect this to "associate" the event with the box...
  ACTUAL_BOX:register_event('left_click', left_click_function())

end

--settings for the box, you can ignore this
windowSettings = T{}
windowSettings.pos = T{}
windowSettings.pos.x = 400
windowSettings.pos.y = 400
windowSettings.bg = T{}
windowSettings.bg.red = 150
windowSettings.bg.green = 150
windowSettings.bg.blue = 150

Copypaste that, name it testing.lua, run it...
and you'll see that the register_event on line 38 is running immediately on addon load. Straight into the chat log. No clicking required, which is not what I wanted.

1) How do I register an event to trigger on a left click?
2) How do I make sure that the left click is located within a specific box? I'm aware that the left click event has (X, Y) parameters, so I could keep a table tracking the position of each object I create, but again, clearly not the easiest way to do it.

I did do some research, I promise:

Any help would be much appreciated, because I am very stupid. If there's just like, a "here's how you do this for dummies" somewhere I'm missing?
 Fenrir.Jinxs
Offline
Serveur: Fenrir
Game: FFXI
User: Jinxs
Posts: 1212
By Fenrir.Jinxs 2026-05-04 13:41:09
Link | Citer | R
 
Ask in the windower discord
Offline
Posts: 8
By Thaylia 2026-05-04 08:55:36
Link | Citer | R
 
Your bug is on line 38.
Code
ACTUAL_BOX:register_event('left_click', left_click_function())


You wrote left_click_function() with parentheses, which calls the function immediately and passes its return value (nil) to register_event. You want to pass the function itself as a reference:
Code
ACTUAL_BOX:register_event('left_click', left_click_function)
[+]
Offline
Posts: 2721
By Felgarr 2026-05-04 14:17:20
Link | Citer | R
 
Thaylia said: »
Your bug is on line 38.
Code
ACTUAL_BOX:register_event('left_click', left_click_function())


You wrote left_click_function() with parentheses, which calls the function immediately and passes its return value (nil) to register_event. You want to pass the function itself as a reference:
Code
ACTUAL_BOX:register_event('left_click', left_click_function)

Wow, a competent BRD *and* a coder. Is there anything you can't do? :)
Offline
By LightningHelix 2026-05-04 09:36:05
Link | Citer | R
 
Fenrir.Jinxs said: »
Ask in the windower discord
I'm gonna be the person Googling this in five years and I sure hope that whatever answer we arrive at is somewhere Google can find rather than on a chat server with non-indexed search!

If this isn't the appropriate place to post, by all means point me to somewhere better.
Thaylia said: »
Your bug is on line 38.
Code
ACTUAL_BOX:register_event('left_click', left_click_function())


You wrote left_click_function() with parentheses, which calls the function immediately and passes its return value (nil) to register_event. You want to pass the function itself as a reference:
Code
ACTUAL_BOX:register_event('left_click', left_click_function)
...okay! (I learned several things in the process of reading this short post. Thank you!)

I did that, it no longer runs on load, but when I click on the box it does nothing.

Didn't get an error (like "event left click not available for text objects", which I can create at will by messing up parts of my code"), just a silent failure.

My current code:
[+]
Offline
Posts: 8
By Thaylia 2026-05-04 18:25:12
Link | Citer | R
 
I thought you were using an older or forked version of the library texts.lua

The version with current Windower use the global mouse event now.

Here's what you need:
Code
--global mouse handler with hit-test against the box
windower.register_event('mouse', function(type, x, y, delta, blocked)
    if type ~= 1 then return end          -- only left click down
    if not ACTUAL_BOX then return end     -- box not created yet
    if not ACTUAL_BOX:visible() then return end

    local bx, by = ACTUAL_BOX:pos()
    local bw, bh = ACTUAL_BOX:extents()

    if x >= bx and x <= bx + bw and y >= by and y <= by + bh then
        left_click_function()
        return true  -- consume the click
    end
end)


Or yet better create a function to test multiple boxes:
Code
windower.register_event('mouse', function(type, x, y, delta, blocked)
    if type ~= 1 then return end
    
    if hit_test(BOX_A, x, y) then box_a_clicked() return true end
    if hit_test(BOX_B, x, y) then box_b_clicked() return true end
    if hit_test(BOX_C, x, y) then box_c_clicked() return true end
end)

function hit_test(box, x, y)
    if not box or not box:visible() then return false end
    local bx, by = box:pos()
    local bw, bh = box:extents()
    return x >= bx and x <= bx + bw and y >= by and y <= by + bh
end
Offline
Posts: 8
By Thaylia 2026-05-04 14:04:50
Link | Citer | R
 
Felgarr said: »
Thaylia said: »
Your bug is on line 38.
Code
ACTUAL_BOX:register_event('left_click', left_click_function())


You wrote left_click_function() with parentheses, which calls the function immediately and passes its return value (nil) to register_event. You want to pass the function itself as a reference:
Code
ACTUAL_BOX:register_event('left_click', left_click_function)

Wow, a competent BRD *and* a coder. Is there anything you can't do? :)
Pretty much everything else... ;)
BRDs and code is the entire skill tree.
[+]
Offline
By LightningHelix 2026-05-04 20:10:41
Link | Citer | R
 
Thaylia said: »
I thought you were using an older or forked version of the library texts.lua

The version with current Windower use the global mouse event now.

Here's what you need:
Code
--global mouse handler with hit-test against the box
windower.register_event('mouse', function(type, x, y, delta, blocked)
    if type ~= 1 then return end          -- only left click down
    if not ACTUAL_BOX then return end     -- box not created yet
    if not ACTUAL_BOX:visible() then return end

    local bx, by = ACTUAL_BOX:pos()
    local bw, bh = ACTUAL_BOX:extents()

    if x >= bx and x <= bx + bw and y >= by and y <= by + bh then
        left_click_function()
        return true  -- consume the click
    end
end)


Or yet better create a function to test multiple boxes:
Code
windower.register_event('mouse', function(type, x, y, delta, blocked)
    if type ~= 1 then return end
    
    if hit_test(BOX_A, x, y) then box_a_clicked() return true end
    if hit_test(BOX_B, x, y) then box_b_clicked() return true end
    if hit_test(BOX_C, x, y) then box_c_clicked() return true end
end)

function hit_test(box, x, y)
    if not box or not box:visible() then return false end
    local bx, by = box:pos()
    local bw, bh = box:extents()
    return x >= bx and x <= bx + bw and y >= by and y <= by + bh
end
Thank you! I'll take a crack at this later when I'm back at my computer. I appreciate both getting responses at all and getting multiple iterated responses :)
 Carbuncle.Nynja
Offline
Serveur: Carbuncle
Game: FFXI
User: NynJa
Posts: 7481
By Carbuncle.Nynja 2026-05-04 21:34:56
Link | Citer | R
 
LightningHelix said: »
I'm gonna be the person Googling this in five years and I sure hope that whatever answer we arrive at is somewhere Google can find rather than on a chat server with non-indexed search!
Online
Posts: 1381
By DaneBlood 2026-05-04 20:48:54
Link | Citer | R
 
LightningHelix said: »
I'm gonna be the person Googling this in five years and I sure hope that whatever answer we arrive at is somewhere Google can find rather than on a chat server with non-indexed search!


[+]
 Valefor.Keylesta
Offline
Serveur: Valefor
Game: FFXI
User: Keyser
Posts: 208
By Valefor.Keylesta 2026-05-27 11:31:57
Link | Citer | R
 
I've done this in two different ways.

The first way is more for a window with lots of clickable things. The simple description is I first use :extents() to give me the total height and width of a text object (ie the window), then divided it out by a known number of characters (width) and lines (height). That creates a grid that I can then use mouse location on click to determine where in the grid was clicked (add in some math with the position of the window object). I then map out where every button is located within that grid, then based on that I can tell which "button" was clicked. See GaolPlan. If the window gets moved around, the buttons and grid math all move with it. It's kindof a lot of work and ugly, but it works.

The second way is more for a window with only a few things to click on, and is one I am using for a coming update to Bars so I have no examples to point to currently, but it is much simpler. Basically each button is it's own text object, and you can simply use :hover(x, y) (where x and y are the mouse coordinates taken from the mouse event handler) as a true/false to tell you if the mouse was within that text object when clicked (ex: `if mouse_type == 1 and ui.toggle_btn:hover(x, y) then`). The issue with using separate text objects is if you drag anything around they don't move together (which can be solved on it's own though anyway, but that's an issue for a different post).
 Fenrir.Jinxs
Offline
Serveur: Fenrir
Game: FFXI
User: Jinxs
Posts: 1212
By Fenrir.Jinxs 2026-05-27 13:24:41
Link | Citer | R
 
Is one of the versions of xivhotbar intended for keyboard clickable?
Log in to post.