package require Tk proc celldef {w px py} { label $w -anchor w \ -text "($px,$py) [string repeat . [expr {$px+$py}]]" } proc ginit {w rows cols} { global cells$w for {set y 0} {$y < $rows} {incr y} { set cmd grid for {set x 0} {$x < $cols} {incr x} { set cell $w.$x,$y celldef $cell $x $y lappend cmd $cell set cells${w}($x,$y) -1,-1 } eval [lappend cmd -sticky nsew -row $y] grid rowconfig $w $y -uniform a } for {set x 0} {$x < $cols} {incr x} { grid columnconfig $w $x -uniform a } } proc gconf {w} { $w.c configure -scrollregion [grid bbox $w.c.f] } proc gview {w} { frame $w scrollbar $w.h -command "$w.c xview" -orient horiz scrollbar $w.v -command "$w.c yview" canvas $w.c -xscrollcommand "$w.h set" -yscrollcommand "$w.v set" pack $w -expand 1 -fill both grid rowconfig $w 0 -weight 1 -minsize 0 grid columnconfig $w 0 -weight 1 -minsize 0 grid $w.c -row 0 -column 0 -sticky news grid $w.v -row 0 -column 1 -sticky news grid $w.h -row 1 -column 0 -sticky news bind $w <Configure> "gconf $w" frame $w.c.f $w.c create window 0 0 -window $w.c.f -anchor nw return $w.c.f } ginit [gview .f] 10 6Feel free to use, re-use, alter, extend, and/or comment as you like.
D. McC: How would this compare with a set of multi-scrolling listboxes using the -listvariable option, which could be vertically scrolled and horizontally gridded or un-gridded as needed? More, less, or equally efficient?I'm not sure. I think that's how Maurice Ulis's virtual listbox works. Listvariable's don't reduce the copying requirements though, if I understand them properly. You still need to hold all N data items in a Tcl list.One reason to explore the above approach is that each cell can contain a widget of arbitrary complexity. -jcwNEM This kind of reminds me of techniques used in side-scrolling platform games like the original Mario, where the background is made up of a grid of cells of a fixed size. The game draws enough cells to fill the screen, plus a border of cells around the edges. As the view moves to the right (say), the cells that disappear off the screen are deleted, while new cells are added on the other side. The difference here is that the cells (widgets) remain the same, we just re-assign their contents as the user scrolls. Interesting.KPV A similar technique is used in Hack-O-Matic to speed up the display of what appears to the user to be a scrollable display of 32K x 8 widgets.PWQ 19 Feb 04 Lets see if I understand this correctly. You scroll the widget down (right) until you get to 2*h-1 (2*w-1) widgets then you snap back to display the first widget (while the scroll bar stays in the same place). I used this technique on my EDA package [1], where a displayed grid scrolls with the canvas until it aligns with the grid size then the grid snaps back to the top left corner, thus simulating a grid of infinite size.Using a canvas as a toplevel for this example:As another technique, I ask the question, do you need to have 2 * the number of widgets. I propose the following:
Given we have a matrix if x by y widgets.
- When a widget row (column) disappears from view (due to scrolling) move it to be at the opposite end of the list of widgets (on the canvas).
- Reconfigure this widget (row of or column of) with the new data.
If a <Prior> or <Next> event makes multiple rows (columns) disappear:
- Do the same as above but move multiple rows (columns).
11may05 jcw - Here's a demo which might be useful. It puts a grid on a canvas, so that the whole thing can be scrolled around:
package require Tk canvas .c -bg red -xscrollcommand ".x set" -yscrollcommand ".y set" \ -highlightthickness 0 frame .c.f .c create window 0 0 -window .c.f -anchor nw bind .c.f <Configure> { .c configure -scrollregion {0 0 %w %h} } label .c.f.l1 -bg blue -text "bonjour les mecs!" -width 30 -height 5 label .c.f.l2 -bg yellow -text "hello there!" -width 30 -height 5 label .c.f.l3 -bg green -text "hallo,\ngabbers" -width 30 -height 5 label .c.f.l4 -bg white -text "hi fans!" -width 30 -height 5 grid .c.f.l1 .c.f.l3 -sticky news grid .c.f.l2 .c.f.l4 -sticky news scrollbar .x -command ".c xview" -orient h scrollbar .y -command ".c yview" grid .c .y -sticky news grid .x -sticky news grid columnconfig . 0 -weight 1 grid rowconfigure . 0 -weight 1This would work even if the cells in the grid are not uniform in size, i.e. a general HTML-like table, so this thing could be the basis for a gridded widget. If the contents is virtual, it could in fact become a data-aware widget, i.e. a widget which does not contain a copy of all data but pulls cell content in as needed (and forgets it again just as easily!).