[CJB]: An example of how to make drag and drop tabs with a ttk::notebook. ---- ====== #Create notebook set n [ttk::notebook .nb] pack $n -fill both -expand 1 #Create tabs foreach tab [list First Second Third] { set w [frame $n.[string tolower $tab]] label $w.src_lab -text "Clicked Tab Index:" -anchor e label $w.src_idx -textvariable src_index -width 3 label $w.dst_lab -text "Released Tab Index:" -anchor e label $w.dst_idx -textvariable dst_index -width 3 grid $w.src_lab $w.src_idx -sticky news grid $w.dst_lab $w.dst_idx -sticky news $n add $w -text $tab } #Bindings bind all {console show} bind $n [list click %W %x %y] bind $n [list release %W %x %y] bind $n [list motion %W %X %Y] #Sets index of tab clicked. proc click {W x y} { variable src_index [$W index @$x,$y] puts stderr "Clicked $src_index" } #Moves the tab to the position where it was dropped. proc release {W x y} { variable src_index variable dst_index puts stderr "Released $src_index" #Check for a valid source if {[string is int -strict $src_index]} { set dst_index [$W index @$x,$y] #Check for a valid destination if {[string is int -strict $dst_index]} { set tab [lindex [$W tabs] $src_index] $W insert $dst_index $tab puts stderr "Insert $tab @ $dst_index" } } } #Passes mouse motion events to underlying widgets while dragging. #Allows the notebook tabs to highlight on mouse-over. proc motion {W X Y} { set w [winfo containing $X $Y] if {$w ne $W && $w ne ""} { set x [expr {$X - [winfo rootx $w]}] set y [expr {$Y - [winfo rooty $w]}] event generate $w -x $x -y $y } } ====== ---- [peterc] 2010-07-29: Looks good and it works well :) My only suggestion would be to change the cursor to a tab-like image during the drag (and change it back after button release) so the user has more visual feedback that they've picked up and are dragging the tab. Bonus points if you can include the tab title somehow :) ---- [WJG] (30/07/10) A similar behaviour is available with the gnoc::notebook widget. In addition to being able to reorganize widgets within a notebook, its also possible to drag and drop widgets within different notebooks in a common group. Here's the demo script. # basic Tcl/Gnocl Script #!/bin/sh \ exec tclsh "$0" "$@" package require Gnocl set notebook1 [gnocl::notebook -scrollable 1 -tabPosition left -groupId 1 -onCreateWindow { puts "%w %w %x %y" }] $notebook1 addPage [gnocl::label -text "First Page"] "%__First" $notebook1 addPage [gnocl::label -text "Second Page"] "%__Second" $notebook1 addPage [gnocl::label -text "Third Page"] "%__Third" $notebook1 addPage [gnocl::label -text "Fourth Page"] "%__Fourth" gnocl::window \ -title "Notebook1" \ -child $notebook1 \ -x 100 \ -y 100 \ -width 200 \ -height 100 set notebook2 [gnocl::notebook -tabPosition right -groupId 1] $notebook2 addPage [gnocl::label \ -text "Fifth Page"] "%__Fifth" $notebook2 addPage [gnocl::label \ -text "Sixth Page"] "%__Sixth" gnocl::window \ -title "Notebook2" \ -child $notebook2 \ -x 100 \ -y 250 \ -width 200 \ -height 100 set notebook3 [gnocl::notebook -groupId 2] $notebook3 addPage [gnocl::label \ -text "Seventh Page"] "%__Seventh" $notebook3 addPage [gnocl::label \ -text "Eigth Page"] "%__Eigth" gnocl::window \ -title "Notebook3" \ -child $notebook3 \ -x 100 \ -y 400 \ -width 200 \ -height 100 ----- <>Example|GUI|Widget