murgaLua FLTK Menu System Problems
Forum: Programming and Scripting
Topic: murgaLua FLTK Menu System Problems
started by: mav_it
Posted by mav_it on Oct. 29 2007,17:38
Hi to all,
Sorry for the inconvenience, but I have a problem using callbacks in the murgaLua FLTK Menu bar. I have managed to create the menu bar with sub menus, but I'm not capable of inserting callbacks for menu items to do something useful. The code is the following (I was trying to converto to murgaLua the FLTK editor example in the FLTK documentation) :
Code Sample | #!/bin/lua
ww = 800 wh = 600
window = fltk:Fl_Double_Window(ww,wh,"My first little app")
textbuf = fltk:Fl_Text_Buffer();
--- Debug only : show something in the editing area textbuf:loadfile("editor.lua"); --editor = fltk:Fl_Text_Editor(10,30,ww-20,wh-30) editor = fltk:Fl_Text_Editor(10,30,ww-20,wh-60) editor:buffer(textbuf)
-- Callbacks for menu items function open_cb(object) end
function insert_cb(object) end
function save_cb(object) end
function saveas_cb(object) end
function view_cb(object) end
function close_cb(object) end
function quit_cb(object) if fltk.fl_choice("Are you sure ?","No",nil,"Yes") >= 1 then window:hide() end end
btn = fltk:Fl_Button((ww / 2)-30,(wh-30),60,30,"QUIT") btn:callback(quit_cb)
--- Build Up dynamically the menu: --- Dont know how to pass a table statically mb = fltk:Fl_Menu_Bar(0,0,800,30) mb:add("&File/&New File", 0, new_cb) mb:add("&File/&Insert File", 0, insert_cb) mb:add("&File/&Save File", 0, save_cb) mb:add("&File/Save File &As", 0, saveas_cb) mb:add("&File/New &View", 0, view_cb) mb:add("&File/&Close View", 0, close_cb) mb:add("&File/E&xit", 0, quit_cb)
mb:add("&Edit",0, 0, 0, FL_SUBMENU) mb:add("&Search",0, 0, 0, FL_SUBMENU) mb:add("&Help",0, 0, 0, FL_SUBMENU)
window:show() Fl:run()
|
The only callback that is not empty is the exit callback, that I have also used for the big QUIT button below: used in the QUIT button, the callback works very well, what I do wrong when I use it in the add menu function ?
Thank You in advance,
Mauro
Posted by roberts on Oct. 29 2007,18:53
Probably many ways... But I would add a callback to mb
mb:callback(menuItem)
Then you can choose to use value or text to retrieve menu item selected. Value is a numerical index into the Fl_menu array or text is the actual value of the menu item.
Make a new function like this:
function menuItem(object) print(object:value()) end
Run this from console and you will see the index value printing. Then you could use this in a case statement to determine what code or function to call.
Or use
print(object:text())
if you prefer to use the text values of the menu items.
Posted by mikshaw on Oct. 29 2007,19:06
The menu features are not fully supported at this time, including individual callbacks for individual menu items.
The only thing I've found to work so far is to make a single callback for the whole menu. In that callback function you test the menu text and run the appropriate function as a result.
for example:
Code Sample | mb:callback( function() if mb:text()=="&New File" then open_cb() elseif mb:text()=="&Insert File" then insert_cb() end end )
|
EDIT:
Quote | choose to use value or text to retrieve menu item selected | I forgot about the nurmerical value.
Posted by mav_it on Oct. 29 2007,20:36
Thank you very much to you both, I will try these methods now.
Mauro.
Posted by mav_it on Nov. 05 2007,22:54
I have managed to reach what I think is a show-stopper.. I have addressed many missing (unimplmented ? ) functions, but currently I cannot impement serching within the text buffer, since using the Fl_text_buffer:search_forward(), or Fl_textBuffer:search backward(), murgaLua gives a "search_forward nil method" error.
Anyway, by using keyboard, the editor is working, except for find/replace functions.
The portion of the code that is not working is :
Code Sample | -- SEARCH MENU CALLBACKS function find_cb() local str local fnd str = fltk.fl_input("Insert a string to search", lastsearch) if (str ~= 0) then fnd = tb:search_forward(0,str,fnd,0) if (fnd ~= 0) then tb:select(fnd, tb:word_end(fnd)) else fltk.fl_message("String " .. str .. "Not found!") end end end
|
Here, the tb:search_forward(0,str,fnd,0) (tb is a Text_Buffer variable) does not work, and MurgaLua gives:
Code Sample | attempt to call method "search_forward" : a nil value
|
I suspect that this method has not been implemented in MurgaLua.
The complete editor, should anyone find it useful for anything, is the following (note that the replace dialog is not implemented, being not able to perform the search...
Code Sample | #!/bin/lua
version = "0.01"
ww = 1024 wh = 768
title = "MURGA LUA FLTK EDITOR - "
-- -- Main window w = fltk:Fl_Double_Window(ww,wh,title) -- -- Text Buffer to hold file to edit tb = fltk:Fl_Text_Buffer();
changed = false filename = "" saved = true newfile = false lastsearch = ""
-- This will be used to hold copied / cutted text clipboard = ""
-- Editor widget will work for standard keyboard shortcuts ed = fltk:Fl_Text_Editor(10,30,ww-20,wh-60) ed:buffer(tb)
function ask_save(object) if (not saved) then if fltk.fl_choice("There are unsevd Buffers. Do you want to save ?","No",nil,"Yes") >= 1 then save_cb() end end end
-- check if we need to save to close function check_save(object) if (not saved) then if fltk.fl_choice("There are unsevd Buffers. Do you Really want to exit ?","No",nil,"Yes") >= 1 then w:hide() end else w:hide() end end
w:callback(check_save)
-- Callback for menu bar function menuItem(object) --print(mb:text() .. ' --> ' .. mb:value()) if (mb:text()=="&New File") then new_cb() -- FILE MENU elseif (mb:text()=="&Open File") then open_cb() elseif (mb:text()=="&Insert File") then insert_cb() elseif (mb:text()=="&Save File") then save_cb() elseif (mb:text()=="Save File &As") then saveas_cb() elseif (mb:text()=="E&xit") then exit_cb() -- EDIT MENU elseif (mb:text()=="&Undo") then undo_cb() elseif (mb:text()=="Cu&t") then cut_cb() elseif (mb:text()=="&Copy") then copy_cb() elseif (mb:text()=="&Paste") then paste_cb() elseif (mb:text()=="&Delete") then delete_cb() -- SEARCH MENU elseif (mb:text()=="&Find...") then find_cb() elseif (mb:text()=="Find &Again") then findagain_cb() elseif (mb:text()=="&Replace...") then replace_cb() elseif (mb:text()=="Re&place Again") then replaceagain_cb() -- HELP MENU elseif (mb:value()==24) then about_cb() end end
-- FILE MENU CALLBACKS
function new_cb() ask_save() newfile = true filename = "untitled" saved = false tb:remove(1,tb:length()) w:label(title .. filename) end
function open_cb() ask_save() filename = fltk.fl_file_chooser("Select File to open", nil, nil, 0) if (filename ~= nil) then tb:loadfile(filename) w:label(title .. filename) saved = false end end
function insert_cb() local fname = fltk.fl_file_chooser("Select File to insert", nil, nil, 0) if (fname ~= nil) then local pos = ed:insert_position() tb:insertfile(fname,pos) end end
function save_cb() if (untitled) then saveas_cb() elseif (not saved) then if (tb:savefile(filename)) then saved = true fltk.fl_message("File " .. filename .. " Saved.") else fltk.fl_alert("Error writing file " .. filename) end end end
function saveas_cb() local fname = fltk.fl_file_chooser("FILENAME TO SAVE", nil, nil, 0) if (fname ~= nil) then if (tb:savefile(fname)) then filename = fname w:label(title .. filename) saved = true fltk.fl_message("File " .. filename .. " Saved.") else fltk.fl_alert("Error writing file " .. filename) end end end
function close_cb() ask_saved() end
function exit_cb() check_save() end
-- EDIT MENU CALLBACKS function undo_cb() end
function cut_cb() if ( tb:selected() ~= 0) then clipboard = tb:selection_text() tb:remove_selection() end end
function copy_cb() if (tb:selected() ~= 0) then clipboard = tb:selection_text() end end
function paste_cb() local pos = ed:insert_position() tb:insert(pos,clipboard) end
function delete_cb() if (tb:selected() ~= 0) then tb:remove_selection() end end
-- SEARCH MENU CALLBACKS function find_cb() local str local fnd str = fltk.fl_input("Insert a string to search", lastsearch) if (str ~= 0) then fnd = tb:search_forward(0,str,fnd,0) if (fnd ~= 0) then tb:select(fnd, tb:word_end(fnd)) else fltk.fl_message("String " .. str .. "Not found!") end end end
function findagain_cb() end
function replace_cb() replace_dlg:show() end
function replaceagain_cb() end
-- HELP CALLBACKS function about_cb() fltk.fl_message("MURGA LUA FLTK EDITOR\n\nMurga Lua Version of an FLTK editor example\nBy mav_it\n\nVersion " .. version) end
--- Build Up dynamically the menu: mb = fltk:Fl_Menu_Bar(0,0,ww,30) mb:callback(menuItem)
mb:add("&File/&New File", 0, 0) mb:add("&File/&Open File", 0, 0) mb:add("&File/&Insert File", 0, 0) mb:add("&File/&Save File", 0, 0) mb:add("&File/Save File &As", 0, 0) mb:add("&File/E&xit", 0, 0)
mb:add("&Edit/&Undo", 0, 0) mb:add("&Edit/Cu&t", 0, 0) mb:add("&Edit/&Copy", 0, 0) mb:add("&Edit/&Paste", 0, 0) mb:add("&Edit/&Delete", 0, 0)
mb:add("&Search/&Find...", 0, 0) mb:add("&Search/Find &Again", 0, 0) mb:add("&Search/&Replace...", 0, 0) mb:add("&Search/Re&place Again",0, 0)
mb:add("&Help/&About", 0, 0)
--This does not seem to be implemented in MurgaLua FLTK --tb:add_modify_callback(changed_cb, w) --tb:call_modify_callbacks()
-- REPLACE DIALOG replace_dlg = fltk:Fl_Window(300, 105, "Replace") replace_find = fltk:Fl_Input(70, 10, 200, 25, "Find:") replace_with = fltk:Fl_Input(70, 40, 200, 25, "Replace:") replace_all = fltk:Fl_Button(10, 70, 90, 25, "Replace All") replace_next = fltk:Fl_Return_Button(105, 70, 120, 25, "Replace Next") replace_cancel = fltk:Fl_Button(230, 70, 60, 25, "Cancel")
-- CALLBACKS FOR REPLACE DIALOG replace_cancel:callback(function () replace_dlg:hide() end )
-- MAIN PROGRAM w:show() Fl:run()
|
Posted by mikshaw on Nov. 06 2007,02:43
I don't know much about the Fl_Text_* widgets at this point, but for searching strings I generally rely on Lua functions rather than FLTK. Check the "string manipulation" section of the Lua documentation.
Posted by roberts on Nov. 06 2007,03:36
Perhaps something along the lines of:
Code Sample | 174 function find_cb() 175 local str 176 local fnd 177 local startPos = 1 178 str = fltk.fl_input("Insert a string to search", lastsearch) 179 if (str ~= 0) then 180 -- fnd = tb:search_forward(0,str,fnd,0) 181 fnd,fndEnd = string.find(tb:text(),str,startPos) 182 if (fnd ~= nil) then 183 fnd = fnd - 1 184 tb:select(fnd, tb:word_end(fnd)) 185 else 186 fltk.fl_message("String " .. str .. "Not found!") 187 end 188 end 189 end
|
Posted by mikshaw on Nov. 06 2007,04:28
another thing I forgot to mention:
Code Sample | local str local fnd local startPos=1
|
can be more simply written:
Code Sample | local startPos,str,fnd=1 |
Posted by mav_it on Nov. 12 2007,12:15
Thank to Mikshaw and Roberts, now the example editor works, more or less.
It uses "standard" keybindings for cut/copy/paste and delete text (ctlr+x, ctlr+C, ctrl+V and Del respctively) and the menus are working.
Posted, should someone find useful, as I have found, to learn some murgaLua basics.)
Thank you again for your help, Mauro
Code Sample | #!/bin/lua
version = "0.02"
ww = 1024 wh = 768
title = "MURGA LUA FLTK EDITOR - "
-- Main window w = fltk:Fl_Double_Window(ww,wh,title)
-- Text Buffer to hold file to edit tb = fltk:Fl_Text_Buffer();
changed = false filename = "" saved = true newfile = false lastsearch = "" startPos = 1
-- This will be used to hold copied / cutted text clipboard = ""
-- Editor widget will work for standard keyboard shortcuts ed = fltk:Fl_Text_Editor(10,30,ww-20,wh-60) ed:buffer(tb)
function ask_save(object) if (not saved) then if fltk.fl_choice("There are unsevd Buffers. Do you want to save ?","No",nil,"Yes") >= 1 then save_cb() end end end
-- check if we need to save to close function check_save(object) if (not saved) then if fltk.fl_choice("There are unsaved Buffers. Do you Really want to exit ?","No",nil,"Yes") >= 1 then w:hide() end else w:hide() end end
w:callback(check_save)
-- Callback for menu bar function menuItem(object) --print(mb:text() .. ' --> ' .. mb:value()) if (mb:text()=="&New File") then new_cb()
-- FILE MENU elseif (mb:text()=="&Open File") then open_cb() elseif (mb:text()=="&Insert File") then insert_cb() elseif (mb:text()=="&Save File") then save_cb() elseif (mb:text()=="Save File &As") then saveas_cb() elseif (mb:text()=="E&xit") then exit_cb()
-- EDIT MENU elseif (mb:text()=="&Undo") then undo_cb() elseif (mb:text()=="Cu&t") then cut_cb() elseif (mb:text()=="&Copy") then copy_cb() elseif (mb:text()=="&Paste") then paste_cb() elseif (mb:text()=="&Delete") then delete_cb()
-- SEARCH MENU elseif (mb:text()=="&Find...") then find_cb() elseif (mb:text()=="Find &Again") then findagain_cb() elseif (mb:text()=="&Replace...") then replace_cb()
-- TOOLS MENU elseif (mb:text()=="&Insert Date") then insertdate_cb()
-- HELP MENU elseif (mb:text()=="&About") then about_cb() end end
-- FILE MENU CALLBACKS
function new_cb() ask_save() newfile = true filename = "untitled" saved = false tb:remove(0,tb:length()) w:label(title .. filename) end
function open_cb() ask_save() filename = fltk.fl_file_chooser("Select File to open", nil, nil, 0) if (filename ~= nil) then tb:loadfile(filename) w:label(title .. filename) saved = false end end
function insert_cb() local fname = fltk.fl_file_chooser("Select File to insert", nil, nil, 0) if (fname ~= nil) then local pos = ed:insert_position() tb:insertfile(fname,pos) end end
function save_cb() if (newfile) then saveas_cb() elseif (not saved) then if (tb:savefile(filename)) then saved = true fltk.fl_message("File " .. filename .. " Saved.") else fltk.fl_alert("Error writing file " .. filename) end end
end
function saveas_cb() local fname = fltk.fl_file_chooser("FILENAME TO SAVE", nil, nil, 0) if (fname ~= nil) then if (tb:savefile(fname)) then filename = fname w:label(title .. filename) saved = true fltk.fl_message("File " .. filename .. " Saved.") else fltk.fl_alert("Error writing file " .. filename) end end end
function close_cb() ask_saved() end
function exit_cb() check_save() end
-- EDIT MENU CALLBACKS function undo_cb() end
function cut_cb() if ( tb:selected() ~= 0) then clipboard = tb:selection_text() tb:remove_selection() end end
function copy_cb() if (tb:selected() ~= 0) then clipboard = tb:selection_text() end end
function paste_cb() local pos = ed:insert_position() tb:insert(pos,clipboard) end
function delete_cb() if (tb:selected() ~= 0) then tb:remove_selection() end end
function delete_cb() if (tb:selected() ~= 0) then tb:remove_selection() end end
-- SEARCH MENU CALLBACKS function find_cb() local str, fnd, fndEnd startPos=1 str = fltk.fl_input("Insert a string to search", lastsearch) if (str ~= nil) then --fnd = tb:search_forward(0,str,fnd,0) fnd,fndEnd = string.find(tb:text(),str,startPos) if (fnd ~= nil) then tb:select(fnd-1, fndEnd) lastsearch = str startPos = fndEnd else fltk.fl_message("String '" .. str .. "' Not found!") end end
end
function findagain_cb()
if (lastsearch == "") then find_cb() else fnd,fndEnd= string.find(tb:text(),lastsearch,startPos) if (fnd ~= nil) then tb:select(fnd-1, fndEnd) startPos = fndEnd else fltk.fl_message("String '" .. lastsearch .. "' Not found!") startPos=1 end end end
function replace_cb() replace_dlg:show() end
-- TOOLS CALLBACKS function insertdate_cb() local pos = ed:insert_position() local date = os.date() tb:insert(pos,date) end
-- HELP CALLBACKS function about_cb() fltk.fl_message("MURGA LUA FLTK EDITOR\n\nMurga Lua Version of FLTK editor example\nBy Mauro Viarizzo (mav_it)\n\nVersion " .. version) end
--- Build Up dynamically the menu: mb = fltk:Fl_Menu_Bar(0,0,ww,30) mb:callback(menuItem)
mb:add("&File/&New File", 0, 0) mb:add("&File/&Open File", 0, 0) mb:add("&File/&Insert File", 0, 0) mb:add("&File/&Save File", 0, 0) mb:add("&File/Save File &As", 0, 0) mb:add("&File/E&xit", 0, 0)
mb:add("&Edit/&Undo", 0, 0) mb:add("&Edit/Cu&t", 0, 0)
mb:add("&Edit/&Copy", 0, 0) mb:add("&Edit/&Paste", 0, 0) mb:add("&Edit/&Delete", 0, 0)
mb:add("&Search/&Find...", 0, 0) mb:add("&Search/Find &Again", 0, 0) mb:add("&Search/&Replace...", 0, 0)
mb:add("&Tools/&Insert Date", 0, 0)
mb:add("&Help/&About", 0, 0)
--This does not seem to be implemented in MurgaLua FLTK --tb:add_modify_callback(changed_cb, w) --tb:call_modify_callbacks()
-- REPLACE DIALOG replace_dlg = fltk:Fl_Window (420, 105, "Replace") replace_find = fltk:Fl_Input ( 70, 10, 330, 25, "Find:") replace_with = fltk:Fl_Input ( 70, 40, 330, 25, "Replace:") replace_all = fltk:Fl_Button ( 10, 70, 90, 25, "Replace All") replace_next = fltk:Fl_Return_Button (105, 70, 120, 25, "Replace Next") replace_skip = fltk:Fl_Button (230, 70, 120, 25, "Skip to Next") replace_cancel = fltk:Fl_Button (355, 70, 60, 25, "Cancel")
replPos=1
-- CALLBACKS FOR REPLACE DIALOG function replace_next_cb(mesg,doRepl) local findTxt = replace_find:value() local replTxt = replace_with:value() local fnd, fndEnd
fnd,fndEnd = string.find(tb:text(),findTxt,replPos) if (fnd ~= nil) then if (doRepl) then tb:replace(fnd-1, fndEnd, replTxt) end replPos = tb:word_end(fnd)+1 return true else if (mesg) then fltk.fl_message("String '" .. findTxt .. "' Not found!") end replPos = 1 return false end end
function replace_all_cb() local replaces = 0 while (replace_next_cb(false, true)) do replaces = replaces + 1 end fltk.fl_message("Replaced " .. replaces .. " occurrences") end
function replace_skip_cb() replace_next_cb(true,false) end
replace_cancel:callback(function () replace_dlg:hide() end ) replace_next:callback(function () replace_next_cb(true, true) end) replace_skip:callback(function () replace_skip_cb() end) replace_all:callback(function () replace_all_cb() end)
-- MAIN PROGRAM w:show() Fl:run()
|
Posted by roberts on Nov. 12 2007,16:37
Impressive! Thanks for sharing.
Posted by roberts on Nov. 23 2007,05:33
I added a few simple changes, started it at 800x600 and made it resizable, added support for command line arguments, which allows drag-n-drop. Going to add it to DSL as our simple notepad.
Posted by mav_it on Nov. 24 2007,14:20
Wow ! Tank You!
How do you make the windows resizable in murgaLua ? I have read documentation but didn't get how to to it.
Cheers, Mauro
Posted by roberts on Nov. 24 2007,14:30
Mauro, Thank you for your efforts and sharing.
Like I said it is very impressive. These are the simple changes I added.
11 -- Main window 12 w = fltk:Fl_Double_Window(ww,wh,title) 13 w:resizable(w)
------------------ 324 -- MAIN PROGRAM 325 if #arg == 1 then 326 filename = arg[1] 327 tb:loadfile(filename) 328 w:label(title .. filename) 329 saved=false 330 end 331 w:show() 332 Fl:run()
|