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).

Powered by Ikonboard 3.1.2a
Ikonboard © 2001 Jarvis Entertainment Group, Inc.