Bwidget Source Code
Check-in [246eaca515]
Not logged in
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

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

Overview
Comment:Display ScrolledWindow scrollbars only if mouse is in the widget. Tciket [d5480d1da2] by Alexandru
Timelines: family | ancestors | descendants | both | rfe-d5480d1da2
Files: files | file ages | folders
SHA1:246eaca515ba4a06bfb6e11bebf29938be718c1f
User & Date: oehhar 2017-01-12 14:39:46
References
2017-01-12
14:42 Ticket [d5480d1da2] ScrollableFrame: show scrollbars only when mouse in widget status still Open with 5 other changes artifact: 23f8863865 user: oehhar
Context
2017-01-14
13:07
-onlyhover not default. Removed dead code. Comments modified. check-in: d2b4cecf3d user: oehhar tags: rfe-d5480d1da2
2017-01-12
14:39
Display ScrolledWindow scrollbars only if mouse is in the widget. Tciket [d5480d1da2] by Alexandru check-in: 246eaca515 user: oehhar tags: rfe-d5480d1da2
2016-11-02
23:56
scrollframe.tcl: Eric advised to check for unmapped window, as the <Map> event may be executed in the unmapped state. check-in: 6d0524a1f8 user: oehhar tags: bwidget
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to scrollframe.tcl.

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
..
64
65
66
67
68
69
70



71
72

73
74





75
76
77
78
79
80
81
..
93
94
95
96
97
98
99


100
101







102
103
104
105



















106
107
108
109
110
111
112
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
...
240
241
242
243
244
245
246
247





248
249
250



















251









252
253
254


255
256
#     - ScrollableFrame::see
#     - ScrollableFrame::xview
#     - ScrollableFrame::yview
#     - ScrollableFrame::_resize
# ----------------------------------------------------------------------------

namespace eval ScrollableFrame {



    Widget::define ScrollableFrame scrollframe

    # If themed, there is no background and -bg option
    if {[Widget::theme]} {
        Widget::declare ScrollableFrame {
            {-width             Int        0  0 {}}
            {-height            Int        0  0 {}}
            {-areawidth         Int        0  0 {}}
            {-areaheight        Int        0  0 {}}
            {-constrainedwidth  Boolean    0 0}
            {-constrainedheight Boolean    0 0}

            {-xscrollcommand    TkResource "" 0 canvas}
            {-yscrollcommand    TkResource "" 0 canvas}
            {-xscrollincrement  TkResource "" 0 canvas}
            {-yscrollincrement  TkResource "" 0 canvas}
        }
    } else {
        Widget::declare ScrollableFrame {
................................................................................
            {-background        TkResource "" 0 frame}
            {-width             Int        0  0 {}}
            {-height            Int        0  0 {}}
            {-areawidth         Int        0  0 {}}
            {-areaheight        Int        0  0 {}}
            {-constrainedwidth  Boolean    0 0}
            {-constrainedheight Boolean    0 0}

            {-xscrollcommand    TkResource "" 0 canvas}
            {-yscrollcommand    TkResource "" 0 canvas}
            {-xscrollincrement  TkResource "" 0 canvas}
            {-yscrollincrement  TkResource "" 0 canvas}
            {-bg                Synonym    -background}
        }
    }

    Widget::addmap ScrollableFrame "" :cmd {
        -width {} -height {} 
        -xscrollcommand {} -yscrollcommand {}
        -xscrollincrement {} -yscrollincrement {}
    }
    if { ! [Widget::theme]} {
        Widget::addmap ScrollableFrame "" .frame {-background {}}
    }

................................................................................
}


