Unnamed Fossil Project

Check-in [89d96acfd8]
Login

Check-in [89d96acfd8]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:New utility, TrackElementState Updated TScrollbar to use TrackElementState; [$scrollbar elementstate] widget method no longer needed. Scrollbar finally displays "active" state properly!
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256: 89d96acfd84b53891f1d6a481c2cfa6a9313d309eff2d72045fcdf247d70adf8
User & Date: jenglish 2004-01-06 21:41:01.000
Context
2004-01-06
22:03
Factored out ScrollbarLayout; added comments. check-in: 7dee9614ed user: jenglish tags: master, trunk
21:41
New utility, TrackElementState Updated TScrollbar to use TrackElementState; [$scrollbar elementstate] widget method no longer needed. Scrollbar finally displays "active" state properly! check-in: 89d96acfd8 user: jenglish tags: master, trunk
21:14
Cleared some warnings from gcc. check-in: a1047b9ac9 user: patthoyts tags: master, trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to ChangeLog.







1
2
3
4
5
6
7







2004-01-06  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkTheme.c:     Fix element lookup to look over multiple
	dot-separated names. eg: Z.x.y -> x.y -> y then lookup the same in
	the parent theme.
	
	* generic/scale.c:       Improved the scale implementation.
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
2004-01-06  Joe English  <jenglish@users.sourceforge.net>
	* generic/track.c: New utility, TrackElementState
	* generic/scrollbar.c, library/scrollbar.tcl:
	Updated TScrollbar to use TrackElementState; 
	[$scrollbar elementstate] widget method no longer needed.
	* Scrollbar finally displays "active" state properly!

2004-01-06  Pat Thoyts  <patthoyts@users.sourceforge.net>

	* generic/tkTheme.c:     Fix element lookup to look over multiple
	dot-separated names. eg: Z.x.y -> x.y -> y then lookup the same in
	the parent theme.
	
	* generic/scale.c:       Improved the scale implementation.
Changes to Makefile.in.
75
76
77
78
79
80
81

82
83
84
85
86
87
88
CLEANFILES	= *.$(OBJEXT) $(tile_LIB_FILE)

GENERIC_OBJECTS	= tkstate.$(OBJEXT) \
		  tile.$(OBJEXT) \
		  scrollbar.$(OBJEXT) \
		  layout.$(OBJEXT) \
		  widget.$(OBJEXT) \

		  altTheme.$(OBJEXT) \
		  stepTheme.$(OBJEXT) \
		  tkElements.$(OBJEXT) \
		  tkTheme.$(OBJEXT) \

UNIX_OBJECTS	=
WIN_OBJECTS	= xpTheme.$(OBJEXT)







>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
CLEANFILES	= *.$(OBJEXT) $(tile_LIB_FILE)

GENERIC_OBJECTS	= tkstate.$(OBJEXT) \
		  tile.$(OBJEXT) \
		  scrollbar.$(OBJEXT) \
		  layout.$(OBJEXT) \
		  widget.$(OBJEXT) \
		  track.$(OBJEXT) \
		  altTheme.$(OBJEXT) \
		  stepTheme.$(OBJEXT) \
		  tkElements.$(OBJEXT) \
		  tkTheme.$(OBJEXT) \

UNIX_OBJECTS	=
WIN_OBJECTS	= xpTheme.$(OBJEXT)
Changes to generic/Makefile.in.
57
58
59
60
61
62
63

64
65
66
67
68
69
70
tile_OBJECTS 	= \
    tkstate.$(OBJEXT) \
    tile.$(OBJEXT) \
    scrollbar.$(OBJEXT) \
    scale.$(OBJEXT) \
    layout.$(OBJEXT) \
    widget.$(OBJEXT) \

    altTheme.$(OBJEXT) \
    tkElements.$(OBJEXT) \
    tkTheme.$(OBJEXT) \
    stepTheme.$(OBJEXT) \
    @EXTRA_OBJS@

WIN_OBJS	= xpTheme.$(OBJEXT)







