head	1.6;
access;
symbols
	core-8-5-9:1.5.4.2
	core-8-5-8:1.5.4.1
	macosx-cocoa-merge:1.6
	macosx-cocoa-premerge:1.6
	macosx-carbon-freeze:1.6
	core-8-5-7:1.5.4.1
	core-8-5-6:1.5.4.1
	core-8-6-b1:1.6
	core-8-6-a3:1.6
	core-8-5-5:1.5.4.1
	core-8-6-a2:1.6
	core-8-5-4:1.5
	core-8-5-3:1.5
	core-8-6-a1:1.5
	core-8-5-branch:1.5.0.4
	core-8-5-2:1.5
	core-8-5-1:1.5
	core-8-5-0:1.5
	core-8-5-b3:1.5
	core-8-5-b2:1.5
	core-8-5-b1:1.5
	core-stablilizer-merge:1.5
	core-stabilizer-branch:1.5.0.2
	core-stabilizer-merge:1.5
	core-8-5-a6:1.5;
locks; strict;
comment	@ * @;


1.6
date	2008.08.19.14.47.55;	author jenglish;	state Exp;
branches;
next	1.5;

1.5
date	2006.12.18.19.33.13;	author jenglish;	state Exp;
branches
	1.5.4.1;
next	1.4;

1.4
date	2006.11.13.00.22.40;	author jenglish;	state Exp;
branches;
next	1.3;

1.3
date	2006.11.12.20.35.38;	author jenglish;	state Exp;
branches;
next	1.2;

1.2
date	2006.11.03.03.06.22;	author das;	state Exp;
branches;
next	1.1;

1.1
date	2006.10.31.01.42.26;	author hobbs;	state Exp;
branches;
next	;

1.5.4.1
date	2008.08.19.14.48.00;	author jenglish;	state Exp;
branches;
next	1.5.4.2;

1.5.4.2
date	2010.08.26.02.06.09;	author hobbs;	state Exp;
branches;
next	;


desc
@@


1.6
log
@generic/ttk/ttkScroll.c: Don't use sprintf "%g" to format floating
point numbers in -[xy]scrollcommand callbacks or [xy]view methods.
Minor incompatibility: 0 and 1 now formatted as "0.0" resp "1.0".
@
text
@/* $Id: ttkScroll.c,v 1.5 2006/12/18 19:33:13 jenglish Exp $
 *
 * Copyright 2004, Joe English
 *
 * Support routines for scrollable widgets.
 *
 * (This is sort of half-baked; needs some work)
 *
 * Scrollable interface:
 *
 * 	+ 'first' is controlled by [xy]view widget command 
 * 	  and other scrolling commands like 'see';
 *      + 'total' depends on widget contents;
 *      + 'last' depends on first, total, and widget size.
 *
 * Choreography (typical usage):
 *
 * 	1. User adjusts scrollbar, scrollbar widget calls its -command
 * 	2. Scrollbar -command invokes the scrollee [xy]view widget method
 * 	3. TtkScrollviewCommand calls TtkScrollTo(), which updates 
 * 	   'first' and schedules a redisplay.
 * 	4. Once the scrollee knows 'total' and 'last' (typically in 
 * 	   the LayoutProc), call TtkScrolled(h,first,last,total) to 
 * 	   synchronize the scrollbar.
 * 	5. The scrollee -[xy]scrollcommand is called (in an idle callback)
 * 	6. Which calls the scrollbar 'set' method and redisplays the scrollbar.
 *
 * If the scrollee has internal scrolling (e.g., a 'see' method), 
 * it should TtkScrollTo() directly (step 2).
 *
 * If the widget value changes, it should call TtkScrolled() (step 4).
 * (This usually happens automatically when the widget is redisplayed).
 *
 * If the scrollee's -[xy]scrollcommand changes, it should call
 * TtkScrollbarUpdateRequired, which will invoke step (5) (@@@@@@ Fix this)
 */

#include <tk.h>
#include "ttkTheme.h"
#include "ttkWidget.h"

/* Private data:
 */
#define SCROLL_UPDATE_PENDING  (0x1)
#define SCROLL_UPDATE_REQUIRED (0x2)

struct ScrollHandleRec
{
    unsigned 	flags;
    WidgetCore	*corePtr;
    Scrollable	*scrollPtr;
};

/* TtkCreateScrollHandle --
 * 	Initialize scroll handle.
 */
