202
#ifdef ENTRY_VALIDATE
204
* Definitions for validate values:
207
#define VALIDATE_NONE 0
208
#define VALIDATE_ALL 1
209
#define VALIDATE_KEY 2
210
#define VALIDATE_FOCUS 3
211
#define VALIDATE_FOCUSIN 4
212
#define VALIDATE_FOCUSOUT 5
214
#define DEF_ENTRY_VALIDATE VALIDATE_NONE
216
static int ValidateParseProc _ANSI_ARGS_((ClientData clientData,
217
Tcl_Interp *interp, Tk_Window tkwin,
218
Arg value, char *entry, int offset));
219
static Arg ValidatePrintProc _ANSI_ARGS_((ClientData clientData,
220
Tk_Window tkwin, char *entry, int offset,
221
Tcl_FreeProc **freeProcPtr));
223
static Tk_CustomOption validateOption = {
227
#endif /* ENTRY_VALIDATE */
230
* Custom options for handling "-state" , "-tile" and "-offset"
233
static Tk_CustomOption stateOption = {
236
(ClientData) NULL /* only "normal" and "disabled" */
239
static Tk_CustomOption tileOption = {
245
static Tk_CustomOption offsetOption = {
252
* Information used for argv parsing.
255
static Tk_ConfigSpec configSpecs[] = {
256
{TK_CONFIG_BORDER, "-background", "background", "Background",
257
DEF_ENTRY_BG_COLOR, Tk_Offset(Entry, normalBorder),
258
TK_CONFIG_COLOR_ONLY},
259
{TK_CONFIG_BORDER, "-background", "background", "Background",
260
DEF_ENTRY_BG_MONO, Tk_Offset(Entry, normalBorder),
261
TK_CONFIG_MONO_ONLY},
262
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
263
(char *) NULL, 0, 0},
264
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
265
(char *) NULL, 0, 0},
266
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
267
DEF_ENTRY_BORDER_WIDTH, Tk_Offset(Entry, borderWidth), 0},
268
{TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
269
DEF_ENTRY_CURSOR, Tk_Offset(Entry, cursor), TK_CONFIG_NULL_OK},
270
{TK_CONFIG_CUSTOM, "-disabledtile", "disabledTile", "Tile", (char *) NULL,
271
Tk_Offset(Entry, disabledTile),TK_CONFIG_DONT_SET_DEFAULT, &tileOption},
272
{TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection",
273
"ExportSelection", DEF_ENTRY_EXPORT_SELECTION,
274
Tk_Offset(Entry, exportSelection), 0},
275
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
276
(char *) NULL, 0, 0},
277
{TK_CONFIG_FONT, "-font", "font", "Font",
278
DEF_ENTRY_FONT, Tk_Offset(Entry, tkfont), 0},
279
{TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
280
DEF_ENTRY_FG, Tk_Offset(Entry, fgColorPtr), 0},
281
{TK_CONFIG_SYNONYM, "-fgtile", "foregroundTile", (char *) NULL,
282
(char *) NULL, 0, 0},
283
{TK_CONFIG_CUSTOM, "-foregroundtile", "foregroundTile", "Tile", (char *) NULL,
284
Tk_Offset(Entry, fgTile),TK_CONFIG_DONT_SET_DEFAULT, &tileOption},
285
{TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
286
"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
287
Tk_Offset(Entry, highlightBgColorPtr), 0},
288
{TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
289
DEF_ENTRY_HIGHLIGHT, Tk_Offset(Entry, highlightColorPtr), 0},
290
{TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
291
"HighlightThickness",
292
DEF_ENTRY_HIGHLIGHT_WIDTH, Tk_Offset(Entry, highlightWidth), 0},
293
{TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
294
DEF_ENTRY_INSERT_BG, Tk_Offset(Entry, insertBorder), 0},
295
{TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
296
DEF_ENTRY_INSERT_BD_COLOR, Tk_Offset(Entry, insertBorderWidth),
297
TK_CONFIG_COLOR_ONLY},
298
{TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
299
DEF_ENTRY_INSERT_BD_MONO, Tk_Offset(Entry, insertBorderWidth),
300
TK_CONFIG_MONO_ONLY},
301
{TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
302
DEF_ENTRY_INSERT_OFF_TIME, Tk_Offset(Entry, insertOffTime), 0},
303
{TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
304
DEF_ENTRY_INSERT_ON_TIME, Tk_Offset(Entry, insertOnTime), 0},
305
{TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
306
DEF_ENTRY_INSERT_WIDTH, Tk_Offset(Entry, insertWidth), 0},
307
#ifdef ENTRY_VALIDATE
308
{TK_CONFIG_CALLBACK, "-invalidcommand", "invalidCommand", "InvalidCommand",
309
(char *) NULL, Tk_Offset(Entry, invalidCmd), TK_CONFIG_DONT_SET_DEFAULT},
310
{TK_CONFIG_SYNONYM, "-invcmd", "invalidCommand", (char *) NULL,
311
(char *) NULL, 0, 0},
312
#endif /* ENTRY_VALIDATE */
313
{TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify",
314
DEF_ENTRY_JUSTIFY, Tk_Offset(Entry, justify), 0},
315
{TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0 0",
316
Tk_Offset(Entry, tsoffset),TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
317
{TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
318
DEF_ENTRY_RELIEF, Tk_Offset(Entry, relief), 0},
319
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
320
DEF_ENTRY_SELECT_COLOR, Tk_Offset(Entry, selBorder),
321
TK_CONFIG_COLOR_ONLY},
322
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
323
DEF_ENTRY_SELECT_MONO, Tk_Offset(Entry, selBorder),
324
TK_CONFIG_MONO_ONLY},
325
{TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
326
DEF_ENTRY_SELECT_BD_COLOR, Tk_Offset(Entry, selBorderWidth),
327
TK_CONFIG_COLOR_ONLY},
328
{TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
329
DEF_ENTRY_SELECT_BD_MONO, Tk_Offset(Entry, selBorderWidth),
330
TK_CONFIG_MONO_ONLY},
331
{TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
332
DEF_ENTRY_SELECT_FG_COLOR, Tk_Offset(Entry, selFgColorPtr),
333
TK_CONFIG_COLOR_ONLY},
334
{TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
335
DEF_ENTRY_SELECT_FG_MONO, Tk_Offset(Entry, selFgColorPtr),
336
TK_CONFIG_MONO_ONLY},
337
{TK_CONFIG_STRING, "-show", "show", "Show",
338
DEF_ENTRY_SHOW, Tk_Offset(Entry, showChar), TK_CONFIG_NULL_OK},
339
{TK_CONFIG_CUSTOM, "-state", "state", "State",
340
DEF_ENTRY_STATE, Tk_Offset(Entry, state), 0, &stateOption},
341
{TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
342
DEF_ENTRY_TAKE_FOCUS, Tk_Offset(Entry, takeFocus), TK_CONFIG_NULL_OK},
343
{TK_CONFIG_SCALARVAR, "-textvariable", "textVariable", "Variable",
344
DEF_ENTRY_TEXT_VARIABLE, Tk_Offset(Entry, textVarName),
346
{TK_CONFIG_CUSTOM, "-tile", "tile", "Tile", (char *) NULL,
347
Tk_Offset(Entry, tile),TK_CONFIG_DONT_SET_DEFAULT, &tileOption},
348
#ifdef ENTRY_VALIDATE
349
{TK_CONFIG_CUSTOM, "-validate", "validate", "Validate",
350
DEF_ENTRY_VALIDATE, Tk_Offset(Entry, validate),
351
TK_CONFIG_DONT_SET_DEFAULT, &validateOption},
352
{TK_CONFIG_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand",
353
(char *) NULL, Tk_Offset(Entry, validateCmd),
354
TK_CONFIG_DONT_SET_DEFAULT},
355
{TK_CONFIG_SYNONYM, "-vcmd", "validateCommand", (char *) NULL,
356
(char *) NULL, 0, 0},
357
#endif /* ENTRY_VALIDATE */
358
{TK_CONFIG_INT, "-width", "width", "Width",
359
DEF_ENTRY_WIDTH, Tk_Offset(Entry, prefWidth), 0},
360
{TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
361
DEF_ENTRY_SCROLL_COMMAND, Tk_Offset(Entry, scrollCmd),
363
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
285
* A comparison function for double values. For Spinboxes.
287
#define MIN_DBL_VAL 1E-9
288
#define DOUBLES_EQ(d1, d2) (fabs((d1) - (d2)) < MIN_DBL_VAL)
291
* The following enum is used to define a type for the -state option
292
* of the Entry widget. These values are used as indices into the
293
* string table below.
297
STATE_DISABLED, STATE_NORMAL, STATE_READONLY
300
static char *stateStrings[] = {
301
"disabled", "normal", "readonly", (char *) NULL
305
* Definitions for -validate option values:
308
static char *validateStrings[] = {
309
"all", "key", "focus", "focusin", "focusout", "none", (char *) NULL
312
VALIDATE_ALL, VALIDATE_KEY, VALIDATE_FOCUS,
313
VALIDATE_FOCUSIN, VALIDATE_FOCUSOUT, VALIDATE_NONE,
315
* These extra enums are for use with EntryValidateChange
317
VALIDATE_FORCED, VALIDATE_DELETE, VALIDATE_INSERT, VALIDATE_BUTTON
319
#define DEF_ENTRY_VALIDATE "none"
320
#define DEF_ENTRY_INVALIDCMD ""
323
* Information used for Entry objv parsing.
326
static Tk_OptionSpec entryOptSpec[] = {
327
{TK_OPTION_BORDER, "-background", "background", "Background",
328
DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
329
0, (ClientData) DEF_ENTRY_BG_MONO, 0},
330
{TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
331
(char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
332
{TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
333
(char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
334
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
335
DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth),
337
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
338
DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor),
339
TK_OPTION_NULL_OK, 0, 0},
340
{TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
341
"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
342
Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
343
(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
344
{TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
345
"DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
346
Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
347
{TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
348
"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
349
Tk_Offset(Entry, exportSelection), 0, 0, 0},
350
{TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
351
(char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
352
{TK_OPTION_FONT, "-font", "font", "Font",
353
DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
354
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
355
DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0,
357
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
358
"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
359
-1, Tk_Offset(Entry, highlightBgColorPtr),
361
{TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
362
DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr),
364
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
365
"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
366
Tk_Offset(Entry, highlightWidth), 0, 0, 0},
367
{TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
369
-1, Tk_Offset(Entry, insertBorder),
371
{TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
372
"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
373
Tk_Offset(Entry, insertBorderWidth), 0,
374
(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
375
{TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
376
DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
378
{TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
379
DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime),
381
{TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
382
DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth),
384
{TK_OPTION_CALLBACK, "-invalidcommand", "invalidCommand", "InvalidCommand",
385
DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
386
TK_OPTION_NULL_OK, 0, 0},
387
{TK_OPTION_SYNONYM, "-invcmd", (char *) NULL, (char *) NULL,
388
(char *) NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0},
389
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
390
DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},
391
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
392
"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
393
Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
394
(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
395
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
396
DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief),
398
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
399
DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
400
0, (ClientData) DEF_ENTRY_SELECT_MONO, 0},
401
{TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
402
"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
403
Tk_Offset(Entry, selBorderWidth),
404
0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
405
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
406
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
407
0, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
408
{TK_OPTION_STRING, "-show", "show", "Show",
409
DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
410
TK_OPTION_NULL_OK, 0, 0},
411
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
412
DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
413
0, (ClientData) stateStrings, 0},
414
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
415
DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
416
TK_OPTION_NULL_OK, 0, 0},
417
{TK_OPTION_OBJ, "-textvariable", "textVariable", "Variable",
418
DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
419
TK_OPTION_NULL_OK, 0, 0},
420
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
421
DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
422
0, (ClientData) validateStrings, 0},
423
{TK_OPTION_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand",
424
(char *) NULL, -1, Tk_Offset(Entry, validateCmd),
425
TK_OPTION_NULL_OK, 0, 0},
426
{TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL,
427
(char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0},
428
{TK_OPTION_INT, "-width", "width", "Width",
429
DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
430
{TK_OPTION_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
431
DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
432
TK_OPTION_NULL_OK, 0, 0},
433
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
434
(char *) NULL, 0, -1, 0, 0, 0}
438
* Information used for Spinbox objv parsing.
441
#define DEF_SPINBOX_REPEAT_DELAY "400"
442
#define DEF_SPINBOX_REPEAT_INTERVAL "100"
444
#define DEF_SPINBOX_CMD ""
446
#define DEF_SPINBOX_FROM "0"
447
#define DEF_SPINBOX_TO "0"
448
#define DEF_SPINBOX_INCREMENT "1"
449
#define DEF_SPINBOX_FORMAT ""
451
#define DEF_SPINBOX_VALUES ""
452
#define DEF_SPINBOX_WRAP "0"
454
static Tk_OptionSpec sbOptSpec[] = {
455
{TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
456
DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(Spinbox, activeBorder),
457
0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0},
458
{TK_OPTION_BORDER, "-background", "background", "Background",
459
DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
460
0, (ClientData) DEF_ENTRY_BG_MONO, 0},
461
{TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
462
(char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
463
{TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
464
(char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
465
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
466
DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth),
468
{TK_OPTION_BORDER, "-buttonbackground", "Button.background", "Background",
469
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder),
470
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
471
{TK_OPTION_CURSOR, "-buttoncursor", "Button.cursor", "Cursor",
472
DEF_BUTTON_CURSOR, -1, Tk_Offset(Spinbox, bCursor),
473
TK_OPTION_NULL_OK, 0, 0},
474
{TK_OPTION_RELIEF, "-buttondownrelief", "Button.relief", "Relief",
475
DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief),
477
{TK_OPTION_RELIEF, "-buttonuprelief", "Button.relief", "Relief",
478
DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief),
480
{TK_OPTION_CALLBACK, "-command", "command", "Command",
481
DEF_SPINBOX_CMD, -1, Tk_Offset(Spinbox, command),
482
TK_OPTION_NULL_OK, 0, 0},
483
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
484
DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor),
485
TK_OPTION_NULL_OK, 0, 0},
486
{TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
487
"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
488
Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
489
(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
490
{TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
491
"DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
492
Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
493
{TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
494
"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
495
Tk_Offset(Entry, exportSelection), 0, 0, 0},
496
{TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
497
(char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
498
{TK_OPTION_FONT, "-font", "font", "Font",
499
DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
500
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
501
DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0,
503
{TK_OPTION_STRING, "-format", "format", "Format",
504
DEF_SPINBOX_FORMAT, -1, Tk_Offset(Spinbox, reqFormat),
505
TK_OPTION_NULL_OK, 0, 0},
506
{TK_OPTION_DOUBLE, "-from", "from", "From",
507
DEF_SPINBOX_FROM, -1, Tk_Offset(Spinbox, fromValue), 0, 0, 0},
508
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
509
"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
510
-1, Tk_Offset(Entry, highlightBgColorPtr),
512
{TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
513
DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr),
515
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
516
"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
517
Tk_Offset(Entry, highlightWidth), 0, 0, 0},
518
{TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
519
DEF_SPINBOX_INCREMENT, -1, Tk_Offset(Spinbox, increment), 0, 0, 0},
520
{TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
521
DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder),
523
{TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
524
"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
525
Tk_Offset(Entry, insertBorderWidth), 0,
526
(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
527
{TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
528
DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
530
{TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
531
DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime),
533
{TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
534
DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth),
536
{TK_OPTION_CALLBACK, "-invalidcommand", "invalidCommand", "InvalidCommand",
537
DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
538
TK_OPTION_NULL_OK, 0, 0},
539
{TK_OPTION_SYNONYM, "-invcmd", (char *) NULL, (char *) NULL,
540
(char *) NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0},
541
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
542
DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},
543
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
544
DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief),
546
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
547
"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
548
Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
549
(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
550
{TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
551
DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay),
553
{TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
554
DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval),
556
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
557
DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
558
0, (ClientData) DEF_ENTRY_SELECT_MONO, 0},
559
{TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
560
"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
561
Tk_Offset(Entry, selBorderWidth),
562
0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
563
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
564
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
565
0, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
566
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
567
DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
568
0, (ClientData) stateStrings, 0},
569
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
570
DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
571
TK_CONFIG_NULL_OK, 0, 0},
572
{TK_OPTION_OBJ, "-textvariable", "textVariable", "Variable",
573
DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
574
TK_CONFIG_NULL_OK, 0, 0},
575
{TK_OPTION_DOUBLE, "-to", "to", "To",
576
DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
577
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
578
DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
579
0, (ClientData) validateStrings, 0},
580
{TK_OPTION_CALLBACK, "-validatecommand", "validateCommand", "ValidateCommand",
581
(char *) NULL, -1, Tk_Offset(Entry, validateCmd),
582
TK_CONFIG_NULL_OK, 0, 0},
583
{TK_OPTION_STRING, "-values", "values", "Values",
584
DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
585
TK_OPTION_NULL_OK, 0, 0},
586
{TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL,
587
(char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0},
588
{TK_OPTION_INT, "-width", "width", "Width",
589
DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
590
{TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
591
DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 0, 0, 0},
592
{TK_OPTION_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
593
DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
594
TK_CONFIG_NULL_OK, 0, 0},
595
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
596
(char *) NULL, 0, -1, 0, 0, 0}
600
* The following tables define the entry widget commands (and sub-
601
* commands) and map the indexes into the string tables into
602
* enumerated types used to dispatch the entry widget command.
605
static CONST char *entryCmdNames[] = {
606
"bbox", "cget", "configure", "delete", "get", "icursor", "index",
607
"insert", "scan", "selection", "validate", "xview", (char *) NULL
611
COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE,
612
COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT,
613
COMMAND_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW
616
static CONST char *selCmdNames[] = {
617
"adjust", "clear", "from", "present", "range", "to", (char *) NULL
621
SELECTION_ADJUST, SELECTION_CLEAR, SELECTION_FROM,
622
SELECTION_PRESENT, SELECTION_RANGE, SELECTION_TO
626
* The following tables define the spinbox widget commands (and sub-
627
* commands) and map the indexes into the string tables into
628
* enumerated types used to dispatch the spinbox widget command.
631
static CONST char *sbCmdNames[] = {
632
"bbox", "cget", "configure", "delete", "get", "icursor", "identify",
633
"index", "insert", "invoke", "scan", "selection", "set",
634
"validate", "xview", (char *) NULL
638
SB_CMD_BBOX, SB_CMD_CGET, SB_CMD_CONFIGURE, SB_CMD_DELETE,
639
SB_CMD_GET, SB_CMD_ICURSOR, SB_CMD_IDENTIFY, SB_CMD_INDEX,
640
SB_CMD_INSERT, SB_CMD_INVOKE, SB_CMD_SCAN, SB_CMD_SELECTION,
641
SB_CMD_SET, SB_CMD_VALIDATE, SB_CMD_XVIEW
644
static CONST char *sbSelCmdNames[] = {
645
"adjust", "clear", "element", "from", "present", "range", "to",
650
SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM,
651
SB_SEL_PRESENT, SB_SEL_RANGE, SB_SEL_TO
655
* Extra for selection of elements
658
static CONST char *selElementNames[] = {
659
"none", "buttondown", "buttonup", (char *) NULL, "entry"
662
SEL_NONE, SEL_BUTTONDOWN, SEL_BUTTONUP, SEL_NULL, SEL_ENTRY
368
666
* Flags for GetEntryIndex procedure:
372
#define LAST_PLUS_ONE_OK 2
670
#define LAST_PLUS_ONE_OK 2
375
673
* Forward declarations for procedures defined later in this file:
378
static int ConfigureEntry _ANSI_ARGS_((Tcl_Interp *interp,
379
Entry *entryPtr, int argc, char **argv,
381
static void DeleteChars _ANSI_ARGS_((Entry *entryPtr, int index,
676
static int ConfigureEntry _ANSI_ARGS_((Tcl_Interp *interp,
677
Entry *entryPtr, int objc,
678
Tcl_Obj *CONST objv[], int flags));
679
static void DeleteChars _ANSI_ARGS_((Entry *entryPtr, int index,
383
static void DestroyEntry _ANSI_ARGS_((char *memPtr));
384
static void DisplayEntry _ANSI_ARGS_((ClientData clientData));
385
static void EntryBlinkProc _ANSI_ARGS_((ClientData clientData));
386
static void EntryCmdDeletedProc _ANSI_ARGS_((
681
static void DestroyEntry _ANSI_ARGS_((char *memPtr));
682
static void DisplayEntry _ANSI_ARGS_((ClientData clientData));
683
static void EntryBlinkProc _ANSI_ARGS_((ClientData clientData));
684
static void EntryCmdDeletedProc _ANSI_ARGS_((
387
685
ClientData clientData));
388
static void EntryComputeGeometry _ANSI_ARGS_((Entry *entryPtr));
389
static void EntryEventProc _ANSI_ARGS_((ClientData clientData,
686
static void EntryComputeGeometry _ANSI_ARGS_((Entry *entryPtr));
687
static void EntryEventProc _ANSI_ARGS_((ClientData clientData,
390
688
XEvent *eventPtr));
391
static void EntryFocusProc _ANSI_ARGS_ ((Entry *entryPtr,
689
static void EntryFocusProc _ANSI_ARGS_ ((Entry *entryPtr,
393
static int EntryFetchSelection _ANSI_ARGS_((ClientData clientData,
691
static int EntryFetchSelection _ANSI_ARGS_((ClientData clientData,
394
692
int offset, char *buffer, int maxBytes));
395
static void EntryLostSelection _ANSI_ARGS_((
693
static void EntryLostSelection _ANSI_ARGS_((
396
694
ClientData clientData));
397
static void EventuallyRedraw _ANSI_ARGS_((Entry *entryPtr));
398
static void EntryScanTo _ANSI_ARGS_((Entry *entryPtr, int y));
399
static void EntrySetValue _ANSI_ARGS_((Entry *entryPtr,
401
static void EntrySelectTo _ANSI_ARGS_((
695
static void EventuallyRedraw _ANSI_ARGS_((Entry *entryPtr));
696
static void EntryScanTo _ANSI_ARGS_((Entry *entryPtr, int y));
697
static void EntrySetValue _ANSI_ARGS_((Entry *entryPtr,
699
static void EntrySelectTo _ANSI_ARGS_((
402
700
Entry *entryPtr, int index));
403
static char * EntryTextVarProc _ANSI_ARGS_((ClientData clientData,
404
Tcl_Interp *interp, Var name1, char *name2,
406
static void EntryUpdateScrollbar _ANSI_ARGS_((Entry *entryPtr));
407
#ifdef ENTRY_VALIDATE
408
static int EntryValidate _ANSI_ARGS_((Entry *entryPtr,
701
static char * EntryTextVarProc _ANSI_ARGS_((ClientData clientData,
702
Tcl_Interp *interp, Tcl_Obj *name1,
703
CONST char *name2, int flags));
704
static void EntryUpdateScrollbar _ANSI_ARGS_((Entry *entryPtr));
705
static int EntryValidate _ANSI_ARGS_((Entry *entryPtr,
409
706
LangCallback *cmd,char *string));
410
static int EntryValidateChange _ANSI_ARGS_((Entry *entryPtr,
411
char *string, char *new, int index, int type));
412
static void ExpandPercents _ANSI_ARGS_((Entry *entryPtr,
413
char *before, char *add, char *new, int index,
414
int type, Tcl_DString *dsPtr));
415
#endif /* ENTRY_VALIDATE */
416
static void EntryValueChanged _ANSI_ARGS_((Entry *entryPtr));
417
static void EntryVisibleRange _ANSI_ARGS_((Entry *entryPtr,
707
static int EntryValidateChange _ANSI_ARGS_((Entry *entryPtr,
708
char *change, CONST char *new, int index,
710
static void ExpandPercents _ANSI_ARGS_((Entry *entryPtr,
711
CONST char *before, char *change, CONST char *new,
712
int index, int type, Tcl_DString *dsPtr));
713
static void EntryValueChanged _ANSI_ARGS_((Entry *entryPtr,
714
CONST char *newValue));
715
static void EntryVisibleRange _ANSI_ARGS_((Entry *entryPtr,
418
716
double *firstPtr, double *lastPtr));
419
static int EntryWidgetCmd _ANSI_ARGS_((ClientData clientData,
420
Tcl_Interp *interp, int argc, char **argv));
421
static void EntryWorldChanged _ANSI_ARGS_((
717
static int EntryWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
718
Tcl_Interp *interp, int objc,
719
Tcl_Obj *CONST objv[]));
720
static void EntryWorldChanged _ANSI_ARGS_((
422
721
ClientData instanceData));
423
static int GetEntryIndex _ANSI_ARGS_((Tcl_Interp *interp,
424
Entry *entryPtr, Arg arg, int *indexPtr));
425
static void InsertChars _ANSI_ARGS_((Entry *entryPtr, int index,
722
static int GetEntryIndex _ANSI_ARGS_((Tcl_Interp *interp,
723
Entry *entryPtr, Tcl_Obj *arg, int *indexPtr));
724
static void InsertChars _ANSI_ARGS_((Entry *entryPtr, int index,
427
static void TileChangedProc _ANSI_ARGS_((ClientData clientData,
428
Tk_Tile tile, Tk_Item *itemPtr));
431
* The structure below defines entry class behavior by means of procedures
728
* These forward declarations are the spinbox specific ones:
731
static int SpinboxWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
732
Tcl_Interp *interp, int objc,
733
Tcl_Obj *CONST objv[]));
734
static int GetSpinboxElement _ANSI_ARGS_((Spinbox *sbPtr,
736
static int SpinboxInvoke _ANSI_ARGS_((Tcl_Interp *interp,
737
Spinbox *sbPtr, int element));
738
static int ComputeFormat _ANSI_ARGS_((Spinbox *sbPtr));
741
* The structure below defines widget class behavior by means of procedures
432
742
* that can be invoked from generic window code.
435
static TkClassProcs entryClass = {
436
NULL, /* createProc. */
437
EntryWorldChanged, /* geometryProc. */
438
NULL /* modalProc. */
745
static Tk_ClassProcs entryClass = {
746
sizeof(Tk_ClassProcs), /* size */
747
EntryWorldChanged, /* worldChangedProc */
443
752
*--------------------------------------------------------------
447
* This procedure is invoked to process the "entry" Tcl
448
* command. See the user documentation for details on what
756
* This procedure is invoked to process the "entry" Tcl
757
* command. See the user documentation for details on what
452
* A standard Tcl result.
761
* A standard Tcl result.
455
* See the user documentation.
764
* See the user documentation.
457
766
*--------------------------------------------------------------
461
Tk_EntryCmd(clientData, interp, argc, argv)
462
ClientData clientData; /* Main window associated with
464
Tcl_Interp *interp; /* Current interpreter. */
465
int argc; /* Number of arguments. */
466
char **argv; /* Argument strings. */
770
Tk_EntryObjCmd(clientData, interp, objc, objv)
771
ClientData clientData; /* NULL. */
772
Tcl_Interp *interp; /* Current interpreter. */
773
int objc; /* Number of arguments. */
774
Tcl_Obj *CONST objv[]; /* Argument objects. */
468
Tk_Window tkwin = (Tk_Window) clientData;
469
776
register Entry *entryPtr;
473
Tcl_AppendResult(interp, "wrong # args: should be \"",
474
argv[0], " pathName ?options?\"", (char *) NULL);
478
new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL);
777
Tk_OptionTable optionTable;
782
Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
786
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
787
Tcl_GetString(objv[1]), (char *) NULL);
793
* Create the option table for this widget class. If it has already
794
* been created, Tk will return the cached value.
797
optionTable = Tk_CreateOptionTable(interp, entryOptSpec);
484
800
* Initialize the fields of the structure that won't be initialized
485
801
* by ConfigureEntry, or that ConfigureEntry requires to be
486
* initialized already (e.g. resource pointers).
802
* initialized already (e.g. resource pointers). Only the non-NULL/0
803
* data must be initialized as memset covers the rest.
489
entryPtr = (Entry *) ckalloc(sizeof(Entry));
490
entryPtr->tkwin = new;
491
entryPtr->display = Tk_Display(new);
492
entryPtr->interp = interp;
493
entryPtr->widgetCmd = Tcl_CreateCommand(interp,
494
Tk_PathName(entryPtr->tkwin), EntryWidgetCmd,
806
entryPtr = (Entry *) ckalloc(sizeof(Entry));
807
memset((VOID *) entryPtr, 0, sizeof(Entry));
809
entryPtr->tkwin = tkwin;
810
entryPtr->display = Tk_Display(tkwin);
811
entryPtr->interp = interp;
812
entryPtr->widgetCmd = Tcl_CreateObjCommand(interp,
813
Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd,
495
814
(ClientData) entryPtr, EntryCmdDeletedProc);
496
entryPtr->string = (char *) ckalloc(1);
497
entryPtr->string[0] = '\0';
498
entryPtr->insertPos = 0;
499
entryPtr->selectFirst = -1;
500
entryPtr->selectLast = -1;
501
entryPtr->selectAnchor = 0;
502
entryPtr->scanMarkX = 0;
503
entryPtr->scanMarkIndex = 0;
505
entryPtr->normalBorder = NULL;
506
entryPtr->borderWidth = 0;
507
entryPtr->cursor = None;
508
entryPtr->exportSelection = 1;
509
entryPtr->tkfont = NULL;
510
entryPtr->fgColorPtr = NULL;
511
entryPtr->highlightBgColorPtr = NULL;
512
entryPtr->highlightColorPtr = NULL;
513
entryPtr->highlightWidth = 0;
514
entryPtr->insertBorder = NULL;
515
entryPtr->insertBorderWidth = 0;
516
entryPtr->insertOffTime = 0;
517
entryPtr->insertOnTime = 0;
518
entryPtr->insertWidth = 0;
519
entryPtr->justify = TK_JUSTIFY_LEFT;
520
entryPtr->relief = TK_RELIEF_FLAT;
521
entryPtr->selBorder = NULL;
522
entryPtr->selBorderWidth = 0;
523
entryPtr->selFgColorPtr = NULL;
524
entryPtr->showChar = NULL;
525
entryPtr->state = TK_STATE_NORMAL;
526
entryPtr->textVarName = NULL;
527
entryPtr->takeFocus = NULL;
528
entryPtr->prefWidth = 0;
529
entryPtr->scrollCmd = NULL;
531
entryPtr->numChars = 0;
532
entryPtr->displayString = NULL;
533
entryPtr->inset = XPAD;
534
entryPtr->textLayout = NULL;
535
entryPtr->layoutX = 0;
536
entryPtr->layoutY = 0;
537
entryPtr->leftIndex = 0;
539
entryPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
540
entryPtr->textGC = None;
541
entryPtr->selTextGC = None;
542
entryPtr->highlightGC = None;
543
entryPtr->avgWidth = 1;
545
entryPtr->tile = NULL;
546
entryPtr->disabledTile = NULL;
547
entryPtr->fgTile = NULL;
548
entryPtr->tileGC = NULL;
549
entryPtr->tsoffset.flags = 0;
550
entryPtr->tsoffset.xoffset = 0;
551
entryPtr->tsoffset.yoffset = 0;
552
#ifdef ENTRY_VALIDATE
553
entryPtr->validateCmd = NULL;
554
entryPtr->validate = VALIDATE_NONE;
555
entryPtr->invalidCmd = NULL;
556
#endif /* ENTRY_VALIDATE */
558
TkClassOption(entryPtr->tkwin, "Entry",&argc,&argv);
559
TkSetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
815
entryPtr->optionTable = optionTable;
816
entryPtr->type = TK_ENTRY;
817
tmp = (char *) ckalloc(1);
819
entryPtr->string = tmp;
820
entryPtr->selectFirst = -1;
821
entryPtr->selectLast = -1;
823
entryPtr->cursor = None;
824
entryPtr->exportSelection = 1;
825
entryPtr->justify = TK_JUSTIFY_LEFT;
826
entryPtr->relief = TK_RELIEF_FLAT;
827
entryPtr->state = STATE_NORMAL;
828
entryPtr->displayString = entryPtr->string;
829
entryPtr->inset = XPAD;
830
entryPtr->textGC = None;
831
entryPtr->selTextGC = None;
832
entryPtr->highlightGC = None;
833
entryPtr->avgWidth = 1;
834
entryPtr->validate = VALIDATE_NONE;
837
* Keep a hold of the associated tkwin until we destroy the listbox,
838
* otherwise Tk might free it while we still need it.
841
Tcl_Preserve((ClientData) entryPtr->tkwin);
843
Tk_SetClass(entryPtr->tkwin, "Entry");
844
Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
560
845
Tk_CreateEventHandler(entryPtr->tkwin,
561
846
ExposureMask|StructureNotifyMask|FocusChangeMask,
562
847
EntryEventProc, (ClientData) entryPtr);
563
848
Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
564
849
EntryFetchSelection, (ClientData) entryPtr, XA_STRING);
565
if (ConfigureEntry(interp, entryPtr, argc-2, argv+2, 0) != TCL_OK) {
851
if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
853
(ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK)) {
854
Tk_DestroyWindow(entryPtr->tkwin);
569
interp->result = Tk_PathName(entryPtr->tkwin);
858
Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC);
573
Tk_DestroyWindow(entryPtr->tkwin);
578
863
*--------------------------------------------------------------
865
* EntryWidgetObjCmd --
582
* This procedure is invoked to process the Tcl command
583
* that corresponds to a widget managed by this module.
584
* See the user documentation for details on what it does.
867
* This procedure is invoked to process the Tcl command
868
* that corresponds to a widget managed by this module.
869
* See the user documentation for details on what it does.
587
* A standard Tcl result.
872
* A standard Tcl result.
590
* See the user documentation.
875
* See the user documentation.
592
877
*--------------------------------------------------------------
596
EntryWidgetCmd(clientData, interp, argc, argv)
597
ClientData clientData; /* Information about entry widget. */
598
Tcl_Interp *interp; /* Current interpreter. */
599
int argc; /* Number of arguments. */
600
char **argv; /* Argument strings. */
881
EntryWidgetObjCmd(clientData, interp, objc, objv)
882
ClientData clientData; /* Information about entry widget. */
883
Tcl_Interp *interp; /* Current interpreter. */
884
int objc; /* Number of arguments. */
885
Tcl_Obj *CONST objv[]; /* Argument objects. */
602
register Entry *entryPtr = (Entry *) clientData;
887
Entry *entryPtr = (Entry *) clientData;
888
int cmdIndex, selIndex, result;
608
Tcl_AppendResult(interp, "wrong # args: should be \"",
609
argv[0], " option ?arg arg ...?\"", (char *) NULL);
892
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
610
893
return TCL_ERROR;
897
* Parse the widget command by looking up the second token in
898
* the list of valid command names.
901
result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames,
902
"option", 0, &cmdIndex);
903
if (result != TCL_OK) {
612
907
Tcl_Preserve((ClientData) entryPtr);
614
length = strlen(argv[1]);
615
if ((c == 'b') && (strncmp(argv[1], "bbox", length) == 0)) {
617
int x, y, width, height;
620
Tcl_AppendResult(interp, "wrong # args: should be \"",
621
argv[0], " bbox index\"",
625
if (GetEntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
628
if ((index == entryPtr->numChars) && (index > 0)) {
631
Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
632
sprintf(interp->result, "%d %d %d %d",
633
x + entryPtr->layoutX, y + entryPtr->layoutY, width, height);
634
} else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
637
Tcl_AppendResult(interp, "wrong # args: should be \"",
638
argv[0], " cget option\"",
642
result = Tk_ConfigureValue(interp, entryPtr->tkwin, configSpecs,
643
(char *) entryPtr, argv[2], 0);
644
} else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
647
result = Tk_ConfigureInfo(interp, entryPtr->tkwin, configSpecs,
648
(char *) entryPtr, (char *) NULL, 0);
649
} else if (argc == 3) {
650
result = Tk_ConfigureInfo(interp, entryPtr->tkwin, configSpecs,
651
(char *) entryPtr, argv[2], 0);
653
result = ConfigureEntry(interp, entryPtr, argc-2, argv+2,
654
TK_CONFIG_ARGV_ONLY);
656
} else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
659
if ((argc < 3) || (argc > 4)) {
660
Tcl_AppendResult(interp, "wrong # args: should be \"",
661
argv[0], " delete firstIndex ?lastIndex?\"",
665
if (GetEntryIndex(interp, entryPtr, objv[2], &first) != TCL_OK) {
671
if (GetEntryIndex(interp, entryPtr, objv[3], &last) != TCL_OK) {
675
if ((last >= first) && (entryPtr->state == TK_STATE_NORMAL)) {
676
DeleteChars(entryPtr, first, last-first);
678
} else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
680
Tcl_AppendResult(interp, "wrong # args: should be \"",
681
argv[0], " get\"", (char *) NULL);
684
interp->result = entryPtr->string;
685
} else if ((c == 'i') && (strncmp(argv[1], "icursor", length) == 0)
688
Tcl_AppendResult(interp, "wrong # args: should be \"",
689
argv[0], " icursor pos\"",
693
if (GetEntryIndex(interp, entryPtr, objv[2], &entryPtr->insertPos)
697
EventuallyRedraw(entryPtr);
698
} else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)
703
Tcl_AppendResult(interp, "wrong # args: should be \"",
704
argv[0], " index string\"", (char *) NULL);
707
if (GetEntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
710
sprintf(interp->result, "%d", index);
711
} else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0)
716
Tcl_AppendResult(interp, "wrong # args: should be \"",
717
argv[0], " insert index text\"",
721
if (GetEntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
724
if (entryPtr->state == TK_STATE_NORMAL) {
725
InsertChars(entryPtr, index, argv[3]);
727
} else if ((c == 's') && (length >= 2)
728
&& (strncmp(argv[1], "scan", length) == 0)) {
732
Tcl_AppendResult(interp, "wrong # args: should be \"",
733
argv[0], " scan mark|dragto x\"", (char *) NULL);
736
if (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) {
739
if ((argv[2][0] == 'm')
740
&& (strncmp(argv[2], "mark", strlen(argv[2])) == 0)) {
741
entryPtr->scanMarkX = x;
742
entryPtr->scanMarkIndex = entryPtr->leftIndex;
743
} else if ((argv[2][0] == 'd')
744
&& (strncmp(argv[2], "dragto", strlen(argv[2])) == 0)) {
745
EntryScanTo(entryPtr, x);
747
Tcl_AppendResult(interp, "bad scan option \"", argv[2],
748
"\": must be mark or dragto", (char *) NULL);
751
} else if ((c == 's') && (length >= 2)
752
&& (strncmp(argv[1], "selection", length) == 0)) {
756
Tcl_AppendResult(interp, "wrong # args: should be \"",
757
argv[0], " select option ?index?\"", (char *) NULL);
760
length = strlen(argv[2]);
762
if ((c == 'c') && (strncmp(argv[2], "clear", length) == 0)) {
764
Tcl_AppendResult(interp, "wrong # args: should be \"",
765
argv[0], " selection clear\"", (char *) NULL);
768
if (entryPtr->selectFirst != -1) {
769
entryPtr->selectFirst = entryPtr->selectLast = -1;
770
EventuallyRedraw(entryPtr);
773
} else if ((c == 'p') && (strncmp(argv[2], "present", length) == 0)) {
775
Tcl_AppendResult(interp, "wrong # args: should be \"",
776
argv[0], " selection present\"", (char *) NULL);
779
if (entryPtr->selectFirst == -1) {
780
interp->result = "0";
908
switch ((enum entryCmd) cmdIndex) {
910
int index, x, y, width, height;
911
char buf[TCL_INTEGER_SPACE * 4];
914
Tcl_WrongNumArgs(interp, 2, objv, "index");
917
if (GetEntryIndex(interp, entryPtr, objv[2],
921
if ((index == entryPtr->numChars) && (index > 0)) {
924
Tk_CharBbox(entryPtr->textLayout, index, &x, &y,
926
Tcl_IntResults(interp, 4, 0,
927
x + entryPtr->layoutX,
928
y + entryPtr->layoutY, width, height);
934
Tcl_WrongNumArgs(interp, 2, objv, "option");
938
objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
939
entryPtr->optionTable, objv[2], entryPtr->tkwin);
940
if (objPtr == NULL) {
782
interp->result = "1";
787
if (GetEntryIndex(interp, entryPtr, objv[3], &index) != TCL_OK) {
791
if ((c == 'a') && (strncmp(argv[2], "adjust", length) == 0)) {
793
Tcl_AppendResult(interp, "wrong # args: should be \"",
794
argv[0], " selection adjust index\"",
798
if (entryPtr->selectFirst >= 0) {
943
Tcl_SetObjResult(interp, objPtr);
801
half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
802
half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
804
entryPtr->selectAnchor = entryPtr->selectLast;
805
} else if (index > half2) {
806
entryPtr->selectAnchor = entryPtr->selectFirst;
948
case COMMAND_CONFIGURE: {
950
objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
951
entryPtr->optionTable,
952
(objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
954
if (objPtr == NULL) {
809
* We're at about the halfway point in the selection;
810
* just keep the existing anchor.
814
EntrySelectTo(entryPtr, index);
815
} else if ((c == 'f') && (strncmp(argv[2], "from", length) == 0)) {
817
Tcl_AppendResult(interp, "wrong # args: should be \"",
818
argv[0], " selection from index\"",
822
entryPtr->selectAnchor = index;
823
} else if ((c == 'r') && (strncmp(argv[2], "range", length) == 0)) {
825
Tcl_AppendResult(interp, "wrong # args: should be \"",
826
argv[0], " selection range start end\"",
830
if (GetEntryIndex(interp, entryPtr, objv[4], &index2) != TCL_OK) {
833
if (index >= index2) {
834
entryPtr->selectFirst = entryPtr->selectLast = -1;
836
entryPtr->selectFirst = index;
837
entryPtr->selectLast = index2;
839
if (!(entryPtr->flags & GOT_SELECTION)
840
&& (entryPtr->exportSelection)) {
841
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
842
EntryLostSelection, (ClientData) entryPtr);
843
entryPtr->flags |= GOT_SELECTION;
845
EventuallyRedraw(entryPtr);
846
} else if ((c == 't') && (strncmp(argv[2], "to", length) == 0)) {
848
Tcl_AppendResult(interp, "wrong # args: should be \"",
849
argv[0], " selection to index\"",
853
EntrySelectTo(entryPtr, index);
855
Tcl_AppendResult(interp, "bad selection option \"", argv[2],
856
"\": must be adjust, clear, from, present, range, or to",
860
#ifdef ENTRY_VALIDATE
861
} else if ((c == 'v') && (strncmp(argv[1], "validate", length) == 0)) {
864
Tcl_AppendResult(interp, "wrong # args: should be \"",
865
argv[0], " validate\"", (char *) NULL);
868
x = entryPtr->validate;
869
entryPtr->validate = VALIDATE_ALL;
870
code = EntryValidateChange(entryPtr, (char *) NULL,
871
entryPtr->string, -1, -1);
872
if (entryPtr->validate) {
873
entryPtr->validate = x;
875
sprintf(interp->result, "%d", (code == TCL_OK) ? 1 : 0);
876
#endif /* ENTRY_VALIDATE */
877
} else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) {
878
int index, type, count, charsPerPage;
879
double fraction, first, last;
882
EntryVisibleRange(entryPtr, &first, &last);
883
sprintf(interp->result, "%g %g", first, last);
885
} else if (argc == 3) {
886
if (GetEntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
890
type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
891
index = entryPtr->leftIndex;
893
case TK_SCROLL_ERROR:
895
case TK_SCROLL_MOVETO:
896
index = (int) ((fraction * entryPtr->numChars) + 0.5);
898
case TK_SCROLL_PAGES:
899
charsPerPage = ((Tk_Width(entryPtr->tkwin)
900
- 2*entryPtr->inset) / entryPtr->avgWidth) - 2;
901
if (charsPerPage < 1) {
904
index += charsPerPage*count;
906
case TK_SCROLL_UNITS:
911
if (index >= entryPtr->numChars) {
912
index = entryPtr->numChars-1;
917
entryPtr->leftIndex = index;
918
entryPtr->flags |= UPDATE_SCROLLBAR;
919
EntryComputeGeometry(entryPtr);
920
EventuallyRedraw(entryPtr);
922
Tcl_AppendResult(interp, "bad option \"", argv[1],
923
"\": must be bbox, cget, configure, delete, get, ",
924
#ifdef ENTRY_VALIDATE
925
"icursor, index, insert, scan, selection, validate, or xview",
927
"icursor, index, insert, scan, selection, or xview",
928
#endif /* ENTRY_VALIDATE */
957
Tcl_SetObjResult(interp, objPtr);
960
result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
965
case COMMAND_DELETE: {
968
if ((objc < 3) || (objc > 4)) {
969
Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
972
if (GetEntryIndex(interp, entryPtr, objv[2],
979
if (GetEntryIndex(interp, entryPtr, objv[3],
984
if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
985
DeleteChars(entryPtr, first, last - first);
992
Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
995
Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
999
case COMMAND_ICURSOR: {
1001
Tcl_WrongNumArgs(interp, 2, objv, "pos");
1004
if (GetEntryIndex(interp, entryPtr, objv[2],
1005
&entryPtr->insertPos) != TCL_OK) {
1008
EventuallyRedraw(entryPtr);
1012
case COMMAND_INDEX: {
1016
Tcl_WrongNumArgs(interp, 2, objv, "string");
1019
if (GetEntryIndex(interp, entryPtr, objv[2],
1020
&index) != TCL_OK) {
1023
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
1027
case COMMAND_INSERT: {
1031
Tcl_WrongNumArgs(interp, 2, objv, "index text");
1034
if (GetEntryIndex(interp, entryPtr, objv[2],
1035
&index) != TCL_OK) {
1038
if (entryPtr->state == STATE_NORMAL) {
1039
InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
1044
case COMMAND_SCAN: {
1049
Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x");
1052
if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
1056
minorCmd = Tcl_GetString(objv[2]);
1057
if (minorCmd[0] == 'm'
1058
&& (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) {
1059
entryPtr->scanMarkX = x;
1060
entryPtr->scanMarkIndex = entryPtr->leftIndex;
1061
} else if ((minorCmd[0] == 'd')
1062
&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
1063
EntryScanTo(entryPtr, x);
1065
Tcl_AppendResult(interp, "bad scan option \"",
1066
Tcl_GetString(objv[2]), "\": must be mark or dragto",
1073
case COMMAND_SELECTION: {
1077
Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
1082
* Parse the selection sub-command, using the command
1083
* table "selCmdNames" defined above.
1086
result = Tcl_GetIndexFromObj(interp, objv[2], selCmdNames,
1087
"selection option", 0, &selIndex);
1088
if (result != TCL_OK) {
1093
* Disabled entries don't allow the selection to be modified,
1094
* but 'selection present' must return a boolean.
1097
if ((entryPtr->state == STATE_DISABLED)
1098
&& (selIndex != SELECTION_PRESENT)) {
1103
case SELECTION_ADJUST: {
1105
Tcl_WrongNumArgs(interp, 3, objv, "index");
1108
if (GetEntryIndex(interp, entryPtr,
1109
objv[3], &index) != TCL_OK) {
1112
if (entryPtr->selectFirst >= 0) {
1115
half1 = (entryPtr->selectFirst
1116
+ entryPtr->selectLast)/2;
1117
half2 = (entryPtr->selectFirst
1118
+ entryPtr->selectLast + 1)/2;
1119
if (index < half1) {
1120
entryPtr->selectAnchor = entryPtr->selectLast;
1121
} else if (index > half2) {
1122
entryPtr->selectAnchor = entryPtr->selectFirst;
1125
* We're at about the halfway point in the
1126
* selection; just keep the existing anchor.
1130
EntrySelectTo(entryPtr, index);
1134
case SELECTION_CLEAR: {
1136
Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
1139
if (entryPtr->selectFirst >= 0) {
1140
entryPtr->selectFirst = -1;
1141
entryPtr->selectLast = -1;
1142
EventuallyRedraw(entryPtr);
1147
case SELECTION_FROM: {
1149
Tcl_WrongNumArgs(interp, 3, objv, "index");
1152
if (GetEntryIndex(interp, entryPtr,
1153
objv[3], &index) != TCL_OK) {
1156
entryPtr->selectAnchor = index;
1160
case SELECTION_PRESENT: {
1162
Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
1165
Tcl_SetObjResult(interp,
1166
Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
1170
case SELECTION_RANGE: {
1172
Tcl_WrongNumArgs(interp, 3, objv, "start end");
1175
if (GetEntryIndex(interp, entryPtr,
1176
objv[3], &index) != TCL_OK) {
1179
if (GetEntryIndex(interp, entryPtr,
1180
objv[4],& index2) != TCL_OK) {
1183
if (index >= index2) {
1184
entryPtr->selectFirst = -1;
1185
entryPtr->selectLast = -1;
1187
entryPtr->selectFirst = index;
1188
entryPtr->selectLast = index2;
1190
if (!(entryPtr->flags & GOT_SELECTION)
1191
&& (entryPtr->exportSelection)) {
1192
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
1193
EntryLostSelection, (ClientData) entryPtr);
1194
entryPtr->flags |= GOT_SELECTION;
1196
EventuallyRedraw(entryPtr);
1200
case SELECTION_TO: {
1202
Tcl_WrongNumArgs(interp, 3, objv, "index");
1205
if (GetEntryIndex(interp, entryPtr,
1206
objv[3], &index) != TCL_OK) {
1209
EntrySelectTo(entryPtr, index);
1216
case COMMAND_VALIDATE: {
1220
Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
1223
selIndex = entryPtr->validate;
1224
entryPtr->validate = VALIDATE_ALL;
1225
code = EntryValidateChange(entryPtr, (char *) NULL,
1226
entryPtr->string, -1, VALIDATE_FORCED);
1227
if (entryPtr->validate != VALIDATE_NONE) {
1228
entryPtr->validate = selIndex;
1230
Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
1234
case COMMAND_XVIEW: {
1239
char buf[TCL_DOUBLE_SPACE * 2];
1241
EntryVisibleRange(entryPtr, &first, &last);
1242
Tcl_DoubleResults(interp,2,0,first, last);
1244
} else if (objc == 3) {
1245
if (GetEntryIndex(interp, entryPtr, objv[2],
1246
&index) != TCL_OK) {
1253
index = entryPtr->leftIndex;
1254
switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
1256
case TK_SCROLL_ERROR: {
1259
case TK_SCROLL_MOVETO: {
1260
index = (int) ((fraction * entryPtr->numChars) + 0.5);
1263
case TK_SCROLL_PAGES: {
1266
charsPerPage = ((Tk_Width(entryPtr->tkwin)
1267
- 2 * entryPtr->inset)
1268
/ entryPtr->avgWidth) - 2;
1269
if (charsPerPage < 1) {
1272
index += count * charsPerPage;
1275
case TK_SCROLL_UNITS: {
1281
if (index >= entryPtr->numChars) {
1282
index = entryPtr->numChars - 1;
1287
entryPtr->leftIndex = index;
1288
entryPtr->flags |= UPDATE_SCROLLBAR;
1289
EntryComputeGeometry(entryPtr);
1290
EventuallyRedraw(entryPtr);
933
1296
Tcl_Release((ClientData) entryPtr);
2792
3586
entryPtr->flags &= ~VALIDATING;
2797
3591
*--------------------------------------------------------------
2799
3593
* ExpandPercents --
2801
* Given a command and an event, produce a new command
2802
* by replacing % constructs in the original command
2803
* with information from the X event.
3595
* Given a command and an event, produce a new command
3596
* by replacing % constructs in the original command
3597
* with information from the X event.
2806
* The new expanded command is appended to the dynamic string
3600
* The new expanded command is appended to the dynamic string
2809
3603
* Side effects:
2812
3606
*--------------------------------------------------------------
2817
ExpandPercents(entryPtr, before, add, new, index, type, dsPtr)
2818
register Entry *entryPtr; /* Entry that needs validation. */
2819
register char *before; /* Command containing percent
3611
ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
3612
register Entry *entryPtr; /* Entry that needs validation. */
3613
register CONST char *before;
3614
/* Command containing percent
2820
3615
* expressions to be replaced. */
2821
char *add; /* New characters to add (NULL-terminated
2823
char *new; /* Potential new value of entry string */
3616
char *change; /* Characters to added/deleted
3617
* (NULL-terminated string). */
3618
CONST char *new; /* Potential new value of entry string */
2824
3619
int index; /* index of insert/delete */
2825
3620
int type; /* INSERT or DELETE */
2826
3621
Tcl_DString *dsPtr; /* Dynamic string in which to append
2827
3622
* new command. */
2829
int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl
3624
int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl
2830
3625
* list element. */
2831
3626
int number, length;
2833
register char *string;
2834
char numStorage[NUM_SIZE+1];
3627
register CONST char *string;
3629
char numStorage[2*TCL_INTEGER_SPACE];
3632
if (*before == '\0') {
2838
3636
* Find everything up to the next % character and append it
2839
3637
* to the result string.
2842
for (string = before; (*string != 0) && (*string != '%'); string++) {
2843
/* Empty loop body. */
2845
if (string != before) {
3641
/* No need to convert '%', as it is in ascii range */
3642
string = Tcl_UtfFindFirst(before, '%');
3643
if (string == (char *) NULL) {
3644
Tcl_DStringAppend(dsPtr, before, -1);
3646
} else if (string != before) {
2846
3647
Tcl_DStringAppend(dsPtr, before, string-before);
2847
3648
before = string;
2854
3652
* There's a percent sequence here. Process it.
2859
switch (before[1]) {
2860
case 'd': /* Type of call that caused validation */
2863
case 'i': /* index of insert/delete */
2866
case 'P': /* 'Peeked' new value of the string */
2869
case 's': /* Current string value of entry */
2870
string = entryPtr->string;
2872
case 'S': /* string to be inserted/delete, if any */
2875
case 'v': /* type of validation */
2876
string = ValidatePrintProc((ClientData) NULL, entryPtr->tkwin,
2877
(char *) entryPtr, 0, 0);
2879
case 'W': /* widget name */
2880
string = Tk_PathName(entryPtr->tkwin);
2883
numStorage[0] = before[1];
2884
numStorage[1] = '\0';
2885
string = numStorage;
2890
sprintf(numStorage, "%d", number);
2891
string = numStorage;
2894
spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
3655
before++; /* skip over % */
3656
if (*before != '\0') {
3657
before += Tcl_UtfToUniChar(before, &ch);
3661
if (type == VALIDATE_BUTTON) {
3663
* -command %-substitution
3666
case 's': /* Current string value of spinbox */
3667
string = entryPtr->string;
3669
case 'd': /* direction, up or down */
3672
case 'W': /* widget name */
3673
string = Tk_PathName(entryPtr->tkwin);
3676
length = Tcl_UniCharToUtf(ch, numStorage);
3677
numStorage[length] = '\0';
3678
string = numStorage;
3683
* -validatecommand / -invalidcommand %-substitution
3686
case 'd': /* Type of call that caused validation */
3688
case VALIDATE_INSERT:
3691
case VALIDATE_DELETE:
3698
sprintf(numStorage, "%d", number);
3699
string = numStorage;
3701
case 'i': /* index of insert/delete */
3702
sprintf(numStorage, "%d", index);
3703
string = numStorage;
3705
case 'P': /* 'Peeked' new value of the string */
3708
case 's': /* Current string value of spinbox */
3709
string = entryPtr->string;
3711
case 'S': /* string to be inserted/deleted, if any */
3714
case 'v': /* type of validation currently set */
3715
string = validateStrings[entryPtr->validate];
3717
case 'V': /* type of validation in effect */
3719
case VALIDATE_INSERT:
3720
case VALIDATE_DELETE:
3721
string = validateStrings[VALIDATE_KEY];
3723
case VALIDATE_FORCED:
3727
string = validateStrings[type];
3731
case 'W': /* widget name */
3732
string = Tk_PathName(entryPtr->tkwin);
3735
length = Tcl_UniCharToUtf(ch, numStorage);
3736
numStorage[length] = '\0';
3737
string = numStorage;
3742
spaceNeeded = Tcl_ScanCountedElement(string, -1, &cvtFlags);
2895
3743
length = Tcl_DStringLength(dsPtr);
2896
3744
Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
2897
spaceNeeded = Tcl_ConvertElement(string,
3745
spaceNeeded = Tcl_ConvertCountedElement(string, -1,
2898
3746
Tcl_DStringValue(dsPtr) + length,
2899
3747
cvtFlags | TCL_DONT_USE_BRACES);
2900
3748
Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
2907
3754
*--------------------------------------------------------------
2909
* ValidateParseProc --
3756
* Tk_SpinboxObjCmd --
2911
* This procedure is invoked by Tk_ConfigureWidget during
2912
* option processing to handle "-validate" options for entry
3758
* This procedure is invoked to process the "spinbox" Tcl
3759
* command. See the user documentation for details on what
2916
* A standard Tcl return value.
3763
* A standard Tcl result.
2918
3765
* Side effects:
2919
* The validation style for the entry widget may change.
3766
* See the user documentation.
2921
3768
*--------------------------------------------------------------
2926
ValidateParseProc(clientData, interp, tkwin, ovalue, widgRec, offset)
2927
ClientData clientData; /* Not used.*/
2928
Tcl_Interp *interp; /* Used for reporting errors. */
2929
Tk_Window tkwin; /* Window for text widget. */
2930
Arg ovalue; /* Value of option. */
2931
char *widgRec; /* Pointer to widgRec structure. */
2932
int offset; /* Offset into item (ignored). */
3772
Tk_SpinboxObjCmd(clientData, interp, objc, objv)
3773
ClientData clientData; /* NULL. */
3774
Tcl_Interp *interp; /* Current interpreter. */
3775
int objc; /* Number of arguments. */
3776
Tcl_Obj *CONST objv[]; /* Argument objects. */
2936
char *value = LangString(ovalue);
2938
register int *validatePtr = (int *) (widgRec + offset);
2940
if(value == NULL || *value == 0) {
2941
*validatePtr = VALIDATE_NONE;
2946
length = strlen(value);
2947
if ((c == 'n') && (strncmp(value, "none", length) == 0)) {
2948
*validatePtr = VALIDATE_NONE;
2949
} else if ((c == 'a') && (strncmp(value, "all", length) == 0)) {
2950
*validatePtr = VALIDATE_ALL;
2951
} else if ((c == 'k') && (strncmp(value, "key", length) == 0)) {
2952
*validatePtr = VALIDATE_KEY;
2953
} else if (strcmp(value, "focus") == 0) {
2954
*validatePtr = VALIDATE_FOCUS;
2955
} else if (strcmp(value, "focusin") == 0) {
2956
*validatePtr = VALIDATE_FOCUSIN;
2957
} else if (strcmp(value, "focusout") == 0) {
2958
*validatePtr = VALIDATE_FOCUSOUT;
2960
Tcl_AppendResult(interp, "bad validation type \"", value,
2961
"\": must be none, all, key, focus, focusin, or focusout",
3778
register Entry *entryPtr;
3779
register Spinbox *sbPtr;
3780
Tk_OptionTable optionTable;
3785
Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
3789
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
3790
Tcl_GetString(objv[1]), (char *) NULL);
3791
if (tkwin == NULL) {
3796
* Create the option table for this widget class. If it has already
3797
* been created, Tk will return the cached value.
3800
optionTable = Tk_CreateOptionTable(interp, sbOptSpec);
3803
* Initialize the fields of the structure that won't be initialized
3804
* by ConfigureEntry, or that ConfigureEntry requires to be
3805
* initialized already (e.g. resource pointers). Only the non-NULL/0
3806
* data must be initialized as memset covers the rest.
3809
sbPtr = (Spinbox *) ckalloc(sizeof(Spinbox));
3810
entryPtr = (Entry *) sbPtr;
3811
memset((VOID *) sbPtr, 0, sizeof(Spinbox));
3813
entryPtr->tkwin = tkwin;
3814
entryPtr->display = Tk_Display(tkwin);
3815
entryPtr->interp = interp;
3816
entryPtr->widgetCmd = Tcl_CreateObjCommand(interp,
3817
Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd,
3818
(ClientData) sbPtr, EntryCmdDeletedProc);
3819
entryPtr->optionTable = optionTable;
3820
entryPtr->type = TK_SPINBOX;
3821
tmp = (char *) ckalloc(1);
3823
entryPtr->string = tmp;
3824
entryPtr->selectFirst = -1;
3825
entryPtr->selectLast = -1;
3827
entryPtr->cursor = None;
3828
entryPtr->exportSelection = 1;
3829
entryPtr->justify = TK_JUSTIFY_LEFT;
3830
entryPtr->relief = TK_RELIEF_FLAT;
3831
entryPtr->state = STATE_NORMAL;
3832
entryPtr->displayString = entryPtr->string;
3833
entryPtr->inset = XPAD;
3834
entryPtr->textGC = None;
3835
entryPtr->selTextGC = None;
3836
entryPtr->highlightGC = None;
3837
entryPtr->avgWidth = 1;
3838
entryPtr->validate = VALIDATE_NONE;
3840
sbPtr->selElement = SEL_NONE;
3841
sbPtr->curElement = SEL_NONE;
3842
sbPtr->bCursor = None;
3843
sbPtr->repeatDelay = 400;
3844
sbPtr->repeatInterval = 100;
3845
sbPtr->fromValue = 0.0;
3846
sbPtr->toValue = 100.0;
3847
sbPtr->increment = 1.0;
3848
sbPtr->formatBuf = (char *) ckalloc(TCL_DOUBLE_SPACE);
3849
sbPtr->bdRelief = TK_RELIEF_FLAT;
3850
sbPtr->buRelief = TK_RELIEF_FLAT;
3853
* Keep a hold of the associated tkwin until we destroy the listbox,
3854
* otherwise Tk might free it while we still need it.
3857
Tcl_Preserve((ClientData) entryPtr->tkwin);
3859
Tk_SetClass(entryPtr->tkwin, "Spinbox");
3860
Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr);
3861
Tk_CreateEventHandler(entryPtr->tkwin,
3862
PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask,
3863
EntryEventProc, (ClientData) entryPtr);
3864
Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
3865
EntryFetchSelection, (ClientData) entryPtr, XA_STRING);
3867
if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin)
3869
Tk_DestroyWindow(entryPtr->tkwin);
3872
if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) {
3876
Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC);
2969
*--------------------------------------------------------------
2971
* ValidatePrintProc --
2973
* This procedure is invoked by the Tk configuration code
2974
* to produce a printable string for the "-validate" configuration
2975
* option for entry widgets.
2978
* The return value is a string describing the entry
2979
* widget's current validation style.
2984
*--------------------------------------------------------------
2989
ValidatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
2990
ClientData clientData; /* Ignored. */
2991
Tk_Window tkwin; /* Window for text widget. */
2992
char *widgRec; /* Pointer to widgRec structure. */
2993
int offset; /* Ignored. */
2994
Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
2995
* information about how to reclaim
2996
* storage for return string. */
2998
register int *validatePtr = (int *) (widgRec + offset);
3001
switch (*validatePtr) {
3003
return LangStringArg("none");
3005
return LangStringArg("all");
3007
return LangStringArg("key");
3008
case VALIDATE_FOCUS:
3009
return LangStringArg("focus");
3010
case VALIDATE_FOCUSIN:
3011
return LangStringArg("focusin");
3013
case VALIDATE_FOCUSOUT:
3014
return LangStringArg("focusout");
3880
Tk_DestroyWindow(entryPtr->tkwin);
3885
*--------------------------------------------------------------
3887
* SpinboxWidgetObjCmd --
3889
* This procedure is invoked to process the Tcl command
3890
* that corresponds to a widget managed by this module.
3891
* See the user documentation for details on what it does.
3894
* A standard Tcl result.
3897
* See the user documentation.
3899
*--------------------------------------------------------------
3903
SpinboxWidgetObjCmd(clientData, interp, objc, objv)
3904
ClientData clientData; /* Information about spinbox widget. */
3905
Tcl_Interp *interp; /* Current interpreter. */
3906
int objc; /* Number of arguments. */
3907
Tcl_Obj *CONST objv[]; /* Argument objects. */
3909
Entry *entryPtr = (Entry *) clientData;
3910
Spinbox *sbPtr = (Spinbox *) clientData;
3911
int cmdIndex, selIndex, result;
3915
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
3920
* Parse the widget command by looking up the second token in
3921
* the list of valid command names.
3924
result = Tcl_GetIndexFromObj(interp, objv[1], sbCmdNames,
3925
"option", 0, &cmdIndex);
3926
if (result != TCL_OK) {
3930
Tcl_Preserve((ClientData) entryPtr);
3931
switch ((enum sbCmd) cmdIndex) {
3933
int index, x, y, width, height;
3934
char buf[TCL_INTEGER_SPACE * 4];
3937
Tcl_WrongNumArgs(interp, 2, objv, "index");
3940
if (GetEntryIndex(interp, entryPtr, objv[2],
3941
&index) != TCL_OK) {
3944
if ((index == entryPtr->numChars) && (index > 0)) {
3947
Tk_CharBbox(entryPtr->textLayout, index, &x, &y,
3949
Tcl_IntResults(interp, 4, 0,
3950
x + entryPtr->layoutX,
3951
y + entryPtr->layoutY, width, height);
3957
Tcl_WrongNumArgs(interp, 2, objv, "option");
3961
objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
3962
entryPtr->optionTable, objv[2], entryPtr->tkwin);
3963
if (objPtr == NULL) {
3966
Tcl_SetObjResult(interp, objPtr);
3971
case SB_CMD_CONFIGURE: {
3973
objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
3974
entryPtr->optionTable,
3975
(objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
3977
if (objPtr == NULL) {
3980
Tcl_SetObjResult(interp, objPtr);
3983
result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
3988
case SB_CMD_DELETE: {
3991
if ((objc < 3) || (objc > 4)) {
3992
Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
3995
if (GetEntryIndex(interp, entryPtr, objv[2],
3996
&first) != TCL_OK) {
4002
if (GetEntryIndex(interp, entryPtr, objv[3],
4007
if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
4008
DeleteChars(entryPtr, first, last - first);
4015
Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
4018
Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
4022
case SB_CMD_ICURSOR: {
4024
Tcl_WrongNumArgs(interp, 2, objv, "pos");
4027
if (GetEntryIndex(interp, entryPtr, objv[2],
4028
&entryPtr->insertPos) != TCL_OK) {
4031
EventuallyRedraw(entryPtr);
4035
case SB_CMD_IDENTIFY: {
4039
Tcl_WrongNumArgs(interp, 2, objv, "x y");
4042
if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
4043
(Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
4046
elem = GetSpinboxElement(sbPtr, x, y);
4047
if (elem != SEL_NONE) {
4048
Tcl_SetStringObj(Tcl_GetObjResult(interp),
4049
selElementNames[elem], -1);
4054
case SB_CMD_INDEX: {
4058
Tcl_WrongNumArgs(interp, 2, objv, "string");
4061
if (GetEntryIndex(interp, entryPtr, objv[2],
4062
&index) != TCL_OK) {
4065
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
4069
case SB_CMD_INSERT: {
4073
Tcl_WrongNumArgs(interp, 2, objv, "index text");
4076
if (GetEntryIndex(interp, entryPtr, objv[2],
4077
&index) != TCL_OK) {
4080
if (entryPtr->state == STATE_NORMAL) {
4081
InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
4086
case SB_CMD_INVOKE: {
4088
Tcl_WrongNumArgs(interp, 2, objv, "elemName");
4091
result = Tcl_GetIndexFromObj(interp, objv[2],
4092
selElementNames, "element", 0, &cmdIndex);
4093
if (result != TCL_OK) {
4096
if (entryPtr->state != STATE_DISABLED) {
4097
if (SpinboxInvoke(interp, sbPtr, cmdIndex) != TCL_OK) {
4109
Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x");
4112
if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
4116
minorCmd = Tcl_GetString(objv[2]);
4117
if (minorCmd[0] == 'm'
4118
&& (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) {
4119
entryPtr->scanMarkX = x;
4120
entryPtr->scanMarkIndex = entryPtr->leftIndex;
4121
} else if ((minorCmd[0] == 'd')
4122
&& (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) {
4123
EntryScanTo(entryPtr, x);
4125
Tcl_AppendResult(interp, "bad scan option \"",
4126
Tcl_GetString(objv[2]), "\": must be mark or dragto",
4133
case SB_CMD_SELECTION: {
4137
Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
4142
* Parse the selection sub-command, using the command
4143
* table "sbSelCmdNames" defined above.
4146
result = Tcl_GetIndexFromObj(interp, objv[2], sbSelCmdNames,
4147
"selection option", 0, &selIndex);
4148
if (result != TCL_OK) {
4153
* Disabled entries don't allow the selection to be modified,
4154
* but 'selection present' must return a boolean.
4157
if ((entryPtr->state == STATE_DISABLED)
4158
&& (selIndex != SB_SEL_PRESENT)) {
4163
case SB_SEL_ADJUST: {
4165
Tcl_WrongNumArgs(interp, 3, objv, "index");
4168
if (GetEntryIndex(interp, entryPtr,
4169
objv[3], &index) != TCL_OK) {
4172
if (entryPtr->selectFirst >= 0) {
4175
half1 = (entryPtr->selectFirst
4176
+ entryPtr->selectLast)/2;
4177
half2 = (entryPtr->selectFirst
4178
+ entryPtr->selectLast + 1)/2;
4179
if (index < half1) {
4180
entryPtr->selectAnchor = entryPtr->selectLast;
4181
} else if (index > half2) {
4182
entryPtr->selectAnchor = entryPtr->selectFirst;
4185
* We're at about the halfway point in the
4186
* selection; just keep the existing anchor.
4190
EntrySelectTo(entryPtr, index);
4194
case SB_SEL_CLEAR: {
4196
Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
4199
if (entryPtr->selectFirst >= 0) {
4200
entryPtr->selectFirst = -1;
4201
entryPtr->selectLast = -1;
4202
EventuallyRedraw(entryPtr);
4209
Tcl_WrongNumArgs(interp, 3, objv, "index");
4212
if (GetEntryIndex(interp, entryPtr,
4213
objv[3], &index) != TCL_OK) {
4216
entryPtr->selectAnchor = index;
4220
case SB_SEL_PRESENT: {
4222
Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
4225
Tcl_SetObjResult(interp,
4226
Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
4230
case SB_SEL_RANGE: {
4232
Tcl_WrongNumArgs(interp, 3, objv, "start end");
4235
if (GetEntryIndex(interp, entryPtr,
4236
objv[3], &index) != TCL_OK) {
4239
if (GetEntryIndex(interp, entryPtr,
4240
objv[4],& index2) != TCL_OK) {
4243
if (index >= index2) {
4244
entryPtr->selectFirst = -1;
4245
entryPtr->selectLast = -1;
4247
entryPtr->selectFirst = index;
4248
entryPtr->selectLast = index2;
4250
if (!(entryPtr->flags & GOT_SELECTION)
4251
&& (entryPtr->exportSelection)) {
4252
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
4253
EntryLostSelection, (ClientData) entryPtr);
4254
entryPtr->flags |= GOT_SELECTION;
4256
EventuallyRedraw(entryPtr);
4262
Tcl_WrongNumArgs(interp, 3, objv, "index");
4265
if (GetEntryIndex(interp, entryPtr,
4266
objv[3], &index) != TCL_OK) {
4269
EntrySelectTo(entryPtr, index);
4273
case SB_SEL_ELEMENT: {
4274
if ((objc < 3) || (objc > 4)) {
4275
Tcl_WrongNumArgs(interp, 3, objv, "?elemName?");
4279
Tcl_SetStringObj(Tcl_GetObjResult(interp),
4280
selElementNames[sbPtr->selElement], -1);
4282
int lastElement = sbPtr->selElement;
4284
result = Tcl_GetIndexFromObj(interp, objv[3],
4285
selElementNames, "selection element", 0,
4286
&(sbPtr->selElement));
4287
if (result != TCL_OK) {
4290
if (lastElement != sbPtr->selElement) {
4291
EventuallyRedraw(entryPtr);
4302
Tcl_WrongNumArgs(interp, 2, objv, "?string?");
4306
EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
4308
Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
4312
case SB_CMD_VALIDATE: {
4316
Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
4319
selIndex = entryPtr->validate;
4320
entryPtr->validate = VALIDATE_ALL;
4321
code = EntryValidateChange(entryPtr, (char *) NULL,
4322
entryPtr->string, -1, VALIDATE_FORCED);
4323
if (entryPtr->validate != VALIDATE_NONE) {
4324
entryPtr->validate = selIndex;
4326
Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
4330
case SB_CMD_XVIEW: {
4335
char buf[TCL_DOUBLE_SPACE * 2];
4337
EntryVisibleRange(entryPtr, &first, &last);
4338
sprintf(buf, "%g %g", first, last);
4339
Tcl_SetResult(interp, buf, TCL_VOLATILE);
4341
} else if (objc == 3) {
4342
if (GetEntryIndex(interp, entryPtr, objv[2],
4343
&index) != TCL_OK) {
4350
index = entryPtr->leftIndex;
4351
switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
4353
case TK_SCROLL_ERROR: {
4356
case TK_SCROLL_MOVETO: {
4357
index = (int) ((fraction * entryPtr->numChars) + 0.5);
4360
case TK_SCROLL_PAGES: {
4363
charsPerPage = ((Tk_Width(entryPtr->tkwin)
4364
- 2 * entryPtr->inset - entryPtr->xWidth)
4365
/ entryPtr->avgWidth) - 2;
4366
if (charsPerPage < 1) {
4369
index += count * charsPerPage;
4372
case TK_SCROLL_UNITS: {
4378
if (index >= entryPtr->numChars) {
4379
index = entryPtr->numChars - 1;
4384
entryPtr->leftIndex = index;
4385
entryPtr->flags |= UPDATE_SCROLLBAR;
4386
EntryComputeGeometry(entryPtr);
4387
EventuallyRedraw(entryPtr);
4393
Tcl_Release((ClientData) entryPtr);
4397
Tcl_Release((ClientData) entryPtr);
4402
*---------------------------------------------------------------------------
4404
* GetSpinboxElement --
4406
* Return the element associated with an x,y coord.
4409
* Element type as enum selelement.
4414
*---------------------------------------------------------------------------
4418
GetSpinboxElement(sbPtr, x, y)
4419
Spinbox *sbPtr; /* Spinbox for which the index is being
4421
int x; /* x coord */
4422
int y; /* y coord */
4424
Entry *entryPtr = (Entry *) sbPtr;
4426
if ((x < 0) || (y < 0) || (y > Tk_Height(entryPtr->tkwin))
4427
|| (x > Tk_Width(entryPtr->tkwin))) {
4431
if (x > (Tk_Width(entryPtr->tkwin) - entryPtr->inset - entryPtr->xWidth)) {
4432
if (y > (Tk_Height(entryPtr->tkwin) / 2)) {
4433
return SEL_BUTTONDOWN;
4435
return SEL_BUTTONUP;
4442
*--------------------------------------------------------------
4446
* This procedure is invoked when the invoke method for the
4453
* An background error condition may arise when invoking the
4454
* callback. The widget value may change.
4456
*--------------------------------------------------------------
4460
SpinboxInvoke(interp, sbPtr, element)
4461
register Tcl_Interp *interp; /* Current interpreter. */
4462
register Spinbox *sbPtr; /* Spinbox to invoke. */
4463
int element; /* element to invoke, either the "up"
4464
* or "down" button. */
4466
Entry *entryPtr = (Entry *) sbPtr;
4476
case SEL_BUTTONDOWN:
3020
#endif /* ENTRY_VALIDATE */
4484
if (fabs(sbPtr->increment) > MIN_DBL_VAL) {
4485
if (sbPtr->listObj != NULL) {
4488
Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr);
4489
if (strcmp(Tcl_GetString(objPtr), entryPtr->string)) {
4491
* Somehow the string changed from what we expected,
4492
* so let's do a search on the list to see if the current
4493
* value is there. If not, move to the first element of
4496
int i, listc, elemLen, length = entryPtr->numChars;
4500
Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
4501
for (i = 0; i < listc; i++) {
4502
bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
4503
if ((length == elemLen) &&
4504
(memcmp(bytes, entryPtr->string,
4505
(size_t) length) == 0)) {
4512
if (++sbPtr->eIndex >= sbPtr->nElements) {
4516
sbPtr->eIndex = sbPtr->nElements-1;
4520
if (--sbPtr->eIndex < 0) {
4522
sbPtr->eIndex = sbPtr->nElements-1;
4528
Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr);
4529
EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
4530
} else if (!DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)) {
4533
if (Tcl_GetDouble(NULL, entryPtr->string, &dvalue) != TCL_OK) {
4535
* If the string is empty, or isn't a valid double value,
4536
* just use the -from value
4538
dvalue = sbPtr->fromValue;
4541
dvalue += sbPtr->increment;
4542
if (dvalue > sbPtr->toValue) {
4544
dvalue = sbPtr->fromValue;
4546
dvalue = sbPtr->toValue;
4548
} else if (dvalue < sbPtr->fromValue) {
4550
* It's possible that when pressing up, we are
4551
* still less than the fromValue, because the
4552
* user may have manipulated the value by hand.
4554
dvalue = sbPtr->fromValue;
4557
dvalue -= sbPtr->increment;
4558
if (dvalue < sbPtr->fromValue) {
4560
dvalue = sbPtr->toValue;
4562
dvalue = sbPtr->fromValue;
4564
} else if (dvalue > sbPtr->toValue) {
4566
* It's possible that when pressing down, we are
4567
* still greater than the toValue, because the
4568
* user may have manipulated the value by hand.
4570
dvalue = sbPtr->toValue;
4574
sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
4575
EntryValueChanged(entryPtr, sbPtr->formatBuf);
4579
if (sbPtr->command != NULL) {
4581
Tcl_DStringInit(&script);
4582
ExpandPercents(entryPtr, sbPtr->command, type, "", 0,
4583
VALIDATE_BUTTON, &script);
4584
Tcl_DStringAppend(&script, "", 1);
4586
code = Tcl_EvalEx(interp, Tcl_DStringValue(&script), -1,
4587
TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
4588
Tcl_DStringFree(&script);
4590
code = LangDoCallback(entryPtr->interp, sbPtr->command, 1, 2,
4591
" %s %s", entryPtr->string, type);
4594
if (code != TCL_OK) {
4595
Tcl_AddErrorInfo(interp, "\n\t(in command executed by spinbox)");
4596
Tcl_BackgroundError(interp);
4598
* Yes, it's an error, but a bg one, so we return OK
4603
Tcl_SetResult(interp, NULL, 0);
4610
*----------------------------------------------------------------------
4614
* This procedure is invoked to recompute the "format" fields
4615
* of a spinbox's widget record, which determines how the value
4616
* of the dial is converted to a string.
4622
* The format fields of the spinbox are modified.
4624
*----------------------------------------------------------------------
4627
ComputeFormat(sbPtr)
4628
Spinbox *sbPtr; /* Information about dial widget. */
4631
int mostSigDigit, numDigits, leastSigDigit, afterDecimal;
4632
int eDigits, fDigits;
4635
* Compute the displacement from the decimal of the most significant
4636
* digit required for any number in the dial's range.
4639
if (sbPtr->reqFormat) {
4640
sbPtr->valueFormat = sbPtr->reqFormat;
4644
maxValue = fabs(sbPtr->fromValue);
4645
x = fabs(sbPtr->toValue);
4649
if (maxValue == 0) {
4652
mostSigDigit = (int) floor(log10(maxValue));
4654
if (fabs(sbPtr->increment) > MIN_DBL_VAL) {
4656
* A increment was specified, so use it.
4658
leastSigDigit = (int) floor(log10(sbPtr->increment));
4662
numDigits = mostSigDigit - leastSigDigit + 1;
4663
if (numDigits < 1) {
4668
* Compute the number of characters required using "e" format and
4669
* "f" format, and then choose whichever one takes fewer characters.
4672
eDigits = numDigits + 4;
4673
if (numDigits > 1) {
4674
eDigits++; /* Decimal point. */
4676
afterDecimal = numDigits - mostSigDigit - 1;
4677
if (afterDecimal < 0) {
4680
fDigits = (mostSigDigit >= 0) ? mostSigDigit + afterDecimal : afterDecimal;
4681
if (afterDecimal > 0) {
4682
fDigits++; /* Decimal point. */
4684
if (mostSigDigit < 0) {
4685
fDigits++; /* Zero to left of decimal point. */
4687
if (fDigits <= eDigits) {
4688
sprintf(sbPtr->digitFormat, "%%.%df", afterDecimal);
4690
sprintf(sbPtr->digitFormat, "%%.%de", numDigits-1);
4692
sbPtr->valueFormat = sbPtr->digitFormat;