>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
tile_OBJECTS 	= \
    tkstate.$(OBJEXT) \
    tile.$(OBJEXT) \
    scrollbar.$(OBJEXT) \
    scale.$(OBJEXT) \
    layout.$(OBJEXT) \
    widget.$(OBJEXT) \
    track.$(OBJEXT) \
    altTheme.$(OBJEXT) \
    tkElements.$(OBJEXT) \
    tkTheme.$(OBJEXT) \
    stepTheme.$(OBJEXT) \
    @EXTRA_OBJS@

WIN_OBJS	= xpTheme.$(OBJEXT)
Changes to generic/TODO.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
	must be the sole children of their parent node, otherwise
	reqsize calculation is wrong.  (probable cause of problem: 
	INSIDE/BORDER flags lack a packing specification).

@@@ TTK_LayoutFindNode, [$sb identify], &c -- need a way to identify
    nodes by name instead of class.


VERY IMPORTANT: error-checking in AllocateResources(), DeallocateResources().
This is a sure-fire way to crash.

~~ Layout engine:
    + Reimplement; the current design is subtly but fatally flawed.
    + Change ElementSpec draw procedure to take a TTK_Box * instead
      of separate x, y, width, height arguments.

~~ General:
    + add fallback fallback "null" element 
    + Need per-engine cleanup procedures.
    + Rethink resource allocation (AllocateResource,DeallocateResources)
    + Provide for drawing by parent style engine. In the XP theme, if 
      themeing is disabled then we need to revert to win32 compatible
      drawing (eg: alt theme).
    + [style configure] should schedule a WorldChanged call
    + WorldChanged handler should reload all elements
    + Need: windows-native theme (use native (non-XP-theme) widgets)
    + Need: MacOSX-native theme (ditto).




~~ Buttons, checkbuttons, radiobuttons:
    + rename 'compound' element to 'label', 'label' => 'text'
    + add -width resource to text element; negative -width => minimum.
    + [$checkbutton configure -variable foo] does not set state
    + [$label configure -textvariable foo] does not update -text
    + alt theme: focus ring should go around text (in check/radio buttons)
      (maybe we can get away with not doing this...)

