--****************************************************************************** --* * --* File: TkLua_06.lua Revision: 1.0 * --* * --* Contents: a simple ASCII table display * --* * --* Creation: 12.03.2002 Last Modification: 12.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: event binding is not yet possible, and characters like \, { * --* and } cause hefty crashes (within Tcl/Tk) * --* * --****************************************************************************** dofile("Lua_02_Lib.lua"); -- provides an extended 'tostring' function etc. dofile("TkLua_00_Lib.lua"); -- provides a simple console for TkLua programs local Icon = "./Lua.gif";-- specifying the file name is already sufficient local Title = "TkLua_06"; local Subtitle = "a simple ASCII table display"; local Status = "click on a character to see its ASCII code"; --**** list of names for all ASCII control characters **** ControlSet = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; --**** list of hexadecimal digits **** HexDigit = { [0]='0';'1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; --****************************************************************************** --* * --* CellSize calculates cell size required to display any ASCII character * --* * --****************************************************************************** function CellSize (CellFont, CellMetrics) local Width,Height = 0,0; --**** calculate required cell width from the foreseen content **** for Col = 0,15 do Width = max(Width,tonumber(tkeval("font measure "..CellFont.." {-"..HexDigit[Col].."}")[1])); end; -- for Row = 0,15 do -- Width = max(Width,tonumber(tkeval("font measure "..CellFont.." {-"..HexDigit[Row].."}")[1])); -- end; for Code = 1,getn(ControlSet) do Width = max(Width,tonumber(tkeval("font measure "..CellFont.." {"..ControlSet[Code].."}")[1])); end; for Code = getn(ControlSet),255 do local Character = strchar(Code); if (Character == "{") then Character = " "; end; -- causes problems if (Character == "}") then Character = " "; end; -- causes problems if (Character == "\\") then Character = " "; end; -- causes problems Width = max(Width,tonumber(tkeval("font measure "..CellFont.." {"..Character.."}")[1])); end; --**** getting the cell height is easy **** Height = CellMetrics.linespace; --**** that's it! **** return Width, Height; end; --****************************************************************************** --* * --* MetricsFrom constructs a "FontMetrics" structure from 'tkeval' result * --* * --****************************************************************************** function MetricsFrom (ArgList) local Result = {}; for i = 1,getn(ArgList)-1,2 do Result[strsub(ArgList[i],2)] = tonumber(ArgList[i+1]); end; return Result; end; --****************************************************************************** --* * --* processClick processes mouse clicks on an ASCII table entry * --* * --****************************************************************************** function processClick (ArgList) print("ArgList = ", ArgList); 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 ContentArea = tkcanvas{}; -- will be filled later local CellFont = tkeval("font create -family {Helvetica} -size 11 -weight {normal}")[1]; local CellMetrics = MetricsFrom(tkeval("font metrics "..CellFont)); local CellWidth,CellHeight = CellSize(CellFont,CellMetrics); local CanvasWidth = CellWidth+3+(16*CellWidth+15)+3+CellWidth; local dW = CellWidth/2; local CanvasHeight = CellHeight+3+(16*CellHeight+15)+3+CellHeight; local dH = CellHeight/2; ContentArea.width,ContentArea.height=CanvasWidth,CanvasHeight; 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"}, ContentArea, {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 --**** it's time to fill the 'ContentArea' **** ContentArea:create("line",CellWidth+2,0, CellWidth+2,CanvasHeight-1); ContentArea:create("line",CanvasWidth-CellWidth-2,0, CanvasWidth-CellWidth-2,CanvasHeight-1); ContentArea:create("line",0,CellHeight+2, CanvasWidth-1,CellHeight+2); ContentArea:create("line",0,CanvasHeight-CellHeight-2, CanvasWidth-1,CanvasHeight-CellHeight-2); local BoldFont = "Helvetica 9 bold";--does not conflict with actual cell sizes for Row = 0,15 do local Label = "-"..HexDigit[Row]; ContentArea:create("text", dW,CellHeight+3+Row*(CellHeight+1)+dH, "-text", Label, "-font", BoldFont); ContentArea:create("text",CanvasWidth-1-dW,CellHeight+3+Row*(CellHeight+1)+dH, "-text", Label, "-font", BoldFont); end; for Col = 0,15 do local Label = "-"..HexDigit[Col]; ContentArea:create("text",CellWidth+3+Col*(CellWidth+1)+dW,dH, "-text", Label, "-font", BoldFont); ContentArea:create("text",CellWidth+3+Col*(CellWidth+1)+dW,CanvasHeight-1-dH, "-text", Label, "-font", BoldFont); end; for Code = 0,getn(ControlSet)-1 do local Row,Col = floor(Code/16),mod(Code,16); local Tag = format("code_0x%02X", Code); ContentArea:create("text", -- x position is moved by +1 pixel CellWidth+3+Col*(CellWidth+1)+dW+1, CellHeight+3+Row*(CellHeight+1)+dH, "-text", ControlSet[Code+1], "-tags", Tag ); -- ContentArea:bind(Tag, "", "processClick(arg)"); -- not yet possible end; for Code = getn(ControlSet),255 do local Row,Col = floor(Code/16),mod(Code,16); local Tag = format("code_0x%02X", Code); local Character = strchar(Code); if (Character == "{") then Character = " "; end; -- causes problems if (Character == "}") then Character = " "; end; -- causes problems if (Character == "\\") then Character = " "; end; -- causes problems ContentArea:create("text", -- x position is moved by +1 pixel CellWidth+3+Col*(CellWidth+1)+dW+1, CellHeight+3+Row*(CellHeight+1)+dH, "-text", Character, "-tags", Tag ); -- ContentArea:bind(Tag, "", "processClick(arg)"); -- not yet possible end; --**** provide an explicit method to terminate this program! **** MainWindow:protocol("WM_DELETE_WINDOW", "print('done...'); tkexit()");