# ----------------------------------------------------------------------------
#  Command ScrollableFrame::create
# ----------------------------------------------------------------------------
proc ScrollableFrame::create { path args } {



    Widget::init ScrollableFrame $path $args


    set canvas [eval [list canvas $path] [Widget::subcget $path :cmd] \
                    -highlightthickness 0 -borderwidth 0 -relief flat]






    if {[Widget::theme]} {
	set frame [eval [list ttk::frame $path.frame] \
		       [Widget::subcget $path .frame]]
	set bg [ttk::style lookup TFrame -background]
    } else {
	set frame [eval [list frame $path.frame] \
................................................................................
    bind $frame <Configure> \
        [list ScrollableFrame::_frameConfigure $canvas]
    # add <unmap> binding: <configure> is not called when frame
    # becomes so small that it suddenly falls outside of currently visible area.
    # but now we need to add a <map> binding too
    bind $frame <Map> \
        [list ScrollableFrame::_frameConfigure $canvas]



    bindtags $path [list $path BwScrollableFrame [winfo toplevel $path] all]








    return [Widget::create ScrollableFrame $path]
}





















# ----------------------------------------------------------------------------
#  Command ScrollableFrame::configure
# ----------------------------------------------------------------------------
proc ScrollableFrame::configure { path args } {
    set res [Widget::configure $path $args]
    set upd 0
................................................................................
    set y1  [expr {$y0+[winfo height $widget]}]
    set xb0 [$path:cmd canvasx 0]
    set yb0 [$path:cmd canvasy 0]
    set xb1 [$path:cmd canvasx [winfo width  $path]]
    set yb1 [$path:cmd canvasy [winfo height $path]]
    set dx  0
    set dy  0
    
    if { [string equal $horz "left"] } {
	if { $x1 > $xb1 } {
	    set dx [expr {$x1-$xb1}]
	}
	if { $x0 < $xb0+$dx } {
	    set dx [expr {$x0-$xb0}]
	}
................................................................................
}


# ----------------------------------------------------------------------------
#  Command ScrollableFrame::_frameConfigure
# ----------------------------------------------------------------------------
proc ScrollableFrame::_max {a b} {return [expr {$a <= $b ? $b : $a}]}
proc ScrollableFrame::_frameConfigure {canvas} {





    # This ensures that we don't get funny scrollability in the frame
    # when it is smaller than the canvas space
    # use [winfo] to get height & width of frame



















    if {![winfo ismapped $canvas.frame]} { return }









    set height [_max [winfo height $canvas.frame] [winfo height $canvas]]
    set width  [_max [winfo width  $canvas.frame] [winfo width  $canvas]]



    $canvas:cmd configure -scrollregion [list 0 0 $width $height]
}







>
>
>











>







 







>









|







 







>
>
>


>


>
>
>
>
>







 







>
>


>
>
>
>
>
>
>




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







 







|







 







|
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
|

>
>


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
..
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
...
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
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#     - ScrollableFrame::see
#     - ScrollableFrame::xview
#     - ScrollableFrame::yview
#     - ScrollableFrame::_resize
# ----------------------------------------------------------------------------

namespace eval ScrollableFrame {
    # This new global variable makes possible that the scrollbar is shown only when the mouse is over the frame
    array set mouseover {}

    Widget::define ScrollableFrame scrollframe

    # If themed, there is no background and -bg option
    if {[Widget::theme]} {
        Widget::declare ScrollableFrame {
            {-width             Int        0  0 {}}
            {-height            Int        0  0 {}}
            {-areawidth         Int        0  0 {}}
            {-areaheight        Int        0  0 {}}
            {-constrainedwidth  Boolean    0 0}
            {-constrainedheight Boolean    0 0}
            {-onlyhover         Boolean    1 1}
            {-xscrollcommand    TkResource "" 0 canvas}
            {-yscrollcommand    TkResource "" 0 canvas}
            {-xscrollincrement  TkResource "" 0 canvas}
            {-yscrollincrement  TkResource "" 0 canvas}
        }
    } else {
        Widget::declare ScrollableFrame {
................................................................................
            {-background        TkResource "" 0 frame}
            {-width             Int        0  0 {}}
            {-height            Int        0  0 {}}
            {-areawidth         Int        0  0 {}}
            {-areaheight        Int        0  0 {}}
            {-constrainedwidth  Boolean    0 0}
            {-constrainedheight Boolean    0 0}
            {-onlyhover         Boolean    0 0}
            {-xscrollcommand    TkResource "" 0 canvas}
            {-yscrollcommand    TkResource "" 0 canvas}
            {-xscrollincrement  TkResource "" 0 canvas}
            {-yscrollincrement  TkResource "" 0 canvas}
            {-bg                Synonym    -background}
        }
    }

    Widget::addmap ScrollableFrame "" :cmd {
        -width {} -height {}
        -xscrollcommand {} -yscrollcommand {}
        -xscrollincrement {} -yscrollincrement {}
    }
    if { ! [Widget::theme]} {
        Widget::addmap ScrollableFrame "" .frame {-background {}}
    }

................................................................................
}


# ----------------------------------------------------------------------------
#  Command ScrollableFrame::create
# ----------------------------------------------------------------------------
proc ScrollableFrame::create { path args } {
    # This new global variable makes possible that the scrollbar is shown only when the mouse is over the frame
    variable mouseover

    Widget::init ScrollableFrame $path $args

    # Actually $canvas is the same as $path
    set canvas [eval [list canvas $path] [Widget::subcget $path :cmd] \
                    -highlightthickness 0 -borderwidth 0 -relief flat]

    # Initialize it to 1 (mouse is over the frame)
    set mouseover($canvas) 1

    set onlyhover [Widget::cget $path -onlyhover]

    if {[Widget::theme]} {
	set frame [eval [list ttk::frame $path.frame] \
		       [Widget::subcget $path .frame]]
	set bg [ttk::style lookup TFrame -background]
    } else {
	set frame [eval [list frame $path.frame] \
................................................................................
    bind $frame <Configure> \
        [list ScrollableFrame::_frameConfigure $canvas]
    # add <unmap> binding: <configure> is not called when frame
    # becomes so small that it suddenly falls outside of currently visible area.
    # but now we need to add a <map> binding too
    bind $frame <Map> \
        [list ScrollableFrame::_frameConfigure $canvas]
    bind $frame <Unmap> \
        [list ScrollableFrame::_frameConfigure $canvas 1]

    bindtags $path [list $path BwScrollableFrame [winfo toplevel $path] all]

    if {$onlyhover} {
        # This makes possible that the scrollbar is shown only when the mouse is over the frame
        bind [winfo parent $path] <Enter> [list ScrollableFrame::enter $canvas]
        # This makes possible that the scrollbar is hidden only when the mouse is not over the frame
        bind [winfo parent $path] <Leave> [list ScrollableFrame::leave $canvas]
    }

    return [Widget::create ScrollableFrame $path]
}

# ----------------------------------------------------------------------------
#  Command ScrollableFrame::enter
# ----------------------------------------------------------------------------
# This makes possible that the scrollbar is shown only when the mouse is over the frame
proc ScrollableFrame::enter {canvas} {
    variable mouseover
    set mouseover($canvas) 1
    ScrollableFrame::_frameConfigure $canvas
}

# ----------------------------------------------------------------------------
#  Command ScrollableFrame::leave
# ----------------------------------------------------------------------------
# This makes possible that the scrollbar is hidden only when the mouse is not over the frame
proc ScrollableFrame::leave {canvas} {
    variable mouseover
    set mouseover($canvas) 0
    ScrollableFrame::_frameConfigure $canvas 1
}

# ----------------------------------------------------------------------------
#  Command ScrollableFrame::configure
# ----------------------------------------------------------------------------
proc ScrollableFrame::configure { path args } {
    set res [Widget::configure $path $args]
    set upd 0
................................................................................
    set y1  [expr {$y0+[winfo height $widget]}]
    set xb0 [$path:cmd canvasx 0]
    set yb0 [$path:cmd canvasy 0]
    set xb1 [$path:cmd canvasx [winfo width  $path]]
    set yb1 [$path:cmd canvasy [winfo height $path]]
    set dx  0
    set dy  0

    if { [string equal $horz "left"] } {
	if { $x1 > $xb1 } {
	    set dx [expr {$x1-$xb1}]
	}
	if { $x0 < $xb0+$dx } {
	    set dx [expr {$x0-$xb0}]
	}
................................................................................
}


# ----------------------------------------------------------------------------
#  Command ScrollableFrame::_frameConfigure
# ----------------------------------------------------------------------------
proc ScrollableFrame::_max {a b} {return [expr {$a <= $b ? $b : $a}]}
proc ScrollableFrame::_frameConfigure {canvas {unmap 0}} {
    variable mouseover
    # This makes possible that the scrollbar is hidden when the mouse is not over the frame
    if {$mouseover($canvas)==0} {
        set unmap 1
    }
    # This ensures that we don't get funny scrollability in the frame
    # when it is smaller than the canvas space
    # use [winfo] to get height & width of frame
    # [winfo] doesn't work for unmapped frame
    set frameh [expr {$unmap ? 0 : [winfo height $canvas.frame]}]
    set framew [expr {$unmap ? 0 : [winfo width  $canvas.frame]}]

    set height [_max $frameh [winfo height $canvas]]
    set width  [_max $framew [winfo width  $canvas]]

    $canvas:cmd configure -scrollregion [list 0 0 $width $height]
}
proc ::ScrollableFrame::_frameConfigure {canvas {unmap 0}} {
    variable mouseover
    # This makes possible that the scrollbar is hidden when the mouse is not over the frame
    if {$mouseover($canvas)==0} {
        set unmap 1
    }

    ## There is a bug in BWidget 1.9.0 related to the ScrollableFrame.
    # Described in https://groups.google.com/forum/#!topic/comp.lang.tcl/Q5prg9lsOYc
    # This added code solves the problem (see https://core.tcl.tk/bwidget/tktview/72a5727d1b7fb76b32cea032eb7d4bf7c6fa28bf)
    if {![winfo ismapped $canvas.frame]} {
       return
    }

    # This ensures that we don't get funny scrollability in the frame
    # when it is smaller than the canvas space
    # use [winfo] to get height & width of frame

    # [winfo] doesn't work for unmapped frame

    set frameh [expr {$unmap ? 0 : [winfo height $canvas.frame]}]
    set framew [expr {$unmap ? 0 : [winfo width  $canvas.frame]}]

    set height [_max $frameh [winfo height $canvas]]
    set width  [_max $framew [winfo width  $canvas]]
    $canvas:cmd configure -scrollregion [list 0 0 $width $height]
}

Changes to scrollw.tcl.

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
..
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
...
148
149
150
151
152
153
154



155
156
157
158
159
160
161
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
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
...
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
#     - ScrolledWindow::_set_vscroll
#     - ScrolledWindow::_setData
#     - ScrolledWindow::_setSBSize
#     - ScrolledWindow::_realize
# -----------------------------------------------------------------------------

namespace eval ScrolledWindow {



    Widget::define ScrolledWindow scrollw

    Widget::declare ScrolledWindow {
	{-background  TkResource ""   0 button}
	{-scrollbar   Enum	 both 0 {none both vertical horizontal}}
	{-auto	      Enum	 both 0 {none both vertical horizontal}}
	{-sides	      Enum	 se   0 {ne en nw wn se es sw ws}}
	{-size	      Int	 0    1 "%d >= 0"}
	{-ipad	      Int	 1    1 "%d >= 0"}
	{-managed     Boolean	 1    1}

	{-relief      TkResource flat 0 frame}
	{-borderwidth TkResource 0    0 frame}
	{-bg	      Synonym	 -background}
	{-bd	      Synonym	 -borderwidth}
    }

    Widget::addmap ScrolledWindow "" :cmd {-relief {} -borderwidth {}}
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::create
# -----------------------------------------------------------------------------
proc ScrolledWindow::create { path args } {





    Widget::init ScrolledWindow $path $args

    Widget::getVariable $path data

    set bg     [Widget::cget $path -background]
    set sbsize [Widget::cget $path -size]


    if { $::Widget::_theme } {
        set sw     [eval [list ttk::frame $path \
                      -relief flat -borderwidth 0 -takefocus 0] \
                        [Widget::subcget $path :cmd]]
        ttk::scrollbar $path.hscroll \
            -takefocus 0 -orient horiz
................................................................................
            $path.hscroll configure -width $sbsize
        } else {
            set sbsize [$path.vscroll cget -width]
        }
    }
    set data(ipad) [Widget::cget $path -ipad]

    if {$data(hsb,packed)} {
	grid $path.hscroll -column 1 -row $data(hsb,row) \
		-sticky ew -ipady $data(ipad)
    }
    if {$data(vsb,packed)} {
	grid $path.vscroll -column $data(vsb,column) -row 1 \
		-sticky ns -ipadx $data(ipad)
    }

    grid columnconfigure $path 1 -weight 1
    grid rowconfigure	 $path 1 -weight 1

    bind $path <Configure> [list ScrolledWindow::_realize $path]
    bind $path <Destroy>   [list ScrolledWindow::_destroy $path]








    return [Widget::create ScrolledWindow $path]
}










































# -----------------------------------------------------------------------------
#  Command ScrolledWindow::getframe
# -----------------------------------------------------------------------------
proc ScrolledWindow::getframe { path } {
    return $path
}
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::configure
# -----------------------------------------------------------------------------
proc ScrolledWindow::configure { path args } {



    Widget::getVariable $path data

    set res [Widget::configure $path $args]
    if { ! $::Widget::_theme && [Widget::hasChanged $path -background bg] } {
        $path configure -background $bg
        catch {$path.hscroll configure -background $bg}
        catch {$path.vscroll configure -background $bg}
................................................................................
		(!$data(hsb,auto) || ($vmin != 0 || $vmax != 1))}]
	foreach {vmin vmax} [$path.vscroll get] { break }
	set data(vsb,packed) [expr {$data(vsb,present) && \
		(!$data(vsb,auto) || ($vmin != 0 || $vmax != 1))}]

	set data(ipad) [Widget::cget $path -ipad]

	if {$data(hsb,packed)} {
	    grid $path.hscroll -column 1 -row $data(hsb,row) \
		-sticky ew -ipady $data(ipad)
	} else {
	    if {![info exists data(hlock)]} {
		set data(hsb,packed) 0
		grid remove $path.hscroll
	    }
	}
	if {$data(vsb,packed)} {
	    grid $path.vscroll -column $data(vsb,column) -row 1 \
		-sticky ns -ipadx $data(ipad)
	} else {
	    if {![info exists data(hlock)]} {
		set data(vsb,packed) 0
		grid remove $path.vscroll
	    }
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::_set_hscroll
# -----------------------------------------------------------------------------
proc ScrolledWindow::_set_hscroll { path vmin vmax } {

    Widget::getVariable $path data

    if {$data(realized) && $data(hsb,present)} {
	if {$data(hsb,auto) && ![info exists data(hlock)]} {
	    if {$data(hsb,packed) && $vmin == 0 && $vmax == 1} {
		set data(hsb,packed) 0
		grid remove $path.hscroll
		set data(hlock) 1
		update idletasks
		unset data(hlock)
	    } elseif {!$data(hsb,packed) && ($vmin != 0 || $vmax != 1)} {
		set data(hsb,packed) 1
		grid $path.hscroll -column 1 -row $data(hsb,row) \
			-sticky ew -ipady $data(ipad)
		set data(hlock) 1
		update idletasks
		unset data(hlock)
	    }
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::_set_vscroll
# -----------------------------------------------------------------------------
proc ScrolledWindow::_set_vscroll { path vmin vmax } {


    Widget::getVariable $path data

    if {$data(realized) && $data(vsb,present)} {
	if {$data(vsb,auto) && ![info exists data(vlock)]} {
	    if {$data(vsb,packed) && $vmin == 0 && $vmax == 1} {
		set data(vsb,packed) 0
		grid remove $path.vscroll
		set data(vlock) 1
		update idletasks
		unset data(vlock)
	    } elseif {!$data(vsb,packed) && ($vmin != 0 || $vmax != 1) } {
		set data(vsb,packed) 1
		grid $path.vscroll -column $data(vsb,column) -row 1 \
			-sticky ns -ipadx $data(ipad)
		set data(vlock) 1
		update idletasks
		unset data(vlock)
	    }







>
>
>









|
>







 







>
>
>
>
>






>







 







|



|










>
>
>
>
>
>
>



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







 







>
>
>







 







|








|







 







>










|







 







>
>










|







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
...
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#     - ScrolledWindow::_set_vscroll
#     - ScrolledWindow::_setData
#     - ScrolledWindow::_setSBSize
#     - ScrolledWindow::_realize
# -----------------------------------------------------------------------------

namespace eval ScrolledWindow {
    # This new global variable makes possible that the scrollbar is shown only when the mouse is over the frame
    array set mouseover {}

    Widget::define ScrolledWindow scrollw

    Widget::declare ScrolledWindow {
	{-background  TkResource ""   0 button}
	{-scrollbar   Enum	 both 0 {none both vertical horizontal}}
	{-auto	      Enum	 both 0 {none both vertical horizontal}}
	{-sides	      Enum	 se   0 {ne en nw wn se es sw ws}}
	{-size	      Int	 0    1 "%d >= 0"}
	{-ipad	      Int	 1    1 "%d >= 0"}
    {-managed     Boolean    1    1}
	{-onlyhover   Boolean	 0    0}
	{-relief      TkResource flat 0 frame}
	{-borderwidth TkResource 0    0 frame}
	{-bg	      Synonym	 -background}
	{-bd	      Synonym	 -borderwidth}
    }

    Widget::addmap ScrolledWindow "" :cmd {-relief {} -borderwidth {}}
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::create
# -----------------------------------------------------------------------------
proc ScrolledWindow::create { path args } {
    # This new global variable makes possible that the scrollbar is shown only when the mouse is over the frame
    variable mouseover
    # Initialize it to 1 (mouse is over the frame)
    set mouseover($path) 1

    Widget::init ScrolledWindow $path $args

    Widget::getVariable $path data

    set bg     [Widget::cget $path -background]
    set sbsize [Widget::cget $path -size]
    set onlyhover [Widget::cget $path -onlyhover]

    if { $::Widget::_theme } {
        set sw     [eval [list ttk::frame $path \
                      -relief flat -borderwidth 0 -takefocus 0] \
                        [Widget::subcget $path :cmd]]
        ttk::scrollbar $path.hscroll \
            -takefocus 0 -orient horiz
................................................................................
            $path.hscroll configure -width $sbsize
        } else {
            set sbsize [$path.vscroll cget -width]
        }
    }
    set data(ipad) [Widget::cget $path -ipad]

    if {$data(hsb,packed) && $mouseover($path)} {
	grid $path.hscroll -column 1 -row $data(hsb,row) \
		-sticky ew -ipady $data(ipad)
    }
    if {$data(vsb,packed) && $mouseover($path)} {
	grid $path.vscroll -column $data(vsb,column) -row 1 \
		-sticky ns -ipadx $data(ipad)
    }

    grid columnconfigure $path 1 -weight 1
    grid rowconfigure	 $path 1 -weight 1

    bind $path <Configure> [list ScrolledWindow::_realize $path]
    bind $path <Destroy>   [list ScrolledWindow::_destroy $path]

    if {$onlyhover} {
        # This makes possible that the scrollbar is shown only when the mouse is over the frame
        bind [winfo parent $path] <Enter> [list ScrolledWindow::enter $path]
        # This makes possible that the scrollbar is hidden only when the mouse is not over the frame
        bind [winfo parent $path] <Leave> [list ScrolledWindow::leave $path]
    }

    return [Widget::create ScrolledWindow $path]
}


# ----------------------------------------------------------------------------
#  Command ScrolledWindow::enter
# ----------------------------------------------------------------------------
# This makes possible that the scrollbar is shown only when the mouse is over the frame
proc ScrolledWindow::enter {path} {
    variable mouseover
    set mouseover($path) 1

    Widget::getVariable $path data

    foreach {vmin vmax} [$path.hscroll get] { break }
    if {!$data(hsb,packed) && ($vmin != 0 || $vmax != 1)} {
        grid $path.hscroll -column 1 -row $data(hsb,row) \
            -sticky ew -ipady $data(ipad)
    }
    foreach {vmin vmax} [$path.vscroll get] { break }
    if {!$data(vsb,packed) && ($vmin != 0 || $vmax != 1)} {
        grid $path.vscroll -column $data(vsb,column) -row 1 \
        -sticky ns -ipadx $data(ipad)
    }
    return -code continue
}

# ----------------------------------------------------------------------------
#  Command ScrolledWindow::leave
# ----------------------------------------------------------------------------
# This makes possible that the scrollbar is hidden only when the mouse is not over the frame
proc ScrolledWindow::leave {path} {
    variable mouseover
    set mouseover($path) 0

    Widget::getVariable $path data

    set data(hsb,packed) 0
    grid remove $path.hscroll
    set data(vsb,packed) 0
    grid remove $path.vscroll
    return -code continue
}

# -----------------------------------------------------------------------------
#  Command ScrolledWindow::getframe
# -----------------------------------------------------------------------------
proc ScrolledWindow::getframe { path } {
    return $path
}
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::configure
# -----------------------------------------------------------------------------
proc ScrolledWindow::configure { path args } {
    variable mouseover
    set mouseover($path) 0

    Widget::getVariable $path data

    set res [Widget::configure $path $args]
    if { ! $::Widget::_theme && [Widget::hasChanged $path -background bg] } {
        $path configure -background $bg
        catch {$path.hscroll configure -background $bg}
        catch {$path.vscroll configure -background $bg}
................................................................................
		(!$data(hsb,auto) || ($vmin != 0 || $vmax != 1))}]
	foreach {vmin vmax} [$path.vscroll get] { break }
	set data(vsb,packed) [expr {$data(vsb,present) && \
		(!$data(vsb,auto) || ($vmin != 0 || $vmax != 1))}]

	set data(ipad) [Widget::cget $path -ipad]

	if {$data(hsb,packed) && $mouseover($path)} {
	    grid $path.hscroll -column 1 -row $data(hsb,row) \
		-sticky ew -ipady $data(ipad)
	} else {
	    if {![info exists data(hlock)]} {
		set data(hsb,packed) 0
		grid remove $path.hscroll
	    }
	}
	if {$data(vsb,packed) && $mouseover($path)} {
	    grid $path.vscroll -column $data(vsb,column) -row 1 \
		-sticky ns -ipadx $data(ipad)
	} else {
	    if {![info exists data(hlock)]} {
		set data(vsb,packed) 0
		grid remove $path.vscroll
	    }
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::_set_hscroll
# -----------------------------------------------------------------------------
proc ScrolledWindow::_set_hscroll { path vmin vmax } {
    variable mouseover
    Widget::getVariable $path data

    if {$data(realized) && $data(hsb,present)} {
	if {$data(hsb,auto) && ![info exists data(hlock)]} {
	    if {$data(hsb,packed) && $vmin == 0 && $vmax == 1} {
		set data(hsb,packed) 0
		grid remove $path.hscroll
		set data(hlock) 1
		update idletasks
		unset data(hlock)
	    } elseif {!$data(hsb,packed) && ($vmin != 0 || $vmax != 1) && $mouseover($path)} {
		set data(hsb,packed) 1
		grid $path.hscroll -column 1 -row $data(hsb,row) \
			-sticky ew -ipady $data(ipad)
		set data(hlock) 1
		update idletasks
		unset data(hlock)
	    }
................................................................................
}


# -----------------------------------------------------------------------------
#  Command ScrolledWindow::_set_vscroll
# -----------------------------------------------------------------------------
proc ScrolledWindow::_set_vscroll { path vmin vmax } {
    variable mouseover

    Widget::getVariable $path data

    if {$data(realized) && $data(vsb,present)} {
	if {$data(vsb,auto) && ![info exists data(vlock)]} {
	    if {$data(vsb,packed) && $vmin == 0 && $vmax == 1} {
		set data(vsb,packed) 0
		grid remove $path.vscroll
		set data(vlock) 1
		update idletasks
		unset data(vlock)
	    } elseif {!$data(vsb,packed) && ($vmin != 0 || $vmax != 1) && $mouseover($path)} {
		set data(vsb,packed) 1
		grid $path.vscroll -column $data(vsb,column) -row 1 \
			-sticky ns -ipadx $data(ipad)
		set data(vlock) 1
		update idletasks
		unset data(vlock)
	    }