forsyth20121205-174063a80cc13 years agoHistory
1248 lines · 32.0 KB · Text
RawDownload
.nr dT 4.nr P1 .2i.de EX.nr x \\$1v\\!h0c n \\nx 0...nr Pd \n(PD.de FG		\" start figure caption: .FG filename.ps verticalsize.KF.BP \\$1 \\$2.sp .5v.EX \\$2v.ps -1.vs -1...de fg		\" end figure caption (yes, it is clumsy).ps.vs.br.KE...de Tk		\" Tk option name and option.CW \\$1.I \\$2 \\$3...de Tc		\" Tk command string.IP "\\f(CW\\$1\\fP \\$2" \w'\f(CWburble\fP'u.br...de Kp		\" Keypress.IP "\\f(CW\\$1\\fP" \w'\f(CWKeypress\fP'u.br...de d0		\" no gap between paragraphs.nr PD 0...de d1		\" restore gap.nr PD \n(Pd...ds Op "\fR[\fP\fIoptions ...\fP\fR]\fP.TLAn Overview of Limbo/Tk.AU.I "Lucent Technologies Inc.".brRevised June 2000 by Vita Nuova.SHOverview.LPLimbo/Tk is a concise and powerful way to construct graphical user interfaces without directly using the Draw module primitives.Standard interfaces can quickly be created from collections of menus, buttons, and other widgets that are part of Limbo/Tk's visual toolkit.It is modelled on Ousterhout's Tk 4.0 [1,2], commonly deployedwith the scripting language Tcl as `Tcl/Tk'.Although inspired by Tk 4.0, Inferno's Tk implementation is new, and unrelated to Ousterhout's.It is intended to be used with the new programming language Limbo, not Tcl.Limbo/Tk applications makeextensive use of Limbo's concurrent programming constructions and data structures,and that is reflected in the interface.Section 9 of Volume 1 of the.I "Inferno Programmer's Manual"provides a detailed reference for Limbo/Tk.This paper provides an overview of its use in some simple staged examples, andconcludes witha summary of the differences between the Limbo/Tk implementation and Tk 4.0.In the rest of this paper, `Tk' refers to Limbo/Tk, and `Tk 4.0' refers to Ousterhout'soriginal implementation..NH 1The Limbo/Tk environment.LPLimbo applications access Tk by means of a built-in module,.CW "$Tk" .The standard distribution also includes the window manager.CW "wm"and the Limbo module.CW Wmlib .Unlike.CW Tk ,.CW Wmlibis not built-in but implemented in Limbo by.CW /appl/lib/wmlib.b .It simplifies and standardises the construction of windowed applications;it also contains some graphical devices such as tabbed notebooks not provideddirectly by Limbo/Tk.The essentials of both.CW Tkand.CW Wmlibare discussed here..LPProgrammers usually need only three functions from the.CW Tkmodule:.IP •.CW toplevel.brCreates a graphical window \- a Tk `top level' widget \-that can be used to build a Limbo/Tk application.The function returns a reference to an adt.CW "\%Tk->Toplevel"adt that represents the window in subsequent Tk operations..IP •.CW cmd.brCreates and arranges graphic objects within the toplevel window by processing Limbo/Tk command strings.The interface to Tk is primarily the passing of strings betweenthe application and Tkof the toolkit using.CW cmd .Each call to.CW cmdreturns a string representing the result of the Tk command;a string starting with.CW ! ' `diagnoses an error..IP •.CW namechan.brGives a name within Tk (in the scope of a given window) to a Limbo.CW "chan of string"that Tk commands can use to send data to a Limbo program..LPOther functions in the module have more specialised uses that will not be discussed here.For instance,.CW "mouse"and.CW "keyboard"are used by a window manager to send mouse and keyboard eventsto the Tk implementation for distribution to applications..LPEven.CW toplevelis not commonly used in the window manager environment:a function.CW Wmlib->titlebarprovides the usual interface to.CW toplevel .The low-level interface will be described first, for completeness,then the normal case using.CW titlebar ..NH 1Basic Limbo/Tk.LPThis section shows a simple Tk application that uses only the fundamental Tk functions..NH 2Preliminaries.LPThe example assumes that the.CW "Tk"module is loaded as.CW "tk" :.P1include "tk.m";	tk:	Tk;	...init(ctxt: ref Draw->Context, nil: list of string){	tk =  load Tk Tk->PATH;	...}.P2.NH 2Creating a toplevel.LPThe following fragment makes the Limbo identifier.CW "top"refer to a new.CW "ref Tk->Toplevel"for use in later Tk commands:.P1	top := tk->toplevel(ctxt.screen, "-x 150 -y 150");.P2The upper left corner of this window will be at point (150, 150), where (0,0) is the upper left corner of the screen;.I xcoordinates increase from left to right, and.I ycoordinates increase from top to bottom..LPIn general,.CW "Tk->toplevel"takes a screen argument and a string containing further options, and it returns a reference to a top-level Limbo/Tk widget on the given screen.The options argument contains.Tk -option valuepairs, such as.CW "-relief raised" .As well as the generic options,.CW "toplevel"accepts the options.Tk -x intand.Tk -y intto specify the upper left corner of the toplevel widget, where (0,0) is the top left corner of the screen,and.Tk -debug boolto cause a trace of all Tk commands to be printed,if the boolean value is true..NH 2Creating a named channel to Tk.LPThe following fragment creates a.CW "chan of string"called.CW "c" ,then associates the name.CW "cmdchan"within Tk with the Limbo channel.CW "c" :.P1	c := chan of string;	tk->namechan(top, c, "cmdchan");.P2The named channel.CW "cmdchan"can now be used in a special Tk.CW sendcommandto send strings to be processed by a Limbo program, typically notifying it of an event.Note that the Limbo identifer name need not match the name given to Tk,although it is invariably easier to follow the code if the two are the same..NH 2Defining and positioning widgets.LPThe following fragment uses.CW "tk->cmd"to define four widgets: two buttons, a label, and an entry widget. The widgets are positioned in their parent window (in this case the toplevel window.CW "top" )using the Tk command.CW "pack" :.P1.ps -1.vs -1	\fI# define widgets\fP	tk->cmd(top, "button .b1 -text Exit -command {send cmdchan exit}");	tk->cmd(top, "button .b2 -text Send -command {send cmdchan send}");	tk->cmd(top, "label .l -text {Name: }");	tk->cmd(top, "entry .e"); 	\fI# bind newline character in entry widget to command\fP	tk->cmd(top, "bind .e <Key-\en> {send cmdchan send}"); 	\fI# pack widgets\fP	tk->cmd(top, "pack .b1 .b2 .l .e -side left; update");.ps +1.vs +1.P2This particular pack command packs the widgets named.CW ".b1" ,.CW ".b2" ,.CW ".l" ,and.CW ".e"into the.CW "top"window beginning at the left side. The.CW "update"command forces Tk to update the screen right away. The result is shown in Figure 1..FG "f1.ps" 0.21i.ce.I "Figure 1. Two buttons, a label and an entry widget.".fg.LPEntering a newline (`return' or `enter' key)\-the character.CW \en ' `in Limbo\-in the entry box results in the execution of the Tk command.CW "{send cmdchan send}" ,because of the binding set by.CW "bind .e <Key-\en>"previously executed by.CW tk->cmd .The.CW "bind"command is often used to bind specific widget events (including key presses, mouse button presses, and mouse motion) to Tk.CW sendcommands..NH 2Processing widget events.LPThis next fragment defines what will happen when a user selects either the.CW "Exit"or the.CW "Send"buttons. The.CW "Exit"behaviour is simple: the program ends. If a user touches.CW Send ,the program executes.CW "tk->cmd"to get whatever text is in the entry widget.CW ".e"then prints it to standard output..P1	for(;;) {		s := <- c;		case s {		"exit" =>			return; 		"send" =>			sys->print("name was: %s\en", tk->cmd(top, ".e get"));		}	}.P2.NH 1Example - using Tk and Wmlib.LPThis section uses both Tk and Wmlib to create a simple window manager application with a titlebar, including resize and exit buttons.This is the usual way to create new windows..NH 1Preamble.LPThe example assumes that the.CW "Tk"module is loaded as before, as module variable.CW "tk" ,but furthermore that the.CW "Wmlib"module is also loaded, as.CW "wmlib" :.P1include "tk.m";	tk:	Tk;include "wmlib.m";	wmlib: Wmlib;	...	tk =  load Tk  Tk->PATH;	wmlib = load Wmlib Wmlib->PATH;	wmlib->init();.P2Note that.CW wmlib->initis called once to initialise the.CW wmlibmodule just loaded, before any other functions are called..LPIn window manager applications the.CW Tk->toplevelfunction is not normally used directly.Instead, a window manager interface is used to create boththe top level widget and a channel to receive events from the window manager.The.CW titlebarfunction has the signature:.ps -1.vs -1.P1	titlebar(scr: Draw->Screen, tkargs: string, title: string, buts: int):		(ref Tk->Toplevel, chan of string);.P2.vs +1.ps +1The.CW Screenis the one on which the window is to be created, normally theone passed in the.CW Contextparameter to a program's.CW initfunction.The.I tkargsparameter can control the position and appearance of the window,but is best left nil (or the empty string) to use the window manager'sdefaults (see.I wmlib (2)for details otherwise),including automatic placement.The.I titlestring gives the title that appears in the title bar.Finally,.I butsis a bit set that selects the buttons to appear.The value.CW Wmlib->Applgives the usual resize and hide buttons;the exit (delete) button always appears.The following is used in the example:.P1	(top, titlechan) := wmlib->titlebar(ctxt.screen, nil,					"Text Browser", Wmlib->Appl);.P2Note that.CW titlebarreturns a tuple.The first element is a reference to the Tk top level widgetfor use in later Tk commands.The second element of the tupleis a Limbo channel of type.CW "chan of string"that passes window manager events to the application..LPThe channel.CW "titlechan"is used by.CW "wmlib"to send messages, but it is normally necessaryto create a channel to Tk to receive events from widgets the application creates:.P1	cmdchan := chan of string;	tk->namechan(top, cmdchan, "cmdchan");.P2.NH 2Defining and positioning widgets.LPThe function.CW "Wmlib->tkcmds"takes two arguments, a.CW "ref Tk->Toplevel"that identifies a top level window,and an.CW "array of string" .Each element of the array is a Tk command acceptable to.CW "Tk->cmd" ;.CW Wmlib->tkcmdssimply applies itto each element of the array..LPMost of the following fragment consists of Tk command strings that are members of the array of strings.CW "tk_config" .The comments describe the widgets being created. Not all widgets and menu items in this example are functional.The last line executes the array of commands using.CW "wmlib->tkcmds" :.nr dP +1.nr dV +1p.P1	tk_config := array[] of { 	\fI# define menubar frame, widget frame, text frame\fP	"frame .mbar -relief groove -bd 2",	"frame .w",	"frame .text", 	\fI# define and pack menus\fP	"menubutton .file -text File -menu .file.m",	"menubutton .edit -text Edit -menu .edit.m",	"menubutton .help -text Help -menu .help.m", 	"menu .file.m",	".file.m add command -label Send -command {send cmdchan send}",	".file.m add command -label Exit -command {send cmdchan exit}",	"menu .edit.m",	".edit.m add command -label Cut", 	"menu .help.m",	".help.m add command -label Index -underline 0", 	"pack .file .edit -side left -in .mbar; update",	"pack .help -side right -in .mbar",.P3 	\fI# define and pack buttons and text entry box (for file name)\fP	"button .b1 -text Send -command {send cmdchan send}",	"button .b2 -text Open -command {send cmdchan open}",	"label .l -text {Name: }", 	"entry .e",	"bind .e <Key-\en> {send cmdchan open}", 	"pack .b1 .b2 .l .e -side left -in .w",.P3 	\fI# define and pack text panel and its scrollbar\fP	"text .t -yscrollcommand {.scroll set} -bg white",	"scrollbar .scroll -command {.t yview}",	"pack .scroll -side left -fill y -in .text",	"pack .t -side right -in .text -expand 1 -fill both", 	\fI# pack frames\fP	"pack .text -side bottom -fill both -expand 1",	"pack .mbar .w -fill x; update",	"pack propagate . 0",	}; 	\fI# run the Tk commands\fP	wmlib->tkcmds(top, tk_config);.P2.nr dP -1.nr dV -1pThe result of executing these Tk commands is shown in Figure 2..LPThe arrays defining Tk widgets are sometimes made global to a modulewhen they can sensibly be used by several functions.It is also common to use small Limbo functions to replicatesimilar widgets by building Tk commands from the value of parameters,using Limbo string concatenationor.CW sys->sprint ..FG "f2.ps" 2.16i.ce.I "Figure 2. A Wm application with a menu bar, a tool bar, and a text window.".fg.LP.NH 2Processing widget events.LPThis fragment uses an.CW "alt"block to wait for strings to arrive from either.CW "titlechan"or

Lines 1–500 of 1248.