--****************************************************************************** --* * --* File: TkLua_00a.lua Revision: 1.0 * --* * --* Contents: similar to 'TkLua_00', but with a console window * --* * --* Creation: 07.03.2002 Last Modification: 07.03.2002 * --* * --* Platform: IBM-compatible PC running Windows 98SE * --* * --* Environment: Lua 4.0, TkLua 4.0 * --* * --* Author: Andreas Rozek Phone: ++49 (711) 6770682 * --* Kirschblütenweg 15 Fax: - * --* D-70569 Stuttgart EMail: Andreas.Rozek@T-Online.De * --* Germany * --* * --* URL: http://www.Andreas-Rozek.de/ * --* * --* Copyright: the software is published under the "GNU Lesser General Pub- * --* lic License" (see "http://www.fsf.org/copyleft/lesser.html" * --* for additional information) * --* * --* Comments: (none) * --* * --****************************************************************************** dofile("Lua_02_Lib.lua"); -- provides an extended 'tostring' function etc. local Icon = "./Lua.gif";-- specifying the file name is already sufficient local Title = "TkLua_00a"; local Subtitle = "a simple TkLua application"; local Status = "(watch the console window)"; --****************************************************************************** --* * --* tkconsole - a simple console window for TkLua * --* * --****************************************************************************** _TkConsole = nil; -- global reference to the console window --**** redefine the built-in write function ('writeln' and 'print' rely on it) **** local _write = write; -- preserve the old version of this function function write (...) -- call(%_write,arg); -- as a backup, send a copy to "stdout" call(tkWrite,arg); -- and now write onto the Tk console end; --**** additionally redirect any error messages to the Tk console as well **** local __ALERT = _ALERT; -- preserve the original setting function _ALERT (...) call(tkWrite,arg); -- send all error messages to the console call(%_ALERT,arg); -- as a backup, call the former '_ALERT' as well end; --**** tkWrite actually does most of the work **** function tkWrite (...) if (_TkConsole == nil) then -- build console, if not yet done local Console = tktext{ font="-*-courier-medium-r-*--11", width=80, height=25, wrap="none", borderwidth=0, -- state="disabled", -- disables editing of the output -- xscrollcommand="print('XScrollbar:set', arg); self.XScrollbar:set(arg)", -- yscrollcommand="print('YScrollbar:set', arg); self.YScrollbar:set(arg)", xscrollcommand="tremove(arg,1); tinsert(arg,1,self.XScrollbar); call(self.XScrollbar.set,arg);", yscrollcommand="tremove(arg,1); tinsert(arg,1,self.YScrollbar); call(self.YScrollbar.set,arg);", }; local XScrollbar = tkscrollbar{ orient="horizontal", command="tremove(arg,1); tinsert(arg,1,self.Console); call(self.Console.xview,arg);" }; local YScrollbar = tkscrollbar{ orient="vertical", command="tremove(arg,1); tinsert(arg,1,self.Console); call(self.Console.yview,arg);" }; Console.XScrollbar = XScrollbar; XScrollbar.Console = Console; Console.YScrollbar = YScrollbar; YScrollbar.Console = Console; _TkConsole = tktoplevel{ tkframe{ Console, YScrollbar, "/", XScrollbar; relief="sunken", borderwidth=2, geoman="grid" }, {fill="both", expand=1}; -- title=%Title.." Console Window", -- doesn't seem to work }; _TkConsole:show(); -- _TkConsole:title(%Title.." Console Window"); -- removed for library usage _TkConsole:title("Console Window"); -- this even works within a library _TkConsole.Console = Console; -- remember 'Console' for output --**** fine-tune the window layout **** tkeval('grid configure '..Console.tkname..' -sticky "news"'); tkeval('grid configure '..YScrollbar.tkname..' -sticky "ns"'); tkeval('grid configure '..XScrollbar.tkname..' -sticky "ew"'); --**** let the "Console" consume all the space within its cell **** tkeval('grid rowconfigure '.._TkConsole.objects[1].tkname..' 0 -weight 1'); tkeval('grid columnconfigure '.._TkConsole.objects[1].tkname..' 0 -weight 1'); --**** prevent console window from being removed by the user **** _TkConsole:protocol("WM_DELETE_WINDOW", "_TkConsole:iconify()"); end; for i = 1,getn(arg) do ArgType = type(arg[i]); if (ArgType == "nil") then _TkConsole.Console:insert("end","(nil)"); elseif (ArgType == "number") then _TkConsole.Console:insert("end",tostring(arg[i])); elseif (ArgType == "string") then _TkConsole.Console:insert("end",arg[i]); elseif (ArgType == "function") then _TkConsole.Console:insert("end","(function)"); elseif (ArgType == "userdata") then _TkConsole.Console:insert("end","(userdata)"); else -- ArgType == "table" _TkConsole.Console:insert("end",tostring(arg[i])); end; _TkConsole.Console:see("end"); -- makes the new text visible --**** limit console content to (approx.) 400 lines **** local LineCount = _TkConsole.Console:index("end")[1]; if (LineCount > 400) then _TkConsole.Console:delete("1.0",tostring(LineCount-399)..".0"); end; end; end; --****************************************************************************** --* * --* main program * --* * --****************************************************************************** --**** define window components **** local IconLabel = tklabel{image=Icon, anchor="center", width=32, height=32}; local TitleLabel = tklabel{Title; anchor="e", font="-*-helvetica-bold-o-*--16"}; local SubtitleLabel = tklabel{Subtitle; anchor="e", font="-*-helvetica-bold-r-*--12"}; local UpperSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local Placeholder = tkframe{relief="sunken", borderwidth=2, width=320, height=240, background="darkgray"}; local LowerSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local StatusBar = tklabel{Status; anchor="w", font="-*-helvetica-medium-r-*--11"}; --**** construct application window **** local MainWindow = tkmain{ tkframe{ IconLabel, {side="left"}, TitleLabel, {side="top", fill="x"}, SubtitleLabel, {side="top", fill="x"} }, {side="top", fill="x"}, UpperSeparator, {side="top", fill="x"}, Placeholder, {side="top", fill="both", expand=1, pady=2}, LowerSeparator, {side="top", fill="x"}, StatusBar, {side="top", fill="x"} }; --**** display application window **** MainWindow:title(Title.." - "..Subtitle); MainWindow:show(); -- also triggers a window layout --MainWindow:resizable(0,0); -- disables window size changes --MainWindow:raise(); -- brings the window into the foreground --**** pop up the console window **** print("Hello, World!"); --**** periodically print some text **** tktimer(1000,function() print(date()); end); --**** provide an explicit method to terminate this program! **** MainWindow:protocol("WM_DELETE_WINDOW", "print('done...'); tkexit()"); --**** test error redirection **** error("explicitly generated error message");