~~ Scrollbars:
    + Need a way to specify per-element state, so arrows press, etc&
      (@@@ done; need a _different_ way)
      (@@@ found a different way, still doesn't work right)

    + minimum width/height for thumb element.
      (Problem: this should really be determined by the theme,
      but the scrollbar widget itself needs to know this value).
      (Finally fixed, 4 Jan 2004)
    + classic theme: scrollbar arrows don't look quite right.
    + alt theme: scrollbar arrows don't look quite right.
    + scrollbar elements don't activate/prelight on hover.







<



















>
>
>













>







8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
	must be the sole children of their parent node, otherwise
	reqsize calculation is wrong.  (probable cause of problem: 
	INSIDE/BORDER flags lack a packing specification).

@@@ TTK_LayoutFindNode, [$sb identify], &c -- need a way to identify
    nodes by name instead of class.


VERY IMPORTANT: error-checking in AllocateResources(), DeallocateResources().
This is a sure-fire way to crash.

~~ Layout engine:
    + Reimplement; the current design is subtly but fatally flawed.
    + Change ElementSpec draw procedure to take a TTK_Box * instead
      of separate x, y, width, height arguments.

~~ General:
    + add fallback fallback "null" element 
    + Need per-engine cleanup procedures.
    + Rethink resource allocation (AllocateResource,DeallocateResources)
    + Provide for drawing by parent style engine. In the XP theme, if 
      themeing is disabled then we need to revert to win32 compatible
      drawing (eg: alt theme).
    + [style configure] should schedule a WorldChanged call
    + WorldChanged handler should reload all elements
    + Need: windows-native theme (use native (non-XP-theme) widgets)
    + Need: MacOSX-native theme (ditto).
    + Need to support both "native/default" L&F and highly-customized L&F
      (Ex: http://www.iit.demokritos.gr/~petasis/Tcl/PeculiarButtons.gif)


~~ Buttons, checkbuttons, radiobuttons:
    + rename 'compound' element to 'label', 'label' => 'text'
    + add -width resource to text element; negative -width => minimum.
    + [$checkbutton configure -variable foo] does not set state
    + [$label configure -textvariable foo] does not update -text
    + alt theme: focus ring should go around text (in check/radio buttons)
      (maybe we can get away with not doing this...)

~~ Scrollbars:
    + Need a way to specify per-element state, so arrows press, etc&
      (@@@ done; need a _different_ way)
      (@@@ found a different way, still doesn't work right)
      (@@@ 6 Jan 2004 Think this finally works now).
    + minimum width/height for thumb element.
      (Problem: this should really be determined by the theme,
      but the scrollbar widget itself needs to know this value).
      (Finally fixed, 4 Jan 2004)
    + classic theme: scrollbar arrows don't look quite right.
    + alt theme: scrollbar arrows don't look quite right.
    + scrollbar elements don't activate/prelight on hover.
Changes to generic/layout.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * layout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 * $Id: layout.c,v 1.10 2004/01/02 01:16:10 patthoyts Exp $
 */

#include <string.h>
#include <tk.h>
#include "tkTheme.h"

#define MAX(a,b) (a > b ? a : b)







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * layout.c --
 *
 * Generic layout processing.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 * $Id: layout.c,v 1.11 2004/01/05 01:24:31 jenglish Exp $
 */

#include <string.h>
#include <tk.h>
#include "tkTheme.h"

#define MAX(a,b) (a > b ? a : b)
71
72
73
74
75
76
77




78
79
80
81
82
83
84
}

void TTK_ModifyElementState(TTK_LayoutNode *node, TTK_WidgetStateSpec *spec)
{
    node->state = TTK_ModifyWidgetState(node->state, spec);
}






static TTK_Box makeBox(int x, int y, int w, int h)
{
    TTK_Box b;
    b.x = x; b.y = y; b.w = w; b.h = h;
    return b;
}







>
>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
}

void TTK_ModifyElementState(TTK_LayoutNode *node, TTK_WidgetStateSpec *spec)
{
    node->state = TTK_ModifyWidgetState(node->state, spec);
}

void TTK_ChangeElementState(TTK_LayoutNode *node,unsigned set,unsigned clr)
{
    node->state = (node->state | set) & ~clr;
}

static TTK_Box makeBox(int x, int y, int w, int h)
{
    TTK_Box b;
    b.x = x; b.y = y; b.w = w; b.h = h;
    return b;
}
Changes to generic/scrollbar.c.
1
2
3
4
5
6
7
8
/* $Id: scrollbar.c,v 1.11 2004/01/05 21:57:04 patthoyts Exp $
 *
 * Copyright (c) 2003, Joe English
 *
 * Scrollbar widget implementation.
 *
 */

|







1
2
3
4
5
6
7
8
/* $Id: scrollbar.c,v 1.12 2004/01/06 01:26:00 jenglish Exp $
 *
 * Copyright (c) 2003, Joe English
 *
 * Scrollbar widget implementation.
 *
 */

51
52
53
54
55
56
57



58
59
60
61
62
63
64

static int 
ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Scrollbar *sb = recordPtr;
    sb->scrollbar.first = 0.0;
    sb->scrollbar.last = 1.0;



    return TCL_OK;
}

static void 
ScrollbarCleanup(void *recordPtr)
{
    /* no-op for now */







>
>
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

static int 
ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr)
{
    Scrollbar *sb = recordPtr;
    sb->scrollbar.first = 0.0;
    sb->scrollbar.last = 1.0;

    TrackElementState(&sb->core);

    return TCL_OK;
}

static void 
ScrollbarCleanup(void *recordPtr)
{
    /* no-op for now */
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	    fraction = (double)(x - b.x) / (double)(b.w - minSize);
    }

    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
    return TCL_OK;
}

/*
 * ScrollbarElementStateCommand --
 * 	[$scrollbar elementstate $elementtag $statespec] --
 *
 * elementtag is of the form "@x,y", identify the element at position x,y 
 */

