Lua: gui library supports textboxes, for numbers or strings.
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@2056 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
ea72bfe13f
commit
495245b17d
@ -12,12 +12,10 @@ local form = gui.dialog{
|
|||||||
gui.button{ label="+",
|
gui.button{ label="+",
|
||||||
x=6, y=38, w=14, h=14, repeatable=true, click=function()
|
x=6, y=38, w=14, h=14, repeatable=true, click=function()
|
||||||
counter.value=counter.value+1;
|
counter.value=counter.value+1;
|
||||||
counter:render();
|
|
||||||
end},
|
end},
|
||||||
gui.button{ label="-",
|
gui.button{ label="-",
|
||||||
x=26, y=38, w=14, h=14, repeatable=true, click=function()
|
x=26, y=38, w=14, h=14, repeatable=true, click=function()
|
||||||
counter.value=counter.value-1;
|
counter.value=counter.value-1;
|
||||||
counter:render();
|
|
||||||
end},
|
end},
|
||||||
gui.button{ label="Help",
|
gui.button{ label="Help",
|
||||||
x=6, y=70, w=54, h=14, click=function()
|
x=6, y=70, w=54, h=14, click=function()
|
||||||
@ -27,6 +25,23 @@ local form = gui.dialog{
|
|||||||
x=6, y=18, w=54, h=14, key=27, click=function()
|
x=6, y=18, w=54, h=14, key=27, click=function()
|
||||||
return true; -- causes closing
|
return true; -- causes closing
|
||||||
end},
|
end},
|
||||||
|
gui.textbox{
|
||||||
|
x=6, y=90, nbchar=8, decimal=1,
|
||||||
|
min=450, max=1450, maxchar=8, value = 1234,
|
||||||
|
change=function()
|
||||||
|
-- do nothing
|
||||||
|
end
|
||||||
|
},
|
||||||
|
gui.textbox{
|
||||||
|
x=6, y=104, nbchar=10, maxchar=20, value = "test"
|
||||||
|
},
|
||||||
|
gui.textbox{
|
||||||
|
x=6, y=118, nbchar=8, decimal=0, min=0,
|
||||||
|
maxchar=8, value = 456,
|
||||||
|
change=function()
|
||||||
|
-- do nothing
|
||||||
|
end
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
form:run()
|
form:run()
|
||||||
|
|||||||
@ -6,7 +6,40 @@
|
|||||||
gui = {
|
gui = {
|
||||||
|
|
||||||
--
|
--
|
||||||
-- dialog() --
|
-- colors
|
||||||
|
--
|
||||||
|
black = 0,
|
||||||
|
dark = 1,
|
||||||
|
light = 2,
|
||||||
|
white = 3,
|
||||||
|
|
||||||
|
-- "do nothing" function. Used as default callback
|
||||||
|
donothing = function(self)
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- Metatable that hides the field "value" behind a property,
|
||||||
|
-- and calls render() after it's set.
|
||||||
|
propvalue = {
|
||||||
|
__newindex = function(self, index, value)
|
||||||
|
if index == "value" then
|
||||||
|
self._value = value
|
||||||
|
-- extra processing
|
||||||
|
self:render()
|
||||||
|
else
|
||||||
|
rawset(self, index, value)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__index = function(self, index )
|
||||||
|
if index == "value" then
|
||||||
|
return self._value
|
||||||
|
else
|
||||||
|
return rawget( self, index )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
--
|
||||||
|
-- dialog()
|
||||||
--
|
--
|
||||||
dialog = function(args)
|
dialog = function(args)
|
||||||
local dia = {
|
local dia = {
|
||||||
@ -22,21 +55,26 @@ dialog = function(args)
|
|||||||
--
|
--
|
||||||
-- dialog.run() --
|
-- dialog.run() --
|
||||||
--
|
--
|
||||||
run = function(this)
|
run = function(self)
|
||||||
windowopen(this.w,this.h, this.title or "");
|
windowopen(self.w,self.h, self.title or "");
|
||||||
-- examine all elements
|
-- examine all elements
|
||||||
for _,widget in ipairs(this.widgets) do
|
for _,widget in ipairs(self.widgets) do
|
||||||
widget:render()
|
widget:create()
|
||||||
end
|
end
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
local button, button2, key = windowdodialog();
|
local button, button2, key = windowdodialog();
|
||||||
|
|
||||||
if button > 0 then
|
if button > 0 then
|
||||||
local c = this.callbacks[button]
|
local c = self.callbacks[button]
|
||||||
-- run the callback and stop the form if it returns true
|
if c ~= nil then
|
||||||
if c ~= nil and c(this) then
|
-- run the callback
|
||||||
break;
|
local retvalue = c:click()
|
||||||
|
-- stop the form if it returns non-nil
|
||||||
|
if retvalue ~= nil then
|
||||||
|
windowclose();
|
||||||
|
return retvalue;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
until key == 27;
|
until key == 27;
|
||||||
@ -51,7 +89,7 @@ dialog = function(args)
|
|||||||
table.insert(dia.widgets, value)
|
table.insert(dia.widgets, value)
|
||||||
-- clickable widgets take up an auto-numbered id
|
-- clickable widgets take up an auto-numbered id
|
||||||
if (value.click) then
|
if (value.click) then
|
||||||
dia.callbacks[id] = value.click
|
dia.callbacks[id] = value
|
||||||
id=id+1
|
id=id+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -60,7 +98,7 @@ dialog = function(args)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
--
|
--
|
||||||
-- button() --
|
-- button()
|
||||||
--
|
--
|
||||||
button = function(args)
|
button = function(args)
|
||||||
local but = {
|
local but = {
|
||||||
@ -70,42 +108,118 @@ button = function(args)
|
|||||||
h = args.h,
|
h = args.h,
|
||||||
key = args.key,
|
key = args.key,
|
||||||
label = args.label,
|
label = args.label,
|
||||||
click = args.click or donothing,
|
click = args.click or gui.donothing,
|
||||||
render = args.repeatable and function(this)
|
create = args.repeatable and function(self)
|
||||||
windowrepeatbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
|
windowrepeatbutton(self.x, self.y, self.w, self.h, self.label, self.key or -1);
|
||||||
end
|
end
|
||||||
or function(this)
|
or function(self)
|
||||||
windowbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
|
windowbutton(self.x, self.y, self.w, self.h, self.label, self.key or -1);
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
return but;
|
return but;
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--
|
--
|
||||||
-- label() --
|
-- label()
|
||||||
--
|
--
|
||||||
label = function(args)
|
label = function(args)
|
||||||
local fld = {
|
local lbl = {
|
||||||
x = args.x,
|
x = args.x,
|
||||||
y = args.y,
|
y = args.y,
|
||||||
value = args.value,
|
_value = args.value,
|
||||||
format = args.format,
|
format = args.format,
|
||||||
fg = args.fg or 0,
|
fg = args.fg or gui.black,
|
||||||
bg = args.bg or 2,
|
bg = args.bg or gui.light,
|
||||||
render = function(this)
|
render = function(self)
|
||||||
if type(this.format) then
|
if type(self.format) then
|
||||||
windowprint(this.x, this.y, string.format(this.format, this.value), this.fg, this.bg);
|
windowprint(self.x, self.y, string.format(self.format, self._value), self.fg, self.bg);
|
||||||
else
|
else
|
||||||
windowprint(this.x, this.y, this.value, this.fg, this.bg);
|
windowprint(self.x, self.y, self._value, self.fg, self.bg);
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
return fld;
|
lbl.create = lbl.render
|
||||||
|
setmetatable(lbl, gui.propvalue)
|
||||||
|
return lbl;
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
--
|
||||||
|
-- textbox
|
||||||
|
--
|
||||||
|
textbox = function(args)
|
||||||
|
local txtbox = {
|
||||||
|
x = args.x,
|
||||||
|
y = args.y,
|
||||||
|
nbchar = args.nbchar, -- visible size in characters
|
||||||
|
--format = args.format, -- numeric, decimal, path
|
||||||
|
decimal = args.decimal or 0,
|
||||||
|
min = args.min,
|
||||||
|
max = args.max,
|
||||||
|
maxchar = args.maxchar, -- internal size
|
||||||
|
_value = args.value,
|
||||||
|
change = args.change or gui.donothing,
|
||||||
|
--fg = args.fg or gui.black,
|
||||||
|
--bg = args.bg or gui.light,
|
||||||
|
create = function(self)
|
||||||
|
windowinput(self.x, self.y, self.nbchar)
|
||||||
|
self:render()
|
||||||
|
end,
|
||||||
|
render = function(self)
|
||||||
|
local val = tostring(self._value)
|
||||||
|
if string.len(val) < self.nbchar then
|
||||||
|
val = string.rep(" ",self.nbchar - string.len(val)) .. val;
|
||||||
|
elseif string.len(val) > self.nbchar then
|
||||||
|
val = string.sub(val, 1, self.nbchar-1) .. gui.char.ellipsis
|
||||||
|
end
|
||||||
|
windowprint(self.x, self.y, val, gui.black, gui.light);
|
||||||
|
end,
|
||||||
|
click = function(self)
|
||||||
|
local inputtype
|
||||||
|
if (type(self._value) == "number" and ((self.min ~= nil and self.min<0) or self.decimal > 0)) then
|
||||||
|
inputtype = 3 -- entry as double
|
||||||
|
elseif (type(self._value) == "number") then
|
||||||
|
inputtype = 1 -- entry as unsigned int
|
||||||
|
else
|
||||||
|
inputtype = 0 -- entry as string
|
||||||
|
end
|
||||||
|
local accept, val = windowreadline(self.x, self.y, self._value, self.nbchar, self.maxchar, self.decimal, inputtype);
|
||||||
|
|
||||||
-- "do nothing" function. Used as default callback
|
if accept then
|
||||||
donothing = function(this)
|
if (inputtype == 1 or inputtype == 3) then
|
||||||
|
val = tonumber(val)
|
||||||
|
-- round the decimal places
|
||||||
|
val = gui.round(val, self.decimal)
|
||||||
|
end
|
||||||
|
if (self.min ~= nil and val < self.min) then
|
||||||
|
val = self.min
|
||||||
|
end
|
||||||
|
if (self.max ~= nil and val > self.max) then
|
||||||
|
val = self.max
|
||||||
|
end
|
||||||
|
|
||||||
|
self._value = val
|
||||||
|
end
|
||||||
|
self:render()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
setmetatable(txtbox, gui.propvalue)
|
||||||
|
return txtbox;
|
||||||
end
|
end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui.round = function(val, ipt)
|
||||||
|
local mult = 10^ipt
|
||||||
|
return math.floor(val * mult + 0.5) / mult
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Character constants. May be useful in screens
|
||||||
|
gui.char = {
|
||||||
|
ellipsis = string.char(133), -- ...
|
||||||
|
arrowup = string.char(24),
|
||||||
|
arrowdown = string.char(25),
|
||||||
|
arrowleft = string.char(27),
|
||||||
|
arrowright = string.char(26),
|
||||||
|
vertical = string.char(18), -- double-ended arrow
|
||||||
|
horizontal = string.char(29) -- double-ended arrow
|
||||||
|
}
|
||||||
@ -1606,7 +1606,7 @@ int L_WindowInput(lua_State* L)
|
|||||||
|
|
||||||
int L_WindowReadline(lua_State* L)
|
int L_WindowReadline(lua_State* L)
|
||||||
{
|
{
|
||||||
int x, y, nbchar, maxchar;
|
int x, y, visible_size, max_size, decimal_places=0;
|
||||||
const char *valuetext;
|
const char *valuetext;
|
||||||
double valuenumber;
|
double valuenumber;
|
||||||
char text[255+1]="";
|
char text[255+1]="";
|
||||||
@ -1616,30 +1616,28 @@ int L_WindowReadline(lua_State* L)
|
|||||||
|
|
||||||
LUA_ARG_NUMBER(1, "windowreadline", x, 3, Window_width-3-8);
|
LUA_ARG_NUMBER(1, "windowreadline", x, 3, Window_width-3-8);
|
||||||
LUA_ARG_NUMBER(2, "windowreadline", y, 3, Window_height-3-8);
|
LUA_ARG_NUMBER(2, "windowreadline", y, 3, Window_height-3-8);
|
||||||
// arg 3 can be either string or number
|
// arg 3 can be either string or number, it's checked below
|
||||||
if (nb_args < (3)) return luaL_error(L, "%s: Argument %d is missing.", "windowreadline", (3));
|
if (nb_args < (3)) return luaL_error(L, "%s: Argument %d is missing.", "windowreadline", (3));
|
||||||
if (lua_isnumber(L, (3)))
|
LUA_ARG_NUMBER(4, "windowreadline", visible_size, 1, (Window_height-3-8)/8);
|
||||||
|
LUA_ARG_NUMBER(5, "windowreadline", max_size, 1, 255);
|
||||||
|
LUA_ARG_NUMBER(6, "windowreadline", decimal_places, 0, 16);
|
||||||
|
LUA_ARG_NUMBER(7, "windowreadline", input_type, 0, 4);
|
||||||
|
LUA_ARG_LIMIT (7, "windowreadline");
|
||||||
|
|
||||||
|
if (input_type == 3 || input_type == 1)
|
||||||
{
|
{
|
||||||
valuenumber = lua_tonumber(L, (3));
|
// expect number
|
||||||
sprintf(text, "%Lf", valuenumber);
|
LUA_ARG_NUMBER(3, "windowreadline", valuenumber, -DBL_MAX, DBL_MAX);
|
||||||
input_type=3;
|
Sprint_double(text, valuenumber, decimal_places, 0);
|
||||||
}
|
}
|
||||||
else if (lua_isstring(L, (3)))
|
else
|
||||||
{
|
{
|
||||||
valuetext = lua_tostring(L, (3));
|
// expect string
|
||||||
|
LUA_ARG_STRING(3, "windowreadline", valuetext);
|
||||||
if (strlen(valuetext)>255)
|
if (strlen(valuetext)>255)
|
||||||
return luaL_error(L, "%s: Argument %d, string too long.", "windowreadline", (3));
|
return luaL_error(L, "%s: Argument %d, string too long.", "windowreadline", (3));
|
||||||
strcpy(text, valuetext);
|
strcpy(text, valuetext);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return luaL_error(L, "%s: Argument %d is neither a number nor a string.", "windowreadline", (3));
|
|
||||||
LUA_ARG_NUMBER(4, "windowreadline", nbchar, 1, (Window_height-3-8)/8);
|
|
||||||
maxchar = nbchar;
|
|
||||||
if (nb_args >= 5)
|
|
||||||
{
|
|
||||||
LUA_ARG_NUMBER(5, "windowreadline", maxchar, 1, 255);
|
|
||||||
LUA_ARG_LIMIT (5, "windowreadline");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Windows_open)
|
if (!Windows_open)
|
||||||
return luaL_error(L, "windowreadline: No window is open");
|
return luaL_error(L, "windowreadline: No window is open");
|
||||||
@ -1649,10 +1647,10 @@ int L_WindowReadline(lua_State* L)
|
|||||||
Hide_cursor();
|
Hide_cursor();
|
||||||
Cursor_is_visible=0;
|
Cursor_is_visible=0;
|
||||||
}
|
}
|
||||||
result = Readline_ex(x, y, text, nbchar, maxchar, input_type, 0);
|
result = Readline_ex(x, y, text, visible_size, max_size, input_type, decimal_places);
|
||||||
Window_needs_update=1;
|
Window_needs_update=1;
|
||||||
|
|
||||||
lua_pushinteger(L, result); // 0=ESC, 1= confirm
|
lua_pushboolean(L, result); // 0=ESC, 1= confirm
|
||||||
lua_pushstring(L, text);
|
lua_pushstring(L, text);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -2280,7 +2278,10 @@ void Run_script(const char *script_subdirectory, const char *script_filename)
|
|||||||
}
|
}
|
||||||
// Clean up any remaining dialog windows
|
// Clean up any remaining dialog windows
|
||||||
while (Windows_open)
|
while (Windows_open)
|
||||||
|
{
|
||||||
Close_window();
|
Close_window();
|
||||||
|
Display_cursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Cleanup
|
// Cleanup
|
||||||
free(Brush_backup);
|
free(Brush_backup);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user