.TH CONTROL 2.SH NAMEControl,Controlset,activate,closecontrol,closecontrolset,controlcalled,controlwire,createbox,createboxbox,createbutton,createcolumn,createentry,createkeyboard,createlabel,createmenu,createradiobutton,createrow,createscribble,createslider,createstack,createtab,createtext,createtextbutton,ctlerror,ctlmalloc,ctlrealloc,ctlstrdup,ctlprint,deactivate,freectlfont,freectlimage,initcontrols,namectlfont,namectlimage,newcontrolset,resizecontrolset\- interactive graphical controls.SH SYNOPSIS.EX.ta 4n +4n +4n +4n +4n +4n +4n#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <keyboard.h>#include <mouse.h>#include <control.h>.sp 0.3typedef struct Control Control;typedef struct Controlset Controlset;.sp 0.3struct Control{ char *name; Rectangle rect; /* area on screen */ Rectangle size; /* min/max Dx, Dy (not a rect) */ Channel *event; /* chan(char*) to client */ Channel *data; /* chan(char*) to client */ \&...};.sp 0.3struct Controlset{ \&... Channel *ctl; Channel *data; \&... int clicktotype; \&...};.sp 0.3void initcontrols(void).sp 0.3Controlset* newcontrolset(Image *i, Channel *kc, Channel *mc, Channel *rc).sp 0.3void closecontrolset(Controlset *cs).sp 0.3int namectlfont(Font *font, char *name).sp 0.3int freectlfont(char *name).sp 0.3int namectlimage(Image *image, char *name).sp 0.3int freectlimage(char *name).sp 0.3Control* createbox(Controlset *cs, char *name).sp 0.3Control* createboxbox(Controlset *cs, char *name).sp 0.3Control* createbutton(Controlset *cs, char *name).sp 0.3Control* createcolumn(Controlset*, char*).sp 0.3Control* createentry(Controlset *cs, char *name).sp 0.3Control* createkeyboard(Controlset *cs, char *name).sp 0.3Control* createlabel(Controlset *cs, char *name).sp 0.3Control* createmenu(Controlset *cs, char *name).sp 0.3Control* createradiobutton(Controlset *cs, char *name).sp 0.3Control* createrow(Controlset*, char*).sp 0.3Control* createscribble(Controlset *cs, char *name).sp 0.3Control* createslider(Controlset *cs, char *name).sp 0.3Control* createstack(Controlset*, char*).sp 0.3Control* createtab(Controlset*, char *).sp 0.3Control* createtext(Controlset *cs, char *name).sp 0.3Control* createtextbutton(Controlset *cs, char *name).sp 0.3void closecontrol(Control *c).sp 0.3int ctlprint(Control*, char*, ...);.sp 0.3void ctlerror(char *fmt, ...).sp 0.3Control* controlcalled(char *name).sp 0.3void controlwire(Control *c, char *cname, Channel *ch).sp 0.3void activate(Control *c).sp 0.3void deactivate(Control *c).sp 0.3void resizecontrolset(Controlset *cs).sp 0.3void* ctlmalloc(uint n).sp 0.3void* ctlrealloc(void *p, uint n).sp 0.3char* ctlstrdup(char *s).sp 0.3int ctldeletequits;.EE.SH DESCRIPTIONThis library provides a set of interactivecontrols for graphical displays: buttons, sliders, text entry boxes, and so on.It also provides aggregator.BR Control s:boxes, columns, rows and stacks of.BR Control s.A stack is a collection of co-located.BR Control s,of which one is normally visible.A.B Controlsetcollects a group of.BR Control sthat share mouse and keyboard. Each.B Controlsethas a separate thread of control that processes keyboard and mouse events aswell as commands to be passed on to the.BR Control s.Since each.B Controlsetuses a thread, programs using the control library mustbe linked with the thread library,.IR thread (2)..PP.BR Control sare manipulated by reading and writing to the control channel,.BR ctl ,of their.BR Controlset ..BR Channel sare defined in.IR thread (2).Each.B Controlhas two output channels:.B Eventdelivers messages about actions within the control (such as a button press) and.B datadelivers (if requested by an appropriate write to.BR ctl )control-specific data such as the contents of a field..PPThe library provides a simple mechanism for automatic layout:the minimum and maximum sizes of each simple control can be specified..BR Boxbox ,.BR row ,.B columnand.B stack.BR Control sthen use these sizes to lay out their constituent.BR Control swhen called uponto do so. See the description of these grouping.BR Control sfor further details..SS "Message formatAll messages are represented as.SM UTF\c-8text.Numbers are formatted in decimal, and strings are transmitted in thequoted form of.IR quote (2)..PPMessages sent to a.B Controlsetare of the form,.IP.IR sender :.I destination.I verb.RI [ argument\&... ].LPThe sender (and the colon following it) may be ommitted.For example, the initial field of a text entry control called.I entrycould be set by sending the message,.IP.B "entry value 'Hello, world!'.PPto its.BR Controlset 's.B ctlfile.This message contains the verb.B valueand the single argument.B "Hello, world!".PPTo make it easy to write messages, the function.IR chanprint(see.IR thread (2))can be used to print formatted text to a.BR Controlset 'schannel..PPThe.B %qand.B %Qformats are convenient for properly quoting string arguments,as in.IP.EXchanprint(e->event, "value %q", "Don't touch!");.EE.PPIt is wise to use.B %qalways instead of.BR %swhen sending messages, and avoid dealing with the quoting explicitly.In the other direction,.B tokenize(see.IR getfields (2))parses these messages and interprets the quotes correctly..PPThe destination of a message can be a named control, or a set of controls identifiedby name or type. The command.IP.B "'entry slider' show.PP(note the quotation) sends the `show' command to the entry named.I entryand all controls of type.IR slider .If there were a control whose name was.I sliderthat control would also be shown..LP\f2Note that we are still experimenting with destination names.One proposal is thata destination of the form\fR"`name1 name2 ⋯ type1 type2 ⋯'\fPselects all controls of the named types in the control hierarchies (of columns, rows andstacks) whose names precede the types..LPMessages sent by a control on its.B eventchannel are of the form.IP.IB sender :.IB event.PPThe.I senderis the name of the control sending the message;the.I eventdescribes the event. Its format can often be controlled by setting the.BR Control 's.IR "format string" .For example, when the user types a newline at a text entry.B Controlnamed.BR entry,the control sends the message.IP.B entry:\ value\ 'Hello\ again!'on its.B eventchannel..SS "Initialization and Control setsAfter.B initdraw(see.IR graphics (2))is called,the function.I initcontrolsshould be called to initialize the library.It calls.I quotefmtinstallto install the.B %qand.B %Qformats; see.IR quote (2)..PPEach control is represented by a.B Controldata structure and is associated with a.B Controlsetthat groups a set of controls sharing mouse, keyboard, and display.Most applications will need only one.BR Controlset ;only those with multiple windows or unusual configurations will needmore than one.The function.I newcontrolsetcreates a.BR Controlset .Its arguments are the image (usually a window)on which its controls will appear, typically the.B screenvariable in the draw library, and three channels:.BR kc ,a channel of.B Runesfrom the keyboard;.BR mc ,a channel of.B Mousestructures from the mouse;and.BR rc ,a channel of.B intthat indicates when the window has been resized.Any of the channels may be nil,in which case.I newcontrolsetwill call.B initkeyboardand/or.B initmouse(see.IR keyboard (2)and.IR mouse (2))to initialize the keyboard and mouseand connect them to the control set.The mouse and resize channels must both be nil or both be non-nil..PPThe function.I closecontrolsetfrees all the controls in the control set and tears down all the associated threads.It does not close the mouse and keyboard..PPThe public elements of a.B Controlsetare the flag.BR clicktotype ,and the.I ctland.I datachannels..PP.I Clicktotypeis zero by default.If it is set to non-zero, the controlsin the set will acquire `focus' by the click-to-type paradigm.Otherwise, focus is always given to the control under the mouse..PPCommands for controls are sent through the.BR Controlset 's.I ctlchannel.One special command is recognized by the.B Controlsetitself: Sendingthe string.B syncto the.I ctlchannel causes tha string to be echoed to the.BR Controlset 's.I datachannel when all commands up to the.I synccommand have been processed. The string isallocated and must be freed (see.IR malloc (2)).Synchronization is necessary between sending a command, for example, to resizeall controls, and using their.I rectfields..PPThe function.I resizecontrolsetmust be provided by the user.When the associated window is resized, the library will call.I resizecontrolsetwith the affected.BR Controlset ;the function should reconnect to and redraw the window..PPIf all windows are organized in a hierachy of.IR boxboxes ,.IR columns ,.I rowsand.IR stacks ,and minimum and maximum sizes have already been supplied, onlythe top control needs to be resized (see the.I rectcommand below)..SS "Fonts and imagesFonts and images must be given names so they may be referencedin messages.The functions.I namectlfontand.I namectlimageassociate a (unique) name with the specified font or image.The association is removed by.I freectlfontand.IR freectlimage .The font or image is not freed by these functions, however..PPThe function.I initcontrolsestablishes name bindings for all the colors mentioned in.BR <draw.h> ,such as.BR black ,.BR white ,.BR red ,.BR yellow ,etc., as well as masks.B transparentand.BR opaque .It also sets the name.B fontto refer to the default.B fontvariable set up by.BR initdraw ..SS CreationEach type of control has an associated creation function:.IR createbutton ,.IR createentry ,etc.,whose arguments are the.B Controlsetto attach it to and a globally unique name for it.A control may be destroyed by calling.IR closecontrol ..PPThe function.I controlcalledreturns a pointer to the.B Controlwith the given.IR name ,or nil if no such control exists..SS ConfigurationAfter a control is created, it must be configured using the control-specificcommands documented below.Commands are sent to the.B ctlchannel of the.BR Controlset .Multiple commands may be sent in a single message; newline charactersseparate commands.For an example, see the implementation of.I resizecontrolsetLines 1–500 of 1948. Load more
.TH CONTROL 2 .SH NAME Control, Controlset, activate, closecontrol, closecontrolset, controlcalled, controlwire, createbox, createboxbox, createbutton, createcolumn, createentry, createkeyboard, createlabel, createmenu, createradiobutton, createrow, createscribble, createslider, createstack, createtab, createtext, createtextbutton, ctlerror, ctlmalloc, ctlrealloc, ctlstrdup, ctlprint, deactivate, freectlfont, freectlimage, initcontrols, namectlfont, namectlimage, newcontrolset, resizecontrolset \- interactive graphical controls .SH SYNOPSIS .EX .ta 4n +4n +4n +4n +4n +4n +4n #include <u.h> #include <libc.h> #include <draw.h> #include <thread.h> #include <keyboard.h> #include <mouse.h> #include <control.h> .sp 0.3 typedef struct Control Control; typedef struct Controlset Controlset; .sp 0.3 struct Control { char *name; Rectangle rect; /* area on screen */ Rectangle size; /* min/max Dx, Dy (not a rect) */ Channel *event; /* chan(char*) to client */ Channel *data; /* chan(char*) to client */ \&... }; .sp 0.3 struct Controlset { \&... Channel *ctl; Channel *data; \&... int clicktotype; \&... }; .sp 0.3 void initcontrols(void) .sp 0.3 Controlset* newcontrolset(Image *i, Channel *kc, Channel *mc, Channel *rc) .sp 0.3 void closecontrolset(Controlset *cs) .sp 0.3 int namectlfont(Font *font, char *name) .sp 0.3 int freectlfont(char *name) .sp 0.3 int namectlimage(Image *image, char *name) .sp 0.3 int freectlimage(char *name) .sp 0.3 Control* createbox(Controlset *cs, char *name) .sp 0.3 Control* createboxbox(Controlset *cs, char *name) .sp 0.3 Control* createbutton(Controlset *cs, char *name) .sp 0.3 Control* createcolumn(Controlset*, char*) .sp 0.3 Control* createentry(Controlset *cs, char *name) .sp 0.3 Control* createkeyboard(Controlset *cs, char *name) .sp 0.3 Control* createlabel(Controlset *cs, char *name) .sp 0.3 Control* createmenu(Controlset *cs, char *name) .sp 0.3 Control* createradiobutton(Controlset *cs, char *name) .sp 0.3 Control* createrow(Controlset*, char*) .sp 0.3 Control* createscribble(Controlset *cs, char *name) .sp 0.3 Control* createslider(Controlset *cs, char *name) .sp 0.3 Control* createstack(Controlset*, char*) .sp 0.3 Control* createtab(Controlset*, char *) .sp 0.3 Control* createtext(Controlset *cs, char *name) .sp 0.3 Control* createtextbutton(Controlset *cs, char *name) .sp 0.3 void closecontrol(Control *c) .sp 0.3 int ctlprint(Control*, char*, ...); .sp 0.3 void ctlerror(char *fmt, ...) .sp 0.3 Control* controlcalled(char *name) .sp 0.3 void controlwire(Control *c, char *cname, Channel *ch) .sp 0.3 void activate(Control *c) .sp 0.3 void deactivate(Control *c) .sp 0.3 void resizecontrolset(Controlset *cs) .sp 0.3 void* ctlmalloc(uint n) .sp 0.3 void* ctlrealloc(void *p, uint n) .sp 0.3 char* ctlstrdup(char *s) .sp 0.3 int ctldeletequits; .EE .SH DESCRIPTION This library provides a set of interactive controls for graphical displays: buttons, sliders, text entry boxes, and so on. It also provides aggregator .BR Control s: boxes, columns, rows and stacks of .BR Control s. A stack is a collection of co-located .BR Control s, of which one is normally visible. A .B Controlset collects a group of .BR Control s that share mouse and keyboard. Each .B Controlset has a separate thread of control that processes keyboard and mouse events as well as commands to be passed on to the .BR Control s. Since each .B Controlset uses a thread, programs using the control library must be linked with the thread library, .IR thread (2). .PP .BR Control s are manipulated by reading and writing to the control channel, .BR ctl , of their .BR Controlset . .BR Channel s are defined in .IR thread (2). Each .B Control has two output channels: .B Event delivers messages about actions within the control (such as a button press) and .B data delivers (if requested by an appropriate write to .BR ctl ) control-specific data such as the contents of a field. .PP The library provides a simple mechanism for automatic layout: the minimum and maximum sizes of each simple control can be specified. .BR Boxbox , .BR row , .B column and .B stack .BR Control s then use these sizes to lay out their constituent .BR Control s when called upon to do so. See the description of these grouping .BR Control s for further details. .SS "Message format All messages are represented as .SM UTF\c -8 text. Numbers are formatted in decimal, and strings are transmitted in the quoted form of .IR quote (2). .PP Messages sent to a .B Controlset are of the form, .IP .IR sender : .I destination .I verb .RI [ argument \&... ] .LP The sender (and the colon following it) may be ommitted. For example, the initial field of a text entry control called .I entry could be set by sending the message, .IP .B "entry value 'Hello, world!' .PP to its .BR Controlset 's .B ctl file. This message contains the verb .B value and the single argument .B "Hello, world!" .PP To make it easy to write messages, the function .IR chanprint (see .IR thread (2)) can be used to print formatted text to a .BR Controlset 's channel. .PP The .B %q and .B %Q formats are convenient for properly quoting string arguments, as in .IP .EX chanprint(e->event, "value %q", "Don't touch!"); .EE .PP It is wise to use .B %q always instead of .BR %s when sending messages, and avoid dealing with the quoting explicitly. In the other direction, .B tokenize (see .IR getfields (2)) parses these messages and interprets the quotes correctly. .PP The destination of a message can be a named control, or a set of controls identified by name or type. The command .IP .B "'entry slider' show .PP (note the quotation) sends the `show' command to the entry named .I entry and all controls of type .IR slider . If there were a control whose name was .I slider that control would also be shown. .LP \f2 Note that we are still experimenting with destination names. One proposal is that a destination of the form \fR"`name1 name2 ⋯ type1 type2 ⋯'\fP selects all controls of the named types in the control hierarchies (of columns, rows and stacks) whose names precede the types. .LP Messages sent by a control on its .B event channel are of the form .IP .IB sender : .IB event .PP The .I sender is the name of the control sending the message; the .I event describes the event. Its format can often be controlled by setting the .BR Control 's .IR "format string" . For example, when the user types a newline at a text entry .B Control named .BR entry, the control sends the message .IP .B entry:\ value\ 'Hello\ again!' on its .B event channel. .SS "Initialization and Control sets After .B initdraw (see .IR graphics (2)) is called, the function .I initcontrols should be called to initialize the library. It calls .I quotefmtinstall to install the .B %q and .B %Q formats; see .IR quote (2). .PP Each control is represented by a .B Control data structure and is associated with a .B Controlset that groups a set of controls sharing mouse, keyboard, and display. Most applications will need only one .BR Controlset ; only those with multiple windows or unusual configurations will need more than one. The function .I newcontrolset creates a .BR Controlset . Its arguments are the image (usually a window) on which its controls will appear, typically the .B screen variable in the draw library, and three channels: .BR kc , a channel of .B Runes from the keyboard; .BR mc , a channel of .B Mouse structures from the mouse; and .BR rc , a channel of .B int that indicates when the window has been resized. Any of the channels may be nil, in which case .I newcontrolset will call .B initkeyboard and/or .B initmouse (see .IR keyboard (2) and .IR mouse (2)) to initialize the keyboard and mouse and connect them to the control set. The mouse and resize channels must both be nil or both be non-nil. .PP The function .I closecontrolset frees all the controls in the control set and tears down all the associated threads. It does not close the mouse and keyboard. .PP The public elements of a .B Controlset are the flag .BR clicktotype , and the .I ctl and .I data channels. .PP .I Clicktotype is zero by default. If it is set to non-zero, the controls in the set will acquire `focus' by the click-to-type paradigm. Otherwise, focus is always given to the control under the mouse. .PP Commands for controls are sent through the .BR Controlset 's .I ctl channel. One special command is recognized by the .B Controlset itself: Sending the string .B sync to the .I ctl channel causes tha string to be echoed to the .BR Controlset 's .I data channel when all commands up to the .I sync command have been processed. The string is allocated and must be freed (see .IR malloc (2)). Synchronization is necessary between sending a command, for example, to resize all controls, and using their .I rect fields. .PP The function .I resizecontrolset must be provided by the user. When the associated window is resized, the library will call .I resizecontrolset with the affected .BR Controlset ; the function should reconnect to and redraw the window. .PP If all windows are organized in a hierachy of .IR boxboxes , .IR columns , .I rows and .IR stacks , and minimum and maximum sizes have already been supplied, only the top control needs to be resized (see the .I rect command below). .SS "Fonts and images Fonts and images must be given names so they may be referenced in messages. The functions .I namectlfont and .I namectlimage associate a (unique) name with the specified font or image. The association is removed by .I freectlfont and .IR freectlimage . The font or image is not freed by these functions, however. .PP The function .I initcontrols establishes name bindings for all the colors mentioned in .BR <draw.h> , such as .BR black , .BR white , .BR red , .BR yellow , etc., as well as masks .B transparent and .BR opaque . It also sets the name .B font to refer to the default .B font variable set up by .BR initdraw . .SS Creation Each type of control has an associated creation function: .IR createbutton , .IR createentry , etc., whose arguments are the .B Controlset to attach it to and a globally unique name for it. A control may be destroyed by calling .IR closecontrol . .PP The function .I controlcalled returns a pointer to the .B Control with the given .IR name , or nil if no such control exists. .SS Configuration After a control is created, it must be configured using the control-specific commands documented below. Commands are sent to the .B ctl channel of the .BR Controlset . Multiple commands may be sent in a single message; newline characters separate commands. For an example, see the implementation of .I resizecontrolset