A general-purpose script for producing buttons. I hope the helpful help text I added helps helpfully.
Silly bit of code, but it's yet another way of allowing the user to interact with a lua script. I hope it feels convenient.
... Maybe I should create sample scripts that uses this...
Download YummyButton.luaLanguage: lua
--[[
Welcome to my Buttons script!
To start, put in the following lines:
require("thisScript")
NewBtn{x= 1, y= 1, fn= function()
((Various code here))
end}
And all of a sudden, you have this bluish button on the top left corner of
the emulator window, once you run the script. Use the mouse to click the
button. The code you put in will happen.
Now, there are ways to configure these buttons to your desires. For one thing,
make as many NewBtn objects as you like. This script will keep track of 'em.
For another, change that x and y up there if you don't like the NewBtn being
stuck in the top-left corner. Finally, there's various options you can use to
tweak your NewBtn desires.
REQUIRED:
x - X position. Where is the button horizontally?
y - Y position. Where do we put it vertically?
fn - Function. The button had better do something!!
Optional:
text - Cute text to display on button. May size button automatically.
x1 - Identical to the otherwise required x. If both present, x has priority
x2 - The right side of the button
y1 - Identical to y. y1 can take y's place, but if you make both, y is used
y2 - The bottom side of the button
width - Width of button. Would interfere with x2, but x2 takes priority.
height- Height of button. Use if you don't feel like using y2.
color - General color scheme of the button. This affects all aspects of color.
MBC - Main Border Color. "Main" is when your mouse isn't over the button.
MFC - Main Fill Color. ... I use "Main" for lack of better words...
SBC - Sub Border Color. "Sub" is used when you're mousing over the button.
SFC - Sub Fill Color. Anyone have better words for me?
tag - Spare variable.
Included functions:
draw - Draws the button. Don't bother using it, it's automatically called.
recolor- Modifies the color scheme. Takes in one value depicting base color.
move - Moves the button so that the top-left corner matches the x,y input.
While it is packaged for simple use as is, the more savvy programmers may want
to read on.
I pass the button object to the clicked button function as the only parameter.
I can't think of any real way of passing variables you want for it, but I
added the "tag" variable for this purpose. Technically, after the button is
constructed, you can add new parameters to the button object itself, but the
"tag" variable seemed like a convenient thing to add to the constructor.
In addition, I put the HandleBtns function in gui.register by default, but go
ahead and call it in another function and replace the gui.register callback.
This function will return whatever the button function returns, so if it is in
your interest to have the button function return something, it will do so
through _FRK_Btn.HandleBtns.
The NewBtn constructor returns the button object it created as a table for you
to mess around with, should you have a reason to. Maybe you want to move it
around or change its colors, who knows.
Finally, _FRK_Btn.MB holds all my buttons. You can, in the middle of creating
new buttons, set another variable (MB2, perhaps?), set _FRK_Btn.MB = {}, then
create more buttons. You'll have two different sets of buttons which you can
switch between, but you'll have to make your own functions to do the switch.
But if you're not experienced in lua programming, none of the previous four
paragraphs are of any interest to you. The simple use of these buttons are
good enough for many uses.
]]--
_FRK_Btn= {}
local EMUCHWID= 6
local EMUCHHGT= 8
if stylus then EMUCHWID= 6; EMUCHHGT= 8
elseif snes9x then EMUCHWID= 4; EMUCHHGT= 6
elseif VBA then EMUCHWID= 4; EMUCHHGT= 6
end
_FRK_Btn.ClickType= "leftclick"
_FRK_Btn.MB= {}
keys, lastkeys= {}, {}
function UpdateKeys() lastkeys= keys; keys= input.get() end
function Press(k) return keys[k] and not lastkeys[k] end
--*****************************************************************************
function _FRK_Btn.FindBtn()
--*****************************************************************************
if (keys.xmouse == lastkeys.xmouse) and
(keys.ymouse == lastkeys.ymouse) then return end
local X,Y= keys.xmouse, keys.ymouse
for i= 1, #_FRK_Btn.MB do -- linear scan, darn it!
local n= _FRK_Btn.MB[i]
if (Y >= n.y1) and (Y <= n.y2)
and (X >= n.x1) and (X <= n.x2) then return i end
end
return -1
end
--*****************************************************************************
function _FRK_Btn.ClickBtn(id)
--*****************************************************************************
if id and _FRK_Btn.MB[id] then
return _FRK_Btn.MB[id]:fn()
end
end
--*****************************************************************************
function _FRK_Btn.DrawUnsel(B)
--*****************************************************************************
gui.box(B.x1, B.y1, B.x2, B.y2, B.MFC, B.MBC)
gui.text(B.xt, B.yt, B.text)
end
--*****************************************************************************
function _FRK_Btn.DrawSel(B)
--*****************************************************************************
gui.box(B.x1, B.y1, B.x2, B.y2, B.SFC, B.SBC)
gui.text(B.xt, B.yt, B.text)
end
--*****************************************************************************
function _FRK_Btn.ShowBtns()
--*****************************************************************************
B= _FRK_Btn.MB
for i= 1, #B do
B[i]:draw()
end
end
--*****************************************************************************
function _FRK_Btn.Recolor(B,color)
--*****************************************************************************
-- Does not like strings. Still will accept them, however.
local t= type(color)
if t == "string" then -- Uh, no. No tricky color stuff. Sorry.
B.MBC= Cns.color
B.SBC= Cns.color
B.MFC= 0x00000040
B.SFC= 0xC0C0C0C0
--Oh, not a string! Better be table or number, please.
else
if t == "table" then
color= 0
local q= color.r or color[1]
if q then color= bit.lshift(q,24) end
q= color.g or color[2]
if q then color= bit.bor(color,bit.lshift(q,16)) end
q= color.b or color[3]
if q then color= bit.bor(color,bit.lshift(q, 8)) end
q= color.a or color[4]
if q then color= bit.bor(color,q)
else color= bit.bor(color,0xFF) end
end
B.MBC= color
B.MFC= bit.rshift(bit.band(color,0xFEFEFEFE),1)
B.SBC= bit.bor(color+bit.band(0xFFFFFFFF-color,0xFEFEFEFE)/2,0xFF)
B.SFC= color
end
end
--*****************************************************************************
function _FRK_Btn.Move(B, x,y)
--*****************************************************************************
-- Moves the whole button for you!
if x then
local XDiff= x - B.x1
B.x1= x
B.x2= B.x2 + XDiff
B.xt= B.xt + XDiff
end
if y then
local YDiff= y - B.y1
B.y1= y
B.y2= B.y2 + YDiff
B.yt= B.yt + YDiff
end
end
--*****************************************************************************
function _FRK_Btn.NewBtn(Cns)
--*****************************************************************************
-- the button constructor!
--Insert universal function pointers while creating a new table.
local NewTbl= {
draw= _FRK_Btn.DrawUnsel,
recolor= _FRK_Btn.Recolor,
move= _FRK_Btn.Move
}
--Insert presumed information.
NewTbl.fn= Cns.fn
NewTbl.x1= Cns.x or Cns.x1
NewTbl.y1= Cns.y or Cns.y1
NewTbl.tag= Cns.tag
--Check if user defined the right side.
if Cns.x2 then
NewTbl.x2= math.max(NewTbl.x1,Cns.x2)
NewTbl.x1= math.min(NewTbl.x1,Cns.x2)
elseif Cns.width then
NewTbl.x2= NewTbl.x1 + Cns.width
end
--Check if user defined the bottom side.
if Cns.y2 then
NewTbl.y2= math.max(NewTbl.y1,Cns.y2)
NewTbl.y1= math.min(NewTbl.y1,Cns.y2)
elseif Cns.height then
NewTbl.y2= NewTbl.y1 + Cns.height
end
--Look for text. Do tricky stuff based on where to put the darn text or
--how to resize the button.
if Cns.text then
NewTbl.text= tostring(Cns.text)
local len= #NewTbl.text * EMUCHWID
if NewTbl.x2 then
NewTbl.xt= math.floor((NewTbl.x1 + NewTbl.x2 - len)/2)
else
NewTbl.x2= NewTbl.x1 + len + 3
NewTbl.xt= NewTbl.x1 + 2
end
if NewTbl.y2 then
NewTbl.yt= math.floor((NewTbl.y1 + NewTbl.y2 - 8)/2)
else
NewTbl.y2= NewTbl.y1 + EMUCHHGT + 4
NewTbl.yt= NewTbl.y1 + 2
end
else
NewTbl.text= ""
NewTbl.xt= NewTbl.x1
NewTbl.yt= NewTbl.y1
if not NewTbl.x2 then NewTbl.x2= NewTbl.x1 + 8 end
if not NewTbl.y2 then NewTbl.y2= NewTbl.y1 + 8 end
end
--Mess with colors!
if Cns.color then
NewTbl:recolor(Cns.color)
else
NewTbl.MBC= Cns.MBC or 0x0020FFC0
NewTbl.MFC= Cns.MFC or 0x00000040
NewTbl.SBC= Cns.SBC or 0x0080FFFF
NewTbl.SFC= Cns.SFC or 0x2000C0C0
end
--Finally add the button to our MB array.
local index= #(_FRK_Btn.MB)+1
_FRK_Btn.MB[index]= NewTbl
--Here's the button object in case you want to handle it yourself.
return NewTbl
end
local ID= -1
--*****************************************************************************
function _FRK_Btn.HandleBtns()
--*****************************************************************************
UpdateKeys()
local id= _FRK_Btn.FindBtn()
if id then
if ID ~= -1 then
_FRK_Btn.MB[ID].draw= _FRK_Btn.DrawUnsel
end
if id ~= -1 then
_FRK_Btn.MB[id].draw= _FRK_Btn.DrawSel
end
ID= id
end
_FRK_Btn.ShowBtns()
if Press(_FRK_Btn.ClickType) and (ID ~= -1) then
return _FRK_Btn.ClickBtn(ID)
end
end
--=============================================================================
if not FRK_NoAuto then
--=============================================================================
gui.register(_FRK_Btn.HandleBtns)
NewBtn= _FRK_Btn.NewBtn
end