Tk Source Code

Check-in [159f9459]
Login

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

Overview
Comment:Factorize the code a bit, and avoid calling the layoutProc twice when calling xview moveto|units|pages.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | bug-2513186fff | bug-8261c517af
Files: files | file ages | folders
SHA3-256: 159f9459ba18138345fb63037ac2922fcabeed082c85abcb6096a2ba71ec9bc0
User & Date: fvogel 2019-04-28 12:52:43.999
Original Comment: Factorized the code a bit, and avoid calling the layoutProc twice when calling xview moveto|units|pages.
Context
2019-04-28
13:57
Fix '.e index @'. The returned answer could be wrong if the scroll info was not yet updated. check-in: f31e1037 user: fvogel tags: bug-2513186fff, bug-8261c517af
12:52
Factorize the code a bit, and avoid calling the layoutProc twice when calling xview moveto|units|pages. check-in: 159f9459 user: fvogel tags: bug-2513186fff, bug-8261c517af
10:45
Add a missing scroll info update needed to make x|yview moveto|units|pages work without an update idletasks call beforehand. check-in: 231587eb user: fvogel tags: bug-2513186fff, bug-8261c517af
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/ttk/ttkEntry.c.
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
{
    Entry *entryPtr = recordPtr;
    if (objc == 3) {
	int newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
}

static const Ttk_Ensemble EntryCommands[] = {
    { "bbox", 		EntryBBoxCommand,0 },







|







1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
{
    Entry *entryPtr = recordPtr;
    if (objc == 3) {
	int newFirst;
	if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
	    return TCL_ERROR;
	}
	TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1);
	return TCL_OK;
    }
    return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
}

static const Ttk_Ensemble EntryCommands[] = {
    { "bbox", 		EntryBBoxCommand,0 },
Changes to generic/ttk/ttkScroll.c.
176
177
178
179
180
181
182













183
184
185
186
187
188
189
190
191
192
193
194
195



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
 * 	-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];

        /*
         * Update the scroll info (first, last, total) if needed.
         */

        if (h->corePtr->flags & REDISPLAY_PENDING) {
            h->corePtr->widgetSpec->layoutProc(h->corePtr);
        }

	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;

        /*
         * Update the scroll info (first, last, total) if needed.
         */

        if (h->corePtr->flags & REDISPLAY_PENDING) {
            h->corePtr->widgetSpec->layoutProc(h->corePtr);
        }

	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;

    /*
     * Update the scroll info (first, last, total) if needed.
     */

    if (h->corePtr->flags & REDISPLAY_PENDING) {
        h->corePtr->widgetSpec->layoutProc(h->corePtr);
    }

    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)







>
>
>
>
>
>
>
>
>
>
>
>
>













>
>
>
|



<
<
<
<
<
<
<
<
<












<
<
<
<
<
<
<
<

















|




|



<
|
<
|
<
<







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215









216
217
218
219
220
221
222
223
224
225
226
227








228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254

255


256
257
258
259
260
261
262
 * 	-yscrollcommand has changed).
 */

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

/* TtkUpdateScrollInfo --
 * 	Call the layoutProc to update the scroll info first, last, and total.
 * 	Do it only if needed, that is when a redisplay is pending (which
 * 	indicates scroll info are possibly out of date).
 */

void TtkUpdateScrollInfo(ScrollHandle h)
{
    if (h->corePtr->flags & REDISPLAY_PENDING) {
        h->corePtr->widgetSpec->layoutProc(h->corePtr);
    }
}

/* 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;

    TtkUpdateScrollInfo(h);
    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, 0);

    return TCL_OK;
}

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


    if (updateScrollInfo) {

        TtkUpdateScrollInfo(h);


    }

    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)
Changes to generic/ttk/ttkTreeview.c.
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
    }
    tv->tree.yscroll.total = CountRows(tv->tree.root) - 1;

    /* Make sure item is visible:
     */
    rowNumber = RowNumber(tv, item);
    if (rowNumber < tv->tree.yscroll.first) {
	TtkScrollTo(tv->tree.yscrollHandle, rowNumber);
    } else if (rowNumber >= tv->tree.yscroll.last) {
	TtkScrollTo(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last));
    }

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- interactive column resize







|


|







2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
    }
    tv->tree.yscroll.total = CountRows(tv->tree.root) - 1;

    /* Make sure item is visible:
     */
    rowNumber = RowNumber(tv, item);
    if (rowNumber < tv->tree.yscroll.first) {
	TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1);
    } else if (rowNumber >= tv->tree.yscroll.last) {
	TtkScrollTo(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1);
    }

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- interactive column resize
Changes to generic/ttk/ttkWidget.h.
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

MODULE_SCOPE ScrollHandle TtkCreateScrollHandle(WidgetCore *, Scrollable *);
MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle);

MODULE_SCOPE int TtkScrollviewCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle);

MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst);
MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total);
MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle);

/*
 * Tag sets (work in progress, half-baked)
 */








|







191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

MODULE_SCOPE ScrollHandle TtkCreateScrollHandle(WidgetCore *, Scrollable *);
MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle);

MODULE_SCOPE int TtkScrollviewCommand(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle);

MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo);
MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total);
MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle);

/*
 * Tag sets (work in progress, half-baked)
 */