|
|
Clickable button documentation?
By LightningHelix 2026-05-04 07:24:13
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: I dug around in vanilla launcher addons - BLUGuide, Rhombus, and Nostrum all do it - but they don't use anything I understand because I am dumb.
BLUGuide's buttons.lua uses the event I'd naively expect from the events documentation page:
windower.register_event("mouse")It then checks whether "eventtype" = 1 for left click, 2 for left release, and so on.
Surely there's a better way, because there's no sane reason to check both of those events for any given button.
(Differentiating the two is good for supporting dragging-to-move, but since the general use purpose of a button is "to be clicked on", you're having to define a second event you actively don't want to do anything!)
Nostrum's prims.lua checks for "left click" and "right click" events, which is great! Exactly what I'm hoping for, if I was smart enough to understand anything about it.
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
Serveur: Fenrir
Game: FFXI
Posts: 1212
By Fenrir.Jinxs 2026-05-04 13:41:09
Ask in the windower discord
By Thaylia 2026-05-04 08:55:36
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)
[+]
By Felgarr 2026-05-04 14:17:20
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? :)
By LightningHelix 2026-05-04 09:36:05
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.
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: 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)
--modified: removed () from left_click_function to call it as a reference
ACTUAL_BOX:register_event('left_click', left_click_function)
end
--settings for the box, you can ignore this
windowSettings = T{}[s][/s]
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
By Thaylia 2026-05-04 18:25:12
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
By Thaylia 2026-05-04 14:04:50
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.
[+]
By LightningHelix 2026-05-04 20:10:41
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
endThank 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
Serveur: Carbuncle
Game: FFXI
Posts: 7481
By Carbuncle.Nynja 2026-05-04 21:34:56
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!
By DaneBlood 2026-05-04 20:48:54
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
Serveur: Valefor
Game: FFXI
Posts: 208
By Valefor.Keylesta 2026-05-27 11:31:57
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
Serveur: Fenrir
Game: FFXI
Posts: 1212
By Fenrir.Jinxs 2026-05-27 13:24:41
Is one of the versions of xivhotbar intended for keyboard clickable?
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: I dug around in vanilla launcher addons - BLUGuide, Rhombus, and Nostrum all do it - but they don't use anything I understand because I am dumb.
BLUGuide's buttons.lua uses the event I'd naively expect from the events documentation page:
windower.register_event("mouse")It then checks whether "eventtype" = 1 for left click, 2 for left release, and so on.
Surely there's a better way, because there's no sane reason to check both of those events for any given button.
(Differentiating the two is good for supporting dragging-to-move, but since the general use purpose of a button is "to be clicked on", you're having to define a second event you actively don't want to do anything!)
Nostrum's prims.lua checks for "left click" and "right click" events, which is great! Exactly what I'm hoping for, if I was smart enough to understand anything about it.
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?
|
|