ScrollHandle TtkCreateScrollHandle(WidgetCore *corePtr, Scrollable *scrollPtr)
{
    ScrollHandle h = (ScrollHandle)ckalloc(sizeof(*h));

    h->flags = 0;
    h->corePtr = corePtr;
    h->scrollPtr = scrollPtr;

    scrollPtr->first = 0;
    scrollPtr->last = 1;
    scrollPtr->total = 1;
    return h;
}

/* UpdateScrollbar --
 *	Call the -scrollcommand callback to sync the scrollbar.
 * 	Returns: Whatever the -scrollcommand does.
 */
static int UpdateScrollbar(Tcl_Interp *interp, ScrollHandle h)
{
    Scrollable *s = h->scrollPtr;
    WidgetCore *corePtr = h->corePtr;
    char arg1[TCL_DOUBLE_SPACE + 2];
    char arg2[TCL_DOUBLE_SPACE + 2];
    int code;

    h->flags &= ~SCROLL_UPDATE_REQUIRED;

    if (s->scrollCmd == NULL) {
	return TCL_OK;
    }

    arg1[0] = arg2[0] = ' ';
    Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
    Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);

    Tcl_Preserve(corePtr);
    code = Tcl_VarEval(interp, s->scrollCmd, arg1, arg2, NULL);
    if (WidgetDestroyed(corePtr)) {
	Tcl_Release(corePtr);
	return TCL_ERROR;
    }
    Tcl_Release(corePtr);

    if (code != TCL_OK && !Tcl_InterpDeleted(interp)) {
	/* Disable the -scrollcommand, add to stack trace:
	 */
	ckfree(s->scrollCmd);
	s->scrollCmd = 0;

	Tcl_AddErrorInfo(interp, /* @@@@@@ "horizontal" / "vertical" */
		"\n    (scrolling command executed by ");
	Tcl_AddErrorInfo(interp, Tk_PathName(h->corePtr->tkwin));
	Tcl_AddErrorInfo(interp, ")");
    }
    return code;
}

/* UpdateScrollbarBG --
 * 	Idle handler to update the scrollbar.
 */
static void UpdateScrollbarBG(ClientData clientData)
{
    ScrollHandle h = (ScrollHandle)clientData;
    Tcl_Interp *interp = h->corePtr->interp;
    int code;

    h->flags &= ~SCROLL_UPDATE_PENDING;
    Tcl_Preserve((ClientData) interp);
    code = UpdateScrollbar(interp, h);
    if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
	Tcl_BackgroundError(interp);
    }
    Tcl_Release((ClientData) interp);
}

/* TtkScrolled --
 * 	Update scroll info, schedule scrollbar update.
 */
void TtkScrolled(ScrollHandle h, int first, int last, int total)
{
    Scrollable *s = h->scrollPtr;
    
    /* Sanity-check inputs:
     */
    if (total <= 0) {
	first = 0;
	last = 1;
	total = 1;
    }

    if (last > total) {
	first -= (last - total);
	if (first < 0) first = 0;
	last = total;
    }

    if (s->first != first || s->last != last || s->total != total
	    || (h->flags & SCROLL_UPDATE_REQUIRED))
    {
	s->first = first;
	s->last = last;
	s->total = total;

	if (!(h->flags & SCROLL_UPDATE_PENDING)) {
	    Tcl_DoWhenIdle(UpdateScrollbarBG, (ClientData)h);
	    h->flags |= SCROLL_UPDATE_PENDING;
	}
    }
}

/* TtkScrollbarUpdateRequired --
 * 	Force a scrollbar update at the next call to TtkScrolled(),
 * 	even if scroll parameters haven't changed (e.g., if
 * 	-yscrollcommand has changed).
 */

void TtkScrollbarUpdateRequired(ScrollHandle h)
{
    h->flags |= SCROLL_UPDATE_REQUIRED;
}

/* TtkScrollviewCommand --
 * 	Widget [xy]view command implementation.
 *
 *  $w [xy]view -- return current view region
 *  $w [xy]view $index -- set topmost item
 *  $w [xy]view moveto $fraction
 *  $w [xy]view scroll $number $what -- scrollbar interface
 */
int TtkScrollviewCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle h)
{
    Scrollable *s = h->scrollPtr;
    int newFirst = s->first;

    if (objc == 2) {
	Tcl_Obj *result[2];
	result[0] = Tcl_NewDoubleObj((double)s->first / s->total);
	result[1] = Tcl_NewDoubleObj((double)s->last / s->total);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
	return TCL_OK;
    } else if (objc == 3) {
	if (Tcl_GetIntFromObj(interp, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	double fraction;
	int count;

	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	    case TK_SCROLL_ERROR:
		return TCL_ERROR;
	    case TK_SCROLL_MOVETO:
		newFirst = (int) ((fraction * s->total) + 0.5);
		break;
	    case TK_SCROLL_UNITS:
		newFirst = s->first + count;
		break;
	    case TK_SCROLL_PAGES: {
		int perPage = s->last - s->first;	/* @@@@@@ */
		newFirst = s->first + count * perPage;
		break;
	    }
	}
    }

    TtkScrollTo(h, newFirst);

    return TCL_OK;
}

void TtkScrollTo(ScrollHandle h, int newFirst)
{
    Scrollable *s = h->scrollPtr;

    if (newFirst >= s->total)
	newFirst = s->total - 1;
    if (newFirst > s->first && s->last >= s->total) /* don't scroll past end */
	newFirst = s->first;
    if (newFirst < 0)
	newFirst = 0;

    if (newFirst != s->first) {
	s->first = newFirst;
	TtkRedisplayWidget(h->corePtr);
    }
}

void TtkFreeScrollHandle(ScrollHandle h)
{
    if (h->flags & SCROLL_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateScrollbarBG, (ClientData)h);
    }
    ckfree((ClientData)h);
}

@


