source: trunk/kitgen/8.x/blt/generic/bltTreeViewStyle.c@ 196

Last change on this file since 196 was 175, checked in by demin, 12 years ago

initial commit

File size: 76.6 KB
Line 
1
2/*
3 * bltTreeViewStyle.c --
4 *
5 * This module implements styles for treeview widget cells.
6 *
7 * Copyright 1998-1999 Lucent Technologies, Inc.
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby
11 * granted, provided that the above copyright notice appear in all
12 * copies and that both that the copyright notice and warranty
13 * disclaimer appear in supporting documentation, and that the names
14 * of Lucent Technologies or any of their entities not be used in
15 * advertising or publicity pertaining to distribution of the software
16 * without specific, written prior permission.
17 *
18 * Lucent Technologies disclaims all warranties with regard to this
19 * software, including all implied warranties of merchantability and
20 * fitness. In no event shall Lucent Technologies be liable for any
21 * special, indirect or consequential damages or any damages
22 * whatsoever resulting from loss of use, data or profits, whether in
23 * an action of contract, negligence or other tortuous action, arising
24 * out of or in connection with the use or performance of this
25 * software.
26 *
27 * The "treeview" widget was created by George A. Howlett.
28 */
29
30#include "bltInt.h"
31
32#ifndef NO_TREEVIEW
33
34#include "bltTreeView.h"
35#include "bltList.h"
36#include <X11/Xutil.h>
37#include <X11/Xatom.h>
38
39#define STYLE_GAP 2
40
41static Blt_OptionParseProc ObjToIcon;
42static Blt_OptionPrintProc IconToObj;
43static Blt_OptionFreeProc FreeIcon;
44Blt_CustomOption bltTreeViewIconOption =
45{
46 /* Contains a pointer to the widget that's currently being
47 * configured. This is used in the custom configuration parse
48 * routine for icons. */
49 ObjToIcon, IconToObj, FreeIcon, NULL,
50};
51
52#define DEF_STYLE_HIGHLIGHT_BACKGROUND STD_NORMAL_BACKGROUND
53#define DEF_STYLE_HIGHLIGHT_FOREGROUND STD_NORMAL_FOREGROUND
54#ifdef WIN32
55#define DEF_STYLE_ACTIVE_BACKGROUND RGB_GREY85
56#else
57#define DEF_STYLE_ACTIVE_BACKGROUND RGB_GREY95
58#endif
59#define DEF_STYLE_ACTIVE_FOREGROUND STD_ACTIVE_FOREGROUND
60#define DEF_STYLE_GAP "2"
61
62typedef struct {
63 int refCount; /* Usage reference count. */
64 unsigned int flags;
65 char *name;
66 TreeViewStyleClass *classPtr; /* Class-specific routines to manage style. */
67 Blt_HashEntry *hashPtr;
68
69 /* General style fields. */
70 Tk_Cursor cursor; /* X Cursor */
71 TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be drawn
72 * in the cell. */
73 int gap; /* # pixels gap between icon and text. */
74 Tk_Font font;
75 XColor *fgColor; /* Normal foreground color of cell. */
76 Tk_3DBorder border; /* Normal background color of cell. */
77 XColor *highlightFgColor; /* Foreground color of cell when
78 * highlighted. */
79 Tk_3DBorder highlightBorder;/* Background color of cell when
80 * highlighted. */
81 XColor *activeFgColor; /* Foreground color of cell when active. */
82 Tk_3DBorder activeBorder; /* Background color of cell when active. */
83
84 /* TextBox-specific fields */
85 GC gc;
86 GC highlightGC;
87 GC activeGC;
88
89 int side; /* Position of the text in relation to
90 * the icon. */
91 Blt_TreeKey key; /* Actual data resides in this tree
92 value. */
93
94} TreeViewTextBox;
95
96#ifdef WIN32
97#define DEF_TEXTBOX_CURSOR "arrow"
98#else
99#define DEF_TEXTBOX_CURSOR "hand2"
100#endif /*WIN32*/
101#define DEF_TEXTBOX_SIDE "left"
102
103static Blt_ConfigSpec textBoxSpecs[] =
104{
105 {BLT_CONFIG_BORDER, "-activebackground", "activeBackground",
106 "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND,
107 Blt_Offset(TreeViewTextBox, activeBorder), 0},
108 {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground",
109 (char *)NULL, (char *)NULL, 0, 0},
110 {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground",
111 (char *)NULL, (char *)NULL, 0, 0},
112 {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground",
113 "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND,
114 Blt_Offset(TreeViewTextBox, activeFgColor), 0},
115 {BLT_CONFIG_BORDER, "-background", "background", "Background",
116 (char *)NULL, Blt_Offset(TreeViewTextBox, border), BLT_CONFIG_NULL_OK},
117 {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL,
118 0, 0},
119 {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor",
120 DEF_TEXTBOX_CURSOR, Blt_Offset(TreeViewTextBox, cursor), 0},
121 {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL,
122 0, 0},
123 {BLT_CONFIG_FONT, "-font", "font", "Font",
124 (char *)NULL, Blt_Offset(TreeViewTextBox, font),
125 BLT_CONFIG_NULL_OK},
126 {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
127 (char *)NULL, Blt_Offset(TreeViewTextBox, fgColor),BLT_CONFIG_NULL_OK },
128 {BLT_CONFIG_DISTANCE, "-gap", "gap", "Gap",
129 DEF_STYLE_GAP, Blt_Offset(TreeViewTextBox, gap),
130 BLT_CONFIG_DONT_SET_DEFAULT},
131 {BLT_CONFIG_BORDER, "-highlightbackground", "highlightBackground",
132 "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND,
133 Blt_Offset(TreeViewTextBox, highlightBorder), BLT_CONFIG_COLOR_ONLY},
134 {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground",
135 "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND,
136 Blt_Offset(TreeViewTextBox, highlightFgColor), 0},
137 {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground",
138 (char *)NULL, (char *)NULL, 0, 0},
139 {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground",
140 (char *)NULL, (char *)NULL, 0, 0},
141 {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon",
142 (char *)NULL, Blt_Offset(TreeViewTextBox, icon),
143 BLT_CONFIG_NULL_OK, &bltTreeViewIconOption},
144 {BLT_CONFIG_STRING, "-key", "key", "key",
145 (char *)NULL, Blt_Offset(TreeViewTextBox, key),
146 BLT_CONFIG_NULL_OK, 0},
147 {BLT_CONFIG_SIDE, "-side", "side", "side",
148 DEF_TEXTBOX_SIDE, Tk_Offset(TreeViewTextBox, side),
149 BLT_CONFIG_DONT_SET_DEFAULT},
150 {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL,
151 (char *)NULL, 0, 0}
152};
153
154typedef struct {
155 int refCount; /* Usage reference count. */
156 unsigned int flags; /* Contains style type and update flags. */
157 char *name; /* Instance name. */
158 TreeViewStyleClass *classPtr; /* Class-specific routines to manage style. */
159 Blt_HashEntry *hashPtr;
160
161 /* General style fields. */
162 Tk_Cursor cursor; /* X Cursor */
163 TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be drawn
164 * in the cell. */
165 int gap; /* # pixels gap between icon and text. */
166 Tk_Font font;
167 XColor *fgColor; /* Normal foreground color of cell. */
168 Tk_3DBorder border; /* Normal background color of cell. */
169 XColor *highlightFgColor; /* Foreground color of cell when
170 * highlighted. */
171 Tk_3DBorder highlightBorder;/* Background color of cell when
172 * highlighted. */
173 XColor *activeFgColor; /* Foreground color of cell when active. */
174 Tk_3DBorder activeBorder; /* Background color of cell when active. */
175
176 /* Checkbox specific fields. */
177 GC gc;
178 GC highlightGC;
179 GC activeGC;
180
181 Blt_TreeKey key; /* Actual data resides in this tree
182 value. */
183 int size; /* Size of the checkbox. */
184 int showValue; /* If non-zero, display the on/off value. */
185 char *onValue;
186 char *offValue;
187 int lineWidth; /* Linewidth of the surrounding box. */
188
189 XColor *boxColor; /* Rectangle (box) color (grey). */
190 XColor *fillColor; /* Fill color (white) */
191 XColor *checkColor; /* Check color (red). */
192
193 GC boxGC;
194 GC fillGC; /* Box fill GC */
195 GC checkGC;
196
197 TextLayout *onPtr, *offPtr;
198
199} TreeViewCheckBox;
200
201#define DEF_CHECKBOX_BOX_COLOR "black"
202#define DEF_CHECKBOX_CHECK_COLOR "red"
203#define DEF_CHECKBOX_FILL_COLOR "white"
204#define DEF_CHECKBOX_OFFVALUE "0"
205#define DEF_CHECKBOX_ONVALUE "1"
206#define DEF_CHECKBOX_SHOWVALUE "yes"
207#define DEF_CHECKBOX_SIZE "11"
208#define DEF_CHECKBOX_LINEWIDTH "2"
209#define DEF_CHECKBOX_GAP "4"
210#ifdef WIN32
211#define DEF_CHECKBOX_CURSOR "arrow"
212#else
213#define DEF_CHECKBOX_CURSOR "hand2"
214#endif /*WIN32*/
215
216static Blt_ConfigSpec checkBoxSpecs[] =
217{
218 {BLT_CONFIG_BORDER, "-activebackground", "activeBackground",
219 "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND,
220 Blt_Offset(TreeViewCheckBox, activeBorder), 0},
221 {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground",
222 (char *)NULL, (char *)NULL, 0, 0},
223 {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground",
224 (char *)NULL, (char *)NULL, 0, 0},
225 {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground",
226 "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND,
227 Blt_Offset(TreeViewCheckBox, activeFgColor), 0},
228 {BLT_CONFIG_BORDER, "-background", "background", "Background",
229 (char *)NULL, Blt_Offset(TreeViewCheckBox, border), BLT_CONFIG_NULL_OK},
230 {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL,
231 0, 0},
232 {BLT_CONFIG_POS_DISTANCE, "-boxsize", "boxSize", "BoxSize",
233 DEF_CHECKBOX_SIZE, Blt_Offset(TreeViewCheckBox, size),
234 BLT_CONFIG_DONT_SET_DEFAULT},
235 {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor",
236 DEF_CHECKBOX_CURSOR, Blt_Offset(TreeViewTextBox, cursor), 0},
237 {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL,
238 0, 0},
239 {BLT_CONFIG_FONT, "-font", "font", "Font",
240 (char *)NULL, Blt_Offset(TreeViewCheckBox, font),
241 BLT_CONFIG_NULL_OK},
242 {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
243 (char *)NULL, Blt_Offset(TreeViewCheckBox, fgColor),
244 BLT_CONFIG_NULL_OK },
245 {BLT_CONFIG_DISTANCE, "-gap", "gap", "Gap",
246 DEF_CHECKBOX_GAP, Blt_Offset(TreeViewCheckBox, gap),
247 BLT_CONFIG_DONT_SET_DEFAULT},
248 {BLT_CONFIG_BORDER, "-highlightbackground", "highlightBackground",
249 "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND,
250 Blt_Offset(TreeViewCheckBox, highlightBorder), BLT_CONFIG_COLOR_ONLY},
251 {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground",
252 "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND,
253 Blt_Offset(TreeViewCheckBox, highlightFgColor), 0},
254 {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground",
255 (char *)NULL, (char *)NULL, 0, 0},
256 {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground",
257 (char *)NULL, (char *)NULL, 0, 0},
258 {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon",
259 (char *)NULL, Blt_Offset(TreeViewCheckBox, icon),
260 BLT_CONFIG_NULL_OK, &bltTreeViewIconOption},
261 {BLT_CONFIG_STRING, "-key", "key", "key",
262 (char *)NULL, Blt_Offset(TreeViewCheckBox, key),
263 BLT_CONFIG_NULL_OK, 0},
264 {BLT_CONFIG_DISTANCE, "-linewidth", "lineWidth", "LineWidth",
265 DEF_CHECKBOX_LINEWIDTH,
266 Blt_Offset(TreeViewCheckBox, lineWidth),
267 BLT_CONFIG_DONT_SET_DEFAULT},
268 {BLT_CONFIG_COLOR, "-checkcolor", "checkColor", "CheckColor",
269 DEF_CHECKBOX_CHECK_COLOR, Blt_Offset(TreeViewCheckBox, checkColor), 0},
270 {BLT_CONFIG_COLOR, "-boxcolor", "boxColor", "BoxColor",
271 DEF_CHECKBOX_BOX_COLOR, Blt_Offset(TreeViewCheckBox, boxColor), 0},
272 {BLT_CONFIG_COLOR, "-fillcolor", "fillColor", "FillColor",
273 DEF_CHECKBOX_FILL_COLOR, Blt_Offset(TreeViewCheckBox, fillColor), 0},
274 {BLT_CONFIG_STRING, "-offvalue", "offValue", "OffValue",
275 DEF_CHECKBOX_OFFVALUE, Blt_Offset(TreeViewCheckBox, offValue),
276 BLT_CONFIG_NULL_OK},
277 {BLT_CONFIG_STRING, "-onvalue", "onValue", "OnValue",
278 DEF_CHECKBOX_ONVALUE, Blt_Offset(TreeViewCheckBox, onValue),
279 BLT_CONFIG_NULL_OK},
280 {BLT_CONFIG_STRING, "-key", "key", "key",
281 (char *)NULL, Blt_Offset(TreeViewCheckBox, key), BLT_CONFIG_NULL_OK, 0},
282 {BLT_CONFIG_BOOLEAN, "-showvalue", "showValue", "ShowValue",
283 DEF_CHECKBOX_SHOWVALUE, Blt_Offset(TreeViewCheckBox, showValue),
284 BLT_CONFIG_DONT_SET_DEFAULT},
285 {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL,
286 (char *)NULL, 0, 0}
287};
288
289typedef struct {
290 int refCount; /* Usage reference count. */
291 unsigned int flags;
292 char *name;
293 TreeViewStyleClass *classPtr;/* Class-specific style routines. */
294 Blt_HashEntry *hashPtr;
295
296 /* General style fields. */
297 Tk_Cursor cursor; /* X Cursor */
298 TreeViewIcon icon; /* If non-NULL, is a Tk_Image to be drawn
299 * in the cell. */
300 int gap; /* # pixels gap between icon and text. */
301 Tk_Font font;
302 XColor *fgColor; /* Normal foreground color of cell. */
303 Tk_3DBorder border; /* Normal background color of cell. */
304 XColor *highlightFgColor; /* Foreground color of cell when
305 * highlighted. */
306 Tk_3DBorder highlightBorder;/* Background color of cell when
307 * highlighted. */
308 XColor *activeFgColor; /* Foreground color of cell when active. */
309 Tk_3DBorder activeBorder; /* Background color of cell when active. */
310
311 /* ComboBox-specific fields */
312 GC gc;
313 GC highlightGC;
314 GC activeGC;
315
316 int borderWidth; /* Width of outer border surrounding
317 * the entire box. */
318 int relief; /* Relief of outer border. */
319
320 Blt_TreeKey key; /* Actual data resides in this tree
321 value. */
322
323 char *choices; /* List of available choices. */
324 char *choiceIcons; /* List of icons associated with choices. */
325 int scrollWidth;
326 int button;
327 int buttonWidth;
328 int buttonBorderWidth; /* Border width of button. */
329 int buttonRelief; /* Normal relief of button. */
330
331} TreeViewComboBox;
332
333#define DEF_COMBOBOX_BORDERWIDTH "1"
334#define DEF_COMBOBOX_BUTTON_BORDERWIDTH "1"
335#define DEF_COMBOBOX_BUTTON_RELIEF "raised"
336#define DEF_COMBOBOX_RELIEF "flat"
337#ifdef WIN32
338#define DEF_COMBOBOX_CURSOR "arrow"
339#else
340#define DEF_COMBOBOX_CURSOR "hand2"
341#endif /*WIN32*/
342
343
344static Blt_ConfigSpec comboBoxSpecs[] =
345{
346 {BLT_CONFIG_BORDER, "-activebackground", "activeBackground",
347 "ActiveBackground", DEF_STYLE_ACTIVE_BACKGROUND,
348 Blt_Offset(TreeViewComboBox, activeBorder), 0},
349 {BLT_CONFIG_SYNONYM, "-activebg", "activeBackground",
350 (char *)NULL, (char *)NULL, 0, 0},
351 {BLT_CONFIG_SYNONYM, "-activefg", "activeFackground",
352 (char *)NULL, (char *)NULL, 0, 0},
353 {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground",
354 "ActiveForeground", DEF_STYLE_ACTIVE_FOREGROUND,
355 Blt_Offset(TreeViewComboBox, activeFgColor), 0},
356 {BLT_CONFIG_BORDER, "-background", "background", "Background",
357 (char *)NULL, Blt_Offset(TreeViewComboBox, border),
358 BLT_CONFIG_NULL_OK},
359 {BLT_CONFIG_SYNONYM, "-bd", "borderWidth", (char *)NULL, (char *)NULL, 0,
360 0},
361 {BLT_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, (char *)NULL,
362 0, 0},
363 {BLT_CONFIG_DISTANCE, "-borderwidth", "borderWidth", "BorderWidth",
364 DEF_COMBOBOX_BORDERWIDTH, Blt_Offset(TreeViewComboBox, borderWidth),
365 BLT_CONFIG_DONT_SET_DEFAULT},
366 {BLT_CONFIG_RELIEF, "-buttonrelief", "buttonRelief", "ButtonRelief",
367 DEF_COMBOBOX_BUTTON_RELIEF, Blt_Offset(TreeViewComboBox, buttonRelief),
368 BLT_CONFIG_DONT_SET_DEFAULT},
369 {BLT_CONFIG_DISTANCE, "-buttonborderwidth", "buttonBorderWidth",
370 "ButtonBorderWidth", DEF_COMBOBOX_BUTTON_BORDERWIDTH,
371 Blt_Offset(TreeViewComboBox, buttonBorderWidth),
372 BLT_CONFIG_DONT_SET_DEFAULT},
373 {BLT_CONFIG_CURSOR, "-cursor", "cursor", "Cursor",
374 DEF_COMBOBOX_CURSOR, Blt_Offset(TreeViewTextBox, cursor), 0},
375 {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, (char *)NULL,
376 0, 0},
377 {BLT_CONFIG_FONT, "-font", "font", "Font",
378 (char *)NULL, Blt_Offset(TreeViewComboBox, font),
379 BLT_CONFIG_NULL_OK},
380 {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
381 (char *)NULL, Blt_Offset(TreeViewComboBox, fgColor),
382 BLT_CONFIG_NULL_OK },
383 {BLT_CONFIG_DISTANCE, "-gap", "gap", "Gap",
384 DEF_STYLE_GAP, Blt_Offset(TreeViewComboBox, gap),
385 BLT_CONFIG_DONT_SET_DEFAULT},
386 {BLT_CONFIG_BORDER, "-highlightbackground", "highlightBackground",
387 "HighlightBackground", DEF_STYLE_HIGHLIGHT_BACKGROUND,
388 Blt_Offset(TreeViewComboBox, highlightBorder), BLT_CONFIG_COLOR_ONLY},
389 {BLT_CONFIG_COLOR, "-highlightforeground", "highlightForeground",
390 "HighlightForeground", DEF_STYLE_HIGHLIGHT_FOREGROUND,
391 Blt_Offset(TreeViewComboBox, highlightFgColor), 0},
392 {BLT_CONFIG_SYNONYM, "-highlightbg", "highlightBackground",
393 (char *)NULL, (char *)NULL, 0, 0},
394 {BLT_CONFIG_SYNONYM, "-highlightfg", "highlightForeground",
395 (char *)NULL, (char *)NULL, 0, 0},
396 {BLT_CONFIG_CUSTOM, "-icon", "icon", "Icon",
397 (char *)NULL, Blt_Offset(TreeViewComboBox, icon),
398 BLT_CONFIG_NULL_OK, &bltTreeViewIconOption},
399 {BLT_CONFIG_STRING, "-key", "key", "key",
400 (char *)NULL, Blt_Offset(TreeViewComboBox, key),
401 BLT_CONFIG_NULL_OK, 0},
402 {BLT_CONFIG_RELIEF, "-relief", "relief", "Relief",
403 DEF_COMBOBOX_RELIEF, Blt_Offset(TreeViewComboBox, relief),
404 BLT_CONFIG_DONT_SET_DEFAULT},
405 {BLT_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL,
406 (char *)NULL, 0, 0}
407};
408
409typedef TreeViewStyle *(StyleCreateProc) _ANSI_ARGS_((TreeView *tvPtr,
410 Blt_HashEntry *hPtr));
411
412static StyleConfigProc ConfigureTextBox, ConfigureCheckBox, ConfigureComboBox;
413static StyleCreateProc CreateTextBox, CreateCheckBox, CreateComboBox;
414static StyleDrawProc DrawTextBox, DrawCheckBox, DrawComboBox;
415static StyleEditProc EditTextBox, EditCheckBox, EditComboBox;
416static StyleFreeProc FreeTextBox, FreeCheckBox, FreeComboBox;
417static StyleMeasureProc MeasureTextBox, MeasureCheckBox, MeasureComboBox;
418static StylePickProc PickCheckBox, PickComboBox;
419
420/*
421 *----------------------------------------------------------------------
422 *
423 * ObjToIcon --
424 *
425 * Convert the name of an icon into a Tk image.
426 *
427 * Results:
428 * If the string is successfully converted, TCL_OK is returned.
429 * Otherwise, TCL_ERROR is returned and an error message is left in
430 * interpreter's result field.
431 *
432 *----------------------------------------------------------------------
433 */
434/*ARGSUSED*/
435static int
436ObjToIcon(clientData, interp, tkwin, objPtr, widgRec, offset)
437 ClientData clientData; /* Not used. */
438 Tcl_Interp *interp; /* Interpreter to send results back to */
439 Tk_Window tkwin; /* Not used. */
440 Tcl_Obj *objPtr; /* Tcl_Obj representing the new value. */
441 char *widgRec;
442 int offset;
443{
444 TreeView *tvPtr = clientData;
445 TreeViewIcon *iconPtr = (TreeViewIcon *)(widgRec + offset);
446 TreeViewIcon icon;
447
448 icon = Blt_TreeViewGetIcon(tvPtr, Tcl_GetString(objPtr));
449 if (icon == NULL) {
450 return TCL_ERROR;
451 }
452 *iconPtr = icon;
453 return TCL_OK;
454}
455
456/*
457 *----------------------------------------------------------------------
458 *
459 * IconToObj --
460 *
461 * Converts the icon into its string representation (its name).
462 *
463 * Results:
464 * The name of the icon is returned.
465 *
466 *----------------------------------------------------------------------
467 */
468/*ARGSUSED*/
469static Tcl_Obj *
470IconToObj(clientData, interp, tkwin, widgRec, offset)
471 ClientData clientData; /* Not used. */
472 Tcl_Interp *interp;
473 Tk_Window tkwin; /* Not used. */
474 char *widgRec;
475 int offset;
476{
477 TreeViewIcon icon = *(TreeViewIcon *)(widgRec + offset);
478
479 if (icon == NULL) {
480 return bltEmptyStringObjPtr;
481 }
482 return Tcl_NewStringObj(Blt_NameOfImage((icon)->tkImage), -1);
483}
484
485/*ARGSUSED*/
486static void
487FreeIcon(clientData, display, widgRec, offset)
488 ClientData clientData;
489 Display *display; /* Not used. */
490 char *widgRec;
491 int offset;
492{
493 TreeViewIcon icon = *(TreeViewIcon *)(widgRec + offset);
494 TreeView *tvPtr = clientData;
495
496 Blt_TreeViewFreeIcon(tvPtr, icon);
497}
498
499static TreeViewStyleClass textBoxClass = {
500 "TextBoxStyle",
501 textBoxSpecs,
502 ConfigureTextBox,
503 MeasureTextBox,
504 DrawTextBox,
505 NULL,
506 EditTextBox,
507 FreeTextBox,
508};
509
510static TreeViewStyleClass checkBoxClass = {
511 "CheckBoxStyle",
512 checkBoxSpecs,
513 ConfigureCheckBox,
514 MeasureCheckBox,
515 DrawCheckBox,
516 NULL,
517 EditCheckBox,
518 FreeCheckBox,
519};
520
521static TreeViewStyleClass comboBoxClass = {
522 "ComboBoxStyle",
523 comboBoxSpecs,
524 ConfigureComboBox,
525 MeasureComboBox,
526 DrawComboBox,
527 PickComboBox,
528 EditComboBox,
529 FreeComboBox,
530};
531
532/*
533 *----------------------------------------------------------------------
534 *
535 * CreateTextBox --
536 *
537 * Creates a "textbox" style.
538 *
539 * Results:
540 * A pointer to the new style structure.
541 *
542 *----------------------------------------------------------------------
543 */
544static TreeViewStyle *
545CreateTextBox(tvPtr, hPtr)
546 TreeView *tvPtr;
547 Blt_HashEntry *hPtr;
548{
549 TreeViewTextBox *tbPtr;
550
551 tbPtr = Blt_Calloc(1, sizeof(TreeViewTextBox));
552 assert(tbPtr);
553 tbPtr->classPtr = &textBoxClass;
554 tbPtr->side = SIDE_LEFT;
555 tbPtr->gap = STYLE_GAP;
556 tbPtr->name = Blt_Strdup(Blt_GetHashKey(&tvPtr->styleTable, hPtr));
557 tbPtr->hashPtr = hPtr;
558 tbPtr->flags = STYLE_TEXTBOX;
559 tbPtr->refCount = 1;
560 Blt_SetHashValue(hPtr, tbPtr);
561 return (TreeViewStyle *)tbPtr;
562}
563
564/*
565 *----------------------------------------------------------------------
566 *
567 * ConfigureTextBox --
568 *
569 * Configures a "textbox" style. This routine performs
570 * generates the GCs required for a textbox style.
571 *
572 * Results:
573 * None.
574 *
575 * Side Effects:
576 * GCs are created for the style.
577 *
578 *----------------------------------------------------------------------
579 */
580static void
581ConfigureTextBox(tvPtr, stylePtr)
582 TreeView *tvPtr;
583 TreeViewStyle *stylePtr;
584{
585 GC newGC;
586 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
587 XColor *bgColor;
588 XGCValues gcValues;
589 unsigned long gcMask;
590
591 gcMask = GCForeground | GCBackground | GCFont;
592 gcValues.font = Tk_FontId(CHOOSE(tvPtr->font, tbPtr->font));
593 bgColor = Tk_3DBorderColor(CHOOSE(tvPtr->border, tbPtr->border));
594
595 gcValues.background = bgColor->pixel;
596 gcValues.foreground = CHOOSE(tvPtr->fgColor, tbPtr->fgColor)->pixel;
597 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
598 if (tbPtr->gc != NULL) {
599 Tk_FreeGC(tvPtr->display, tbPtr->gc);
600 }
601 tbPtr->gc = newGC;
602 gcValues.background = Tk_3DBorderColor(tbPtr->highlightBorder)->pixel;
603 gcValues.foreground = tbPtr->highlightFgColor->pixel;
604 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
605 if (tbPtr->highlightGC != NULL) {
606 Tk_FreeGC(tvPtr->display, tbPtr->highlightGC);
607 }
608 tbPtr->highlightGC = newGC;
609
610 gcValues.background = Tk_3DBorderColor(tbPtr->activeBorder)->pixel;
611 gcValues.foreground = tbPtr->activeFgColor->pixel;
612 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
613 if (tbPtr->activeGC != NULL) {
614 Tk_FreeGC(tvPtr->display, tbPtr->activeGC);
615 }
616 tbPtr->activeGC = newGC;
617 tbPtr->flags |= STYLE_DIRTY;
618}
619
620/*
621 *----------------------------------------------------------------------
622 *
623 * MeasureTextBox --
624 *
625 * Determines the space requirements for the "textbox" given
626 * the value to be displayed. Depending upon whether an icon
627 * or text is displayed and their relative placements, this
628 * routine computes the space needed for the text entry.
629 *
630 * Results:
631 * None.
632 *
633 * Side Effects:
634 * The width and height fields of *valuePtr* are set with the
635 * computed dimensions.
636 *
637 *----------------------------------------------------------------------
638 */
639static void
640MeasureTextBox(tvPtr, stylePtr, valuePtr)
641 TreeView *tvPtr;
642 TreeViewStyle *stylePtr;
643 TreeViewValue *valuePtr;
644{
645 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
646 int iconWidth, iconHeight;
647 int textWidth, textHeight;
648 int gap;
649
650 textWidth = textHeight = 0;
651 iconWidth = iconHeight = 0;
652 valuePtr->width = valuePtr->height = 0;
653
654 if (tbPtr->icon != NULL) {
655 iconWidth = TreeViewIconWidth(tbPtr->icon);
656 iconHeight = TreeViewIconHeight(tbPtr->icon);
657 }
658 if (valuePtr->textPtr != NULL) {
659 Blt_Free(valuePtr->textPtr);
660 valuePtr->textPtr = NULL;
661 }
662 if (valuePtr->string != NULL) { /* New string defined. */
663 TextStyle ts;
664
665 Blt_InitTextStyle(&ts);
666 ts.font = CHOOSE(tvPtr->font, tbPtr->font);
667 ts.anchor = TK_ANCHOR_NW;
668 ts.justify = TK_JUSTIFY_LEFT;
669 valuePtr->textPtr = Blt_GetTextLayout(valuePtr->string, &ts);
670 }
671 gap = 0;
672 if (valuePtr->textPtr != NULL) {
673 textWidth = valuePtr->textPtr->width;
674 textHeight = valuePtr->textPtr->height;
675 if (tbPtr->icon != NULL) {
676 gap = tbPtr->gap;
677 }
678 }
679 if (SIDE_VERTICAL(tbPtr->side)) {
680 valuePtr->height = iconHeight + gap + textHeight;
681 valuePtr->width = MAX(textWidth, iconWidth);
682 } else {
683 valuePtr->width = iconWidth + gap + textWidth;
684 valuePtr->height = MAX(textHeight, iconHeight);
685 }
686}
687
688/*
689 *----------------------------------------------------------------------
690 *
691 * DrawTextBox --
692 *
693 * Draws the "textbox" given the screen coordinates and the
694 * value to be displayed.
695 *
696 * Results:
697 * None.
698 *
699 * Side Effects:
700 * The textbox value is drawn.
701 *
702 *----------------------------------------------------------------------
703 */
704static void
705DrawTextBox(tvPtr, drawable, entryPtr, valuePtr, stylePtr, x, y)
706 TreeView *tvPtr;
707 Drawable drawable;
708 TreeViewEntry *entryPtr;
709 TreeViewValue *valuePtr;
710 TreeViewStyle *stylePtr;
711 int x, y;
712{
713 GC gc;
714 TreeViewColumn *columnPtr;
715 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
716 int iconX, iconY, iconWidth, iconHeight;
717 int textX, textY, textWidth, textHeight;
718 int gap, columnWidth;
719 Tk_3DBorder border;
720 XColor *fgColor;
721
722 columnPtr = valuePtr->columnPtr;
723
724 if (stylePtr->flags & STYLE_HIGHLIGHT) {
725 gc = tbPtr->highlightGC;
726 border = tbPtr->highlightBorder;
727 fgColor = tbPtr->highlightFgColor;
728 } else {
729 gc = tbPtr->gc;
730 border = CHOOSE(tvPtr->border, tbPtr->border);
731 fgColor = CHOOSE(tvPtr->fgColor, tbPtr->fgColor);
732 }
733 if (!Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
734 /*
735 * Draw the active or normal background color over the entire
736 * label area. This includes both the tab's text and image.
737 * The rectangle should be 2 pixels wider/taller than this
738 * area. So if the label consists of just an image, we get an
739 * halo around the image when the tab is active.
740 */
741 if (border != NULL) {
742 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, border, x, y,
743 columnPtr->width, entryPtr->height, 0, TK_RELIEF_FLAT);
744 }
745 }
746 columnWidth = columnPtr->width -
747 (2 * columnPtr->borderWidth + PADDING(columnPtr->pad));
748 if (columnWidth > valuePtr->width) {
749 switch(columnPtr->justify) {
750 case TK_JUSTIFY_RIGHT:
751 x += (columnWidth - valuePtr->width);
752 break;
753 case TK_JUSTIFY_CENTER:
754 x += (columnWidth - valuePtr->width) / 2;
755 break;
756 case TK_JUSTIFY_LEFT:
757 break;
758 }
759 }
760
761 textX = textY = iconX = iconY = 0; /* Suppress compiler warning. */
762
763 iconWidth = iconHeight = 0;
764 if (tbPtr->icon != NULL) {
765 iconWidth = TreeViewIconWidth(tbPtr->icon);
766 iconHeight = TreeViewIconHeight(tbPtr->icon);
767 }
768 textWidth = textHeight = 0;
769 if (valuePtr->textPtr != NULL) {
770 textWidth = valuePtr->textPtr->width;
771 textHeight = valuePtr->textPtr->height;
772 }
773 gap = 0;
774 if ((tbPtr->icon != NULL) && (valuePtr->textPtr != NULL)) {
775 gap = tbPtr->gap;
776 }
777 switch (tbPtr->side) {
778 case SIDE_RIGHT:
779 textX = x;
780 textY = y + (entryPtr->height - textHeight) / 2;
781 iconX = textX + textWidth + gap;
782 iconY = y + (entryPtr->height - iconHeight) / 2;
783 break;
784 case SIDE_LEFT:
785 iconX = x;
786 iconY = y + (entryPtr->height - iconHeight) / 2;
787 textX = iconX + iconWidth + gap;
788 textY = y + (entryPtr->height - textHeight) / 2;
789 break;
790 case SIDE_TOP:
791 iconY = y;
792 iconX = x + (columnWidth - iconWidth) / 2;
793 textY = iconY + iconHeight + gap;
794 textX = x + (columnWidth - textWidth) / 2;
795 break;
796 case SIDE_BOTTOM:
797 textY = y;
798 textX = x + (columnWidth - textWidth) / 2;
799 iconY = textY + textHeight + gap;
800 iconX = x + (columnWidth - iconWidth) / 2;
801 break;
802 }
803 if (tbPtr->icon != NULL) {
804 Tk_RedrawImage(TreeViewIconBits(tbPtr->icon), 0, 0, iconWidth,
805 iconHeight, drawable, iconX, iconY);
806 }
807 if (valuePtr->textPtr != NULL) {
808 TextStyle ts;
809 XColor *color;
810 Tk_Font font;
811
812 font = CHOOSE(tvPtr->font, tbPtr->font);
813 if (Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
814 color = SELECT_FG(tvPtr);
815 XSetForeground(tvPtr->display, gc, color->pixel);
816 } else if (entryPtr->color != NULL) {
817 color = entryPtr->color;
818 XSetForeground(tvPtr->display, gc, color->pixel);
819 } else {
820 color = fgColor;
821 }
822 Blt_SetDrawTextStyle(&ts, font, gc, color, fgColor, NULL, 0.0,
823 TK_ANCHOR_NW, TK_JUSTIFY_LEFT, 0, 0);
824 Blt_DrawTextLayout(tvPtr->tkwin, drawable, valuePtr->textPtr,
825 &ts, textX, textY);
826 if (color != fgColor) {
827 XSetForeground(tvPtr->display, gc, fgColor->pixel);
828 }
829 }
830 stylePtr->flags &= ~STYLE_DIRTY;
831}
832
833/*
834 *----------------------------------------------------------------------
835 *
836 * EditCombobox --
837 *
838 * Edits the "combobox".
839 *
840 * Results:
841 * None.
842 *
843 * Side Effects:
844 * The checkbox value is drawn.
845 *
846 *----------------------------------------------------------------------
847 */
848/*ARGSUSED*/
849static int
850EditTextBox(tvPtr, entryPtr, valuePtr, stylePtr)
851 TreeView *tvPtr;
852 TreeViewEntry *entryPtr;
853 TreeViewValue *valuePtr;
854 TreeViewStyle *stylePtr; /* Not used. */
855{
856 return Blt_TreeViewTextbox(tvPtr, entryPtr, valuePtr->columnPtr);
857}
858
859
860/*
861 *----------------------------------------------------------------------
862 *
863 * FreeTextBox --
864 *
865 * Releases resources allocated for the textbox. The resources
866 * freed by this routine are specific only to the "textbox".
867 * Other resources (common to all styles) are freed in the
868 * Blt_TreeViewFreeStyle routine.
869 *
870 * Results:
871 * None.
872 *
873 * Side Effects:
874 * GCs allocated for the textbox are freed.
875 *
876 *----------------------------------------------------------------------
877 */
878static void
879FreeTextBox(tvPtr, stylePtr)
880 TreeView *tvPtr;
881 TreeViewStyle *stylePtr;
882{
883 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
884
885 if (tbPtr->highlightGC != NULL) {
886 Tk_FreeGC(tvPtr->display, tbPtr->highlightGC);
887 }
888 if (tbPtr->activeGC != NULL) {
889 Tk_FreeGC(tvPtr->display, tbPtr->activeGC);
890 }
891 if (tbPtr->gc != NULL) {
892 Tk_FreeGC(tvPtr->display, tbPtr->gc);
893 }
894 if (tbPtr->icon != NULL) {
895 Blt_TreeViewFreeIcon(tvPtr, tbPtr->icon);
896 }
897}
898
899
900/*
901 *----------------------------------------------------------------------
902 *
903 * CreateCheckbox --
904 *
905 * Creates a "checkbox" style.
906 *
907 * Results:
908 * A pointer to the new style structure.
909 *
910 *----------------------------------------------------------------------
911 */
912static TreeViewStyle *
913CreateCheckBox(tvPtr, hPtr)
914 TreeView *tvPtr;
915 Blt_HashEntry *hPtr;
916{
917 TreeViewCheckBox *cbPtr;
918
919 cbPtr = Blt_Calloc(1, sizeof(TreeViewCheckBox));
920 assert(cbPtr);
921 cbPtr->classPtr = &checkBoxClass;
922 cbPtr->gap = 4;
923 cbPtr->size = 11;
924 cbPtr->lineWidth = 2;
925 cbPtr->showValue = TRUE;
926 cbPtr->name = Blt_Strdup(Blt_GetHashKey(&tvPtr->styleTable, hPtr));
927 cbPtr->hashPtr = hPtr;
928 cbPtr->flags = STYLE_CHECKBOX;
929 cbPtr->refCount = 1;
930 Blt_SetHashValue(hPtr, cbPtr);
931 return (TreeViewStyle *)cbPtr;
932}
933
934/*
935 *----------------------------------------------------------------------
936 *
937 * ConfigureCheckbox --
938 *
939 * Configures a "checkbox" style. This routine performs
940 * generates the GCs required for a checkbox style.
941 *
942 * Results:
943 * None.
944 *
945 * Side Effects:
946 * GCs are created for the style.
947 *
948 *----------------------------------------------------------------------
949 */
950static void
951ConfigureCheckBox(tvPtr, stylePtr)
952 TreeView *tvPtr;
953 TreeViewStyle *stylePtr;
954{
955 GC newGC;
956 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
957 XColor *bgColor;
958 XGCValues gcValues;
959 unsigned long gcMask;
960
961 gcMask = GCForeground | GCBackground | GCFont;
962 gcValues.font = Tk_FontId(CHOOSE(tvPtr->font, cbPtr->font));
963 bgColor = Tk_3DBorderColor(CHOOSE(tvPtr->border, cbPtr->border));
964
965 gcValues.background = bgColor->pixel;
966 gcValues.foreground = CHOOSE(tvPtr->fgColor, cbPtr->fgColor)->pixel;
967 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
968 if (cbPtr->gc != NULL) {
969 Tk_FreeGC(tvPtr->display, cbPtr->gc);
970 }
971 cbPtr->gc = newGC;
972 gcValues.background = Tk_3DBorderColor(cbPtr->highlightBorder)->pixel;
973 gcValues.foreground = cbPtr->highlightFgColor->pixel;
974 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
975 if (cbPtr->highlightGC != NULL) {
976 Tk_FreeGC(tvPtr->display, cbPtr->highlightGC);
977 }
978 cbPtr->highlightGC = newGC;
979
980 gcValues.background = Tk_3DBorderColor(cbPtr->activeBorder)->pixel;
981 gcValues.foreground = cbPtr->activeFgColor->pixel;
982 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
983 if (cbPtr->activeGC != NULL) {
984 Tk_FreeGC(tvPtr->display, cbPtr->activeGC);
985 }
986 cbPtr->activeGC = newGC;
987
988 gcMask = GCForeground;
989 gcValues.foreground = cbPtr->fillColor->pixel;
990 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
991 if (cbPtr->fillGC != NULL) {
992 Tk_FreeGC(tvPtr->display, cbPtr->fillGC);
993 }
994 cbPtr->fillGC = newGC;
995
996 gcMask = GCForeground | GCLineWidth;
997 gcValues.line_width = cbPtr->lineWidth;
998 gcValues.foreground = cbPtr->boxColor->pixel;
999 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
1000 if (cbPtr->boxGC != NULL) {
1001 Tk_FreeGC(tvPtr->display, cbPtr->boxGC);
1002 }
1003 cbPtr->boxGC = newGC;
1004
1005 gcMask = GCForeground | GCLineWidth;
1006 gcValues.line_width = 1;
1007 gcValues.foreground = cbPtr->checkColor->pixel;
1008 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
1009 if (cbPtr->checkGC != NULL) {
1010 Tk_FreeGC(tvPtr->display, cbPtr->checkGC);
1011 }
1012 cbPtr->checkGC = newGC;
1013 cbPtr->flags |= STYLE_DIRTY;
1014}
1015
1016/*
1017 *----------------------------------------------------------------------
1018 *
1019 * MeasureCheckbox --
1020 *
1021 * Determines the space requirements for the "checkbox" given
1022 * the value to be displayed. Depending upon whether an icon
1023 * or text is displayed and their relative placements, this
1024 * routine computes the space needed for the text entry.
1025 *
1026 * Results:
1027 * None.
1028 *
1029 * Side Effects:
1030 * The width and height fields of *valuePtr* are set with the
1031 * computed dimensions.
1032 *
1033 *----------------------------------------------------------------------
1034 */
1035static void
1036MeasureCheckBox(tvPtr, stylePtr, valuePtr)
1037 TreeView *tvPtr;
1038 TreeViewStyle *stylePtr;
1039 TreeViewValue *valuePtr;
1040{
1041 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
1042 int iconWidth, iconHeight;
1043 int textWidth, textHeight;
1044 int gap;
1045 int boxWidth, boxHeight;
1046
1047 boxWidth = boxHeight = ODD(cbPtr->size);
1048
1049 textWidth = textHeight = iconWidth = iconHeight = 0;
1050 valuePtr->width = valuePtr->height = 0;
1051 if (cbPtr->icon != NULL) {
1052 iconWidth = TreeViewIconWidth(cbPtr->icon);
1053 iconHeight = TreeViewIconHeight(cbPtr->icon);
1054 }
1055 if (cbPtr->onPtr != NULL) {
1056 Blt_Free(cbPtr->onPtr);
1057 cbPtr->onPtr = NULL;
1058 }
1059 if (cbPtr->offPtr != NULL) {
1060 Blt_Free(cbPtr->offPtr);
1061 cbPtr->offPtr = NULL;
1062 }
1063 gap = 0;
1064 if (cbPtr->showValue) {
1065 TextStyle ts;
1066 char *string;
1067
1068 Blt_InitTextStyle(&ts);
1069 ts.font = CHOOSE(tvPtr->font, cbPtr->font);
1070 ts.anchor = TK_ANCHOR_NW;
1071 ts.justify = TK_JUSTIFY_LEFT;
1072 string = (cbPtr->onValue != NULL) ? cbPtr->onValue : valuePtr->string;
1073 cbPtr->onPtr = Blt_GetTextLayout(string, &ts);
1074 string = (cbPtr->offValue != NULL) ? cbPtr->offValue : valuePtr->string;
1075 cbPtr->offPtr = Blt_GetTextLayout(string, &ts);
1076 textWidth = MAX(cbPtr->offPtr->width, cbPtr->onPtr->width);
1077 textHeight = MAX(cbPtr->offPtr->height, cbPtr->onPtr->height);
1078 if (cbPtr->icon != NULL) {
1079 gap = cbPtr->gap;
1080 }
1081 }
1082 valuePtr->width = cbPtr->gap * 2 + boxWidth + iconWidth + gap + textWidth;
1083 valuePtr->height = MAX3(boxHeight, textHeight, iconHeight);
1084}
1085
1086/*
1087 *----------------------------------------------------------------------
1088 *
1089 * DrawCheckbox --
1090 *
1091 * Draws the "checkbox" given the screen coordinates and the
1092 * value to be displayed.
1093 *
1094 * Results:
1095 * None.
1096 *
1097 * Side Effects:
1098 * The checkbox value is drawn.
1099 *
1100 *----------------------------------------------------------------------
1101 */
1102static void
1103DrawCheckBox(tvPtr, drawable, entryPtr, valuePtr, stylePtr, x, y)
1104 TreeView *tvPtr;
1105 Drawable drawable;
1106 TreeViewEntry *entryPtr;
1107 TreeViewValue *valuePtr;
1108 TreeViewStyle *stylePtr;
1109 int x, y;
1110{
1111 GC gc;
1112 TreeViewColumn *columnPtr;
1113 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
1114 int iconX, iconY, iconWidth, iconHeight;
1115 int textX, textY, textHeight;
1116 int gap, columnWidth;
1117 Tk_3DBorder border;
1118 XColor *fgColor;
1119 Tk_Font font;
1120 int bool;
1121 int borderWidth, relief;
1122 TextLayout *textPtr;
1123 int boxX, boxY, boxWidth, boxHeight;
1124
1125 font = CHOOSE(tvPtr->font, cbPtr->font);
1126 columnPtr = valuePtr->columnPtr;
1127 borderWidth = 0;
1128 relief = TK_RELIEF_FLAT;
1129 if (valuePtr == tvPtr->activeValuePtr) {
1130 gc = cbPtr->activeGC;
1131 border = cbPtr->activeBorder;
1132 fgColor = cbPtr->activeFgColor;
1133 borderWidth = 1;
1134 relief = TK_RELIEF_RAISED;
1135 } else if (stylePtr->flags & STYLE_HIGHLIGHT) {
1136 gc = cbPtr->highlightGC;
1137 border = cbPtr->highlightBorder;
1138 fgColor = cbPtr->highlightFgColor;
1139 } else {
1140 gc = cbPtr->gc;
1141 border = CHOOSE(tvPtr->border, cbPtr->border);
1142 fgColor = CHOOSE(tvPtr->fgColor, cbPtr->fgColor);
1143 }
1144 columnWidth = columnPtr->width - PADDING(columnPtr->pad);
1145 if (valuePtr == tvPtr->activeValuePtr) {
1146 /*
1147 * Draw the active or normal background color over the entire
1148 * label area. This includes both the tab's text and image.
1149 * The rectangle should be 2 pixels wider/taller than this
1150 * area. So if the label consists of just an image, we get an
1151 * halo around the image when the tab is active.
1152 */
1153 if (Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
1154 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, SELECT_BORDER(tvPtr),
1155 x, y, columnWidth, entryPtr->height - 1, borderWidth, relief);
1156 } else {
1157 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, border, x, y,
1158 columnWidth, entryPtr->height - 1, borderWidth, relief);
1159 }
1160 }
1161
1162 if (columnWidth > valuePtr->width) {
1163 switch(columnPtr->justify) {
1164 case TK_JUSTIFY_RIGHT:
1165 x += (columnWidth - valuePtr->width);
1166 break;
1167 case TK_JUSTIFY_CENTER:
1168 x += (columnWidth - valuePtr->width) / 2;
1169 break;
1170 case TK_JUSTIFY_LEFT:
1171 break;
1172 }
1173 }
1174
1175 bool = (strcmp(valuePtr->string, cbPtr->onValue) == 0);
1176 textPtr = (bool) ? cbPtr->onPtr : cbPtr->offPtr;
1177
1178 /*
1179 * Draw the box and check.
1180 *
1181 * +-----------+
1182 * | |
1183 * | * |
1184 * | * |
1185 * | * * |
1186 * | * * |
1187 * | * * |
1188 * | * |
1189 * +-----------+
1190 */
1191 boxWidth = boxHeight = ODD(cbPtr->size);
1192 boxX = x + cbPtr->gap;
1193 boxY = y + (entryPtr->height - boxHeight) / 2;
1194 XFillRectangle(tvPtr->display, drawable, cbPtr->fillGC, boxX, boxY,
1195 boxWidth, boxHeight);
1196 XDrawRectangle(tvPtr->display, drawable, cbPtr->boxGC, boxX, boxY,
1197 boxWidth, boxHeight);
1198
1199 if (bool) {
1200 int midX, midY;
1201 int i;
1202
1203 for (i = 0; i < 3; i++) {
1204 midX = boxX + 2 * boxWidth / 5;
1205 midY = boxY + boxHeight - 5 + i;
1206 XDrawLine(tvPtr->display, drawable, cbPtr->checkGC,
1207 boxX + 2, boxY + boxHeight / 3 + 1 + i, midX, midY);
1208 XDrawLine(tvPtr->display, drawable, cbPtr->checkGC,
1209 midX, midY, boxX + boxWidth - 2, boxY + i + 1);
1210 }
1211 }
1212#ifdef notdef
1213 textX = textY = iconX = iconY = 0; /* Suppress compiler warning. */
1214#endif
1215 iconWidth = iconHeight = 0;
1216 if (cbPtr->icon != NULL) {
1217 iconWidth = TreeViewIconWidth(cbPtr->icon);
1218 iconHeight = TreeViewIconHeight(cbPtr->icon);
1219 }
1220 textHeight = 0;
1221 gap = 0;
1222 if (cbPtr->showValue) {
1223 textHeight = textPtr->height;
1224 if (cbPtr->icon != NULL) {
1225 gap = cbPtr->gap;
1226 }
1227 }
1228 x = boxX + boxWidth + cbPtr->gap;
1229
1230 /* The icon sits to the left of the text. */
1231 iconX = x;
1232 iconY = y + (entryPtr->height - iconHeight) / 2;
1233 textX = iconX + iconWidth + gap;
1234 textY = y + (entryPtr->height - textHeight) / 2;
1235
1236 if (cbPtr->icon != NULL) {
1237 Tk_RedrawImage(TreeViewIconBits(cbPtr->icon), 0, 0, iconWidth,
1238 iconHeight, drawable, iconX, iconY);
1239 }
1240 if ((cbPtr->showValue) && (textPtr != NULL)) {
1241 TextStyle ts;
1242 XColor *color;
1243
1244 if (Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
1245 color = SELECT_FG(tvPtr);
1246 XSetForeground(tvPtr->display, gc, color->pixel);
1247 } else if (entryPtr->color != NULL) {
1248 color = entryPtr->color;
1249 XSetForeground(tvPtr->display, gc, color->pixel);
1250 } else {
1251 color = fgColor;
1252 }
1253 Blt_SetDrawTextStyle(&ts, font, gc, color, fgColor, NULL, 0.0,
1254 TK_ANCHOR_NW, TK_JUSTIFY_LEFT, 0, 0);
1255 Blt_DrawTextLayout(tvPtr->tkwin, drawable, textPtr, &ts, textX, textY);
1256 if (color != fgColor) {
1257 XSetForeground(tvPtr->display, gc, fgColor->pixel);
1258 }
1259 }
1260 stylePtr->flags &= ~STYLE_DIRTY;
1261}
1262
1263/*
1264 *----------------------------------------------------------------------
1265 *
1266 * PickCheckbox --
1267 *
1268 * Draws the "checkbox" given the screen coordinates and the
1269 * value to be displayed.
1270 *
1271 * Results:
1272 * None.
1273 *
1274 * Side Effects:
1275 * The checkbox value is drawn.
1276 *
1277 *----------------------------------------------------------------------
1278 */
1279static int
1280PickCheckBox(entryPtr, valuePtr, stylePtr, worldX, worldY)
1281 TreeViewEntry *entryPtr;
1282 TreeViewValue *valuePtr;
1283 TreeViewStyle *stylePtr;
1284 int worldX, worldY;
1285{
1286 TreeViewColumn *columnPtr;
1287 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
1288 int columnWidth;
1289 int x, y, width, height;
1290
1291 columnPtr = valuePtr->columnPtr;
1292 columnWidth = columnPtr->width -
1293 (2 * columnPtr->borderWidth + PADDING(columnPtr->pad));
1294 if (columnWidth > valuePtr->width) {
1295 switch(columnPtr->justify) {
1296 case TK_JUSTIFY_RIGHT:
1297 worldX += (columnWidth - valuePtr->width);
1298 break;
1299 case TK_JUSTIFY_CENTER:
1300 worldX += (columnWidth - valuePtr->width) / 2;
1301 break;
1302 case TK_JUSTIFY_LEFT:
1303 break;
1304 }
1305 }
1306 width = height = ODD(cbPtr->size) + 2 * cbPtr->lineWidth;
1307 x = columnPtr->worldX + columnPtr->pad.side1 + cbPtr->gap -
1308 cbPtr->lineWidth;
1309 y = entryPtr->worldY + (entryPtr->height - height) / 2;
1310 if ((worldX >= x) && (worldX < (x + width)) &&
1311 (worldY >= y) && (worldY < (y + height))) {
1312 return TRUE;
1313 }
1314 return FALSE;
1315}
1316
1317/*
1318 *----------------------------------------------------------------------
1319 *
1320 * EditCheckbox --
1321 *
1322 * Edits the "checkbox".
1323 *
1324 * Results:
1325 * None.
1326 *
1327 * Side Effects:
1328 * The checkbox value is drawn.
1329 *
1330 *----------------------------------------------------------------------
1331 */
1332static int
1333EditCheckBox(tvPtr, entryPtr, valuePtr, stylePtr)
1334 TreeView *tvPtr;
1335 TreeViewEntry *entryPtr;
1336 TreeViewValue *valuePtr;
1337 TreeViewStyle *stylePtr;
1338{
1339 TreeViewColumn *columnPtr;
1340 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
1341 Tcl_Obj *objPtr;
1342
1343 columnPtr = valuePtr->columnPtr;
1344 if (Blt_TreeGetValueByKey(tvPtr->interp, tvPtr->tree,
1345 entryPtr->node, columnPtr->key, &objPtr) != TCL_OK) {
1346 return TCL_ERROR;
1347 }
1348 if (strcmp(Tcl_GetString(objPtr), cbPtr->onValue) == 0) {
1349 objPtr = Tcl_NewStringObj(cbPtr->offValue, -1);
1350 } else {
1351 objPtr = Tcl_NewStringObj(cbPtr->onValue, -1);
1352 }
1353 entryPtr->flags |= ENTRY_DIRTY;
1354 tvPtr->flags |= (TV_DIRTY | TV_LAYOUT | TV_SCROLL | TV_RESORT);
1355 if (Blt_TreeSetValueByKey(tvPtr->interp, tvPtr->tree,
1356 entryPtr->node, columnPtr->key, objPtr) != TCL_OK) {
1357 return TCL_ERROR;
1358 }
1359 return TCL_OK;
1360}
1361
1362/*
1363 *----------------------------------------------------------------------
1364 *
1365 * FreeCheckbox --
1366 *
1367 * Releases resources allocated for the checkbox. The resources
1368 * freed by this routine are specific only to the "checkbox".
1369 * Other resources (common to all styles) are freed in the
1370 * Blt_TreeViewFreeStyle routine.
1371 *
1372 * Results:
1373 * None.
1374 *
1375 * Side Effects:
1376 * GCs allocated for the checkbox are freed.
1377 *
1378 *----------------------------------------------------------------------
1379 */
1380static void
1381FreeCheckBox(tvPtr, stylePtr)
1382 TreeView *tvPtr;
1383 TreeViewStyle *stylePtr;
1384{
1385 TreeViewCheckBox *cbPtr = (TreeViewCheckBox *)stylePtr;
1386
1387 if (cbPtr->highlightGC != NULL) {
1388 Tk_FreeGC(tvPtr->display, cbPtr->highlightGC);
1389 }
1390 if (cbPtr->activeGC != NULL) {
1391 Tk_FreeGC(tvPtr->display, cbPtr->activeGC);
1392 }
1393 if (cbPtr->gc != NULL) {
1394 Tk_FreeGC(tvPtr->display, cbPtr->gc);
1395 }
1396 if (cbPtr->fillGC != NULL) {
1397 Tk_FreeGC(tvPtr->display, cbPtr->fillGC);
1398 }
1399 if (cbPtr->boxGC != NULL) {
1400 Tk_FreeGC(tvPtr->display, cbPtr->boxGC);
1401 }
1402 if (cbPtr->checkGC != NULL) {
1403 Tk_FreeGC(tvPtr->display, cbPtr->checkGC);
1404 }
1405 if (cbPtr->icon != NULL) {
1406 Blt_TreeViewFreeIcon(tvPtr, cbPtr->icon);
1407 }
1408 if (cbPtr->offPtr != NULL) {
1409 Blt_Free(cbPtr->offPtr);
1410 }
1411 if (cbPtr->onPtr != NULL) {
1412 Blt_Free(cbPtr->onPtr);
1413 }
1414}
1415
1416/*
1417 *----------------------------------------------------------------------
1418 *
1419 * CreateComboBox --
1420 *
1421 * Creates a "combobox" style.
1422 *
1423 * Results:
1424 * A pointer to the new style structure.
1425 *
1426 *----------------------------------------------------------------------
1427 */
1428static TreeViewStyle *
1429CreateComboBox(tvPtr, hPtr)
1430 TreeView *tvPtr;
1431 Blt_HashEntry *hPtr;
1432{
1433 TreeViewComboBox *cbPtr;
1434
1435 cbPtr = Blt_Calloc(1, sizeof(TreeViewComboBox));
1436 assert(cbPtr);
1437 cbPtr->classPtr = &comboBoxClass;
1438 cbPtr->gap = STYLE_GAP;
1439 cbPtr->buttonRelief = TK_RELIEF_RAISED;
1440 cbPtr->buttonBorderWidth = 1;
1441 cbPtr->borderWidth = 1;
1442 cbPtr->relief = TK_RELIEF_FLAT;
1443 cbPtr->name = Blt_Strdup(Blt_GetHashKey(&tvPtr->styleTable, hPtr));
1444 cbPtr->hashPtr = hPtr;
1445 cbPtr->flags = STYLE_COMBOBOX;
1446 cbPtr->refCount = 1;
1447 Blt_SetHashValue(hPtr, cbPtr);
1448 return (TreeViewStyle *)cbPtr;
1449}
1450
1451/*
1452 *----------------------------------------------------------------------
1453 *
1454 * ConfigureComboBox --
1455 *
1456 * Configures a "combobox" style. This routine performs
1457 * generates the GCs required for a combobox style.
1458 *
1459 * Results:
1460 * None.
1461 *
1462 * Side Effects:
1463 * GCs are created for the style.
1464 *
1465 *----------------------------------------------------------------------
1466 */
1467static void
1468ConfigureComboBox(tvPtr, stylePtr)
1469 TreeView *tvPtr;
1470 TreeViewStyle *stylePtr;
1471{
1472 GC newGC;
1473 TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr;
1474 XColor *bgColor;
1475 XGCValues gcValues;
1476 unsigned long gcMask;
1477
1478 gcValues.font = Tk_FontId(CHOOSE(tvPtr->font, cbPtr->font));
1479 bgColor = Tk_3DBorderColor(CHOOSE(tvPtr->border, cbPtr->border));
1480 gcMask = GCForeground | GCBackground | GCFont;
1481
1482 /* Normal foreground */
1483 gcValues.background = bgColor->pixel;
1484 gcValues.foreground = CHOOSE(tvPtr->fgColor, cbPtr->fgColor)->pixel;
1485 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
1486 if (cbPtr->gc != NULL) {
1487 Tk_FreeGC(tvPtr->display, cbPtr->gc);
1488 }
1489 cbPtr->gc = newGC;
1490
1491 /* Highlight foreground */
1492 gcValues.background = Tk_3DBorderColor(cbPtr->highlightBorder)->pixel;
1493 gcValues.foreground = cbPtr->highlightFgColor->pixel;
1494 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
1495 if (cbPtr->highlightGC != NULL) {
1496 Tk_FreeGC(tvPtr->display, cbPtr->highlightGC);
1497 }
1498 cbPtr->highlightGC = newGC;
1499
1500 /* Active foreground */
1501 gcValues.background = Tk_3DBorderColor(cbPtr->activeBorder)->pixel;
1502 gcValues.foreground = cbPtr->activeFgColor->pixel;
1503 newGC = Tk_GetGC(tvPtr->tkwin, gcMask, &gcValues);
1504 if (cbPtr->activeGC != NULL) {
1505 Tk_FreeGC(tvPtr->display, cbPtr->activeGC);
1506 }
1507 cbPtr->activeGC = newGC;
1508 cbPtr->flags |= STYLE_DIRTY;
1509}
1510
1511/*
1512 *----------------------------------------------------------------------
1513 *
1514 * MeasureComboBox --
1515 *
1516 * Determines the space requirements for the "combobox" given
1517 * the value to be displayed. Depending upon whether an icon
1518 * or text is displayed and their relative placements, this
1519 * routine computes the space needed for the text entry.
1520 *
1521 * Results:
1522 * None.
1523 *
1524 * Side Effects:
1525 * The width and height fields of *valuePtr* are set with the
1526 * computed dimensions.
1527 *
1528 *----------------------------------------------------------------------
1529 */
1530static void
1531MeasureComboBox(tvPtr, stylePtr, valuePtr)
1532 TreeView *tvPtr;
1533 TreeViewStyle *stylePtr;
1534 TreeViewValue *valuePtr;
1535{
1536 TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr;
1537 int iconWidth, iconHeight;
1538 int textWidth, textHeight;
1539 int gap;
1540 Tk_Font font;
1541
1542 textWidth = textHeight = 0;
1543 iconWidth = iconHeight = 0;
1544 valuePtr->width = valuePtr->height = 0;
1545
1546 if (cbPtr->icon != NULL) {
1547 iconWidth = TreeViewIconWidth(cbPtr->icon);
1548 iconHeight = TreeViewIconHeight(cbPtr->icon);
1549 }
1550 if (valuePtr->textPtr != NULL) {
1551 Blt_Free(valuePtr->textPtr);
1552 valuePtr->textPtr = NULL;
1553 }
1554 font = CHOOSE(tvPtr->font, cbPtr->font);
1555 if (valuePtr->string != NULL) { /* New string defined. */
1556 TextStyle ts;
1557
1558 Blt_InitTextStyle(&ts);
1559 ts.font = font;
1560 ts.anchor = TK_ANCHOR_NW;
1561 ts.justify = TK_JUSTIFY_LEFT;
1562 valuePtr->textPtr = Blt_GetTextLayout(valuePtr->string, &ts);
1563 }
1564 gap = 0;
1565 if (valuePtr->textPtr != NULL) {
1566 textWidth = valuePtr->textPtr->width;
1567 textHeight = valuePtr->textPtr->height;
1568 if (cbPtr->icon != NULL) {
1569 gap = cbPtr->gap;
1570 }
1571 }
1572 cbPtr->buttonWidth = STD_ARROW_WIDTH + 6 + 2 * cbPtr->buttonBorderWidth;
1573 valuePtr->width = 2 * cbPtr->borderWidth + iconWidth + 4 * gap +
1574 cbPtr->buttonWidth + textWidth;
1575 valuePtr->height = MAX(textHeight, iconHeight) + 2 * cbPtr->borderWidth;
1576}
1577
1578
1579/*
1580 *----------------------------------------------------------------------
1581 *
1582 * DrawComboBox --
1583 *
1584 * Draws the "combobox" given the screen coordinates and the
1585 * value to be displayed.
1586 *
1587 * Results:
1588 * None.
1589 *
1590 * Side Effects:
1591 * The combobox value is drawn.
1592 *
1593 *----------------------------------------------------------------------
1594 */
1595static void
1596DrawComboBox(tvPtr, drawable, entryPtr, valuePtr, stylePtr, x, y)
1597 TreeView *tvPtr;
1598 Drawable drawable;
1599 TreeViewEntry *entryPtr;
1600 TreeViewValue *valuePtr;
1601 TreeViewStyle *stylePtr;
1602 int x, y;
1603{
1604 GC gc;
1605 TreeViewColumn *columnPtr;
1606 TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr;
1607 int iconX, iconY, iconWidth, iconHeight;
1608 int textX, textY, textHeight;
1609 int buttonX, buttonY;
1610 int gap, columnWidth;
1611 Tk_3DBorder border;
1612 XColor *fgColor;
1613
1614 columnPtr = valuePtr->columnPtr;
1615 if (stylePtr->flags & STYLE_HIGHLIGHT) {
1616 gc = cbPtr->highlightGC;
1617 border = cbPtr->highlightBorder;
1618 fgColor = cbPtr->highlightFgColor;
1619 } else {
1620 gc = cbPtr->gc;
1621 border = CHOOSE(tvPtr->border, cbPtr->border);
1622 fgColor = CHOOSE(tvPtr->fgColor, cbPtr->fgColor);
1623 }
1624 if (!Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
1625 /*
1626 * Draw the active or normal background color over the entire
1627 * label area. This includes both the tab's text and image.
1628 * The rectangle should be 2 pixels wider/taller than this
1629 * area. So if the label consists of just an image, we get an
1630 * halo around the image when the tab is active.
1631 */
1632 if (border != NULL) {
1633 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, border, x, y,
1634 columnPtr->width, entryPtr->height, cbPtr->borderWidth,
1635 cbPtr->relief);
1636 }
1637 }
1638 buttonX = x + columnPtr->width;
1639 buttonX -= columnPtr->pad.side2 + cbPtr->borderWidth +
1640 cbPtr->buttonWidth + cbPtr->gap;
1641 buttonY = y;
1642
1643 columnWidth = columnPtr->width -
1644 (2 * columnPtr->borderWidth + PADDING(columnPtr->pad));
1645 if (columnWidth > valuePtr->width) {
1646 switch(columnPtr->justify) {
1647 case TK_JUSTIFY_RIGHT:
1648 x += (columnWidth - valuePtr->width);
1649 break;
1650 case TK_JUSTIFY_CENTER:
1651 x += (columnWidth - valuePtr->width) / 2;
1652 break;
1653 case TK_JUSTIFY_LEFT:
1654 break;
1655 }
1656 }
1657
1658#ifdef notdef
1659 textX = textY = iconX = iconY = 0; /* Suppress compiler warning. */
1660#endif
1661
1662 iconWidth = iconHeight = 0;
1663 if (cbPtr->icon != NULL) {
1664 iconWidth = TreeViewIconWidth(cbPtr->icon);
1665 iconHeight = TreeViewIconHeight(cbPtr->icon);
1666 }
1667 textHeight = 0;
1668 if (valuePtr->textPtr != NULL) {
1669 textHeight = valuePtr->textPtr->height;
1670 }
1671 gap = 0;
1672 if ((cbPtr->icon != NULL) && (valuePtr->textPtr != NULL)) {
1673 gap = cbPtr->gap;
1674 }
1675
1676 iconX = x + gap;
1677 iconY = y + (entryPtr->height - iconHeight) / 2;
1678 textX = iconX + iconWidth + gap;
1679 textY = y + (entryPtr->height - textHeight) / 2;
1680
1681 if (cbPtr->icon != NULL) {
1682 Tk_RedrawImage(TreeViewIconBits(cbPtr->icon), 0, 0, iconWidth,
1683 iconHeight, drawable, iconX, iconY);
1684 }
1685 if (valuePtr->textPtr != NULL) {
1686 TextStyle ts;
1687 XColor *color;
1688 Tk_Font font;
1689
1690 font = CHOOSE(tvPtr->font, cbPtr->font);
1691 if (Blt_TreeViewEntryIsSelected(tvPtr, entryPtr)) {
1692 color = SELECT_FG(tvPtr);
1693 XSetForeground(tvPtr->display, gc, color->pixel);
1694 } else if (entryPtr->color != NULL) {
1695 color = entryPtr->color;
1696 XSetForeground(tvPtr->display, gc, color->pixel);
1697 } else {
1698 color = fgColor;
1699 }
1700 Blt_SetDrawTextStyle(&ts, font, gc, color, fgColor, NULL, 0.0,
1701 TK_ANCHOR_NW, TK_JUSTIFY_LEFT, 0, 0);
1702 Blt_DrawTextLayout(tvPtr->tkwin, drawable, valuePtr->textPtr,
1703 &ts, textX, textY);
1704 if (color != fgColor) {
1705 XSetForeground(tvPtr->display, gc, fgColor->pixel);
1706 }
1707 }
1708 if (valuePtr == tvPtr->activeValuePtr) {
1709 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, stylePtr->activeBorder,
1710 buttonX, buttonY + cbPtr->borderWidth, cbPtr->buttonWidth,
1711 entryPtr->height - 2 * cbPtr->borderWidth,
1712 cbPtr->buttonBorderWidth, cbPtr->buttonRelief);
1713 } else {
1714 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, columnPtr->titleBorder,
1715 buttonX, buttonY + cbPtr->borderWidth, cbPtr->buttonWidth,
1716 entryPtr->height - 2 * cbPtr->borderWidth,
1717 cbPtr->buttonBorderWidth, cbPtr->buttonRelief);
1718 }
1719 buttonX += cbPtr->buttonWidth / 2;
1720 buttonY += entryPtr->height / 2;
1721 Blt_DrawArrow(tvPtr->display, drawable, gc, buttonX, buttonY,
1722 STD_ARROW_HEIGHT, ARROW_DOWN);
1723 stylePtr->flags &= ~STYLE_DIRTY;
1724}
1725
1726/*
1727 *----------------------------------------------------------------------
1728 *
1729 * PickCombobox --
1730 *
1731 * Draws the "checkbox" given the screen coordinates and the
1732 * value to be displayed.
1733 *
1734 * Results:
1735 * None.
1736 *
1737 * Side Effects:
1738 * The checkbox value is drawn.
1739 *
1740 *----------------------------------------------------------------------
1741 */
1742static int
1743PickComboBox(entryPtr, valuePtr, stylePtr, worldX, worldY)
1744 TreeViewEntry *entryPtr;
1745 TreeViewValue *valuePtr;
1746 TreeViewStyle *stylePtr;
1747 int worldX, worldY;
1748{
1749 TreeViewColumn *columnPtr;
1750 TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr;
1751 int x, y, width, height;
1752
1753 columnPtr = valuePtr->columnPtr;
1754 width = cbPtr->buttonWidth;
1755 height = entryPtr->height - 4;
1756 x = columnPtr->worldX + columnPtr->width - columnPtr->pad.side2 -
1757 cbPtr->borderWidth - columnPtr->borderWidth - width;
1758 y = entryPtr->worldY + cbPtr->borderWidth;
1759 if ((worldX >= x) && (worldX < (x + width)) &&
1760 (worldY >= y) && (worldY < (y + height))) {
1761 return TRUE;
1762 }
1763 return FALSE;
1764}
1765
1766/*
1767 *----------------------------------------------------------------------
1768 *
1769 * EditCombobox --
1770 *
1771 * Edits the "combobox".
1772 *
1773 * Results:
1774 * None.
1775 *
1776 * Side Effects:
1777 * The checkbox value is drawn.
1778 *
1779 *----------------------------------------------------------------------
1780 */
1781/*ARGSUSED*/
1782static int
1783EditComboBox(tvPtr, entryPtr, valuePtr, stylePtr)
1784 TreeView *tvPtr;
1785 TreeViewEntry *entryPtr;
1786 TreeViewValue *valuePtr;
1787 TreeViewStyle *stylePtr; /* Not used. */
1788{
1789 return Blt_TreeViewTextbox(tvPtr, entryPtr, valuePtr->columnPtr);
1790}
1791
1792/*
1793 *----------------------------------------------------------------------
1794 *
1795 * FreeComboBox --
1796 *
1797 * Releases resources allocated for the combobox. The resources
1798 * freed by this routine are specific only to the "combobox".
1799 * Other resources (common to all styles) are freed in the
1800 * Blt_TreeViewFreeStyle routine.
1801 *
1802 * Results:
1803 * None.
1804 *
1805 * Side Effects:
1806 * GCs allocated for the combobox are freed.
1807 *
1808 *----------------------------------------------------------------------
1809 */
1810static void
1811FreeComboBox(tvPtr, stylePtr)
1812 TreeView *tvPtr;
1813 TreeViewStyle *stylePtr;
1814{
1815 TreeViewComboBox *cbPtr = (TreeViewComboBox *)stylePtr;
1816
1817 if (cbPtr->highlightGC != NULL) {
1818 Tk_FreeGC(tvPtr->display, cbPtr->highlightGC);
1819 }
1820 if (cbPtr->activeGC != NULL) {
1821 Tk_FreeGC(tvPtr->display, cbPtr->activeGC);
1822 }
1823 if (cbPtr->gc != NULL) {
1824 Tk_FreeGC(tvPtr->display, cbPtr->gc);
1825 }
1826 if (cbPtr->icon != NULL) {
1827 Blt_TreeViewFreeIcon(tvPtr, cbPtr->icon);
1828 }
1829}
1830
1831static TreeViewStyle *
1832GetStyle(interp, tvPtr, styleName)
1833 Tcl_Interp *interp;
1834 TreeView *tvPtr;
1835 char *styleName;
1836{
1837 Blt_HashEntry *hPtr;
1838
1839 hPtr = Blt_FindHashEntry(&tvPtr->styleTable, styleName);
1840 if (hPtr == NULL) {
1841 if (interp != NULL) {
1842 Tcl_AppendResult(interp, "can't find cell style \"", styleName,
1843 "\"", (char *)NULL);
1844 }
1845 return NULL;
1846 }
1847 return Blt_GetHashValue(hPtr);
1848}
1849
1850int
1851Blt_TreeViewGetStyle(interp, tvPtr, styleName, stylePtrPtr)
1852 Tcl_Interp *interp;
1853 TreeView *tvPtr;
1854 char *styleName;
1855 TreeViewStyle **stylePtrPtr;
1856{
1857 TreeViewStyle *stylePtr;
1858
1859 stylePtr = GetStyle(interp, tvPtr, styleName);
1860 if (stylePtr == NULL) {
1861 return TCL_ERROR;
1862 }
1863 stylePtr->refCount++;
1864 *stylePtrPtr = stylePtr;
1865 return TCL_OK;
1866}
1867
1868static TreeViewStyle *
1869CreateStyle(interp, tvPtr, type, styleName, objc, objv)
1870 Tcl_Interp *interp;
1871 TreeView *tvPtr; /* TreeView widget. */
1872 int type; /* Type of style: either
1873 * STYLE_TEXTBOX,
1874 * STYLE_COMBOBOX, or
1875 * STYLE_CHECKBOX */
1876 char *styleName; /* Name of the new style. */
1877 int objc;
1878 Tcl_Obj *CONST *objv;
1879{
1880 Blt_HashEntry *hPtr;
1881 int isNew;
1882 TreeViewStyle *stylePtr;
1883
1884 hPtr = Blt_CreateHashEntry(&tvPtr->styleTable, styleName, &isNew);
1885 if (!isNew) {
1886 if (interp != NULL) {
1887 Tcl_AppendResult(interp, "cell style \"", styleName,
1888 "\" already exists", (char *)NULL);
1889 }
1890 return NULL;
1891 }
1892 /* Create the new marker based upon the given type */
1893 switch (type) {
1894 case STYLE_TEXTBOX:
1895 stylePtr = CreateTextBox(tvPtr, hPtr);
1896 break;
1897 case STYLE_COMBOBOX:
1898 stylePtr = CreateComboBox(tvPtr, hPtr);
1899 break;
1900 case STYLE_CHECKBOX:
1901 stylePtr = CreateCheckBox(tvPtr, hPtr);
1902 break;
1903 default:
1904 return NULL;
1905 }
1906 bltTreeViewIconOption.clientData = tvPtr;
1907 if (Blt_ConfigureComponentFromObj(interp, tvPtr->tkwin, styleName,
1908 stylePtr->classPtr->className, stylePtr->classPtr->specsPtr,
1909 objc, objv, (char *)stylePtr, 0) != TCL_OK) {
1910 Blt_TreeViewFreeStyle(tvPtr, stylePtr);
1911 return NULL;
1912 }
1913 return stylePtr;
1914}
1915
1916void
1917Blt_TreeViewUpdateStyleGCs(tvPtr, stylePtr)
1918 TreeView *tvPtr;
1919 TreeViewStyle *stylePtr;
1920{
1921 (*stylePtr->classPtr->configProc)(tvPtr, stylePtr);
1922 stylePtr->flags |= STYLE_DIRTY;
1923 Blt_TreeViewEventuallyRedraw(tvPtr);
1924}
1925
1926TreeViewStyle *
1927Blt_TreeViewCreateStyle(interp, tvPtr, type, styleName)
1928 Tcl_Interp *interp;
1929 TreeView *tvPtr; /* TreeView widget. */
1930 int type; /* Type of style: either
1931 * STYLE_TEXTBOX,
1932 * STYLE_COMBOBOX, or
1933 * STYLE_CHECKBOX */
1934 char *styleName; /* Name of the new style. */
1935{
1936 return CreateStyle(interp, tvPtr, type, styleName, 0, (Tcl_Obj **)NULL);
1937}
1938
1939void
1940Blt_TreeViewFreeStyle(tvPtr, stylePtr)
1941 TreeView *tvPtr;
1942 TreeViewStyle *stylePtr;
1943{
1944 stylePtr->refCount--;
1945#ifdef notdef
1946 fprint(f(stderr, "Blt_TreeViewFreeStyle %s count=%d\n", stylePtr->name,
1947 stylePtr->refCount);
1948#endif
1949 /* Remove the style from the hash table so that it's name can be used.*/
1950 /* If no cell is using the style, remove it.*/
1951 if ((stylePtr->refCount <= 0) && !(stylePtr->flags & STYLE_USER)){
1952#ifdef notdef
1953 fprintf(stderr, "freeing %s\n", stylePtr->name);
1954#endif
1955 bltTreeViewIconOption.clientData = tvPtr;
1956 Blt_FreeObjOptions(stylePtr->classPtr->specsPtr, (char *)stylePtr,
1957 tvPtr->display, 0);
1958 (*stylePtr->classPtr->freeProc)(tvPtr, stylePtr);
1959 if (stylePtr->hashPtr != NULL) {
1960 Blt_DeleteHashEntry(&tvPtr->styleTable, stylePtr->hashPtr);
1961 }
1962 if (stylePtr->name != NULL) {
1963 Blt_Free(stylePtr->name);
1964 }
1965 Blt_Free(stylePtr);
1966 }
1967}
1968
1969void
1970Blt_TreeViewSetStyleIcon(tvPtr, stylePtr, icon)
1971 TreeView *tvPtr;
1972 TreeViewStyle *stylePtr;
1973 TreeViewIcon icon;
1974{
1975 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
1976
1977 if (tbPtr->icon != NULL) {
1978 Blt_TreeViewFreeIcon(tvPtr, tbPtr->icon);
1979 }
1980 tbPtr->icon = icon;
1981}
1982
1983GC
1984Blt_TreeViewGetStyleGC(stylePtr)
1985 TreeViewStyle *stylePtr;
1986{
1987 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
1988 return tbPtr->gc;
1989}
1990
1991Tk_3DBorder
1992Blt_TreeViewGetStyleBorder(tvPtr, stylePtr)
1993 TreeView *tvPtr;
1994 TreeViewStyle *stylePtr;
1995{
1996 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
1997 Tk_3DBorder border;
1998
1999 border = (tbPtr->flags & STYLE_HIGHLIGHT)
2000 ? tbPtr->highlightBorder : tbPtr->border;
2001 return (border != NULL) ? border : tvPtr->border;
2002}
2003
2004Tk_Font
2005Blt_TreeViewGetStyleFont(tvPtr, stylePtr)
2006 TreeView *tvPtr;
2007 TreeViewStyle *stylePtr;
2008{
2009 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
2010
2011 if (tbPtr->font != NULL) {
2012 return tbPtr->font;
2013 }
2014 return tvPtr->font;
2015}
2016
2017XColor *
2018Blt_TreeViewGetStyleFg(tvPtr, stylePtr)
2019 TreeView *tvPtr;
2020 TreeViewStyle *stylePtr;
2021{
2022 TreeViewTextBox *tbPtr = (TreeViewTextBox *)stylePtr;
2023
2024 if (tbPtr->fgColor != NULL) {
2025 return tbPtr->fgColor;
2026 }
2027 return tvPtr->fgColor;
2028}
2029
2030static void
2031DrawValue(tvPtr, entryPtr, valuePtr)
2032 TreeView *tvPtr;
2033 TreeViewEntry *entryPtr;
2034 TreeViewValue *valuePtr;
2035{
2036 Drawable drawable;
2037 int sx, sy, dx, dy;
2038 int width, height;
2039 int left, right, top, bottom;
2040 TreeViewColumn *columnPtr;
2041 TreeViewStyle *stylePtr;
2042
2043 stylePtr = valuePtr->stylePtr;
2044 if (stylePtr == NULL) {
2045 stylePtr = valuePtr->columnPtr->stylePtr;
2046 }
2047 if (stylePtr->cursor != None) {
2048 if (valuePtr == tvPtr->activeValuePtr) {
2049 Tk_DefineCursor(tvPtr->tkwin, stylePtr->cursor);
2050 } else {
2051 if (tvPtr->cursor != None) {
2052 Tk_DefineCursor(tvPtr->tkwin, tvPtr->cursor);
2053 } else {
2054 Tk_UndefineCursor(tvPtr->tkwin);
2055 }
2056 }
2057 }
2058 columnPtr = valuePtr->columnPtr;
2059 dx = SCREENX(tvPtr, columnPtr->worldX) + columnPtr->pad.side1;
2060 dy = SCREENY(tvPtr, entryPtr->worldY);
2061 height = entryPtr->height - 1;
2062 width = valuePtr->columnPtr->width - PADDING(columnPtr->pad);
2063
2064 top = tvPtr->titleHeight + tvPtr->inset;
2065 bottom = Tk_Height(tvPtr->tkwin) - tvPtr->inset;
2066 left = tvPtr->inset;
2067 right = Tk_Width(tvPtr->tkwin) - tvPtr->inset;
2068
2069 if (((dx + width) < left) || (dx > right) ||
2070 ((dy + height) < top) || (dy > bottom)) {
2071 return; /* Value is clipped. */
2072 }
2073
2074 drawable = Tk_GetPixmap(tvPtr->display, Tk_WindowId(tvPtr->tkwin),
2075 width, height, Tk_Depth(tvPtr->tkwin));
2076 /* Draw the background of the value. */
2077 if ((valuePtr == tvPtr->activeValuePtr) ||
2078 (!Blt_TreeViewEntryIsSelected(tvPtr, entryPtr))) {
2079 Tk_3DBorder border;
2080
2081 border = Blt_TreeViewGetStyleBorder(tvPtr, tvPtr->stylePtr);
2082 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, border, 0, 0, width, height,
2083 0, TK_RELIEF_FLAT);
2084 } else {
2085 Blt_Fill3DRectangle(tvPtr->tkwin, drawable, SELECT_BORDER(tvPtr), 0, 0,
2086 width, height, tvPtr->selBorderWidth, tvPtr->selRelief);
2087 }
2088 Blt_TreeViewDrawValue(tvPtr, entryPtr, valuePtr, drawable, 0, 0);
2089
2090 /* Clip the drawable if necessary */
2091 sx = sy = 0;
2092 if (dx < left) {
2093 width -= left - dx;
2094 sx += left - dx;
2095 dx = left;
2096 }
2097 if ((dx + width) >= right) {
2098 width -= (dx + width) - right;
2099 }
2100 if (dy < top) {
2101 height -= top - dy;
2102 sy += top - dy;
2103 dy = top;
2104 }
2105 if ((dy + height) >= bottom) {
2106 height -= (dy + height) - bottom;
2107 }
2108 XCopyArea(tvPtr->display, drawable, Tk_WindowId(tvPtr->tkwin),
2109 tvPtr->lineGC, sx, sy, width, height, dx, dy);
2110 Tk_FreePixmap(tvPtr->display, drawable);
2111}
2112
2113/*
2114 *----------------------------------------------------------------------
2115 *
2116 * StyleActivateOp --
2117 *
2118 * Turns on/off highlighting for a particular style.
2119 *
2120 * .t style activate entry column
2121 *
2122 * Results:
2123 * A standard Tcl result. If TCL_ERROR is returned, then
2124 * interp->result contains an error message.
2125 *
2126 *----------------------------------------------------------------------
2127 */
2128/*ARGSUSED*/
2129static int
2130StyleActivateOp(tvPtr, interp, objc, objv)
2131 TreeView *tvPtr;
2132
2133 Tcl_Interp *interp;
2134 int objc; /* Not used. */
2135 Tcl_Obj *CONST *objv;
2136{
2137 TreeViewEntry *entryPtr;
2138 TreeViewValue *valuePtr, *oldPtr;
2139
2140 oldPtr = tvPtr->activeValuePtr;
2141 if (objc == 3) {
2142 Tcl_Obj *listObjPtr;
2143
2144 valuePtr = tvPtr->activeValuePtr;
2145 entryPtr = tvPtr->activePtr;
2146 listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
2147 if ((entryPtr != NULL) && (valuePtr != NULL)) {
2148 Tcl_Obj *objPtr;
2149 objPtr = Tcl_NewIntObj(Blt_TreeNodeId(entryPtr->node));
2150 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
2151 objPtr = Tcl_NewStringObj(valuePtr->columnPtr->key, -1);
2152 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
2153 }
2154 Tcl_SetObjResult(interp, listObjPtr);
2155 return TCL_OK;
2156 } else if (objc == 4) {
2157 tvPtr->activeValuePtr = NULL;
2158 if ((oldPtr != NULL) && (tvPtr->activePtr != NULL)) {
2159 DrawValue(tvPtr, tvPtr->activePtr, oldPtr);
2160 }
2161 } else {
2162 TreeViewColumn *columnPtr;
2163
2164 if (Blt_TreeViewGetEntry(tvPtr, objv[3], &entryPtr) != TCL_OK) {
2165 return TCL_ERROR;
2166 }
2167
2168 if (Blt_TreeViewGetColumn(interp, tvPtr, objv[4], &columnPtr)
2169 != TCL_OK) {
2170 return TCL_ERROR;
2171 }
2172 valuePtr = Blt_TreeViewFindValue(entryPtr, columnPtr);
2173 if (valuePtr == NULL) {
2174 return TCL_OK;
2175 }
2176 tvPtr->activePtr = entryPtr;
2177 tvPtr->activeColumnPtr = columnPtr;
2178 oldPtr = tvPtr->activeValuePtr;
2179 tvPtr->activeValuePtr = valuePtr;
2180 if (valuePtr != oldPtr) {
2181 if (oldPtr != NULL) {
2182 DrawValue(tvPtr, entryPtr, oldPtr);
2183 }
2184 if (valuePtr != NULL) {
2185 DrawValue(tvPtr, entryPtr, valuePtr);
2186 }
2187 }
2188 }
2189 return TCL_OK;
2190}
2191
2192
2193/*
2194 *----------------------------------------------------------------------
2195 *
2196 * StyleCgetOp --
2197 *
2198 * .t style cget "styleName" -background
2199 *
2200 *----------------------------------------------------------------------
2201 */
2202/*ARGSUSED*/
2203static int
2204StyleCgetOp(tvPtr, interp, objc, objv)
2205 TreeView *tvPtr;
2206 Tcl_Interp *interp;
2207 int objc; /* Not used. */
2208 Tcl_Obj *CONST *objv;
2209{
2210 TreeViewStyle *stylePtr;
2211
2212 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[3]));
2213 if (stylePtr == NULL) {
2214 return TCL_ERROR;
2215 }
2216 return Blt_ConfigureValueFromObj(interp, tvPtr->tkwin,
2217 stylePtr->classPtr->specsPtr, (char *)tvPtr, objv[4], 0);
2218}
2219
2220/*
2221 *----------------------------------------------------------------------
2222 *
2223 * StyleCheckBoxOp --
2224 *
2225 * .t style checkbox "styleName" -background blue
2226 *
2227 *----------------------------------------------------------------------
2228 */
2229/*ARGSUSED*/
2230static int
2231StyleCheckBoxOp(tvPtr, interp, objc, objv)
2232 TreeView *tvPtr;
2233 Tcl_Interp *interp;
2234 int objc; /* Not used. */
2235 Tcl_Obj *CONST *objv;
2236{
2237 TreeViewStyle *stylePtr;
2238
2239 stylePtr = CreateStyle(interp, tvPtr, STYLE_CHECKBOX,
2240 Tcl_GetString(objv[3]), objc - 4, objv + 4);
2241 if (stylePtr == NULL) {
2242 return TCL_ERROR;
2243 }
2244 stylePtr->refCount = 0;
2245 stylePtr->flags |= STYLE_USER;
2246 Blt_TreeViewUpdateStyleGCs(tvPtr, stylePtr);
2247 Tcl_SetObjResult(interp, objv[3]);
2248 return TCL_OK;
2249}
2250
2251/*
2252 *----------------------------------------------------------------------
2253 *
2254 * StyleComboBoxOp --
2255 *
2256 * .t style combobox "styleName" -background blue
2257 *
2258 *----------------------------------------------------------------------
2259 */
2260/*ARGSUSED*/
2261static int
2262StyleComboBoxOp(tvPtr, interp, objc, objv)
2263 TreeView *tvPtr;
2264 Tcl_Interp *interp;
2265 int objc; /* Not used. */
2266 Tcl_Obj *CONST *objv;
2267{
2268 TreeViewStyle *stylePtr;
2269
2270 stylePtr = CreateStyle(interp, tvPtr, STYLE_COMBOBOX,
2271 Tcl_GetString(objv[3]), objc - 4, objv + 4);
2272 if (stylePtr == NULL) {
2273 return TCL_ERROR;
2274 }
2275 stylePtr->refCount = 0;
2276 stylePtr->flags |= STYLE_USER;
2277 Blt_TreeViewUpdateStyleGCs(tvPtr, stylePtr);
2278 Tcl_SetObjResult(interp, objv[3]);
2279 return TCL_OK;
2280}
2281
2282/*
2283 *----------------------------------------------------------------------
2284 *
2285 * StyleConfigureOp --
2286 *
2287 * This procedure is called to process a list of configuration
2288 * options database, in order to reconfigure a style.
2289 *
2290 * .t style configure "styleName" option value
2291 *
2292 * Results:
2293 * A standard Tcl result. If TCL_ERROR is returned, then
2294 * interp->result contains an error message.
2295 *
2296 * Side effects:
2297 * Configuration information, such as text string, colors, font,
2298 * etc. get set for stylePtr; old resources get freed, if there
2299 * were any.
2300 *
2301 *----------------------------------------------------------------------
2302 */
2303static int
2304StyleConfigureOp(tvPtr, interp, objc, objv)
2305 TreeView *tvPtr;
2306 Tcl_Interp *interp;
2307 int objc;
2308 Tcl_Obj *CONST *objv;
2309{
2310 TreeViewStyle *stylePtr;
2311
2312 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[3]));
2313 if (stylePtr == NULL) {
2314 return TCL_ERROR;
2315 }
2316 if (objc == 4) {
2317 return Blt_ConfigureInfoFromObj(interp, tvPtr->tkwin,
2318 stylePtr->classPtr->specsPtr, (char *)stylePtr, (Tcl_Obj *)NULL, 0);
2319 } else if (objc == 5) {
2320 return Blt_ConfigureInfoFromObj(interp, tvPtr->tkwin,
2321 stylePtr->classPtr->specsPtr, (char *)stylePtr, objv[5], 0);
2322 }
2323 bltTreeViewIconOption.clientData = tvPtr;
2324 if (Blt_ConfigureWidgetFromObj(interp, tvPtr->tkwin,
2325 stylePtr->classPtr->specsPtr, objc - 4, objv + 4, (char *)stylePtr,
2326 BLT_CONFIG_OBJV_ONLY) != TCL_OK) {
2327 return TCL_ERROR;
2328 }
2329 (*stylePtr->classPtr->configProc)(tvPtr, stylePtr);
2330 stylePtr->flags |= STYLE_DIRTY;
2331 tvPtr->flags |= (TV_LAYOUT | TV_DIRTY);
2332 Blt_TreeViewEventuallyRedraw(tvPtr);
2333 return TCL_OK;
2334}
2335
2336/*
2337 *----------------------------------------------------------------------
2338 *
2339 * StyleForgetOp --
2340 *
2341 * Eliminates one or more style names. A style still may be in
2342 * use after its name has been officially removed. Only its hash
2343 * table entry is removed. The style itself remains until its
2344 * reference count returns to zero (i.e. no one else is using it).
2345 *
2346 * .t style forget "styleName"...
2347 *
2348 * Results:
2349 * A standard Tcl result. If TCL_ERROR is returned, then
2350 * interp->result contains an error message.
2351 *
2352 *----------------------------------------------------------------------
2353 */
2354static int
2355StyleForgetOp(tvPtr, interp, objc, objv)
2356 TreeView *tvPtr;
2357
2358 Tcl_Interp *interp;
2359 int objc;
2360 Tcl_Obj *CONST *objv;
2361{
2362 TreeViewStyle *stylePtr;
2363 int i;
2364
2365 for (i = 3; i < objc; i++) {
2366 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[i]));
2367 if (stylePtr == NULL) {
2368 return TCL_ERROR;
2369 }
2370 if (stylePtr->hashPtr != NULL) {
2371 Blt_DeleteHashEntry(&tvPtr->styleTable, stylePtr->hashPtr);
2372 stylePtr->hashPtr = NULL;
2373 }
2374 stylePtr->flags &= ~STYLE_USER;
2375 if (stylePtr->refCount <= 0) {
2376 Blt_TreeViewFreeStyle(tvPtr, stylePtr);
2377 }
2378 }
2379 Blt_TreeViewEventuallyRedraw(tvPtr);
2380 return TCL_OK;
2381}
2382
2383/*
2384 *----------------------------------------------------------------------
2385 *
2386 * StyleHighlightOp --
2387 *
2388 * Turns on/off highlighting for a particular style.
2389 *
2390 * .t style highlight styleName on|off
2391 *
2392 * Results:
2393 * A standard Tcl result. If TCL_ERROR is returned, then
2394 * interp->result contains an error message.
2395 *
2396 *----------------------------------------------------------------------
2397 */
2398/*ARGSUSED*/
2399static int
2400StyleHighlightOp(tvPtr, interp, objc, objv)
2401 TreeView *tvPtr;
2402
2403 Tcl_Interp *interp;
2404 int objc; /* Not used. */
2405 Tcl_Obj *CONST *objv;
2406{
2407 TreeViewStyle *stylePtr;
2408 int bool, oldBool;
2409
2410 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[3]));
2411 if (stylePtr == NULL) {
2412 return TCL_ERROR;
2413 }
2414 if (Tcl_GetBooleanFromObj(interp, objv[4], &bool) != TCL_OK) {
2415 return TCL_ERROR;
2416 }
2417 oldBool = ((stylePtr->flags & STYLE_HIGHLIGHT) != 0);
2418 if (oldBool != bool) {
2419 if (bool) {
2420 stylePtr->flags |= STYLE_HIGHLIGHT;
2421 } else {
2422 stylePtr->flags &= ~STYLE_HIGHLIGHT;
2423 }
2424 Blt_TreeViewEventuallyRedraw(tvPtr);
2425 }
2426 return TCL_OK;
2427}
2428
2429/*
2430 *----------------------------------------------------------------------
2431 *
2432 * StyleNamesOp --
2433 *
2434 * Lists the names of all the current styles in the treeview widget.
2435 *
2436 * .t style names
2437 *
2438 * Results:
2439 * Always TCL_OK.
2440 *
2441 *----------------------------------------------------------------------
2442 */
2443/*ARGSUSED*/
2444static int
2445StyleNamesOp(tvPtr, interp, objc, objv)
2446 TreeView *tvPtr;
2447
2448 Tcl_Interp *interp;
2449 int objc; /* Not used. */
2450 Tcl_Obj *CONST *objv; /* Not used. */
2451{
2452 Blt_HashEntry *hPtr;
2453 Blt_HashSearch cursor;
2454 Tcl_Obj *listObjPtr, *objPtr;
2455 TreeViewStyle *stylePtr;
2456
2457 listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL);
2458 for (hPtr = Blt_FirstHashEntry(&tvPtr->styleTable, &cursor); hPtr != NULL;
2459 hPtr = Blt_NextHashEntry(&cursor)) {
2460 stylePtr = Blt_GetHashValue(hPtr);
2461 objPtr = Tcl_NewStringObj(stylePtr->name, -1);
2462 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
2463 }
2464 Tcl_SetObjResult(interp, listObjPtr);
2465 return TCL_OK;
2466}
2467
2468/*
2469 *----------------------------------------------------------------------
2470 *
2471 * StyleSetOp --
2472 *
2473 * Sets a style for a given key for all the ids given.
2474 *
2475 * .t style set styleName key node...
2476 *
2477 * Results:
2478 * A standard Tcl result. If TCL_ERROR is returned, then
2479 * interp->result contains an error message.
2480 *
2481 *----------------------------------------------------------------------
2482 */
2483static int
2484StyleSetOp(tvPtr, interp, objc, objv)
2485 TreeView *tvPtr;
2486
2487 Tcl_Interp *interp;
2488 int objc;
2489 Tcl_Obj *CONST *objv;
2490{
2491 Blt_TreeKey key;
2492 TreeViewEntry *entryPtr;
2493 TreeViewStyle *stylePtr, *oldStylePtr;
2494 TreeViewTagInfo info;
2495 int i;
2496
2497 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[3]));
2498 if (stylePtr == NULL) {
2499 return TCL_ERROR;
2500 }
2501 key = Blt_TreeGetKey(Tcl_GetString(objv[4]));
2502 stylePtr->flags |= STYLE_LAYOUT;
2503 for (i = 5; i < objc; i++) {
2504 if (Blt_TreeViewFindTaggedEntries(tvPtr, objv[i], &info) != TCL_OK) {
2505 return TCL_ERROR;
2506 }
2507 for (entryPtr = Blt_TreeViewFirstTaggedEntry(&info); entryPtr != NULL;
2508 entryPtr = Blt_TreeViewNextTaggedEntry(&info)) {
2509 register TreeViewValue *valuePtr;
2510
2511 for (valuePtr = entryPtr->values; valuePtr != NULL;
2512 valuePtr = valuePtr->nextPtr) {
2513 if (valuePtr->columnPtr->key == key) {
2514 stylePtr->refCount++;
2515 oldStylePtr = valuePtr->stylePtr;
2516 valuePtr->stylePtr = stylePtr;
2517 if (oldStylePtr != NULL) {
2518 Blt_TreeViewFreeStyle(tvPtr, oldStylePtr);
2519 }
2520 break;
2521 }
2522 }
2523 }
2524 }
2525 Blt_TreeViewEventuallyRedraw(tvPtr);
2526 return TCL_OK;
2527}
2528
2529/*
2530 *----------------------------------------------------------------------
2531 *
2532 * StyleTextBoxOp --
2533 *
2534 * .t style text "styleName" -background blue
2535 *
2536 *----------------------------------------------------------------------
2537 */
2538/*ARGSUSED*/
2539static int
2540StyleTextBoxOp(tvPtr, interp, objc, objv)
2541 TreeView *tvPtr;
2542 Tcl_Interp *interp;
2543 int objc; /* Not used. */
2544 Tcl_Obj *CONST *objv;
2545{
2546 TreeViewStyle *stylePtr;
2547
2548 stylePtr = CreateStyle(interp, tvPtr, STYLE_TEXTBOX,
2549 Tcl_GetString(objv[3]), objc - 4, objv + 4);
2550 if (stylePtr == NULL) {
2551 return TCL_ERROR;
2552 }
2553 stylePtr->refCount = 0;
2554 stylePtr->flags |= STYLE_USER;
2555 Blt_TreeViewUpdateStyleGCs(tvPtr, stylePtr);
2556 Tcl_SetObjResult(interp, objv[3]);
2557 return TCL_OK;
2558}
2559
2560/*
2561 *----------------------------------------------------------------------
2562 *
2563 * StyleUnsetOp --
2564 *
2565 * Removes a style for a given key for all the ids given.
2566 * The cell's style is returned to its default state.
2567 *
2568 * .t style unset styleName key node...
2569 *
2570 * Results:
2571 * A standard Tcl result. If TCL_ERROR is returned, then
2572 * interp->result contains an error message.
2573 *
2574 *----------------------------------------------------------------------
2575 */
2576static int
2577StyleUnsetOp(tvPtr, interp, objc, objv)
2578 TreeView *tvPtr;
2579 Tcl_Interp *interp;
2580 int objc;
2581 Tcl_Obj *CONST *objv;
2582{
2583 Blt_TreeKey key;
2584 TreeViewEntry *entryPtr;
2585 TreeViewStyle *stylePtr;
2586 TreeViewTagInfo info;
2587 int i;
2588
2589 stylePtr = GetStyle(interp, tvPtr, Tcl_GetString(objv[3]));
2590 if (stylePtr == NULL) {
2591 return TCL_ERROR;
2592 }
2593 key = Blt_TreeGetKey(Tcl_GetString(objv[4]));
2594 stylePtr->flags |= STYLE_LAYOUT;
2595 for (i = 5; i < objc; i++) {
2596 if (Blt_TreeViewFindTaggedEntries(tvPtr, objv[i], &info) != TCL_OK) {
2597 return TCL_ERROR;
2598 }
2599 for (entryPtr = Blt_TreeViewFirstTaggedEntry(&info); entryPtr != NULL;
2600 entryPtr = Blt_TreeViewNextTaggedEntry(&info)) {
2601 register TreeViewValue *valuePtr;
2602
2603 for (valuePtr = entryPtr->values; valuePtr != NULL;
2604 valuePtr = valuePtr->nextPtr) {
2605 if (valuePtr->columnPtr->key == key) {
2606 if (valuePtr->stylePtr != NULL) {
2607 Blt_TreeViewFreeStyle(tvPtr, valuePtr->stylePtr);
2608 valuePtr->stylePtr = NULL;
2609 }
2610 break;
2611 }
2612 }
2613 }
2614 }
2615 Blt_TreeViewEventuallyRedraw(tvPtr);
2616 return TCL_OK;
2617}
2618
2619/*
2620 *----------------------------------------------------------------------
2621 *
2622 * StyleOp --
2623 *
2624 * .t style activate $node $column
2625 * .t style activate
2626 * .t style cget "highlight" -foreground
2627 * .t style configure "highlight" -fg blue -bg green
2628 * .t style checkbox "highlight"
2629 * .t style highlight "highlight" on|off
2630 * .t style combobox "highlight"
2631 * .t style text "highlight"
2632 * .t style forget "highlight"
2633 * .t style get "mtime" $node
2634 * .t style names
2635 * .t style set "mtime" "highlight" all
2636 * .t style unset "mtime" all
2637 *
2638 *----------------------------------------------------------------------
2639 */
2640static Blt_OpSpec styleOps[] = {
2641 {"activate", 1, (Blt_Op)StyleActivateOp, 3, 5,"entry column",},
2642 {"cget", 2, (Blt_Op)StyleCgetOp, 5, 5, "styleName option",},
2643 {"checkbox", 2, (Blt_Op)StyleCheckBoxOp, 4, 0, "styleName options...",},
2644 {"combobox", 3, (Blt_Op)StyleComboBoxOp, 4, 0, "styleName options...",},
2645 {"configure", 3, (Blt_Op)StyleConfigureOp, 4, 0, "styleName options...",},
2646 {"forget", 1, (Blt_Op)StyleForgetOp, 3, 0, "styleName...",},
2647 {"highlight", 1, (Blt_Op)StyleHighlightOp, 5, 5, "styleName boolean",},
2648 {"names", 1, (Blt_Op)StyleNamesOp, 3, 3, "",},
2649 {"set", 1, (Blt_Op)StyleSetOp, 6, 6, "key styleName tagOrId...",},
2650 {"textbox", 1, (Blt_Op)StyleTextBoxOp, 4, 0, "styleName options...",},
2651 {"unset", 1, (Blt_Op)StyleUnsetOp, 5, 5, "key tagOrId",},
2652};
2653
2654static int nStyleOps = sizeof(styleOps) / sizeof(Blt_OpSpec);
2655
2656int
2657Blt_TreeViewStyleOp(tvPtr, interp, objc, objv)
2658 TreeView *tvPtr;
2659 Tcl_Interp *interp;
2660 int objc;
2661 Tcl_Obj *CONST *objv;
2662{
2663 Blt_Op proc;
2664 int result;
2665
2666 proc = Blt_GetOpFromObj(interp, nStyleOps, styleOps, BLT_OP_ARG2, objc,
2667 objv, 0);
2668 if (proc == NULL) {
2669 return TCL_ERROR;
2670 }
2671 result = (*proc)(tvPtr, interp, objc, objv);
2672 return result;
2673}
2674#endif /* NO_TREEVIEW */
Note: See TracBrowser for help on using the repository browser.