tiny lua-fltk script
Forum: Programming and Scripting
Topic: tiny lua-fltk script
started by: mikshaw
Posted by mikshaw on Aug. 16 2006,15:27
Just messing around, seeing how small I can make some useable tools.
This is a simple "run" dialog, 155 bytes (opposed to grun's 30k). Since lua-fltk calls "sh -c" for its execute command, it should support any bash syntax (keyword "should"...i've tested only environment variables).
Code Sample | #!/bin/flua w=Window{200,24} i=Input{0,0,200,24;when=When.enter_key} function i.callback() c=i.value if c>"" then execute(c.." &") exit() end end w:show() |
Posted by kuangtu on Aug. 29 2006,08:28
is there any detailed documents about flua? i want to use it create some simple graphical dialog in dsl.
Posted by mikshaw on Aug. 29 2006,14:22
I'd recommend going with MurgaLua rather than Lua-FLTK. The latter is pretty much a dead project. MurgaLua is a new project, using the latest stable versions of Lua and FLTK. < http://www.murga.org/devPages/murgaLua/index.html > In addition to this, DSL tools are (apparently) being ported over to ML. I have no idea how long this process will take, as there are many Lua files in DSL.
Neither project is well documented in itself, but you can learn a lot from the documentation of the individual Lua and FLTK packages. The trick is to figure out how the grammar used in each works together. The FLTK docs focus entirely on C++ syntax, so you have to figure out how to use Lua to control the FLTK widgets. Maybe it's not a difficult task for a "true" programmer, but I've been finding parts of it very confusing.
There is another thread in this programming forum in which I've been posting ML scripts as I learn new things about it. Maybe that will help as well.
Posted by kuangtu on Aug. 30 2006,09:20
thanks! Now i use it to create some graphic programs.
Posted by kuangtu on Aug. 31 2006,07:53
i create a simple dialog using flua script. it contains a button(OK) and a input text(address). i use address.value get the input text.(it's a address of a http server). when entering the button OK.the program will download a file.
the command is: execute('wget -P /usr/ < http://address.value/***') >
*** is the file name. is error is : the program can't resolving the address.value .the program can't download the file. so how could I write the command?
i got it. execute('wget -P /usr/ < http://'..adress.value..'***') > the .. conbinate two strings.
Posted by MakodFilu on Mar. 09 2007,00:36
Damn! I should have figured out this, lol
I even submitted a flRun.lua I was doing without noticing this: the prize of not doing my homework and being able to make a simple search. :s
Anyway, if someone is interested or is involved in the same task, I made a near clone, with .flrun history file.
The most apparent lacking feature is the pulldown button and the lack of support for parameters for flRun itself (a la flRun --help ).
Or so I thougt: I noticed /opt/grun/consfile and /opt/grun/gassoc and I am guessing what are these good for.
Posted by MakodFilu on Mar. 09 2007,19:18
BTW, I have difficulties trying to find sample code using pulldown menu buttons, neither in murgaLua nor c++, and I am having a hard time trying to grasp the concept.
Can anybody help, please?
Posted by roberts on Mar. 09 2007,21:15
Have you tried using fluid to see what it generates. See mikshaw's fltk.uci extension. Also look at the fltk site.
Posted by MakodFilu on Mar. 10 2007,20:46
About fluid... well, I suppose it was a severe case of 'blinding fulgurant splendor of the rather obvious' on my part :s I should have thought about it earlier.
Unfortunately that didn't help, but managed to overcome the issue anyway.
Fairly complete functional implementation already sent to Extensions
Posted by mikshaw on Mar. 10 2007,23:21
Would you be willing to post your script here (assuming it's Lua rather than C)? I've never had much success with pulldown menus in murgalua, even with fluid, and would be interested in seeing something that works. I'm particularly interested in the idea of dynamically created menus, but anything similar would probably be helpful.
Posted by MakodFilu on Mar. 11 2007,04:10
Sure!
Code Sample | #!/bin/lua -- Launches applications under X -- by Daniel Plata Lorenzo "MakodFilu"
version="0.9.1" max_history=10 history_file=os.getenv("HOME").."/.flrun_history" ww=250 --window width wh=100 --window height bw=60 --button width bh=25 --button height
-- L10N (Somewhat) window_text="flRun v"..version input_text="Launch Application" cancel_text="&Cancel" cancel_tooltip="Cancel launch" ok_text="&Ok" ok_tooltip="Launch application" browse_text="&Browse" browse_tooltip="Browse for command" choose_text="Choose Application"
-- Code w=fltk:Fl_Window(ww,wh,window_text)
history_table={} table_length=0 file = io.open(history_file, "r") if file then for line in file:lines() do table.insert(history_table, line) end file:close() table_length=table.maxn(history_table) if not table_length then table_length=0 end end
input = fltk:Fl_Input_Choice(10,30,230,bh,input_text) input:align(fltk.FL_ALIGN_TOP) if table_length~=0 then input:value(history_table[table_length]) -- Show last feed command -- input:mark(1) for i=1,table_length,1 do input:add(history_table[i]) end end
ok = fltk:Fl_Return_Button(ww-3*bw*1.2,wh-35,bw,bh,ok_text) ok:tooltip(ok_tooltip) ok:callback( function(ok) if input:value() == "" then io.write(string.char(7)) io.flush() else if table_length < max_history then start=1 else start=table_length-(max_history-2) -- Discard older entries end io.output(io.open(history_file,"w+")) for i=start,table_length,1 do if history_table[i]~=input:value() then io.write(history_table[i]..'\n') end end io.write(input:value()..'\n') io.close() os.execute(input:value()..' 2>/dev/null &') os.exit(0) end end)
cancel = fltk:Fl_Button(ww-2*bw*1.2,wh-35,bw,bh,cancel_text) cancel:tooltip(cancel_tooltip) cancel:callback( function(cancel) os.exit(0) end)
browse = fltk:Fl_Button(ww-1*bw*1.2,wh-35,bw,bh,browse_text) browse:tooltip(browse_tooltip) browse:callback( function(browse) input:value(fltk.fl_file_chooser(choose_text,"*",single,nil)) end)
w:show() Fl:run()
|
Posted by mikshaw on Mar. 11 2007,05:25
Thank you.
A couple of problems I'm having... Fl_Input_Choice was not accepted by my murgaLua (version 0.3). Using Fl_Input or Fl_Choice does work, though. After trying to run it a second time I get an error with line 45 (input:add(history_table[i])) if using Fl_Input, and a messed up result in history if using Fl_Choice. I haven't looked into it any further yet, but I do know the script posted does not work for me as is.
Posted by MakodFilu on Mar. 11 2007,13:36
I am using DSL 3.3RC2. I have not noticed any version disparities, but I remember reading in www.FLTK.org that Fl_Input_Choice was recently introduced into FLTK. I amazed it was already available in murgaLua wich seemengly predated the announcement.
What you are experiencing is consistent: if using Fl_Input you can't create a menu there, and if using Fl_Choice you can't get the new command to write it into the history_file. I'll try to separate that into two widgets if I can reproduce it in a clean DSL 3.3RC2. The way I did it would be not as hard as I presumed from the very start I would need two widgets for the trick.
Robert, may I ask... is the bundled DSL 3.3RC2 murgaLua newer than the DSL 3.2 one?
Posted by mikshaw on Mar. 11 2007,13:43
It's probably my version causing the trouble. I was testing on a different system, because i'm not running DSL at the moment (and was assuming all binaries involved are the same). I think this may be the xft-enabled version i'm using, which does have some minor differences. Another possible difference is if Robert compiled murgaLua for DSL rather than using one of the official binaries. I'll mess around with the script later when I get back into DSL (i'm using 3.2).
Posted by roberts on Mar. 11 2007,15:08
muragLua was updated to v0.3 in DSL v3.2. The script works fine for me.
Posted by mikshaw on Mar. 15 2007,18:16
my dumb mistake. I'd downloaded 0.3 to my slackware system the day it was released, but never actually installed it =o)
I think the Fl_Input_Choice behavior is visually odd, although its actual behavior is as expected.
Posted by MakodFilu on Mar. 15 2007,19:11
In fact it behaves like a Fl_Menu_Button and certainly that is odd, considering the beginning of the widget is far to the left and all that space is wasted fot the menu.
I expect the next revision of the toolkit adresses that.
BTW, is it correct to asume a simple regex of *: matches all text in a string before double dots and :* matches all the string after that? Not at the right machine right now, and I need exactly that. Yeah, /opt/grun/gassoc
Mmmmm, thinking about it, it will match that *AND* the double dots, and I don't want that. Will try anyway.
[Edit]: .*:?? :??.* [Edit2]: < http://www.regular-expressions.info/anchors.html > <--- This is interesting, but my head hurts already. I'll try to grasp the concept later. I need a rest. [Edit3]: ^[a-z]*:\b :\b[a-z]*$ <---- Argh! :lol: cu l8r
Posted by mikshaw on Mar. 16 2007,01:11
This might help: < http://www.lua.org/manual/5.1/manual.html#5.4.1 >
for all text in a string before a colon I'd try .*: and following a colon I'd use :.*
You may need to add a % before the colon if it is not interpreted as part of the string (i don't think this is necessary, though)
Posted by MakodFilu on Mar. 16 2007,23:45
Thanks mikshaw. Didn't work, but pointed me into the (almost) right direction. I did some dirty workaround here and there, but flRun v1.0.0 made it into usefulness
Potentially spaghetti code follows:
Code Sample | #!/bin/lua -- Launches applications under X -- by Daniel Plata Lorenzo "MakodFilu"
version="1.0.0" max_history=10 history_file=os.getenv("HOME").."/.flrun_history" gassoc_file="/opt/grun/gassoc" ww=250 --window width wh=100 --window height bw=60 --button width bh=25 --button height
-- L10N (Somewhat) window_text="flRun v"..version -- Try FireSomething for the fun of it input_text="Launch Application" cancel_text="&Cancel" cancel_tooltip="Cancel launch" ok_text="&Ok" ok_tooltip="Launch application" browse_text="&Browse" browse_tooltip="Browse for command" choose_text="Choose Application"
-- Code w=fltk:Fl_Window(ww,wh,window_text)
history_table={} table_length=0 file = io.open(history_file, "r") if file then for line in file:lines() do table.insert(history_table, line) end file:close() table_length=table.maxn(history_table) if not table_length then table_length=0 end end
gassoc_table={} file = io.open(gassoc_file, "r") if file then for line in file:lines() do table.insert(gassoc_table,{ line:sub(line:find(".*%f[:]")); line:sub(line:find("%a*$"))}) end file:close() end
input = fltk:Fl_Input_Choice(10,30,ww-20,bh,input_text) input:align(fltk.FL_ALIGN_TOP) if table_length~=0 then input:value(history_table[table_length]) -- Show last feed command for i=1,table_length,1 do input:add(history_table[i]) end end
ok = fltk:Fl_Return_Button(ww-3*bw*1.2,wh-35,bw,bh,ok_text) ok:tooltip(ok_tooltip) ok:callback( function(ok) if input:value() == "" then io.write(string.char(7)) io.flush() else if table_length < max_history then start=1 else start=table_length-(max_history-2) -- Discard older entries end io.output(io.open(history_file,"w+")) for i=start,table_length,1 do if history_table[i]~=input:value() then io.write(history_table[i]..'\n') end end io.write(input:value()..'\n') io.close() command=input:value() if command:find("%.%a*$") then ext=command:sub(command:find("%.%a*$")) for i=1,table.maxn(gassoc_table),1 do if ext == '.'..gassoc_table[i][1] then command=gassoc_table[i][2]..' '..command end end end os.execute(command..' 2>/dev/null &') os.exit(0) end end)
cancel = fltk:Fl_Button(ww-2*bw*1.2,wh-35,bw,bh,cancel_text) cancel:tooltip(cancel_tooltip) cancel:callback( function(cancel) os.exit(0) end)
browse = fltk:Fl_Button(ww-1*bw*1.2,wh-35,bw,bh,browse_text) browse:tooltip(browse_tooltip) browse:callback( function(browse) input:value(fltk.fl_file_chooser(choose_text,"*",single,nil)) end)
if not arg[1] then w:show() Fl:run() else print ("flRun v"..version.." launches applications under X\n") print "Usage flrun\n" -- [options] [file options]\n" -- print " file options Launch file directly, no dialog boxes" -- print " --persist Dialog persistance" -- print " --preload file Load file as default command" -- print " --notips Disable tooltips" -- print " --version Show version" -- print " --help Show this guide\n" end
|
Posted by roberts on Mar. 17 2007,15:40
Nice Job!
When looking through this, I thought of a way to implement console based applications. Instead of using pattern matching on the associations table build, use the colon as a delimiter, by doing this we could eliminate the need of the grun consfile and its implementation. Simply by specifying, as we do for fluxbox menu, via an aterm -e prefix. For example, in my assoc file I added the following lines:
lua:aterm -e vi lst:aterm -e vi sh:aterm -e vi
To implement this meant only to change the table build from pattern matching to delimiter. Here is the modded flrun.lua
Code Sample | #!/bin/lua -- Launches applications under X -- by Daniel Plata Lorenzo "MakodFilu"
version="1.0.0" max_history=10 history_file=os.getenv("HOME").."/.flrun_history" gassoc_file="/opt/grun/gassoc" ww=250 --window width wh=100 --window height bw=60 --button width bh=25 --button height
-- L10N (Somewhat) window_text="flRun v"..version -- Try FireSomething for the fun of it input_text="Launch Application" cancel_text="&Cancel" cancel_tooltip="Cancel launch" ok_text="&Ok" ok_tooltip="Launch application" browse_text="&Browse" browse_tooltip="Browse for command" choose_text="Choose Application"
-- Code w=fltk:Fl_Window(ww,wh,window_text)
history_table={} table_length=0 file = io.open(history_file, "r") if file then for line in file:lines() do table.insert(history_table, line) end file:close() table_length=table.maxn(history_table) if not table_length then table_length=0 end end
assoc = {} file = io.open(gassoc_file, "r") if file then for line in file:lines() do i,_ = string.find(line,":") if i then local j = #assoc+1 assoc[j] = {} assoc[j][1] = string.sub(line,1,i-1) assoc[j][2] = string.sub(line,i+1) end end end
input = fltk:Fl_Input_Choice(10,30,ww-20,bh,input_text) input:align(fltk.FL_ALIGN_TOP) if table_length~=0 then input:value(history_table[table_length]) -- Show last feed command for i=1,table_length,1 do input:add(history_table[i]) end end
ok = fltk:Fl_Return_Button(ww-3*bw*1.2,wh-35,bw,bh,ok_text) ok:tooltip(ok_tooltip) ok:callback( function(ok) if input:value() == "" then io.write(string.char(7)) io.flush() else if table_length < max_history then start=1 else start=table_length-(max_history-2) -- Discard older entries end io.output(io.open(history_file,"w+")) for i=start,table_length,1 do if history_table[i]~=input:value() then io.write(history_table[i]..'\n') end end io.write(input:value()..'\n') io.close() command=input:value() if command:find("%.%a*$") then ext=command:sub(command:find("%.%a*$")) for i=1,#assoc,1 do if ext == '.'..assoc[i][1] then command=assoc[i][2]..' '..command end end end os.execute(command..' 2>/dev/null &') os.exit(0) end end)
cancel = fltk:Fl_Button(ww-2*bw*1.2,wh-35,bw,bh,cancel_text) cancel:tooltip(cancel_tooltip) cancel:callback( function(cancel) os.exit(0) end)
browse = fltk:Fl_Button(ww-1*bw*1.2,wh-35,bw,bh,browse_text) browse:tooltip(browse_tooltip) browse:callback( function(browse) input:value(fltk.fl_file_chooser(choose_text,"*",single,nil)) end)
if not arg[1] then w:show() Fl:run() else print ("flRun v"..version.." launches applications under X\n") print "Usage flrun\n" -- [options] [file options]\n" -- print " file options Launch file directly, no dialog boxes" -- print " --persist Dialog persistance" -- print " --preload file Load file as default command" -- print " --notips Disable tooltips" -- print " --version Show version" -- print " --help Show this guide\n" end
|
Posted by MakodFilu on Mar. 17 2007,16:53
Nice! That was what I was trying, but couldn't. Took me a little to understand what you were doing. I understand the sharp operator returns table lenght. Already cleaning the code
Code Sample | #!/bin/lua -- Launches applications under X -- by Daniel Plata Lorenzo "MakodFilu"
version="1.0.1" max_history=10 history_file=os.getenv("HOME").."/.flrun_history" gassoc_file="/opt/grun/gassoc" ww=250 --window width wh=100 --window height bw=60 --button width bh=25 --button height
-- L10N (Somewhat) window_text="flRun v"..version -- Try FireSomething for the fun of it input_text="Launch Application" cancel_text="&Cancel" cancel_tooltip="Cancel launch" ok_text="&Ok" ok_tooltip="Launch application" browse_text="&Browse" browse_tooltip="Browse for command" choose_text="Choose Application"
-- Code w=fltk:Fl_Window(ww,wh,window_text)
history_table={} file = io.open(history_file, "r") if file then for line in file:lines() do table.insert(history_table, line) end file:close() end
assoc = {} -- Code by Robert Shingledecker file = io.open(gassoc_file, "r") if file then for line in file:lines() do i,_ = string.find(line,":") if i then local j = #assoc+1 assoc[j] = {} assoc[j][1] = string.sub(line,1,i-1) assoc[j][2] = string.sub(line,i+1) end end file:close() end
input = fltk:Fl_Input_Choice(10,30,ww-20,bh,input_text) input:align(fltk.FL_ALIGN_TOP) if #history_table then input:value(history_table[#history_table]) -- Show last feed command for i=1,#history_table,1 do input:add(history_table[i]) end end
ok = fltk:Fl_Return_Button(ww-3*bw*1.2,wh-35,bw,bh,ok_text) ok:tooltip(ok_tooltip) ok:callback( function(ok) if input:value() == "" then io.write(string.char(7)) io.flush() else command=input:value() io.output(io.open(history_file,"w+")) if #history_table then start=1 if #history_table >= max_history then start=#history_table-(max_history-2) -- Discard older entries end for i=start,#history_table,1 do if history_table[i]~=command then io.write(history_table[i]..'\n') end end end io.write(command..'\n') io.close() if command:find("%.%a*$") then ext=command:sub(command:find("%.%a*$")) for i=1,#assoc,1 do if ext == '.'..assoc[i][1] then command=assoc[i][2]..' '..command -- Redefine as app + doc end end end -- Note: if an .ext is found but not recognized, it would be os.execute(command..' 2>/dev/null &') -- launched anyway, as .sh os.exit(0) end end)
cancel = fltk:Fl_Button(ww-2*bw*1.2,wh-35,bw,bh,cancel_text) cancel:tooltip(cancel_tooltip) cancel:callback( function(cancel) os.exit(0) end)
browse = fltk:Fl_Button(ww-1*bw*1.2,wh-35,bw,bh,browse_text) browse:tooltip(browse_tooltip) browse:callback( function(browse) input:value(fltk.fl_file_chooser(choose_text,"*",single,nil)) end)
if not arg[1] then w:show() Fl:run() else print ("flRun v"..version.." launches applications under X\n") print "Usage flrun\n" -- [options] [file options]\n" -- print " file options Launch file directly, no dialog boxes" -- print " --persist Dialog persistance" -- print " --preload file Load file as default command" -- print " --notips Disable tooltips" -- print " --version Show version" -- print " --help Show this guide\n" end
|
Sent to extensions, as well
Posted by MakodFilu on Mar. 17 2007,20:33
Some more minor updates, more cleanup and rethought of the roberts code.
Code Sample | assoc = {} file = io.open(assoc_file, "r") if file then for line in file:lines() do i,i = line:find(":") if i then table.insert(assoc, {line:sub(1,i-1),line:sub(i+1)}) end end file:close() end
|
I am not sending it, though. Instead of annoying at Extensions I'll save those for some 'major' update (like full command line support).
|