1.5
log
@Big batch of ttk::treeview improvements:
    Added column '-stretch' and '-minwidth' options.
    Improved column drag and resize behavior.
    Added horizontal scrolling [#1518650].
    Row height and child indent specifiable on Treeview style.
    Decreased default row height, no default -padding.
    Use correct heading height [#1163349].
    Apply tag settings to tree item as well as to data columns
    [NOTE: 'tag configure' still buggy].
    Fix off-by-one condition when moving nodes forward [#1618142]
    Prevent overscroll ([#1173434])
    Treeview style settings specified separately in each theme.
    Added disclosure triangle element in aqua theme.
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.4 2006/11/13 00:22:40 jenglish Exp $
d79 2
a80 1
    char args[TCL_DOUBLE_SPACE * 2];
d89 3
a91 3
    sprintf(args, " %g %g",
		(double)s->first / s->total,
		(double)s->last / s->total);
d94 1
a94 1
    code = Tcl_VarEval(interp, s->scrollCmd, args, NULL);
d194 4
a197 5
	char buf[TCL_DOUBLE_SPACE * 2];
	sprintf(buf, "%g %g",
		(double)s->first / s->total,
		(double)s->last / s->total);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
@


1.5.4.1
log
@generic/ttk/ttkScroll.c: Don't use sprintf "%g" to format floating
point numbers in -[xy]scrollcommand callbacks or [xy]view methods.
Minor incompatibility: 0 and 1 now formatted as "0.0" resp "1.0".
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.5 2006/12/18 19:33:13 jenglish Exp $
d79 1
a79 2
    char arg1[TCL_DOUBLE_SPACE + 2];
    char arg2[TCL_DOUBLE_SPACE + 2];
d88 3
a90 3
    arg1[0] = arg2[0] = ' ';
    Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
    Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);
d93 1
a93 1
    code = Tcl_VarEval(interp, s->scrollCmd, arg1, arg2, NULL);
d193 5
a197 4
	Tcl_Obj *result[2];
	result[0] = Tcl_NewDoubleObj((double)s->first / s->total);
	result[1] = Tcl_NewDoubleObj((double)s->last / s->total);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
@


1.5.4.2
log
@        Major backport of 8.6 Ttk for 8.5.9.  Most changes were only being
        committed to head (8.6), although they could apply for 8.5 as well.
        This re-sync makes future work easier to maintain and adds some
        useful work for 8.5 users. Notable changes:
        - Lots of code cleanup
        - Some bug fixes never backported
        - Addition of ttk::spinbox
        - minor color changes
        - Improved Vista/7 styling
        - Move to tile version 0.8.6 (pseudo-package)
        - ABI and API compatible (even $w identify)
        - minor new features (extended $w identify)
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.6 2008/08/19 14:47:55 jenglish Exp $
@


1.4
log
@*correct* fix for #1588251.
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.3 2006/11/12 20:35:38 jenglish Exp $
d147 6
@


1.3
log
@Reworked cleanup procedure -- "self-cancelling" idle call is not robust,
call Tcl_CancelIdleCall() in TtkFreeScrollHandle instead.
[fixes #1588251]
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.2 2006/11/03 03:06:22 das Exp $
d78 1
d84 1
a84 1
    if (s->scrollCmd == NULL)
d86 1
d92 1
a92 1
    Tcl_Preserve(h->corePtr);
d94 2
a95 2
    if (WidgetDestroyed(h->corePtr)) {
	Tcl_Release(h->corePtr);
d98 1
a98 1
    Tcl_Release(h->corePtr);
d245 1
a245 1
    Tcl_Free((ClientData)h);
@


1.2
log
@	* generic/ttk/ttkBlink.c, generic/ttk/ttkButton.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.h:
	* generic/ttk/ttkNotebook.c, generic/ttk/ttkPanedwindow.c:
	* generic/ttk/ttkProgress.c, generic/ttk/ttkScale.c:
	* generic/ttk/ttkScroll.c, generic/ttk/ttkScrollbar.c:
	* generic/ttk/ttkSeparator.c, generic/ttk/ttkSquare.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTheme.c, generic/ttk/ttkTheme.h:
	* generic/ttk/ttkThemeInt.h, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h, macosx/ttkMacOSXTheme.c:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c: ensure
	all global Ttk symbols have Ttk or ttk prefix; declare all externally
	visible Ttk symbols not contained in stubs table as MODULE_SCOPE (or as
	static when possible); so that 'make check{exports,stubs}' once again
	complete without errors.
@
text
@d1 1
a1 1
/* $Id: ttkScroll.c,v 1.1 2006/10/31 01:42:26 hobbs Exp $
a70 5
void TtkFreeScrollHandle(ScrollHandle h)
{
    Tcl_EventuallyFree((ClientData)h, TCL_DYNAMIC);
}

d81 1
a81 1
    h->flags &= ~(SCROLL_UPDATE_PENDING | SCROLL_UPDATE_REQUIRED);
d98 1
a98 1
    if (code != TCL_OK) {
d121 1
a121 5
    if (WidgetDestroyed(h->corePtr)) {
	Tcl_Release(clientData);
	return;
    }

a127 1
    Tcl_Release(clientData);
a152 1
	    Tcl_Preserve((ClientData)h);
d238 8
@


1.1
log
@	* doc/ttk_Geometry.3, doc/ttk_Theme.3, doc/ttk_button.n:
	* doc/ttk_checkbutton.n, doc/ttk_combobox.n, doc/ttk_dialog.n:
	* doc/ttk_entry.n, doc/ttk_frame.n, doc/ttk_image.n:
	* doc/ttk_intro.n, doc/ttk_label.n, doc/ttk_labelframe.n:
	* doc/ttk_menubutton.n, doc/ttk_notebook.n, doc/ttk_panedwindow.n:
	* doc/ttk_progressbar.n, doc/ttk_radiobutton.n, doc/ttk_scrollbar.n:
	* doc/ttk_separator.n, doc/ttk_sizegrip.n, doc/ttk_style.n:
	* doc/ttk_treeview.n, doc/ttk_widget.n,:
	* generic/ttk/ttk.decls, generic/ttk/ttkBlink.c:
	* generic/ttk/ttkButton.c, generic/ttk/ttkCache.c:
	* generic/ttk/ttkClamTheme.c, generic/ttk/ttkClassicTheme.c:
	* generic/ttk/ttkDecls.h, generic/ttk/ttkDefaultTheme.c:
	* generic/ttk/ttkElements.c, generic/ttk/ttkEntry.c:
	* generic/ttk/ttkFrame.c, generic/ttk/ttkImage.c:
	* generic/ttk/ttkInit.c, generic/ttk/ttkLabel.c:
	* generic/ttk/ttkLayout.c, generic/ttk/ttkManager.c:
	* generic/ttk/ttkManager.h, generic/ttk/ttkNotebook.c:
	* generic/ttk/ttkPanedwindow.c, generic/ttk/ttkProgress.c:
	* generic/ttk/ttkScale.c, generic/ttk/ttkScroll.c:
	* generic/ttk/ttkScrollbar.c, generic/ttk/ttkSeparator.c:
	* generic/ttk/ttkSquare.c, generic/ttk/ttkState.c:
	* generic/ttk/ttkStubInit.c, generic/ttk/ttkStubLib.c:
	* generic/ttk/ttkTagSet.c, generic/ttk/ttkTheme.c:
	* generic/ttk/ttkTheme.h, generic/ttk/ttkThemeInt.h:
	* generic/ttk/ttkTrace.c, generic/ttk/ttkTrack.c:
	* generic/ttk/ttkTreeview.c, generic/ttk/ttkWidget.c:
	* generic/ttk/ttkWidget.h:
	* library/demos/ttk_demo.tcl, library/demos/ttk_iconlib.tcl:
	* library/demos/ttk_repeater.tcl:
	* library/ttk/altTheme.tcl, library/ttk/aquaTheme.tcl:
	* library/ttk/button.tcl, library/ttk/clamTheme.tcl:
	* library/ttk/classicTheme.tcl, library/ttk/combobox.tcl:
	* library/ttk/cursors.tcl, library/ttk/defaults.tcl:
	* library/ttk/dialog.tcl, library/ttk/entry.tcl:
	* library/ttk/fonts.tcl, library/ttk/icons.tcl:
	* library/ttk/keynav.tcl, library/ttk/menubutton.tcl:
	* library/ttk/notebook.tcl, library/ttk/panedwindow.tcl:
	* library/ttk/progress.tcl, library/ttk/scale.tcl:
	* library/ttk/scrollbar.tcl, library/ttk/sizegrip.tcl:
	* library/ttk/treeview.tcl, library/ttk/ttk.tcl:
	* library/ttk/utils.tcl, library/ttk/winTheme.tcl:
	* library/ttk/xpTheme.tcl:
	* macosx/ttkMacOSXTheme.c:
	* tests/ttk/all.tcl, tests/ttk/bwidget.test, tests/ttk/combobox.test:
	* tests/ttk/entry.test, tests/ttk/image.test:
	* tests/ttk/labelframe.test, tests/ttk/layout.test:
	* tests/ttk/misc.test, tests/ttk/notebook.test:
	* tests/ttk/panedwindow.test, tests/ttk/progressbar.test:
	* tests/ttk/scrollbar.test, tests/ttk/treetags.test:
	* tests/ttk/treeview.test, tests/ttk/ttk.test, tests/ttk/validate.test:
	* win/ttkWinMonitor.c, win/ttkWinTheme.c, win/ttkWinXPTheme.c:
	First import of Ttk themed Tk widgets as branched from tile 0.7.8

	* generic/tkInt.h, generic/tkWindow.c: add Ttk_Init call, copy
	tk classic widgets to ::tk namespace.
	* library/tk.tcl: add source of ttk/ttk.tcl, define $::ttk::library.
	* unix/Makefile.in, win/Makefile.in: add Ttk build bits
	* win/configure, win/configure.in: check for uxtheme.h (XP theme).
@
text
@d1 1
a1 1
/* $Id: scroll.c,v 1.5 2006/08/27 16:01:00 jenglish Exp $
d20 1
a20 1
 * 	3. ScrollviewCommand calls ScrollTo(), which updates 
d23 1
a23 1
 * 	   the LayoutProc), call Scrolled(h,first,last,total) to 
d29 1
a29 1
 * it should ScrollTo() directly (step 2).
d31 1
a31 1
 * If the widget value changes, it should call Scrolled() (step 4).
d35 1
a35 1
 * ScrollbarUpdateRequired, which will invoke step (5) (@@@@@@ Fix this)
d54 1
a54 1
/* CreateScrollHandle --
d57 1
a57 1
ScrollHandle CreateScrollHandle(WidgetCore *corePtr, Scrollable *scrollPtr)
d71 1
a71 1
void FreeScrollHandle(ScrollHandle h)
d140 1
a140 1
/* Scrolled --
d143 1
a143 1
void Scrolled(ScrollHandle h, int first, int last, int total)
d170 2
a171 2
/* ScrollbarUpdateRequired --
 * 	Force a scrollbar update at the next call to Scrolled(),
d176 1
a176 1
void ScrollbarUpdateRequired(ScrollHandle h)
d181 1
a181 1
/* ScrollviewCommand --
d189 1
a189 1
int ScrollviewCommand(
d227 1
a227 1
    ScrollTo(h, newFirst);
d232 1
a232 1
void ScrollTo(ScrollHandle h, int newFirst)
@