static int
ScrollbarElementStateCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr)
{
    Scrollbar *scrollbar = recordPtr;
    TTK_LayoutNode *node;
    const char *elementSpec;
    int x, y;
    TTK_WidgetStateSpec stateSpec;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "@x,y statespec");
	return TCL_ERROR;
    }

    if (TTK_GetWidgetStateSpecFromObj(interp, objv[3], &stateSpec) != TCL_OK)
	return TCL_ERROR;
    elementSpec = Tcl_GetString(objv[2]);
    if (sscanf(elementSpec, "@%d,%d", &x, &y) == 2) {
	node = TTK_LayoutIdentify(scrollbar->core.layout, x, y); 
	if (!node) {
	    /* @x,y -- OK if this fails */
	    return TCL_OK;
	}
    } else {
	node = TTK_LayoutFindNode(scrollbar->core.layout, elementSpec);
	if (!node) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp,"Bad element specification ",
		    elementSpec,NULL);
	    return TCL_ERROR;
	}
    }

    TTK_ModifyElementState(node, &stateSpec);
    WidgetChanged(&scrollbar->core, REDISPLAY_REQUIRED);

    return TCL_OK;
}

static WidgetCommandSpec ScrollbarCommands[] =
{
    { "configure",	WidgetConfigureCommand },
    { "cget",		WidgetCgetCommand },
    { "delta",    	ScrollbarDeltaCommand },
    { "elementstate",  	ScrollbarElementStateCommand },
    { "fraction",    	ScrollbarFractionCommand },
    { "get",    	ScrollbarGetCommand },
    { "identify",	ScrollbarIdentifyCommand },
    { "instate",	WidgetInstateCommand },
    { "set",  		ScrollbarSetCommand },
    { "state",  	WidgetStateCommand },
    { 0,0 }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<







323
324
325
326
327
328
329















































330
331
332
333
334

335
336
337
338
339
340
341
	    fraction = (double)(x - b.x) / (double)(b.w - minSize);
    }

    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
    return TCL_OK;
}
















































