/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkscrollbar.c
ViewVC logotype

Contents of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkscrollbar.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (show annotations) (download)
Sat Nov 5 10:54:17 2016 UTC (6 years, 3 months ago) by dashley
File MIME type: text/plain
File size: 22972 byte(s)
License and property (keyword) changes.
1 /* $Header$ */
2
3 /*
4 * tkScrollbar.c --
5 *
6 * This module implements a scrollbar widgets for the Tk
7 * toolkit. A scrollbar displays a slider and two arrows;
8 * mouse clicks on features within the scrollbar cause
9 * scrolling commands to be invoked.
10 *
11 * Copyright (c) 1990-1994 The Regents of the University of California.
12 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
13 *
14 * See the file "license.terms" for information on usage and redistribution
15 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 *
17 * RCS: @(#) $Id: tkscrollbar.c,v 1.1.1.1 2001/06/13 05:07:52 dtashley Exp $
18 */
19
20 #include "tkPort.h"
21 #include "tkScrollbar.h"
22 #include "default.h"
23
24 /*
25 * Custom option for handling "-orient"
26 */
27
28 static Tk_CustomOption orientOption = {
29 (Tk_OptionParseProc *) TkOrientParseProc,
30 TkOrientPrintProc,
31 (ClientData) NULL
32 };
33
34 /*
35 * Information used for argv parsing.
36 */
37
38 Tk_ConfigSpec tkpScrollbarConfigSpecs[] = {
39 {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
40 DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(TkScrollbar, activeBorder),
41 TK_CONFIG_COLOR_ONLY},
42 {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
43 DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(TkScrollbar, activeBorder),
44 TK_CONFIG_MONO_ONLY},
45 {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
46 DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(TkScrollbar, activeRelief), 0},
47 {TK_CONFIG_BORDER, "-background", "background", "Background",
48 DEF_SCROLLBAR_BG_COLOR, Tk_Offset(TkScrollbar, bgBorder),
49 TK_CONFIG_COLOR_ONLY},
50 {TK_CONFIG_BORDER, "-background", "background", "Background",
51 DEF_SCROLLBAR_BG_MONO, Tk_Offset(TkScrollbar, bgBorder),
52 TK_CONFIG_MONO_ONLY},
53 {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
54 (char *) NULL, 0, 0},
55 {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
56 (char *) NULL, 0, 0},
57 {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
58 DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(TkScrollbar, borderWidth), 0},
59 {TK_CONFIG_STRING, "-command", "command", "Command",
60 DEF_SCROLLBAR_COMMAND, Tk_Offset(TkScrollbar, command),
61 TK_CONFIG_NULL_OK},
62 {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
63 DEF_SCROLLBAR_CURSOR, Tk_Offset(TkScrollbar, cursor), TK_CONFIG_NULL_OK},
64 {TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth",
65 "BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH,
66 Tk_Offset(TkScrollbar, elementBorderWidth), 0},
67 {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
68 "HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
69 Tk_Offset(TkScrollbar, highlightBgColorPtr), 0},
70 {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
71 DEF_SCROLLBAR_HIGHLIGHT,
72 Tk_Offset(TkScrollbar, highlightColorPtr), 0},
73 {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
74 "HighlightThickness",
75 DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0},
76 {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
77 DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0},
78 {TK_CONFIG_CUSTOM, "-orient", "orient", "Orient",
79 DEF_SCROLLBAR_ORIENT, Tk_Offset(TkScrollbar, vertical), 0,
80 &orientOption},
81 {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
82 DEF_SCROLLBAR_RELIEF, Tk_Offset(TkScrollbar, relief), 0},
83 {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
84 DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(TkScrollbar, repeatDelay), 0},
85 {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
86 DEF_SCROLLBAR_REPEAT_INTERVAL, Tk_Offset(TkScrollbar, repeatInterval), 0},
87 {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
88 DEF_SCROLLBAR_TAKE_FOCUS, Tk_Offset(TkScrollbar, takeFocus),
89 TK_CONFIG_NULL_OK},
90 {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
91 DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(TkScrollbar, troughColorPtr),
92 TK_CONFIG_COLOR_ONLY},
93 {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
94 DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(TkScrollbar, troughColorPtr),
95 TK_CONFIG_MONO_ONLY},
96 {TK_CONFIG_PIXELS, "-width", "width", "Width",
97 DEF_SCROLLBAR_WIDTH, Tk_Offset(TkScrollbar, width), 0},
98 {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
99 (char *) NULL, 0, 0}
100 };
101
102 /*
103 * Forward declarations for procedures defined later in this file:
104 */
105
106 static int ConfigureScrollbar _ANSI_ARGS_((Tcl_Interp *interp,
107 TkScrollbar *scrollPtr, int argc, char **argv,
108 int flags));
109 static void ScrollbarCmdDeletedProc _ANSI_ARGS_((
110 ClientData clientData));
111 static int ScrollbarWidgetCmd _ANSI_ARGS_((ClientData clientData,
112 Tcl_Interp *, int argc, char **argv));
113
114 /*
115 *--------------------------------------------------------------
116 *
117 * Tk_ScrollbarCmd --
118 *
119 * This procedure is invoked to process the "scrollbar" Tcl
120 * command. See the user documentation for details on what
121 * it does.
122 *
123 * Results:
124 * A standard Tcl result.
125 *
126 * Side effects:
127 * See the user documentation.
128 *
129 *--------------------------------------------------------------
130 */
131
132 int
133 Tk_ScrollbarCmd(clientData, interp, argc, argv)
134 ClientData clientData; /* Main window associated with
135 * interpreter. */
136 Tcl_Interp *interp; /* Current interpreter. */
137 int argc; /* Number of arguments. */
138 char **argv; /* Argument strings. */
139 {
140 Tk_Window tkwin = (Tk_Window) clientData;
141 register TkScrollbar *scrollPtr;
142 Tk_Window new;
143
144 if (argc < 2) {
145 Tcl_AppendResult(interp, "wrong # args: should be \"",
146 argv[0], " pathName ?options?\"", (char *) NULL);
147 return TCL_ERROR;
148 }
149
150 new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL);
151 if (new == NULL) {
152 return TCL_ERROR;
153 }
154
155 Tk_SetClass(new, "Scrollbar");
156 scrollPtr = TkpCreateScrollbar(new);
157
158 TkSetClassProcs(new, &tkpScrollbarProcs, (ClientData) scrollPtr);
159
160 /*
161 * Initialize fields that won't be initialized by ConfigureScrollbar,
162 * or which ConfigureScrollbar expects to have reasonable values
163 * (e.g. resource pointers).
164 */
165
166 scrollPtr->tkwin = new;
167 scrollPtr->display = Tk_Display(new);
168 scrollPtr->interp = interp;
169 scrollPtr->widgetCmd = Tcl_CreateCommand(interp,
170 Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetCmd,
171 (ClientData) scrollPtr, ScrollbarCmdDeletedProc);
172 scrollPtr->vertical = 0;
173 scrollPtr->width = 0;
174 scrollPtr->command = NULL;
175 scrollPtr->commandSize = 0;
176 scrollPtr->repeatDelay = 0;
177 scrollPtr->repeatInterval = 0;
178 scrollPtr->borderWidth = 0;
179 scrollPtr->bgBorder = NULL;
180 scrollPtr->activeBorder = NULL;
181 scrollPtr->troughColorPtr = NULL;
182 scrollPtr->relief = TK_RELIEF_FLAT;
183 scrollPtr->highlightWidth = 0;
184 scrollPtr->highlightBgColorPtr = NULL;
185 scrollPtr->highlightColorPtr = NULL;
186 scrollPtr->inset = 0;
187 scrollPtr->elementBorderWidth = -1;
188 scrollPtr->arrowLength = 0;
189 scrollPtr->sliderFirst = 0;
190 scrollPtr->sliderLast = 0;
191 scrollPtr->activeField = 0;
192 scrollPtr->activeRelief = TK_RELIEF_RAISED;
193 scrollPtr->totalUnits = 0;
194 scrollPtr->windowUnits = 0;
195 scrollPtr->firstUnit = 0;
196 scrollPtr->lastUnit = 0;
197 scrollPtr->firstFraction = 0.0;
198 scrollPtr->lastFraction = 0.0;
199 scrollPtr->cursor = None;
200 scrollPtr->takeFocus = NULL;
201 scrollPtr->flags = 0;
202
203 if (ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2, 0) != TCL_OK) {
204 Tk_DestroyWindow(scrollPtr->tkwin);
205 return TCL_ERROR;
206 }
207
208 Tcl_SetResult(interp, Tk_PathName(scrollPtr->tkwin), TCL_STATIC);
209 return TCL_OK;
210 }
211
212 /*
213 *--------------------------------------------------------------
214 *
215 * ScrollbarWidgetCmd --
216 *
217 * This procedure is invoked to process the Tcl command
218 * that corresponds to a widget managed by this module.
219 * See the user documentation for details on what it does.
220 *
221 * Results:
222 * A standard Tcl result.
223 *
224 * Side effects:
225 * See the user documentation.
226 *
227 *--------------------------------------------------------------
228 */
229
230 static int
231 ScrollbarWidgetCmd(clientData, interp, argc, argv)
232 ClientData clientData; /* Information about scrollbar
233 * widget. */
234 Tcl_Interp *interp; /* Current interpreter. */
235 int argc; /* Number of arguments. */
236 char **argv; /* Argument strings. */
237 {
238 register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
239 int result = TCL_OK;
240 size_t length;
241 int c;
242
243 if (argc < 2) {
244 Tcl_AppendResult(interp, "wrong # args: should be \"",
245 argv[0], " option ?arg arg ...?\"", (char *) NULL);
246 return TCL_ERROR;
247 }
248 Tcl_Preserve((ClientData) scrollPtr);
249 c = argv[1][0];
250 length = strlen(argv[1]);
251 if ((c == 'a') && (strncmp(argv[1], "activate", length) == 0)) {
252 int oldActiveField;
253 if (argc == 2) {
254 switch (scrollPtr->activeField) {
255 case TOP_ARROW:
256 Tcl_SetResult(interp, "arrow1", TCL_STATIC);
257 break;
258 case SLIDER:
259 Tcl_SetResult(interp, "slider", TCL_STATIC);
260 break;
261 case BOTTOM_ARROW:
262 Tcl_SetResult(interp, "arrow2", TCL_STATIC);
263 break;
264 }
265 goto done;
266 }
267 if (argc != 3) {
268 Tcl_AppendResult(interp, "wrong # args: should be \"",
269 argv[0], " activate element\"", (char *) NULL);
270 goto error;
271 }
272 c = argv[2][0];
273 length = strlen(argv[2]);
274 oldActiveField = scrollPtr->activeField;
275 if ((c == 'a') && (strcmp(argv[2], "arrow1") == 0)) {
276 scrollPtr->activeField = TOP_ARROW;
277 } else if ((c == 'a') && (strcmp(argv[2], "arrow2") == 0)) {
278 scrollPtr->activeField = BOTTOM_ARROW;
279 } else if ((c == 's') && (strncmp(argv[2], "slider", length) == 0)) {
280 scrollPtr->activeField = SLIDER;
281 } else {
282 scrollPtr->activeField = OUTSIDE;
283 }
284 if (oldActiveField != scrollPtr->activeField) {
285 TkScrollbarEventuallyRedraw(scrollPtr);
286 }
287 } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
288 && (length >= 2)) {
289 if (argc != 3) {
290 Tcl_AppendResult(interp, "wrong # args: should be \"",
291 argv[0], " cget option\"",
292 (char *) NULL);
293 goto error;
294 }
295 result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
296 tkpScrollbarConfigSpecs, (char *) scrollPtr, argv[2], 0);
297 } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
298 && (length >= 2)) {
299 if (argc == 2) {
300 result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
301 tkpScrollbarConfigSpecs, (char *) scrollPtr,
302 (char *) NULL, 0);
303 } else if (argc == 3) {
304 result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
305 tkpScrollbarConfigSpecs, (char *) scrollPtr, argv[2], 0);
306 } else {
307 result = ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2,
308 TK_CONFIG_ARGV_ONLY);
309 }
310 } else if ((c == 'd') && (strncmp(argv[1], "delta", length) == 0)) {
311 int xDelta, yDelta, pixels, length;
312 double fraction;
313 char buf[TCL_DOUBLE_SPACE];
314
315 if (argc != 4) {
316 Tcl_AppendResult(interp, "wrong # args: should be \"",
317 argv[0], " delta xDelta yDelta\"", (char *) NULL);
318 goto error;
319 }
320 if ((Tcl_GetInt(interp, argv[2], &xDelta) != TCL_OK)
321 || (Tcl_GetInt(interp, argv[3], &yDelta) != TCL_OK)) {
322 goto error;
323 }
324 if (scrollPtr->vertical) {
325 pixels = yDelta;
326 length = Tk_Height(scrollPtr->tkwin) - 1
327 - 2*(scrollPtr->arrowLength + scrollPtr->inset);
328 } else {
329 pixels = xDelta;
330 length = Tk_Width(scrollPtr->tkwin) - 1
331 - 2*(scrollPtr->arrowLength + scrollPtr->inset);
332 }
333 if (length == 0) {
334 fraction = 0.0;
335 } else {
336 fraction = ((double) pixels / (double) length);
337 }
338 sprintf(buf, "%g", fraction);
339 Tcl_SetResult(interp, buf, TCL_VOLATILE);
340 } else if ((c == 'f') && (strncmp(argv[1], "fraction", length) == 0)) {
341 int x, y, pos, length;
342 double fraction;
343 char buf[TCL_DOUBLE_SPACE];
344
345 if (argc != 4) {
346 Tcl_AppendResult(interp, "wrong # args: should be \"",
347 argv[0], " fraction x y\"", (char *) NULL);
348 goto error;
349 }
350 if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
351 || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
352 goto error;
353 }
354 if (scrollPtr->vertical) {
355 pos = y - (scrollPtr->arrowLength + scrollPtr->inset);
356 length = Tk_Height(scrollPtr->tkwin) - 1
357 - 2*(scrollPtr->arrowLength + scrollPtr->inset);
358 } else {
359 pos = x - (scrollPtr->arrowLength + scrollPtr->inset);
360 length = Tk_Width(scrollPtr->tkwin) - 1
361 - 2*(scrollPtr->arrowLength + scrollPtr->inset);
362 }
363 if (length == 0) {
364 fraction = 0.0;
365 } else {
366 fraction = ((double) pos / (double) length);
367 }
368 if (fraction < 0) {
369 fraction = 0;
370 } else if (fraction > 1.0) {
371 fraction = 1.0;
372 }
373 sprintf(buf, "%g", fraction);
374 Tcl_SetResult(interp, buf, TCL_VOLATILE);
375 } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
376 if (argc != 2) {
377 Tcl_AppendResult(interp, "wrong # args: should be \"",
378 argv[0], " get\"", (char *) NULL);
379 goto error;
380 }
381 if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
382 char first[TCL_DOUBLE_SPACE], last[TCL_DOUBLE_SPACE];
383
384 Tcl_PrintDouble(interp, scrollPtr->firstFraction, first);
385 Tcl_PrintDouble(interp, scrollPtr->lastFraction, last);
386 Tcl_AppendResult(interp, first, " ", last, (char *) NULL);
387 } else {
388 char buf[TCL_INTEGER_SPACE * 4];
389
390 sprintf(buf, "%d %d %d %d", scrollPtr->totalUnits,
391 scrollPtr->windowUnits, scrollPtr->firstUnit,
392 scrollPtr->lastUnit);
393 Tcl_SetResult(interp, buf, TCL_VOLATILE);
394 }
395 } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) {
396 int x, y, thing;
397
398 if (argc != 4) {
399 Tcl_AppendResult(interp, "wrong # args: should be \"",
400 argv[0], " identify x y\"", (char *) NULL);
401 goto error;
402 }
403 if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
404 || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
405 goto error;
406 }
407 thing = TkpScrollbarPosition(scrollPtr, x,y);
408 switch (thing) {
409 case TOP_ARROW:
410 Tcl_SetResult(interp, "arrow1", TCL_STATIC);
411 break;
412 case TOP_GAP:
413 Tcl_SetResult(interp, "trough1", TCL_STATIC);
414 break;
415 case SLIDER:
416 Tcl_SetResult(interp, "slider", TCL_STATIC);
417 break;
418 case BOTTOM_GAP:
419 Tcl_SetResult(interp, "trough2", TCL_STATIC);
420 break;
421 case BOTTOM_ARROW:
422 Tcl_SetResult(interp, "arrow2", TCL_STATIC);
423 break;
424 }
425 } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) {
426 int totalUnits, windowUnits, firstUnit, lastUnit;
427
428 if (argc == 4) {
429 double first, last;
430
431 if (Tcl_GetDouble(interp, argv[2], &first) != TCL_OK) {
432 goto error;
433 }
434 if (Tcl_GetDouble(interp, argv[3], &last) != TCL_OK) {
435 goto error;
436 }
437 if (first < 0) {
438 scrollPtr->firstFraction = 0;
439 } else if (first > 1.0) {
440 scrollPtr->firstFraction = 1.0;
441 } else {
442 scrollPtr->firstFraction = first;
443 }
444 if (last < scrollPtr->firstFraction) {
445 scrollPtr->lastFraction = scrollPtr->firstFraction;
446 } else if (last > 1.0) {
447 scrollPtr->lastFraction = 1.0;
448 } else {
449 scrollPtr->lastFraction = last;
450 }
451 scrollPtr->flags |= NEW_STYLE_COMMANDS;
452 } else if (argc == 6) {
453 if (Tcl_GetInt(interp, argv[2], &totalUnits) != TCL_OK) {
454 goto error;
455 }
456 if (totalUnits < 0) {
457 totalUnits = 0;
458 }
459 if (Tcl_GetInt(interp, argv[3], &windowUnits) != TCL_OK) {
460 goto error;
461 }
462 if (windowUnits < 0) {
463 windowUnits = 0;
464 }
465 if (Tcl_GetInt(interp, argv[4], &firstUnit) != TCL_OK) {
466 goto error;
467 }
468 if (Tcl_GetInt(interp, argv[5], &lastUnit) != TCL_OK) {
469 goto error;
470 }
471 if (totalUnits > 0) {
472 if (lastUnit < firstUnit) {
473 lastUnit = firstUnit;
474 }
475 } else {
476 firstUnit = lastUnit = 0;
477 }
478 scrollPtr->totalUnits = totalUnits;
479 scrollPtr->windowUnits = windowUnits;
480 scrollPtr->firstUnit = firstUnit;
481 scrollPtr->lastUnit = lastUnit;
482 if (scrollPtr->totalUnits == 0) {
483 scrollPtr->firstFraction = 0.0;
484 scrollPtr->lastFraction = 1.0;
485 } else {
486 scrollPtr->firstFraction = ((double) firstUnit)/totalUnits;
487 scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits;
488 }
489 scrollPtr->flags &= ~NEW_STYLE_COMMANDS;
490 } else {
491 Tcl_AppendResult(interp, "wrong # args: should be \"",
492 argv[0], " set firstFraction lastFraction\" or \"",
493 argv[0],
494 " set totalUnits windowUnits firstUnit lastUnit\"",
495 (char *) NULL);
496 goto error;
497 }
498 TkpComputeScrollbarGeometry(scrollPtr);
499 TkScrollbarEventuallyRedraw(scrollPtr);
500 } else {
501 Tcl_AppendResult(interp, "bad option \"", argv[1],
502 "\": must be activate, cget, configure, delta, fraction, ",
503 "get, identify, or set", (char *) NULL);
504 goto error;
505 }
506 done:
507 Tcl_Release((ClientData) scrollPtr);
508 return result;
509
510 error:
511 Tcl_Release((ClientData) scrollPtr);
512 return TCL_ERROR;
513 }
514
515 /*
516 *----------------------------------------------------------------------
517 *
518 * ConfigureScrollbar --
519 *
520 * This procedure is called to process an argv/argc list, plus
521 * the Tk option database, in order to configure (or
522 * reconfigure) a scrollbar widget.
523 *
524 * Results:
525 * The return value is a standard Tcl result. If TCL_ERROR is
526 * returned, then the interp's result contains an error message.
527 *
528 * Side effects:
529 * Configuration information, such as colors, border width,
530 * etc. get set for scrollPtr; old resources get freed,
531 * if there were any.
532 *
533 *----------------------------------------------------------------------
534 */
535
536 static int
537 ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
538 Tcl_Interp *interp; /* Used for error reporting. */
539 register TkScrollbar *scrollPtr; /* Information about widget; may or
540 * may not already have values for
541 * some fields. */
542 int argc; /* Number of valid entries in argv. */
543 char **argv; /* Arguments. */
544 int flags; /* Flags to pass to
545 * Tk_ConfigureWidget. */
546 {
547 if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, tkpScrollbarConfigSpecs,
548 argc, argv, (char *) scrollPtr, flags) != TCL_OK) {
549 return TCL_ERROR;
550 }
551
552 /*
553 * A few options need special processing, such as setting the
554 * background from a 3-D border.
555 */
556
557 if (scrollPtr->command != NULL) {
558 scrollPtr->commandSize = strlen(scrollPtr->command);
559 } else {
560 scrollPtr->commandSize = 0;
561 }
562
563 /*
564 * Configure platform specific options.
565 */
566
567 TkpConfigureScrollbar(scrollPtr);
568
569 /*
570 * Register the desired geometry for the window (leave enough space
571 * for the two arrows plus a minimum-size slider, plus border around
572 * the whole window, if any). Then arrange for the window to be
573 * redisplayed.
574 */
575
576 TkpComputeScrollbarGeometry(scrollPtr);
577 TkScrollbarEventuallyRedraw(scrollPtr);
578 return TCL_OK;
579 }
580
581 /*
582 *--------------------------------------------------------------
583 *
584 * TkScrollbarEventProc --
585 *
586 * This procedure is invoked by the Tk dispatcher for various
587 * events on scrollbars.
588 *
589 * Results:
590 * None.
591 *
592 * Side effects:
593 * When the window gets deleted, internal structures get
594 * cleaned up. When it gets exposed, it is redisplayed.
595 *
596 *--------------------------------------------------------------
597 */
598
599 void
600 TkScrollbarEventProc(clientData, eventPtr)
601 ClientData clientData; /* Information about window. */
602 XEvent *eventPtr; /* Information about event. */
603 {
604 TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
605
606 if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
607 TkScrollbarEventuallyRedraw(scrollPtr);
608 } else if (eventPtr->type == DestroyNotify) {
609 TkpDestroyScrollbar(scrollPtr);
610 if (scrollPtr->tkwin != NULL) {
611 scrollPtr->tkwin = NULL;
612 Tcl_DeleteCommandFromToken(scrollPtr->interp,
613 scrollPtr->widgetCmd);
614 }
615 if (scrollPtr->flags & REDRAW_PENDING) {
616 Tcl_CancelIdleCall(TkpDisplayScrollbar, (ClientData) scrollPtr);
617 }
618 /*
619 * Free up all the stuff that requires special handling, then
620 * let Tk_FreeOptions handle all the standard option-related
621 * stuff.
622 */
623
624 Tk_FreeOptions(tkpScrollbarConfigSpecs, (char *) scrollPtr,
625 scrollPtr->display, 0);
626 Tcl_EventuallyFree((ClientData) scrollPtr, TCL_DYNAMIC);
627 } else if (eventPtr->type == ConfigureNotify) {
628 TkpComputeScrollbarGeometry(scrollPtr);
629 TkScrollbarEventuallyRedraw(scrollPtr);
630 } else if (eventPtr->type == FocusIn) {
631 if (eventPtr->xfocus.detail != NotifyInferior) {
632 scrollPtr->flags |= GOT_FOCUS;
633 if (scrollPtr->highlightWidth > 0) {
634 TkScrollbarEventuallyRedraw(scrollPtr);
635 }
636 }
637 } else if (eventPtr->type == FocusOut) {
638 if (eventPtr->xfocus.detail != NotifyInferior) {
639 scrollPtr->flags &= ~GOT_FOCUS;
640 if (scrollPtr->highlightWidth > 0) {
641 TkScrollbarEventuallyRedraw(scrollPtr);
642 }
643 }
644 }
645 }
646
647 /*
648 *----------------------------------------------------------------------
649 *
650 * ScrollbarCmdDeletedProc --
651 *
652 * This procedure is invoked when a widget command is deleted. If
653 * the widget isn't already in the process of being destroyed,
654 * this command destroys it.
655 *
656 * Results:
657 * None.
658 *
659 * Side effects:
660 * The widget is destroyed.
661 *
662 *----------------------------------------------------------------------
663 */
664
665 static void
666 ScrollbarCmdDeletedProc(clientData)
667 ClientData clientData; /* Pointer to widget record for widget. */
668 {
669 TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
670 Tk_Window tkwin = scrollPtr->tkwin;
671
672 /*
673 * This procedure could be invoked either because the window was
674 * destroyed and the command was then deleted (in which case tkwin
675 * is NULL) or because the command was deleted, and then this procedure
676 * destroys the widget.
677 */
678
679 if (tkwin != NULL) {
680 scrollPtr->tkwin = NULL;
681 Tk_DestroyWindow(tkwin);
682 }
683 }
684
685 /*
686 *--------------------------------------------------------------
687 *
688 * TkScrollbarEventuallyRedraw --
689 *
690 * Arrange for one or more of the fields of a scrollbar
691 * to be redrawn.
692 *
693 * Results:
694 * None.
695 *
696 * Side effects:
697 * None.
698 *
699 *--------------------------------------------------------------
700 */
701
702 void
703 TkScrollbarEventuallyRedraw(scrollPtr)
704 register TkScrollbar *scrollPtr; /* Information about widget. */
705 {
706 if ((scrollPtr->tkwin == NULL) || (!Tk_IsMapped(scrollPtr->tkwin))) {
707 return;
708 }
709 if ((scrollPtr->flags & REDRAW_PENDING) == 0) {
710 Tcl_DoWhenIdle(TkpDisplayScrollbar, (ClientData) scrollPtr);
711 scrollPtr->flags |= REDRAW_PENDING;
712 }
713 }
714
715 /* End of tkscrollbar.c */

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25