1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828 |
- .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.8
- typedef struct Control Control;
- typedef struct Controlset Controlset;
- .sp 0.8
- 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.8
- struct Controlset
- {
- \&...
- Channel *ctl;
- Channel *data;
- \&...
- int clicktotype;
- \&...
- };
- .sp 0.8
- void initcontrols(void)
- .sp 0.8
- Controlset* newcontrolset(Image *i,
- Channel *kc, Channel *mc, Channel *rc)
- .sp 0.8
- void closecontrolset(Controlset *cs)
- .sp 0.8
- int namectlfont(Font *font, char *name)
- .sp 0.8
- int freectlfont(char *name)
- .sp 0.8
- int namectlimage(Image *image, char *name)
- .sp 0.8
- int freectlimage(char *name)
- .sp 0.8
- Control* createbox(Controlset *cs, char *name)
- .sp 0.8
- Control* createboxbox(Controlset *cs, char *name)
- .sp 0.8
- Control* createbutton(Controlset *cs, char *name)
- .sp 0.8
- Control* createcolumn(Controlset*, char*)
- .sp 0.8
- Control* createentry(Controlset *cs, char *name)
- .sp 0.8
- Control* createkeyboard(Controlset *cs, char *name)
- .sp 0.8
- Control* createlabel(Controlset *cs, char *name)
- .sp 0.8
- Control* createmenu(Controlset *cs, char *name)
- .sp 0.8
- Control* createradiobutton(Controlset *cs, char *name)
- .sp 0.8
- Control* createrow(Controlset*, char*)
- .sp 0.8
- Control* createscribble(Controlset *cs, char *name)
- .sp 0.8
- Control* createslider(Controlset *cs, char *name)
- .sp 0.8
- Control* createstack(Controlset*, char*)
- .sp 0.8
- Control* createtab(Controlset*, char *)
- .sp 0.8
- Control* createtext(Controlset *cs, char *name)
- .sp 0.8
- Control* createtextbutton(Controlset *cs, char *name)
- .sp 0.8
- void closecontrol(Control *c)
- .sp 0.8
- int ctlprint(Control*, char*, ...);
- .sp 0.8
- void ctlerror(char *fmt, ...)
- .sp 0.8
- Control* controlcalled(char *name)
- .sp 0.8
- void controlwire(Control *c, char *cname, Channel *ch)
- .sp 0.8
- void activate(Control *c)
- .sp 0.8
- void deactivate(Control *c)
- .sp 0.8
- void resizecontrolset(Controlset *cs)
- .sp 0.8
- void* ctlmalloc(uint n)
- .sp 0.8
- void* ctlrealloc(void *p, uint n)
- .sp 0.8
- char* ctlstrdup(char *s)
- .sp 0.8
- int ctldeletequits
- .EE
- .SH DESCRIPTION
- .PP
- This library provides a set of interactive
- controls for graphical displays: buttons, sliders, text entry boxes, and so on.
- It also provides aggregator controls: boxes, columns, rows and stacks of controls.
- A stack is a collection of colocated controls, of which one is normally visible.
- A
- .B controlset
- collects a group of controls that share mouse and keyboard. Each controlset
- has a separate thread of control that processes keyboard and mouse events as
- well as commands to be passed on to the controls.
- Since each controlset uses a thread, programs using the control library must
- be linked with the thread library,
- .IR thread (2).
- .PP
- Controls are manipulated by reading and writing to the control channel,
- .BR ctl ,
- of their controlset.
- Channels are defined in
- .IR thread (2).
- Each 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
- controls then use these sizes to lay out their constituent controls when called upon
- to do so. See the description of these grouping controls 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 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 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 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
- .sp
- 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
- control's
- .IR "format string" .
- For example, when the user types a newline at a text entry 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 controlset's
- .I ctl
- channel.
- One special command is recognized by the controlset itself: Sending
- the string
- .B sync
- to the
- .I ctl
- channel causes tha string to be echoed to the 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 controlset.
- Multiple commands may be sent in a single message; newline characters
- separate commands.
- For an example, see the implementation of
- .I resizecontrolset
- in the EXAMPLES section.
- Note that newline is a separator, not a terminator; the final command
- does not need a newline.
- .PP
- Messages sent to the
- .I ctl
- channel are delivered to all controls that match the
- .I destination
- field. This field is a set of names separated by spaces, tabs or newlines.
- A control matches the destination if its name or its type is among the set.
- .PP
- The recipient of a message ignores the initial
- .IB sender :
- field of the message, if present,
- making it possible to send messages generated on an
- .B event
- channel directly to another control's
- .B ctl
- channel.
- .SS Activation
- When they are created, controls are disabled: they do not respond to
- user input.
- Not all controls need to be responsive;
- for example, labels are static and a text display
- might show a log of messages but not be useful to edit.
- But buttons, entry boxes, and other text displays should be active.
- .PP
- To enable a control, call the
- .I activate
- function, which
- specifies that the
- .B Control
- .I c
- should respond to mouse and keyboard events;
- .I deactivate
- turns it off again.
- .PP
- Controls can be either
- .I revealed
- (default) or
- .IR hidden .
- When a control is hidden, it will not receive mouse or keyboard events
- and state changes or
- .I show
- commands will be ignored until the control is once again
- .IR revealed .
- Control hiding is particularly useful when different controls are overlayed,
- revealing only the `top' one.
- .PP
- The function
- .I controlwire
- permits rearrangement of the channels associated with a
- .BR Control .
- The channel
- .I cname
- (one of
- \f5"data"\fP
- or
- \f5"event"\fP)
- of
- .B Control
- .I c
- is reassigned to the channel
- .IR ch .
- There are several uses for this operation:
- one may reassign all the
- .B event
- channels to a single channel, in effect multiplexing all the events onto
- a single channel;
- or connect the
- .B event
- channel of a slider to the
- .B ctl
- channel for delivery to a text display (after setting the format for the slider's messages
- to name the destination control and the appropriate syntax for the rest of the command)
- to let the slider act as a scroll bar for the text without rerouting the messages explicitly.
- .SS Controls
- The following sections document the individual controls in alphabetical order.
- The layout of each section is a brief description of the control's behavior,
- followed by the messages it sends on
- .BR event ,
- followed by the messages it accepts via the
- .B ctl
- channel.
- The
- .B event
- messages are triggered
- .I only
- by mouse or keyboard action; messages to the
- .B ctl
- file do not cause events to be generated.
- .PP
- All controls accept the following messages:
- .TP
- .BI rect " minx miny maxx maxy
- Set the bounding rectangle for the control on the display.
- The syntax generated by the
- .B %R
- print format of the draw library is also acceptable for the coordinates.
- .TP
- .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
- Set the minimum and maximum size for automatic layout in
- .IR columns ,
- .I rows
- and
- .IR stacks .
- Without its four arguments, this command is ignored by primitive controls
- and used by grouping controls to calculate their minimum and maximum sizes
- by examining those of their constituent members.
- If all primitive controls have been assigned a size, a single size request addressed
- to the top of a layout hierarchy will assign sizes to all grouping controls.
- .TP
- .B hide
- Disable drawing of the control and ignore mouse and keyboard events
- until the control is once again revealed.
- Grouping controls (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
- request down to their constituent controls.
- .TP
- .B reveal
- This is the opposite of
- .BR hide :
- the control is displayed and mouse and keyboard operations resume.
- Grouping controls (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
- request down to their constituent controls.
- The
- .B reveal
- command for
- .I stacks
- takes an optional argument naming the control to be revealed; all
- other controls will be hidden.
- .TP
- .B show
- Display the control on its screen if not hidden.
- Some actions will also cause the controls to show themselves automatically
- (but never when the control is hidden).
- Grouping controls (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
- request down to their constituent controls.
- .PP
- Many messages are common between multiple controls.
- Such messages are described in detail here to avoid repetition.
- In the individual descriptions, only the syntax is presented.
- .TP
- .BI align " n
- Specify the alignment of (some part of) the control's display within its rectangle.
- For textual controls, the alignment specifies where the text should appear.
- For multiline text, the alignment refers to each line within its box, and only the
- horizontal part is honored.
- For other controls, the alignment affects the appearance of the display in
- a reasonable way.
- The valid alignments are words with obvious interpretations:
- .BR upperleft ,
- .BR uppercenter ,
- .BR upperright ,
- .BR centerleft ,
- .BR center ,
- .BR centerright ,
- .BR lowerleft,
- .BR lowercenter ,
- and
- .BR lowerright .
- .TP
- .BI border " n
- Inset the control (or separate constituent controls in
- .IR boxbox ,
- .I column
- and
- .I row
- controls after the next
- .I rect
- command) within its rectangle by
- .I n
- pixels, default zero.
- .TP
- .BI bordercolor " name
- Paint the border of the control with the named color, default black.
- .TP
- .BI focus " n
- The control now has (if
- .I n
- is non-zero) or does not have ( if
- .I n
- is zero) focus.
- Most controls ignore the message; there are plans to make them react.
- .TP
- .BI format " fmt
- Set the format of `value' messages sent on the
- .B event
- channel.
- By default, the format is
- .B \&"%q: value %q"
- for string-valued controls,
- .B \&"%q: value %d"
- for integer-valued controls such as buttons,
- and
- .B \&"%q: value 0x%x"
- for the keyboard and scribble controls.
- The
- .B %q
- prints the name of the control; the rest the value.
- Any supplied format string must be type-equivalent to the default for that control.
- .TP
- .BI image " name
- .TP
- .BI light " name
- .TP
- .BI mask " name
- Many controls set a background image or color for display.
- The
- .B image
- message sets the image.
- The
- .B mask
- and
- .B light
- images together specify how the control shows it is enabled:
- the
- .B light
- is printed through the
- .B mask
- when the state is `on' or `pressed'.
- Otherwise, the image appears unmodified.
- The default image is white; mask opaque; light yellow.
- .TP
- .BI font " name
- .TP
- .BI textcolor " name
- These commands set the font and color for displaying text.
- The defaults are the default
- .B font
- set up by the draw library, and black.
- .TP
- .BI value " v
- Set the value of the control. Textual images accept an arbitrary string;
- others an integral value.
- .SS Box
- A box is a trivial control that does nothing more than pass keyboard, mouse,
- and focus messages back on its
- .B event
- channel.
- Keyboard characters are sent in the format
- .IP
- .EX
- boxname: key 0x\f2nn
- .EE
- .PP
- where
- .I nn
- is the hexadecimal value of the character.
- Mouse messages are sent in the format
- .IP
- .EX
- boxname: mouse [\f2x\fP \f2y\fP] \f2but\fP \f2msec\fP
- .EE
- .PP
- where
- .IR x ,
- .IR y ,
- .IR but ,
- and
- .I msec
- are the various fields of the
- .B Mouse
- structure.
- The focus message is just
- .IP
- .EX
- boxname: focus \f2n\f1
- .EE
- .PP
- where
- .I n
- is 0 if the box has lost focus, 1 if it has acquired it.
- .PP
- The box displays within its rectangle
- an image, under mask, with specified alignment.
- The control messages it accepts are:
- .TP
- .BI align " a
- Controls the placement of the image in the rectangle (unimplemented).
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .BI show
- .TP
- .BI size " minΔx minΔy maxΔx maxΔy
- .PP
- .SS Boxbox
- A
- .B boxbox
- allows a set of controls (``boxes'') to be displayed in rows and columns within the
- rectangle of the
- .IR boxbox .
- The maximum of the minimum heights of the constituent controls determines the
- number of rows to be displayed. The number of columns is the minimum that
- allows all controls to be displayed. This aggregator works well for collections
- of buttons, labels, or textbuttons that all have a fixed height.
- .TP
- .BI add " name ...
- adds the named control to the box of controls. The display order
- is determined by the order of adding. The first named control is top left,
- the second goes below it, etc.
- It is possible to add one control to multiple grouping controls but
- the layout of the result will be quite unpredictable.
- .TP
- .BI border " width
- .TP
- .BI bordercolor " color
- .TP
- .B hide
- This command is passed on to the member controls.
- .TP
- .B image " color
- Background color displayed between member controls.
- .TP
- .B reveal
- This command is passed on to the member controls.
- .TP
- .BI separation " width
- Set the separation between member controls to
- .I n
- pixels.
- .TP
- .BI rect " minx miny maxx maxy
- The member controls are layed out within the given rectangle according to
- the minimum and maximum sizes given. If the rectangle is not large enough
- for the minimum a fatal error is currently generated.
- If the controls at their maximum size are not big enough to fit, they are top-left justified
- at their maximum size in the space given.
- Otherwise, controls will get their minimum size and be enlarged proportional
- to the extra size given by the maximum until they fit given rectangle.
- The members are separated by borders of the width established by
- .IR borderwidth .
- .TP
- .BI remove " name
- Remove the named
- control from the box.
- .TP
- .B show
- This command is passed on to the member controls.
- Show also (re)displays background and borders.
- .TP
- .BR size " \f2minΔx minΔy maxΔx maxΔy\fP
- .PP
- .SS Button
- A button is a simple control that toggles its state when mouse button 1 is pressed on its rectangle.
- Each state change triggers an event message:
- .IP
- .EX
- buttonname: value \f2n\fP
- .EE
- where
- .I n
- encodes the mouse buttons used to make the selection.
- .PP
- The button displays an image (which may of course be a simple color)
- and illuminates in the standard way when it is `on'.
- The control messages it accepts are:
- .TP
- .BI align " a
- Controls the placement of the image in the rectangle (unimplemented).
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI light " name
- .TP
- .BI mask " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .B show
- .TP
- .BI size " minΔx minΔy maxΔx maxΔy
- .TP
- .BI value " n
- Set the button to `on' (if
- .I n
- is non-zero) or `off' (if
- .I n
- is zero).
- .PP
- .SS Column
- A column is a grouping control which lays out its members vertically,
- from top to bottom. Currently, columns ignore mouse and keyboard
- events, but there are plans to allow dragging the borders (when they
- have non-zero width) between constituent members.
- .TP
- .BI add " name ...
- adds the named control to the column of controls. The vertical order
- is determined by the order of adding. The first named control goes at
- the top. It is possible to add one control to multiple grouping controls but
- the layout of the result will be quite unpredictable.
- .TP
- .BI border " width
- Set the border between members to the width given.
- .TP
- .BI bordercolor " color
- .TP
- .B hide
- .TP
- .B image " color
- Background color displayed between member controls.
- .TP
- .B reveal
- .TP
- .BI separation " width
- Set the separation between member controls to
- .I n
- pixels.
- .TP
- .B show
- These three commands are passed on to the member controls.
- Show also (re)displays the borders between members.
- .TP
- .BI rect " minx miny maxx maxy
- The member controls are layed out within the given rectangle according to
- the minimum and maximum sizes given. If the rectangle is not large enough
- for the minimum a fatal error is currently generated. However, see the example
- at the end of this man page.
- If the controls at their maximum size are not big enough to fit, they are centered
- at their maximum size in the space given.
- Otherwise, controls will get their minimum size and be enlarged proportional
- to the extra size given by the maximum until they fit given rectangle.
- The members are separated by borders of the width established by
- .IR borderwidth .
- .TP
- .BI remove " name
- Remove the named control from the column.
- .TP
- .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
- Without arguments, this command computes the minimum and
- maximum size of a column by adding the minimum and maximum
- heights to set
- .I minΔy
- and
- .IR maxΔy ,
- and it finds the largest minimum and maximum widths to set
- .I minΔy
- and
- .IR maxΔy .
- When called with arguments, it simply sets the minimum and maximum
- sizes to those given.
- .PP
- .SS Entry
- The entry control manages a single line of editable text.
- When the user hits a carriage return anywhere
- in the text, the control generates the event message,
- .IP
- .EX
- entryname: value \f2s\fP
- .EE
- .PP
- with
- .I s
- the complete text of the entry box.
- .PP
- The cursor can be moved by clicking button 1; at the moment,
- there is no way to select characters, only a typing position.
- Some control characters have special actions:
- control-H (backspace) deletes the character before the cursor;
- control-U clears the line; and
- control-V pastes the snarf buffer at the typing position.
- Most important, carriage return sends the text to the event channel.
- .PP
- To enter passwords and other secret text without displaying the
- contents, set the font to one in which all characters are the same.
- The easiest way to do this is to make a font containing only one character,
- at position 0 (NUL), since that position is used to render all
- characters not otherwise defined in the font (see
- .IR draw (2)).
- The file
- .B /lib/font/bit/lucm/passwd.9.font
- defines such a font.
- .PP
- The control messages the entry control accepts are:
- .TP
- .BI align " a
- Controls the placement of the text in the rectangle.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI data
- After receiving this message, the entry will send its value to its
- .B data
- channel as an unadorned, unquoted string.
- .TP
- .BI focus " n
- When it receives focus, the entry box displays a typing cursor.
- When it does not have focus, the cursor is not displayed.
- .TP
- .BI font " name
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .B reveal
- .TP
- .B show
- .TP
- .BI size " minΔx minΔy maxΔx maxΔy
- .TP
- .BI textcolor " name
- .TP
- .BI value " s
- Set the string displayed in the entry box.
- .SS Keyboard
- The keyboard control implements a simulated keyboard useful on palmtop devices.
- Keystrokes, generated by mouse button 1 on the simulated keys,
- are sent as event messages:
- .IP
- .EX
- keyboardname: value 0x\f2nn\f1
- .EE
- .PP
- where
- .I nn
- is the hexadecimal Unicode value of the character.
- Shift, control, and caps lock are handled by the keyboard control itself;
- shift and control affect only the next regular keystroke.
- The Alt key is unimplemented; it will become equivalent to the standard Plan 9
- key for synthesizing non-ASCII characters.
- .PP
- There are two special keys,
- .B Scrib
- and
- .BR Menu ,
- which return values
- .B 0x10000
- and
- .BR 0x10001 .
- .PP
- The image, mask, light rules are used to indicate that a key is pressed,
- but to aid clumsy fingers the keystroke is not generated until the key is released,
- so it is possible to slide the pointer to a different key to correct for bad aim.
- .PP
- The control messages the keyboard accepts are:
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI font " name1 name2
- Sets the font for the keys.
- If only one font is named, it is used for all keys.
- If two are named, the second is used for key caps with special names such
- as Shift and Enter.
- (Good choices on the Bitsy are
- .B /lib/font/bit/lucidasans/boldlatin1.6.font
- for the first and
- .B /lib/font/bit/lucidasans/unicode.6.font
- for the second argument.)
- If neither is specified, both will be set to the default global font.
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI light " name
- .TP
- .BI mask " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .B show
- .TP
- .BI size " minx miny maxx maxy
- .SS Label
- A label is like a textbutton
- .RI ( q.v. )
- that does not react, but whose value is the text it displays.
- The control messages it accepts are:
- .TP
- .BI align " a
- Controls the placement of the image in the rectangle.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI font " name
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .B show
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .BI textcolor " name
- .TP
- .BI value " s
- The value is a string that can be modified only by sending this message to the
- .B ctl
- file.
- .SS Menu
- A menu is a pop-up window containing a set of textual selections.
- When a selection is made, it removes itself from the screen and reports the selection
- by value:
- .IP
- .EX
- menuname: value \f2n\fP
- .EE
- .PP
- If no selection is made, no message is reported.
- Because it creates a window, programs using a menu must have their
- .B screen
- variable (see
- .IR graphics (2)
- and
- .IR window (2))
- set up to be refreshed properly.
- The easiest way to do this is to call
- .B getwindow
- with refresh argument
- .B Refbackup
- (see
- .IR graphics (2));
- most programs use
- .BR Refnone .
- .PP
- The control messages accepted by a menu are:
- .TP
- .BI add " text
- Add a line of
- .I text
- to the end of the menu.
- .TP
- .BI align " a
- Controls the left-right placement of the text in its rectangle.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI font " name
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .BI size " minx miny maxx maxy
- Only the origin of the rectangle is significant; menus calculate the appropriate size.
- .TP
- .BI selectcolor " name
- Set the color in which to highlight selected lines; default yellow.
- .TP
- .BI selecttextcolor " name
- Set the color in which to draw the text in selected lines; default black.
- .TP
- .B show
- Display the menu. Not usually needed unless the menu is changed while visible; use
- .I window
- instead.
- .TP
- .B window
- .TP
- .BI window " n
- With no arguments, toggle the menu's visibility; otherwise make it visible (1) or invisible (0).
- When the selection is made, the menu will remove its window automatically.
- .SS Radiobutton
- The radiobutton assembles a group of buttons or textbuttons into a
- single control with a numeric value.
- Its value is \-1 if none of the constituent buttons is pressed; otherwise
- it is the index, starting at zero, of the button that is pressed.
- Only one button may be pressed; the radiobutton manipulates its
- buttons to guarantee this.
- State changes trigger an event message:
- .IP
- .EX
- radiobuttonname: value \f2n\fP
- .EE
- .PP
- Buttons are added to the radio button using the
- .B add
- message; there is no way to remove them, although they may be turned off
- independently using
- .IR deactivate .
- The index reported in the value is defined by the order
- in which the buttons are added.
- The constituent buttons should be configured and layed out in the usual way;
- the rectangle of the radiobutton is used only to `catch' mouse events and
- should almost always correspond to the bounding box of the constituent
- buttons.
- In other words, the geometry is not maintained automatically.
- .PP
- The control messages the radiobutton accepts are:
- .TP
- .BI add " name
- Add the control with the specified
- .I name
- to the radiobutton.
- .TP
- .BI focus " n
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .B show
- .TP
- .BI value " n
- .SS Row
- A row groups a number of member controls left to right in a rectangle.
- Rows behave exactly like columns with the roles of
- .I x
- and
- .I y
- interchanged.
- .TP
- .BI add " name ...
- .TP
- .BI border " width
- .TP
- .BI bordercolor " color
- .TP
- .BI hide
- .TP
- .B image " color
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI remove " name
- .TP
- .BI reveal
- .TP
- .BI separation " width
- .TP
- .BI show
- .TP
- .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
- .SS Scribble
- The scribble control provides a region in which strokes drawn with mouse button
- 1 are interpreted as characters in the manner of
- .IR scribble (2).
- In most respects, including the format of its event messages, it is equivalent
- to a keyboard control.
- .PP
- The control messages it accepts are:
- .TP
- .BI align " a
- Controls the placement of the image in the rectangle (unimplemented).
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI font " name
- Used to display the indicia.
- .TP
- .BI hide
- TP
- .BI image " name
- .TP
- .BI linecolor " name
- The color in which to draw the strokes; default black.
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .B show
- .SS Stack
- A stack groups a number of member controls in the same shared rectangle.
- Only one of these controls will be visible (revealed), the others are hidden.
- .TP
- .BI hide
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI remove " name
- .TP
- .BR reveal " [ \f2n\fP ]
- Without argument,
- .B reveal
- is the opposite of
- .BR hide :
- it makes its selected control visible after it was hidden.
- With an argument, it makes the
- .IR n 'th
- added control visible, hiding all others.
- .TP
- .BI show
- .TP
- .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
- Without argument,
- .I size
- computes the maximum of the minimum and maximum sizes of
- its constituent controls. With arguments, it sets the size to the
- given values.
- .SS Slider
- A slider controls an integer value by dragging the mouse with a button.
- Configured appropriately, it can serve as a scroll bar with the standard
- Plan 9 behavior.
- When the value changes, an event message is sent:
- .IP
- .EX
- slidername: value \f2n\f1
- .EE
- .PP
- The slider is a good candidate for connecting to another control
- by setting its format and rewiring its
- .B event
- channel to the other's
- .B ctl
- channel.
- .PP
- The geometry of the slider is defined by three numbers:
- .B max
- is a number representing the range of the slider;
- .B vis
- is a number representing how much of what is being controlled is visible;
- and
- .B value
- is a number representing the value of the slider within its range.
- For example, if the slider is managing a textual display of 1000 lines, with
- 18 visible, and the first visible line (numbered starting form 0) is 304,
- .B max
- will be 1000,
- .B vis
- will be 18, and
- .B value
- will be 304.
- The
- .I indicator
- is the visual representation of the
- .I vis
- portion of the controlled object.
- .PP
- The control messages the slider accepts are:
- .TP
- .BI absolute " n
- If
- .I n
- is zero,
- the slider behaves like a Plan 9 scroll bar:
- button 2 sets absolute position, button 1 decreases the value,
- and button 3 increases it.
- If
- .I n
- is non-zero, all buttons behave like button 2, setting the absolute value.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI clamp " end n
- The
- .I end
- is either the word
- .B high
- or
- .BR low ;
- .I n
- sets whether that end is clamped or not.
- If it is clamped, that end of the indicator is always at its supremum.
- A standard scroll bar has neither end clamped; a volume slider would
- have its low end clamped.
- If the low end is clamped, the value of the slider is represented by the
- high end of the indicator; otherwise it is represented by the low end.
- .TP
- .BI focus " n
- .TP
- .BI format " fmt
- .TP
- .BI hide
- .TP
- .BI image " name
- .TP
- .BI indicatorcolor " name
- Set the color in which to draw the indicator; default black.
- .TP
- .BI max " n
- Set the maximum value of the range covered by the slider.
- .TP
- .BI orient " dir
- The string
- .I dir
- begins either
- .B hor
- or
- .B ver
- to specify the orientation of the slider.
- The default is vertical.
- The value always increases to the right for horizontal sliders and
- downwards for vertical sliders.
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI reveal
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .B show
- .TP
- .BI value " n
- .TP
- .BI vis " n
- Set the visible area shown by the indicator.
- .SS Tab
- A tab control combines radiobottuns with a stack of windows giving the
- appearance of tabbed controls. Currently, the tabs are positioned at the
- top of the stack. The radiobutton consists of textbuttons, the stack
- can be composed of any type of control.
- .PP
- Control messages are
- .TP
- .BI add " button control button control ...
- Adds a button to the radiobutton, and an associated control to the stack.
- Buttons and controls are numbered in the order of addition. There is
- no remove operation.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " color
- .TP
- .BI focus " n
- .TP
- .BI format " fmt
- When a format string is defined, the tab control reports which tab
- is selected using the format string (which must print a
- .B char*
- and an
- .BR int ).
- .TP
- .BI image " color
- Color between member controls.
- .TP
- .BI separation " n
- Spacing between buttons in the radiobutton and between the row of
- buttons and the stack below it.
- .TP
- .BI rect " n n n n
- .TP
- .B hide
- .TP
- .B reveal
- .TP
- .BI size " n n n n
- .TP
- .B show
- .TP
- .BI value " n
- Value must be an integer indicating which tab to bring to the top.
- .SS Text
- A text control presents a set of lines of text.
- The text cannot be edited with the keyboard, but can be
- changed by control messages.
- (A more interactive text control will be created eventually.)
- The mouse can be used to select lines of text.
- The only event message reports a state change in the selection of a line:
- .IP
- .EX
- textname: select \f2n\f1 \f2s\f1
- .EE
- .PP
- states that line
- .I n
- has changed its selection state to
- .IR s ,
- either zero (unselected) or non-zero (selected).
- The non-zero value encodes the mouse buttons that were down
- when the selection occurred.
- .PP
- .PP
- The control messages the text control accepts are:
- .TP
- .BI accumulate " s
- .TP
- .BI accumulate " n s
- .TP
- .BI add " s
- .TP
- .BI add " n s
- With one argument, append the string
- .I s
- as a new last line of the control; if
- .I n
- is specified, add the line
- .I before
- the current line
- .IR n ,
- making the new line number
- .IR n.
- The lines are zero indexed and
- .I n
- can be no greater than the current number of lines.
- .I Add
- refreshes the display, but
- .I accumulate
- does not, to avoid n-squared behavior when assembling a piece of text.
- .TP
- .BI align " a
- Controls the placement of each line of text left-to-right in its rectangle.
- Vertically, lines are tightly packed with separation set by the font's interline
- spacing.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI clear
- Delete all text.
- .TP
- .BI delete " n
- Delete line
- .IR n .
- .TP
- .BI focus " n
- .TP
- .BI font " name
- .TP
- .BI image " name
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .BI replace " n s
- Replace line
- .I n
- by the string
- .IR s .
- .TP
- .BI reveal
- .TP
- .B scroll " n
- If
- .I n
- is non-zero, the text will automatically scroll so the last line is always visible
- when new text is added.
- .TP
- .BI select " n m
- Set the selection state of line
- .I n
- to
- .IR m .
- .TP
- .BI selectcolor " name
- Set the color in which to highlight selected lines; default yellow.
- .TP
- .BI selectmode " s
- The string
- .I s
- is either
- .B single
- or
- .BR multi .
- If
- .BR single ,
- the default,
- only one line may be selected at a time; when a line is selected,
- other lines are unselected.
- If
- .BR multi ,
- the selection state of individual lines can be toggled independently.
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .B show
- .TP
- .BI textcolor " name
- .TP
- .BI topline " n
- Scroll the text so the top visible line is number
- .IR n .
- .TP
- .BI value " s
- Delete all the text in the control and then add the single line
- .IR s .
- .SS Textbutton
- A textbutton is a textual variant of a plain button.
- Each state change triggers an event message:
- .IP
- .EX
- textbuttonname: value \f2n\fP
- .EE
- where
- .I n
- encodes the mouse buttons used to make the selection.
- .PP
- Like a regular button, the value of a textbutton is an integer; the
- .I text
- is the string that appears in the button.
- It uses the image, light, mask method of indicating its state;
- moreover, the color of the text can be set to change when the button is pressed.
- The control messages it accepts are:
- .TP
- .BI align " a
- Controls the placement of the text in the rectangle.
- .TP
- .BI border " b
- .TP
- .BI bordercolor " name
- .TP
- .BI focus " n
- .TP
- .BI font " name
- .TP
- .BI format " fmt
- .TP
- .B hide
- .TP
- .BI image " name
- .TP
- .BI light " name
- .TP
- .BI mask " name
- .TP
- .BI pressedtextcolor " name
- Set the color in which to display text when the textbutton is pressed.
- .TP
- .BI rect " minx miny maxx maxy
- .TP
- .B reveal
- .TP
- .BI size " minx miny maxx maxy
- .TP
- .B show
- .TP
- .BI text " s
- Set the text displayed in the button.
- .TP
- .BI textcolor " name
- .TP
- .BI value " n
- Set the button to `on' (if
- .I n
- is non-zero) or `off' (if
- .I n
- is zero).
- .SS "Helper functions
- The function
- .I ctlerror
- is called when the library encounters an error.
- It prints the formatted message and exits the program.
- .PP
- The functions
- .IR ctlmalloc ,
- .IR ctlrealloc ,
- .IR ctlstrdup ,
- and
- .I ctlrunestrdup
- are packagings of the corresponding C library functions.
- They call
- .I ctlerror
- if they fail to allocate memory, and
- .I ctlmalloc
- zeros the memory it returns.
- .PP
- Finally, for debugging, if the global variable
- .I ctldeletequits
- is set to a non-zero value, typing a
- .SM DEL
- will cause the program to call
- .IP
- .EX
- ctlerror("delete");
- .EE
- .SS Caveat
- This library is very new and is still missing a number of important features.
- The details are all subject to change.
- Another level of library that handles geometry and has sensible default
- appearances for the controls would be useful.
- .PP
- One unusual design goal of this library was to make the controls themselves
- easy to implement.
- The reader is encouraged
- to create new controls by adapting the source to existing ones.
- .SH EXAMPLES
- This example creates two entry boxes,
- .BR top
- and
- .BR bot ,
- and copies the contents of one to the other whenever a newline is typed.
- .PP
- .EX
- #include <u.h>
- #include <libc.h>
- #include <thread.h>
- #include <draw.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- Controlset *cs;
- int ctldeletequits = 1;
- void
- resizecontrolset(Controlset*)
- {
- int i;
- Rectangle r, r1, r2;
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- r = insetrect(screen->r, 10);
- r1 = r;
- r2 = r;
- r1.max.y = r1.min.y+1+font->height+1;
- r2.min.y = r1.max.y+10;
- r2.max.y = r2.min.y+1+font->height+1;
- chanprint(cs->ctl, "top rect %R\entop show", r1);
- chanprint(cs->ctl, "bot rect %R\enbot show", r2);
- }
- void
- threadmain(int argc, char *argv[])
- {
- char *s, *args[3];
- Channel *c;
- Control *top, *bot;
- int n;
- initdraw(0, 0, "example");
- initcontrols();
- cs = newcontrolset(screen, nil, nil, nil);
- cs->clicktotype = 1;
- top = createentry(cs, "top");
- chanprint(cs->ctl, "top image paleyellow");
- chanprint(cs->ctl, "top border 1");
- bot = createentry(cs, "bot");
- chanprint(cs->ctl, "bot image paleyellow");
- chanprint(cs->ctl, "bot border 1");
- c = chancreate(sizeof(char*), 0);
- controlwire(top, "event", c);
- controlwire(bot, "event", c);
- activate(top);
- activate(bot);
- resizecontrolset(cs);
- for(;;){
- s = recvp(c);
- n = tokenize(s, args, nelem(args));
- if(n==3 && strcmp(args[1], "value")==0){
- if(strcmp(args[0], "top:") == 0)
- chanprint(cs->ctl, "bot value %q", args[2]);
- else
- chanprint(cs->ctl, "top value %q", args[2]);
- }
- }
- threadexitsall(nil);
- }
- .EE
- .PP
- A richer variant couples a text entry box to a slider.
- Since the value of a slider is its numerical setting, as a decimal number,
- all that needs changing is the setup of
- .BR bot :
- .PP
- .EX
- bot = createslider(cs, "bot");
- chanprint(cs->ctl, "bot border 1");
- chanprint(cs->ctl, "bot image paleyellow");
- chanprint(cs->ctl, "bot indicatorcolor red");
- chanprint(cs->ctl, "bot max 100");
- chanprint(cs->ctl, "bot clamp low 1");
- chanprint(cs->ctl, "bot orient horizontal");
- .EE
- .PP
- The rest is the same.
- Of course, the value of the entry box is only meaningful to the slider
- if it is also a decimal number.
- .PP
- Finally, we can avoid processing events altogether by cross-coupling
- the controls. Replace the rest of
- .B threadmain
- with this:
- .PP
- .EX
- chanprint(cs->ctl, "bot format %q", "%q: top value %q");
- chanprint(cs->ctl, "top format %q", "%q: bot value %q");
- controlwire(top, "event", cs->ctl);
- controlwire(bot, "event", cs->ctl);
- activate(top);
- activate(bot);
- resizecontrolset(cs);
- for(;;)
- yield();
- threadexitsall(nil);
- .EE
- .SH SOURCE
- .B /sys/src/libcontrol
- .SH SEE ALSO
- .IR draw (2),
- .IR frame (2),
- .IR graphics (2),
- .IR quote (2),
- .IR thread (2)
- .SH BUGS
- The library is strict about matters of formatting, argument count in messages,
- etc., and calls
- .I ctlerror
- in situations where it may be fine to ignore the error and continue.
|