39 \- interactive graphical controls
42 .ta 4n +4n +4n +4n +4n +4n +4n
51 typedef struct Control Control;
52 typedef struct Controlset Controlset;
57 Rectangle rect; /* area on screen */
58 Rectangle size; /* min/max Dx, Dy (not a rect) */
59 Channel *event; /* chan(char*) to client */
60 Channel *data; /* chan(char*) to client */
74 void initcontrols(void)
76 Controlset* newcontrolset(Image *i, Channel *kc, Channel *mc, Channel *rc)
78 void closecontrolset(Controlset *cs)
80 int namectlfont(Font *font, char *name)
82 int freectlfont(char *name)
84 int namectlimage(Image *image, char *name)
86 int freectlimage(char *name)
88 Control* createbox(Controlset *cs, char *name)
90 Control* createboxbox(Controlset *cs, char *name)
92 Control* createbutton(Controlset *cs, char *name)
94 Control* createcolumn(Controlset*, char*)
96 Control* createentry(Controlset *cs, char *name)
98 Control* createkeyboard(Controlset *cs, char *name)
100 Control* createlabel(Controlset *cs, char *name)
102 Control* createmenu(Controlset *cs, char *name)
104 Control* createradiobutton(Controlset *cs, char *name)
106 Control* createrow(Controlset*, char*)
108 Control* createscribble(Controlset *cs, char *name)
110 Control* createslider(Controlset *cs, char *name)
112 Control* createstack(Controlset*, char*)
114 Control* createtab(Controlset*, char *)
116 Control* createtext(Controlset *cs, char *name)
118 Control* createtextbutton(Controlset *cs, char *name)
120 void closecontrol(Control *c)
122 int ctlprint(Control*, char*, ...);
124 void ctlerror(char *fmt, ...)
126 Control* controlcalled(char *name)
128 void controlwire(Control *c, char *cname, Channel *ch)
130 void activate(Control *c)
132 void deactivate(Control *c)
134 void resizecontrolset(Controlset *cs)
136 void* ctlmalloc(uint n)
138 void* ctlrealloc(void *p, uint n)
140 char* ctlstrdup(char *s)
145 This library provides a set of interactive
146 controls for graphical displays: buttons, sliders, text entry boxes, and so on.
147 It also provides aggregator
149 boxes, columns, rows and stacks of
151 A stack is a collection of co-located
153 of which one is normally visible.
158 that share mouse and keyboard. Each
160 has a separate thread of control that processes keyboard and mouse events as
161 well as commands to be passed on to the
165 uses a thread, programs using the control library must
166 be linked with the thread library,
170 are manipulated by reading and writing to the control channel,
179 has two output channels:
181 delivers messages about actions within the control (such as a button press) and
183 delivers (if requested by an appropriate write to
185 control-specific data such as the contents of a field.
187 The library provides a simple mechanism for automatic layout:
188 the minimum and maximum sizes of each simple control can be specified.
195 then use these sizes to lay out their constituent
198 to do so. See the description of these grouping
202 All messages are represented as
206 Numbers are formatted in decimal, and strings are transmitted in the
220 The sender (and the colon following it) may be omitted.
221 For example, the initial field of a text entry control called
223 could be set by sending the message,
225 .B "entry value 'Hello, world!'
231 This message contains the verb
233 and the single argument
236 To make it easy to write messages, the function
240 can be used to print formatted text to a
248 formats are convenient for properly quoting string arguments,
252 chanprint(e->event, "value %q", "Don't touch!");
259 when sending messages, and avoid dealing with the quoting explicitly.
260 In the other direction,
264 parses these messages and interprets the quotes correctly.
266 The destination of a message can be a named control, or a set of controls identified
267 by name or type. The command
269 .B "'entry slider' show
271 (note the quotation) sends the `show' command to the entry named
273 and all controls of type
275 If there were a control whose name was
277 that control would also be shown.
280 Note that we are still experimenting with destination names.
282 a destination of the form
283 \fR"`name1 name2 ⋯ type1 type2 ⋯'\fP
284 selects all controls of the named types in the control hierarchies (of columns, rows and
285 stacks) whose names precede the types.
287 Messages sent by a control on its
289 channel are of the form
296 is the name of the control sending the message;
299 describes the event. Its format can often be controlled by setting the
301 .IR "format string" .
302 For example, when the user types a newline at a text entry
306 the control sends the message
308 .B entry:\ value\ 'Hello\ again!'
312 .SS "Initialization and Control sets
320 should be called to initialize the library.
330 Each control is represented by a
332 data structure and is associated with a
334 that groups a set of controls sharing mouse, keyboard, and display.
335 Most applications will need only one
337 only those with multiple windows or unusual configurations will need
343 Its arguments are the image (usually a window)
344 on which its controls will appear, typically the
346 variable in the draw library, and three channels:
354 structures from the mouse;
359 that indicates when the window has been resized.
360 Any of the channels may be nil,
371 to initialize the keyboard and mouse
372 and connect them to the control set.
373 The mouse and resize channels must both be nil or both be non-nil.
377 frees all the controls in the control set and tears down all the associated threads.
378 It does not close the mouse and keyboard.
380 The public elements of a
392 If it is set to non-zero, the controls
393 in the set will acquire `focus' by the click-to-type paradigm.
394 Otherwise, focus is always given to the control under the mouse.
396 Commands for controls are sent through the
400 One special command is recognized by the
407 channel causes that string to be echoed to the
410 channel when all commands up to the
412 command have been processed. The string is
413 allocated and must be freed (see
415 Synchronization is necessary between sending a command, for example, to resize
416 all controls, and using their
422 must be provided by the user.
423 When the associated window is resized, the library will call
427 the function should reconnect to and redraw the window.
429 If all windows are organized in a hierachy of
435 and minimum and maximum sizes have already been supplied, only
436 the top control needs to be resized (see the
439 .SS "Fonts and images
440 Fonts and images must be given names so they may be referenced
446 associate a (unique) name with the specified font or image.
447 The association is removed by
451 The font or image is not freed by these functions, however.
455 establishes name bindings for all the colors mentioned in
462 etc., as well as masks
466 It also sets the name
468 to refer to the default
473 Each type of control has an associated creation function:
477 whose arguments are the
479 to attach it to and a globally unique name for it.
480 A control may be destroyed by calling
485 returns a pointer to the
489 or nil if no such control exists.
491 After a control is created, it must be configured using the control-specific
492 commands documented below.
493 Commands are sent to the
497 Multiple commands may be sent in a single message; newline characters
499 For an example, see the implementation of
504 Note that newline is a separator, not a terminator; the final command
505 does not need a newline.
509 channel are delivered to all controls that match the
511 field. This field is a set of names separated by spaces, tabs or newlines.
512 A control matches the destination if its name or its type is among the set.
514 The recipient of a message ignores the initial
516 field of the message, if present,
517 making it possible to send messages generated on an
519 channel directly to another control's
523 When they are created, controls are disabled: they do not respond to
525 Not all controls need to be responsive;
526 for example, labels are static and a text display
527 might show a log of messages but not be useful to edit.
528 But buttons, entry boxes, and other text displays should be active.
530 To enable a control, call the
536 should respond to mouse and keyboard events;
540 Controls can be either
544 When a control is hidden, it will not receive mouse or keyboard events
547 commands will be ignored until the control is once again
549 Control hiding is particularly useful when different controls are overlayed,
550 revealing only the `top' one.
554 permits rearrangement of the channels associated with a
565 is reassigned to the channel
567 There are several uses for this operation:
568 one may reassign all the
570 channels to a single channel, in effect multiplexing all the events onto
574 channel of a slider to the
576 channel for delivery to a text display (after setting the format for the slider's messages
577 to name the destination control and the appropriate syntax for the rest of the command)
578 to let the slider act as a scroll bar for the text without rerouting the messages explicitly.
580 The following sections document the individual controls in alphabetical order.
581 The layout of each section is a brief description of the control's behavior,
582 followed by the messages it sends on
584 followed by the messages it accepts via the
589 messages are triggered
591 by mouse or keyboard action; messages to the
593 file do not cause events to be generated.
595 All controls accept the following messages:
598 .BI rect " minx miny maxx maxy
599 Set the bounding rectangle for the control on the display.
600 The syntax generated by the
602 print format of the draw library is also acceptable for the coordinates.
604 .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
605 Set the minimum and maximum size for automatic layout in
610 Without its four arguments, this command is ignored by primitive controls
611 and used by grouping controls to calculate their minimum and maximum sizes
612 by examining those of their constituent members.
613 If all primitive controls have been assigned a size, a single size request addressed
614 to the top of a layout hierarchy will assign sizes to all grouping
618 Disable drawing of the control and ignore mouse and keyboard events
619 until the control is once again revealed.
622 (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
623 request down to their constituent
627 This is the opposite of
631 is displayed and mouse and keyboard operations resume.
634 (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
635 request down to their constituent
641 takes an optional argument naming the
651 on its screen if not hidden.
652 Some actions will also cause the
654 to show themselves automatically
660 (\f2column\fP, \f2row\fP, and \f2stack\fP) pass the
661 request down to their constituent
665 Many messages are common between multiple
667 Such messages are described in detail here to avoid repetition.
668 In the individual descriptions, only the syntax is presented.
672 Specify the alignment of (some part of) the
674 display within its rectangle.
677 the alignment specifies where the text should appear.
678 For multiline text, the alignment refers to each line within its box,
680 horizontal part is honored.
683 the alignment affects the appearance of the display in
685 The valid alignments are words with obvious interpretations:
700 (or separate constituent
710 command) within its rectangle by
712 pixels, default zero.
714 .BI bordercolor " name
715 Paint the border of the control with the named color, default black.
722 is non-zero) or does not have ( if
727 ignore the message; there are plans to make them react.
730 Set the format of `value' messages sent on the
733 By default, the format is
742 .B \&"%q: value 0x%x"
743 for the keyboard and scribble
747 prints the name of the
750 Any supplied format string must be type-equivalent to the default for that
758 Many controls set a background image or color for display.
761 message sets the image.
766 images together specify how the
771 is printed through the
773 when the state is `on' or `pressed'.
774 Otherwise, the image appears unmodified.
775 The default image is white; mask opaque; light yellow.
780 These commands set the font and color for displaying text.
781 The defaults are the default
783 set up by the draw library, and black.
788 Textual images accept an arbitrary string;
789 others an integral value.
791 A box is a trivial control that does nothing more than pass keyboard, mouse,
792 and focus messages back on its
795 Keyboard characters are sent in the format
803 is the hexadecimal value of the character.
804 Mouse messages are sent in the format
807 boxname: mouse [\f2x\fP \f2y\fP] \f2but\fP \f2msec\fP
816 are the various fields of the
819 The focus message is just
822 boxname: focus \f2n\f1
827 is 0 if the box has lost focus, 1 if it has acquired it.
829 The box displays within its rectangle
830 an image, under mask, with specified alignment.
831 The control messages it accepts are:
835 Controls the placement of the image in the rectangle (unimplemented).
839 .BI bordercolor " name
847 .BI rect " minx miny maxx maxy
853 .BI size " minΔx minΔy maxΔx maxΔy
858 allows a set of controls (``boxes'')
859 to be displayed in rows and columns within the
862 The maximum of the minimum heights of the constituent controls determines the
863 number of rows to be displayed. The number of columns is the minimum that
866 to be displayed. This aggregator works well for collections
867 of buttons, labels, or textbuttons that all have a fixed height.
868 .TF "\fLadd name ..."
871 adds the named control to the box of controls. The display order
872 is determined by the order of adding. The first named control is top left,
873 the second goes below it, etc.
874 It is possible to add one control to multiple grouping controls but
875 the layout of the result will be quite unpredictable.
879 .BI bordercolor " color
882 This command is passed on to the member controls.
885 Background color displayed between member controls.
888 This command is passed on to the member controls.
890 .BI separation " width
891 Set the separation between member controls to
895 .BI rect " minx miny maxx maxy
896 The member controls are layed out within the given rectangle according to
897 the minimum and maximum sizes given. If the rectangle is not large enough
898 for the minimum a fatal error is currently generated.
899 If the controls at their maximum size are not big enough to fit, they are top-left justified
900 at their maximum size in the space given.
901 Otherwise, controls will get their minimum size and be enlarged proportional
902 to the extra size given by the maximum until they fit given rectangle.
903 The members are separated by borders of the width established by
908 control from the box.
911 This command is passed on to the member controls.
912 Show also (re)displays background and borders.
914 .BR size " \f2minΔx minΔy maxΔx maxΔy\fP
917 A button is a simple control that toggles its state when mouse button 1 is pressed on its rectangle.
918 Each state change triggers an event message:
921 buttonname: value \f2n\fP
925 encodes the mouse buttons used to make the selection.
927 The button displays an image (which may of course be a simple color)
928 and illuminates in the standard way when it is `on'.
929 The control messages it accepts are:
933 Controls the placement of the image in the rectangle (unimplemented).
937 .BI bordercolor " name
951 .BI rect " minx miny maxx maxy
957 .BI size " minΔx minΔy maxΔx maxΔy
960 Set the button to `on' (if
962 is non-zero) or `off' (if
967 A column is a grouping control which lays out its members vertically,
968 from top to bottom. Currently, columns ignore mouse and keyboard
969 events, but there are plans to allow dragging the borders (when they
970 have non-zero width) between constituent members.
974 adds the named control to the column of controls. The vertical order
975 is determined by the order of adding. The first named control goes at
976 the top. It is possible to add one control to multiple grouping controls but
977 the layout of the result will be quite unpredictable.
980 Set the border between members to the width given.
982 .BI bordercolor " color
987 Background color displayed between member controls.
991 .BI separation " width
992 Set the separation between member controls to
997 These three commands are passed on to the member controls.
998 Show also (re)displays the borders between members.
1000 .BI rect " minx miny maxx maxy
1001 The member controls are layed out within the given rectangle according to
1002 the minimum and maximum sizes given. If the rectangle is not large enough
1003 for the minimum a fatal error is currently generated. However, see the example
1004 at the end of this man page.
1005 If the controls at their maximum size are not big enough to fit, they are centered
1006 at their maximum size in the space given.
1007 Otherwise, controls will get their minimum size and be enlarged proportional
1008 to the extra size given by the maximum until they fit given rectangle.
1009 The members are separated by borders of the width established by
1013 Remove the named control from the column.
1015 .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
1016 Without arguments, this command computes the minimum and
1017 maximum size of a column by adding the minimum and maximum
1022 and it finds the largest minimum and maximum widths to set
1026 When called with arguments, it simply sets the minimum and maximum
1027 sizes to those given.
1030 The entry control manages a single line of editable text.
1031 When the user hits a carriage return anywhere
1032 in the text, the control generates the event message,
1035 entryname: value \f2s\fP
1040 the complete text of the entry box.
1042 The cursor can be moved by clicking button 1; at the moment,
1043 there is no way to select characters, only a typing position.
1044 Some control characters have special actions:
1045 control-H (backspace) deletes the character before the cursor;
1046 control-U clears the line; and
1047 control-V pastes the snarf buffer at the typing position.
1048 Most important, carriage return sends the text to the event channel.
1050 To enter passwords and other secret text without displaying the
1051 contents, set the font to one in which all characters are the same.
1052 The easiest way to do this is to make a font containing only one character,
1053 at position 0 (NUL), since that position is used to render all
1054 characters not otherwise defined in the font (see
1057 .B /lib/font/bit/lucm/passwd.9.font
1058 defines such a font.
1060 The control messages the entry control accepts are:
1064 Controls the placement of the text in the rectangle.
1068 .BI bordercolor " name
1071 After receiving this message, the entry will send its value to its
1073 channel as an unadorned, unquoted string.
1076 When it receives focus, the entry box displays a typing cursor.
1077 When it does not have focus, the cursor is not displayed.
1087 .BI rect " minx miny maxx maxy
1093 .BI size " minΔx minΔy maxΔx maxΔy
1095 .BI textcolor " name
1098 Set the string displayed in the entry box.
1101 The keyboard control implements a simulated keyboard useful on palmtop devices.
1102 Keystrokes, generated by mouse button 1 on the simulated keys,
1103 are sent as event messages:
1106 keyboardname: value 0x\f2nn\f1
1111 is the hexadecimal Unicode value of the character.
1112 Shift, control, and caps lock are handled by the keyboard control itself;
1113 shift and control affect only the next regular keystroke.
1114 The Alt key is unimplemented; it will become equivalent to the standard Plan 9
1115 key for synthesizing non-ASCII characters.
1117 There are two special keys,
1126 The image, mask, light rules are used to indicate that a key is pressed,
1127 but to aid clumsy fingers the keystroke is not generated until the key is released,
1128 so it is possible to slide the pointer to a different key to correct for bad aim.
1130 The control messages the keyboard accepts are:
1135 .BI bordercolor " name
1139 .BI font " name1 name2
1140 Sets the font for the keys.
1141 If only one font is named, it is used for all keys.
1142 If two are named, the second is used for key caps with special names such
1144 (Good choices on the Bitsy are
1145 .B /lib/font/bit/lucidasans/boldlatin1.6.font
1147 .B /lib/font/bit/lucidasans/unicode.6.font
1148 for the second argument.)
1149 If neither is specified, both will be set to the default global font.
1161 .BI rect " minx miny maxx maxy
1167 .BI size " minx miny maxx maxy
1170 A label is like a textbutton
1172 that does not react, but whose value is the text it displays.
1173 The control messages it accepts are:
1177 Controls the placement of the image in the rectangle.
1181 .BI bordercolor " name
1191 .BI rect " minx miny maxx maxy
1197 .BI size " minx miny maxx maxy
1199 .BI textcolor " name
1202 The value is a string that can be modified only by sending this message to the
1207 A menu is a pop-up window containing a set of textual selections.
1208 When a selection is made, it removes itself from the screen and reports the selection
1212 menuname: value \f2n\fP
1215 If no selection is made, no message is reported.
1216 Because it creates a window, programs using a menu must have their
1222 set up to be refreshed properly.
1223 The easiest way to do this is to call
1225 with refresh argument
1232 The control messages accepted by a menu are:
1238 to the end of the menu.
1241 Controls the left-right placement of the text in its rectangle.
1245 .BI bordercolor " name
1257 .BI rect " minx miny maxx maxy
1261 .BI size " minx miny maxx maxy
1262 Only the origin of the rectangle is significant; menus calculate the appropriate size.
1264 .BI selectcolor " name
1265 Set the color in which to highlight selected lines; default yellow.
1267 .BI selecttextcolor " name
1268 Set the color in which to draw the text in selected lines; default black.
1271 Display the menu. Not usually needed unless the menu is changed while visible; use
1278 With no arguments, toggle the menu's visibility; otherwise make it visible (1) or invisible (0).
1279 When the selection is made, the menu will remove its window automatically.
1282 The radiobutton assembles a group of buttons or textbuttons into a
1283 single control with a numeric value.
1284 Its value is \-1 if none of the constituent buttons is pressed; otherwise
1285 it is the index, starting at zero, of the button that is pressed.
1286 Only one button may be pressed; the radiobutton manipulates its
1287 buttons to guarantee this.
1288 State changes trigger an event message:
1291 radiobuttonname: value \f2n\fP
1294 Buttons are added to the radio button using the
1296 message; there is no way to remove them, although they may be turned off
1299 The index reported in the value is defined by the order
1300 in which the buttons are added.
1301 The constituent buttons should be configured and layed out in the usual way;
1302 the rectangle of the radiobutton is used only to `catch' mouse events and
1303 should almost always correspond to the bounding box of the constituent
1305 In other words, the geometry is not maintained automatically.
1307 The control messages the radiobutton accepts are:
1311 Add the control with the specified
1321 .BI rect " minx miny maxx maxy
1325 .BI size " minx miny maxx maxy
1332 A row groups a number of member controls left to right in a rectangle.
1333 Rows behave exactly like columns with the roles of
1339 The control messages it accepts are:
1346 .BI bordercolor " color
1352 .BI rect " minx miny maxx maxy
1358 .BI separation " width
1362 .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
1365 The scribble control provides a region in which strokes drawn with mouse button
1366 1 are interpreted as characters in the manner of
1368 In most respects, including the format of its event messages, it is equivalent
1369 to a keyboard control.
1371 The control messages it accepts are:
1372 .TF "\fLlinecolor \fIname\f(CW "
1375 Controls the placement of the image in the rectangle (unimplemented).
1379 .BI bordercolor " name
1384 Used to display the indicia.
1390 .BI linecolor " name
1391 The color in which to draw the strokes; default black.
1393 .BI rect " minx miny maxx maxy
1397 .BI size " minx miny maxx maxy
1402 A stack groups a number of member controls in the same shared rectangle.
1403 Only one of these controls will be visible (revealed), the others are hidden.
1405 The control messages it accepts are:
1406 .TF "\fLreveal [\f2n\fP]"
1410 .BI rect " minx miny maxx maxy
1414 .BR reveal " [ \f2n\fP ]
1419 it makes its selected control visible after it was hidden.
1420 With an argument, it makes the
1422 added control visible, hiding all others.
1426 .BR size " [ \f2minΔx minΔy maxΔx maxΔy\fP ]
1429 computes the maximum of the minimum and maximum sizes of
1430 its constituent controls. With arguments, it sets the size to the
1434 A slider controls an integer value by dragging the mouse with a button.
1435 Configured appropriately, it can serve as a scroll bar with the standard
1437 When the value changes, an event message is sent:
1440 slidername: value \f2n\f1
1443 The slider is a good candidate for connecting to another control
1444 by setting its format and rewiring its
1446 channel to the other's
1450 The geometry of the slider is defined by three numbers:
1452 is a number representing the range of the slider;
1454 is a number representing how much of what is being controlled is visible;
1457 is a number representing the value of the slider within its range.
1458 For example, if the slider is managing a textual display of 1000 lines, with
1459 18 visible, and the first visible line (numbered starting form 0) is 304,
1468 is the visual representation of the
1470 portion of the controlled object.
1472 The control messages the slider accepts are:
1479 the slider behaves like a Plan 9 scroll bar:
1480 button 2 sets absolute position, button 1 decreases the value,
1481 and button 3 increases it.
1484 is non-zero, all buttons behave like button 2, setting the absolute value.
1488 .BI bordercolor " name
1498 sets whether that end is clamped or not.
1499 If it is clamped, that end of the indicator is always at its supremum.
1500 A standard scroll bar has neither end clamped; a volume slider would
1501 have its low end clamped.
1502 If the low end is clamped, the value of the slider is represented by the
1503 high end of the indicator; otherwise it is represented by the low end.
1513 .BI indicatorcolor " name
1514 Set the color in which to draw the indicator; default black.
1517 Set the maximum value of the range covered by the slider.
1526 to specify the orientation of the slider.
1527 The default is vertical.
1528 The value always increases to the right for horizontal sliders and
1529 downwards for vertical sliders.
1531 .BI rect " minx miny maxx maxy
1535 .BI size " minx miny maxx maxy
1542 Set the visible area shown by the indicator.
1545 A tab control combines radiobottuns with a stack of windows giving the
1546 appearance of tabbed controls. Currently, the tabs are positioned at the
1547 top of the stack. The radiobutton consists of textbuttons, the stack
1548 can be composed of any type of control.
1550 Control messages are
1553 .BI add " button control button control ...
1554 Adds a button to the radiobutton, and an associated control to the stack.
1555 Buttons and controls are numbered in the order of addition. There is
1556 no remove operation.
1560 .BI bordercolor " color
1565 When a format string is defined, the tab control reports which tab
1566 is selected using the format string (which must print a
1572 Color between member controls.
1575 Spacing between buttons in the radiobutton and between the row of
1576 buttons and the stack below it.
1589 Value must be an integer indicating which tab to bring to the top.
1592 A text control presents a set of lines of text.
1593 The text cannot be edited with the keyboard, but can be
1594 changed by control messages.
1595 (A more interactive text control will be created eventually.)
1596 The mouse can be used to select lines of text.
1597 The only event message reports a state change in the selection of a line:
1600 textname: select \f2n\f1 \f2s\f1
1605 has changed its selection state to
1607 either zero (unselected) or non-zero (selected).
1608 The non-zero value encodes the mouse buttons that were down
1609 when the selection occurred.
1611 The control messages the text control accepts are:
1612 .TF "\fLselectmode \fIs\fP "
1616 .BI accumulate " n s
1621 With one argument, append the string
1623 as a new last line of the control; if
1625 is specified, add the line
1629 making the new line number
1631 The lines are zero indexed and
1633 can be no greater than the current number of lines.
1635 refreshes the display, but
1637 does not, to avoid n-squared behavior when assembling a piece of text.
1640 Controls the placement of each line of text left-to-right in its rectangle.
1641 Vertically, lines are tightly packed with separation set by the font's interline
1646 .BI bordercolor " name
1661 .BI rect " minx miny maxx maxy
1674 is non-zero, the text will automatically scroll so the last line is always visible
1675 when new text is added.
1678 Set the selection state of line
1683 .BI selectcolor " name
1684 Set the color in which to highlight selected lines; default yellow.
1696 only one line may be selected at a time; when a line is selected,
1697 other lines are unselected.
1700 the selection state of individual lines can be toggled independently.
1702 .BI size " minx miny maxx maxy
1706 .BI textcolor " name
1709 Scroll the text so the top visible line is number
1713 Delete all the text in the control and then add the single line
1717 A textbutton is a textual variant of a plain button.
1718 Each state change triggers an event message:
1721 textbuttonname: value \f2n\fP
1726 encodes the mouse buttons used to make the selection.
1728 Like a regular button, the value of a textbutton is an integer; the
1730 is the string that appears in the button.
1731 It uses the image, light, mask method of indicating its state;
1732 moreover, the color of the text can be set to change when the button is pressed.
1733 The control messages it accepts are:
1737 Controls the placement of the text in the rectangle.
1741 .BI bordercolor " name
1757 .BI pressedtextcolor " name
1758 Set the color in which to display text when the textbutton is pressed.
1760 .BI rect " minx miny maxx maxy
1764 .BI size " minx miny maxx maxy
1769 Set the text displayed in the button.
1771 .BI textcolor " name
1774 Set the button to `on' (if
1776 is non-zero) or `off' (if
1779 .SS "Helper functions
1782 is called when the library encounters an error.
1783 It prints the formatted message and exits the program.
1791 are packagings of the corresponding C library functions.
1794 if they fail to allocate memory, and
1796 zeros the memory it returns.
1798 Finally, for debugging, if the global variable
1800 is set to a non-zero value, typing a
1802 will cause the program to call
1808 This library is very new and is still missing a number of important features.
1809 The details are all subject to change.
1810 Another level of library that handles geometry and has sensible default
1811 appearances for the controls would be useful.
1813 One unusual design goal of this library was to make the controls themselves
1815 The reader is encouraged
1816 to create new controls by adapting the source to existing ones.
1818 This example creates two entry boxes,
1822 and copies the contents of one to the other whenever a newline is typed.
1830 #include <keyboard.h>
1831 #include <control.h>
1835 int ctldeletequits = 1;
1838 resizecontrolset(Controlset*)
1841 Rectangle r, r1, r2;
1843 if(getwindow(display, Refnone) < 0)
1844 sysfatal("resize failed: %r");
1845 r = insetrect(screen->r, 10);
1848 r1.max.y = r1.min.y+1+font->height+1;
1849 r2.min.y = r1.max.y+10;
1850 r2.max.y = r2.min.y+1+font->height+1;
1851 chanprint(cs->ctl, "top rect %R\entop show", r1);
1852 chanprint(cs->ctl, "bot rect %R\enbot show", r2);
1856 threadmain(int argc, char *argv[])
1863 initdraw(0, 0, "example");
1865 cs = newcontrolset(screen, nil, nil, nil);
1866 cs->clicktotype = 1;
1868 top = createentry(cs, "top");
1869 chanprint(cs->ctl, "top image paleyellow");
1870 chanprint(cs->ctl, "top border 1");
1871 bot = createentry(cs, "bot");
1872 chanprint(cs->ctl, "bot image paleyellow");
1873 chanprint(cs->ctl, "bot border 1");
1875 c = chancreate(sizeof(char*), 0);
1876 controlwire(top, "event", c);
1877 controlwire(bot, "event", c);
1881 resizecontrolset(cs);
1885 n = tokenize(s, args, nelem(args));
1886 if(n==3 && strcmp(args[1], "value")==0){
1887 if(strcmp(args[0], "top:") == 0)
1888 chanprint(cs->ctl, "bot value %q", args[2]);
1890 chanprint(cs->ctl, "top value %q", args[2]);
1893 threadexitsall(nil);
1897 A richer variant couples a text entry box to a slider.
1898 Since the value of a slider is its numerical setting, as a decimal number,
1899 all that needs changing is the setup of
1903 bot = createslider(cs, "bot");
1904 chanprint(cs->ctl, "bot border 1");
1905 chanprint(cs->ctl, "bot image paleyellow");
1906 chanprint(cs->ctl, "bot indicatorcolor red");
1907 chanprint(cs->ctl, "bot max 100");
1908 chanprint(cs->ctl, "bot clamp low 1");
1909 chanprint(cs->ctl, "bot orient horizontal");
1912 The rest is the same.
1913 Of course, the value of the entry box is only meaningful to the slider
1914 if it is also a decimal number.
1916 Finally, we can avoid processing events altogether by cross-coupling
1917 the controls. Replace the rest of
1922 chanprint(cs->ctl, "bot format %q", "%q: top value %q");
1923 chanprint(cs->ctl, "top format %q", "%q: bot value %q");
1925 controlwire(top, "event", cs->ctl);
1926 controlwire(bot, "event", cs->ctl);
1930 resizecontrolset(cs);
1934 threadexitsall(nil);
1937 .B /sys/src/libcontrol
1945 The library is strict about matters of formatting, argument count in messages,
1948 in situations where it may be fine to ignore the error and continue.