static WidgetCommandSpec ScrollbarCommands[] =
{
    { "configure",	WidgetConfigureCommand },
    { "cget",		WidgetCgetCommand },
    { "delta",    	ScrollbarDeltaCommand },

    { "fraction",    	ScrollbarFractionCommand },
    { "get",    	ScrollbarGetCommand },
    { "identify",	ScrollbarIdentifyCommand },
    { "instate",	WidgetInstateCommand },
    { "set",  		ScrollbarSetCommand },
    { "state",  	WidgetStateCommand },
    { 0,0 }
Changes to generic/tkTheme.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkTheme.h --
 *      Declarations for Tk style engine.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 * $Id: tkTheme.h,v 1.14 2004/01/05 01:24:31 jenglish Exp $
 */

#ifndef TKTHEME_H
#define TKTHEME_H 1

#ifndef WIN32
#define NO_PRIVATE_HEADERS 1






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkTheme.h --
 *      Declarations for Tk style engine.
 *
 * Copyright (c) 2003 Joe English.  Freely redistributable.
 *
 * $Id: tkTheme.h,v 1.15 2004/01/05 21:57:04 patthoyts Exp $
 */

#ifndef TKTHEME_H
#define TKTHEME_H 1

#ifndef WIN32
#define NO_PRIVATE_HEADERS 1
257
258
259
260
261
262
263

264
265
266
267
268
269
270

extern const char *TTK_LayoutNodeName(TTK_LayoutNode *);
extern TTK_Box TTK_LayoutNodeParcel(TTK_LayoutNode *);
extern TTK_Element TTK_LayoutNodeElement(TTK_LayoutNode *);

extern void TTK_LayoutNodeSetParcel(TTK_LayoutNode *node, TTK_Box parcel);
extern void TTK_ModifyElementState(TTK_LayoutNode *, TTK_WidgetStateSpec *);


extern TTK_Style TTK_RegisterLayout(
    TTK_Theme theme, const char *className, TTK_LayoutSpec layoutSpec);

extern TTK_LayoutSpec TTK_FindLayout(TTK_Theme theme, const char *className);

extern TTK_Layout TTK_CreateLayout(







>







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

extern const char *TTK_LayoutNodeName(TTK_LayoutNode *);
extern TTK_Box TTK_LayoutNodeParcel(TTK_LayoutNode *);
extern TTK_Element TTK_LayoutNodeElement(TTK_LayoutNode *);

extern void TTK_LayoutNodeSetParcel(TTK_LayoutNode *node, TTK_Box parcel);
extern void TTK_ModifyElementState(TTK_LayoutNode *, TTK_WidgetStateSpec *);
extern void TTK_ChangeElementState(TTK_LayoutNode *,unsigned set,unsigned clr);

extern TTK_Style TTK_RegisterLayout(
    TTK_Theme theme, const char *className, TTK_LayoutSpec layoutSpec);

extern TTK_LayoutSpec TTK_FindLayout(TTK_Theme theme, const char *className);

extern TTK_Layout TTK_CreateLayout(
Added generic/track.c.














































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* $Id$
 * Copyright (c) 2004, Joe English
 *
 * TrackElementState() -- helper routine for widgets
 * like scrollbars in which individual elements may
 * be active or pressed instead of the widget as a whole.
 *
 * Usage:
 * 	TrackElementState(&recordPtr->core);
 *
 * Registers an event handler on the widget that tracks pointer
 * events and updates the state of the element under the
 * mouse cursor.
 *
 * The "active" element is the one under the mouse cursor,
 * and is normally set to the ACTIVE state unless another element
 * is currently being pressed.
 *
 * The active element becomes "pressed" on <ButtonPress> events,
 * and remains "active" and "pressed" until the corresponding
 * <ButtonRelease> event.
 *
 * TODO: Handle "chords" properly (e.g., <B1-ButtonPress-2>)
 *
 */

#include <tk.h>
#include "tkTheme.h"
#include "widget.h"


typedef struct 
{
    WidgetCore		*corePtr;	/* Widget to track */
    TTK_LayoutNode	*activeElement;	/* element under the mouse cursor */
    TTK_LayoutNode	*pressedElement; /* currently pressed element */
} ElementStateTracker;

/* ReleaseElement --
 * 	Releases the currently pressed element, if any.
 */
void ReleaseElement(ElementStateTracker *es)
{
    if (!es->pressedElement)
	return;

    TTK_ChangeElementState(es->pressedElement, 0,TK_WIDGET_STATE_PRESSED);
    es->pressedElement = 0;

    /* Reactivate element under the mouse cursor:
     */
    if (es->activeElement)
	TTK_ChangeElementState(es->activeElement, TK_WIDGET_STATE_ACTIVE, 0);

    WidgetChanged(es->corePtr, REDISPLAY_REQUIRED);
}

/* PressElement --
 * 	Presses the specified element.
 */
static void PressElement(ElementStateTracker *es, TTK_LayoutNode *node)
{
    if (es->pressedElement)
	ReleaseElement(es);

    if (node)
	TTK_ChangeElementState(node, TK_WIDGET_STATE_PRESSED, 0);

    es->pressedElement = node;
    WidgetChanged(es->corePtr, REDISPLAY_REQUIRED);
}

/*
 * ActivateElement(es, node) --
 * 	Make 'node' the active element if non-NULL.
 * 	Deactivates the currently active element if different.
 *
 * 	The active element has TTK_WIDGET_STATE_ACTIVE set _unless_
 * 	another element is 'pressed'
 */
static void ActivateElement(ElementStateTracker *es, TTK_LayoutNode *node)
{
    if (es->activeElement == node) {
	/* No change */
	return;
    }

    if (!es->pressedElement) {
	if (es->activeElement)
	    TTK_ChangeElementState(es->activeElement, 0,TK_WIDGET_STATE_ACTIVE);
	if (node)
	    TTK_ChangeElementState(node, TK_WIDGET_STATE_ACTIVE,0);
	WidgetChanged(es->corePtr, REDISPLAY_REQUIRED);
    }

    es->activeElement = node;
}

/* ElementStateEventProc --
 * 	Event handler for tracking element states.
 */

static const unsigned ElementStateMask =
      ButtonPressMask 
    | ButtonReleaseMask 
    | PointerMotionMask 
    | LeaveWindowMask 
    | EnterWindowMask
    | StructureNotifyMask
    ;

static void
ElementStateEventProc(ClientData clientData, XEvent *ev)
{
    ElementStateTracker *es = (ElementStateTracker *)clientData;
    TTK_LayoutNode *node;

    switch (ev->type)
    {
	case MotionNotify :
	    node = TTK_LayoutIdentify(
		es->corePtr->layout,ev->xmotion.x,ev->xmotion.y);
	    ActivateElement(es, node);
	    break;
	case LeaveNotify:
	    ActivateElement(es, 0);
	    break;
	case EnterNotify:
	    node = TTK_LayoutIdentify(
		es->corePtr->layout,ev->xcrossing.x,ev->xcrossing.y);
	    ActivateElement(es, node);
	    break;
	case ButtonPress:
	    node = TTK_LayoutIdentify(
		es->corePtr->layout, ev->xbutton.x, ev->xbutton.y);
	    if (node) 
		PressElement(es, node);
	    break;
	case ButtonRelease:
	    ReleaseElement(es);
	    break;
	case DestroyNotify:
	    /* Unregister this event handler and free client data. 
	     */
	    Tk_DeleteEventHandler(es->corePtr->tkwin,
		    ElementStateMask, ElementStateEventProc, es);
	    ckfree((ClientData)es);
	    break;
    }
}

/*
 * TrackElementState --
 * 	Register an event handler to manage the 'pressed'
 * 	and 'active' states of individual widget elements.
 */

void TrackElementState(WidgetCore *corePtr)
{
    ElementStateTracker *es = (ElementStateTracker*)ckalloc(sizeof(*es));
    es->corePtr = corePtr;
    es->activeElement = es->pressedElement = 0;
    Tk_CreateEventHandler(corePtr->tkwin,
	    ElementStateMask,ElementStateEventProc,es);
}


Changes to generic/widget.h.
1
2
3
4
5
6
7
8
/* $Id: widget.h,v 1.10 2003/10/22 02:13:36 jenglish Exp $
 * Copyright (c) 2003, Joe English
 *
 * Helper routines for widget implementations.
 *
 * Require: tkTheme.h, layout.h
 */

|







1
2
3
4
5
6
7
8
/* $Id: widget.h,v 1.11 2004/01/05 21:57:04 patthoyts Exp $
 * Copyright (c) 2003, Joe English
 *
 * Helper routines for widget implementations.
 *
 * Require: tkTheme.h, layout.h
 */

106
107
108
109
110
111
112


113
114
115
116
117
118
119

extern void WidgetChangeState(WidgetCore *,
	unsigned int setBits, unsigned int clearBits);

extern void WidgetChanged(WidgetCore *, unsigned flags);

extern void WidgetSetLayout(Tcl_Interp *,WidgetCore *, const char *layoutName);



/*
 * Useful widget base classes:
 */
extern Tk_OptionSpec CoreOptionSpecs[];

typedef struct 	/* Common resources for nearly every widget. */







>
>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

extern void WidgetChangeState(WidgetCore *,
	unsigned int setBits, unsigned int clearBits);

extern void WidgetChanged(WidgetCore *, unsigned flags);

extern void WidgetSetLayout(Tcl_Interp *,WidgetCore *, const char *layoutName);

extern void TrackElementState(WidgetCore *);

/*
 * Useful widget base classes:
 */
extern Tk_OptionSpec CoreOptionSpecs[];

typedef struct 	/* Common resources for nearly every widget. */
Changes to library/scrollbar.tcl.
1
2
3
4
5
6
7
8
9
#
# $Id: scrollbar.tcl,v 1.8 2004/01/05 01:24:31 jenglish Exp $
#
# Bindings for TScrollbar widget
#

namespace eval Tile { 
    namespace eval Scrollbar { 
    	variable State

|







1
2
3
4
5
6
7
8
9
#
# $Id: scrollbar.tcl,v 1.9 2004/01/06 01:26:00 jenglish Exp $
#
# Bindings for TScrollbar widget
#

namespace eval Tile { 
    namespace eval Scrollbar { 
    	variable State
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

proc Scrollbar::Press {w x y} {
    variable State

    set State(xPress) $x
    set State(yPress) $y
    $w elementstate @$x,$y pressed

    switch -glob -- [$w identify $x $y] {
    	*uparrow -
	*leftarrow {
	    Tile::Repeatedly Scroll $w -1 unit
	}
	*downarrow -







<







38
39
40
41
42
43
44

45
46
47
48
49
50
51
}

proc Scrollbar::Press {w x y} {
    variable State

    set State(xPress) $x
    set State(yPress) $y


    switch -glob -- [$w identify $x $y] {
    	*uparrow -
	*leftarrow {
	    Tile::Repeatedly Scroll $w -1 unit
	}
	*downarrow -
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}

proc Scrollbar::Release {w x y} {
    variable State

    #
    # @@@ KNOWN BUG: this does not always "unpress" the pressed element.
    #
    $w elementstate @$x,$y !pressed
    if {[info exists State(xPress)]} {
	$w elementstate @$State(xPress),$State(yPress) !pressed
    }
    unset -nocomplain State(xPress) State(yPress) State(first)
    Tile::CancelRepeat
}

# Scrollbar::Jump -- ButtonPress-2 binding for scrollbars.
# 	Behaves exactly like Scrollbar::Press, except that
#	clicking in the trough jumps to the the selected position.
#
proc Scrollbar::Jump {w x y} {
    variable State

    switch -glob -- [$w identify $x $y] {
	*hthumb -
	*vthumb -
	*trough {
	    set State(first) [$w fraction $x $y]
	    Moveto $w $State(first)
	    set State(xPress) $x
	    set State(yPress) $y
	    $w elementstate @$x,$y pressed
	}
	default {
	    Press $w $x $y
	}
    }
}

}; # namespace eval Tile







<
<
<
<
<
<
<
<



















<








82
83
84
85
86
87
88








89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
    set xDelta [expr {$x - $State(xPress)}]
    set yDelta [expr {$y - $State(yPress)}]
    Moveto $w [expr {$State(first) + [$w delta $xDelta $yDelta]}]
}

proc Scrollbar::Release {w x y} {
    variable State








    unset -nocomplain State(xPress) State(yPress) State(first)
    Tile::CancelRepeat
}

# Scrollbar::Jump -- ButtonPress-2 binding for scrollbars.
# 	Behaves exactly like Scrollbar::Press, except that
#	clicking in the trough jumps to the the selected position.
#
proc Scrollbar::Jump {w x y} {
    variable State

    switch -glob -- [$w identify $x $y] {
	*hthumb -
	*vthumb -
	*trough {
	    set State(first) [$w fraction $x $y]
	    Moveto $w $State(first)
	    set State(xPress) $x
	    set State(yPress) $y

	}
	default {
	    Press $w $x $y
	}
    }
}

}; # namespace eval Tile
Changes to library/tile.tcl.
1
2
3
4
5
6
7
8
9
#
# $Id: tile.tcl,v 1.23 2004/01/06 01:26:00 jenglish Exp $
#
# Widget bindings and default appearance for Tile widget set.
#

if {![info exists tile_library]} {
    set tile_library [file dirname [info script]]
}

|







1
2
3
4
5
6
7
8
9
#
# $Id: tile.tcl,v 1.24 2004/01/06 16:43:23 patthoyts Exp $
#
# Widget bindings and default appearance for Tile widget set.
#

if {![info exists tile_library]} {
    set tile_library [file dirname [info script]]
}
123
124
125
126
127
128
129
130




131
132
133
134
135

136
137
138
139
140
141
142
	{}		$defaultBG
    "
    style elementconfigure "alt" background -background "
	disabled	$defaultBG
	active 		$activeBG
	{}		$defaultBG
    "
    foreach class {TRadiobutton TCheckbutton} {




	style configure "alt" $class -background "
	    disabled	$defaultBG
	    active 	$activeBG
	    {}		$defaultBG
	"

    }

    style configure "" TButton -relief {
	{pressed !disabled} 	sunken
	{active !disabled} 	raised
    }








|
>
>
>
>
|
|
|
|
|
>







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	{}		$defaultBG
    "
    style elementconfigure "alt" background -background "
	disabled	$defaultBG
	active 		$activeBG
	{}		$defaultBG
    "
    foreach class {
    	TRadiobutton TCheckbutton
	TScrollbarHorizontal TScrollbarVertical
    } {
	foreach theme {"" "alt"} {
	    style configure $theme $class -background "
		disabled	$defaultBG
		active 		$activeBG
		{}		$defaultBG
	    "
	}
    }

    style configure "" TButton -relief {
	{pressed !disabled} 	sunken
	{active !disabled} 	raised
    }

179
180
181
182
183
184
185

186

187
188
189
190
191
192
193
        "
    }

    foreach theme {{} alt step} {
	style configure $theme TScrollbarHorizontal -relief {
	    pressed sunken
	    {} raised 

	} -troughcolor [list {} $troughColor]

	style configure $theme TScrollbarVertical -relief {
	    pressed sunken
	    {} raised 
	} -troughcolor [list {} $troughColor]
	# @@@ Sort out scrollbar "background" vs. "trough"
	style elementconfigure $theme Scrollbar.background \
	    -background [list {} $troughColor]







>
|
>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        "
    }

    foreach theme {{} alt step} {
	style configure $theme TScrollbarHorizontal -relief {
	    pressed sunken
	    {} raised 
	} \
	-troughcolor [list {} $troughColor]  \

	style configure $theme TScrollbarVertical -relief {
	    pressed sunken
	    {} raised 
	} -troughcolor [list {} $troughColor]
	# @@@ Sort out scrollbar "background" vs. "trough"
	style elementconfigure $theme Scrollbar.background \
	    -background [list {} $troughColor]
Changes to win/makefile.vc.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001 ActiveState Corporation.
# Copyright (c) 2001-2002 David Gravereaux.
# Copyright (c) 2003 Pat Thoyts
#
#-------------------------------------------------------------------------
# RCS: @(#)$Id: makefile.vc,v 1.6 2003/11/29 01:49:30 patthoyts Exp $
#-------------------------------------------------------------------------

!if "$(MSVCDIR)" == ""
MSG = ^
You will need to run vcvars32.bat from Developer Studio, first, to setup^
the environment.  Jump to this line to read the new instructions.
!error $(MSG)







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001 ActiveState Corporation.
# Copyright (c) 2001-2002 David Gravereaux.
# Copyright (c) 2003 Pat Thoyts
#
#-------------------------------------------------------------------------
# RCS: @(#)$Id: makefile.vc,v 1.7 2004/01/05 21:57:04 patthoyts Exp $
#-------------------------------------------------------------------------

!if "$(MSVCDIR)" == ""
MSG = ^
You will need to run vcvars32.bat from Developer Studio, first, to setup^
the environment.  Jump to this line to read the new instructions.
!error $(MSG)
163
164
165
166
167
168
169

170
171
172
173
174
175
176
DLLOBJS = \
	$(TMP_DIR)\tile.obj \
	$(TMP_DIR)\tkElements.obj \
	$(TMP_DIR)\layout.obj \
	$(TMP_DIR)\scrollbar.obj \
	$(TMP_DIR)\scale.obj \
	$(TMP_DIR)\widget.obj \

	$(TMP_DIR)\tkstate.obj \
	$(TMP_DIR)\altTheme.obj \
	$(TMP_DIR)\tkTheme.obj \
	$(TMP_DIR)\stepTheme.obj \
	$(TMP_DIR)\xpTheme.obj

#-------------------------------------------------------------------------







>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
DLLOBJS = \
	$(TMP_DIR)\tile.obj \
	$(TMP_DIR)\tkElements.obj \
	$(TMP_DIR)\layout.obj \
	$(TMP_DIR)\scrollbar.obj \
	$(TMP_DIR)\scale.obj \
	$(TMP_DIR)\widget.obj \
	$(TMP_DIR)\track.obj \
	$(TMP_DIR)\tkstate.obj \
	$(TMP_DIR)\altTheme.obj \
	$(TMP_DIR)\tkTheme.obj \
	$(TMP_DIR)\stepTheme.obj \
	$(TMP_DIR)\xpTheme.obj

#-------------------------------------------------------------------------