18 namespace eval ::win {}
21 proc ::win::createWindow { {w} {title} {default_geometry ""} } {
22 if { [
winfo exists $w] } {
27 if {![
info exists ::winGeometry($w)]} {
28 set ::winGeometry($w) $default_geometry
42 proc ::win::closeWindow {w} {
44 if {$docked_nb ne ""} {
53 proc ::win::getWindows {} {
55 foreach undocked [
array names ::docking::notebook_name] {
56 if {[
winfo exists $undocked]} {
60 foreach noteb [
array names ::docking::tbs] {
61 foreach docked [$noteb tabs] {
71 proc setTitle { w title } {
73 if {$docked_nb ne ""} {
75 if {[
string equal -length 6 $title "Scid: "]} {
76 set title [
string range $title 6 end]
78 $docked_nb tab $w -text $title
87 proc ::win::getMenu {w} {
89 if {[
string equal -length 6 $wnd ".fdock"]} {
90 set w [
string replace $wnd 1 5]
92 if {[
info exists ::win::menu_($wnd)]} {
93 return [list $::win::menu_($wnd) $w]
104 if {$docked_nb ne ""} {
105 $docked_nb tab $wnd -image tb_tabmenu -compound left
107 $w configure -menu $m
109 set ::win::menu_($wnd) $m
115 proc ::win::saveWinGeometry {w} {
117 if {$docked_nb eq ""} {
119 if {[
wm state $w] == "zoomed"} {
120 set ::winGeometry($w) "zoomed"
122 set ::winGeometry($w) [
wm geometry $w]
129 proc ::win::restoreWinGeometry {w} {
130 if {[
info exists ::winGeometry($w)]} {
131 if {$::winGeometry($w) == "zoomed"} {
132 if { $::windowsOS || $::macOS } {
135 wm attributes $w -zoomed
138 wm geometry $w $::winGeometry($w)
148 proc ::win::isDocked {wnd} {
150 regexp {[.]\w*} "$wnd" wnd
151 set f ".fdock[
string range $wnd 1 end]"
152 if {[
winfo exists $f]} {
set wnd $f}
155 return [list $docked_nb $wnd]
159 proc ::win::undockWindow { wnd srctab {title ""} } {
160 if {$srctab ne "" } {
162 set title "Scid: [dict get $old_options -text]"
167 wm protocol $wnd WM_DELETE_WINDOW "::win::closeWindow $wnd"
178 set ::docking::notebook_name($wnd) $srctab
182 after idle after 1 "::win::restoreWinGeometry $wnd"
186 proc ::win::dockWindow {wnd} {
189 set title [
wm title $wnd]
190 if {[
string equal -length 6 $title "Scid: "]} {
191 set title [
string range $title 6 end]
195 $wmenu configure -menu {}
199 if {[
winfo exists $::docking::notebook_name($wnd)]} {
200 set dsttab $::docking::notebook_name($wnd)
204 unset ::docking::notebook_name($wnd)
206 [list -text $title -image tb_close -compound left]
208 if {$menu ne ""} {
::setMenu $wmenu $menu}
213 proc ::win::toggleDocked {wnd} {
217 if {$wnd eq ".fdockmain" || [
winfo class $wnd] ne "Frame"} {
221 if {$docked_nb ne ""} {
228 proc ::win::manageWindow {wnd title} {
229 unset -nocomplain ::win::menu_($wnd)
230 unset -nocomplain ::docking::notebook_name($wnd)
232 if { [
info exists ::docking::layout_dest_notebook]} {
233 set dsttab $::docking::layout_dest_notebook
234 set docked [
expr { $dsttab ne "undocked" }]
236 set docked $::windowsDock
239 if {![
info exists dsttab]} {
243 [list -text $title -image tb_close -compound left]
252 proc ::win::createDialog {w {y 10}} {
253 toplevel $w -padx 10 -pady $y
258 proc ::win::makeVisible { wnd } {
261 $wnd_nb select $wnd_top
262 set wnd_top [
winfo toplevel $wnd_top]
265 wm deiconify $wnd_top
272 proc ::utils::win::Centre {w} {
275 set x [
expr {[winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
277 set y [
expr {[winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
293 namespace eval docking {
300 proc ::docking::find_tbn {path} {
301 foreach tb [
array names ::docking::tbs] {
302 if {[lsearch -exact [$tb tabs] $path]>=0} {
311 proc ::docking::_cleanup_tabs {srctab} {
315 if {[
llength [$srctab tabs]]==0} {
320 while {[
llength [$pw panes]]==0} {
321 set parent [
winfo parent $pw]
383 proc ::docking::choose_notebook { path } {
386 foreach tb [
array names ::docking::tbs] {
387 if {[
winfo class $tb] != "TNotebook"} { continue}
393 set coeff(0) "105622.84"
395 set feat(1) [
llength [lsearch -all -regexp $tabs ".*main"]]
396 set coeff(1) "-48019.31"
398 set feat(2) [
llength $tabs]
399 set coeff(2) "-51266.84"
401 set feat(3) [
expr { $feat(2) * $feat(2) }]
402 set coeff(3) "8661.97"
404 set name_striptrailnum [regsub {\d*$} $path ""]
405 set feat(4) [
llength [lsearch -all -regexp $tabs ".*$name_striptrailnum.*"]]
406 set coeff(4) "29942.45"
408 set feat(5) [
expr { $feat(4) * $feat(4) }]
409 set coeff(5) "-3053.05"
411 set feat(6) [
expr { $feat(4) * $feat(4) * $feat(4) }]
412 set coeff(6) "-323.52"
414 set feat(7) [
expr { double([winfo width $tb] * [winfo height $tb]) }]
415 set feat(7) [
expr { $feat(7) / ([winfo screenwidth $tb] * [winfo screenheight $tb]) }]
419 for {
set i 0} {$i < [
array size feat]} {
incr i} {
420 set fit [
expr { $fit + $feat($i) * $coeff($i)}]
423 if {$best_fitting == "" || $fit > $best_fitting} {
424 set best_fitting $fit
432 proc ::docking::insert_tab {wnd dest_noteb {dest_pos "end"} {options ""}} {
433 $dest_noteb insert $dest_pos $wnd {*}$options
434 $dest_noteb select $wnd
439 proc ::docking::remove_tab {wnd src_noteb} {
440 set options [$src_noteb tab $wnd]
441 $src_noteb forget $wnd
446 proc ::docking::generate_unique_path_ { prefix } {
448 while {[
winfo exists $prefix$tmp]} {
455 proc ::docking::move_tab_ {wnd src_noteb dest_noteb {dest_pos "end"} } {
457 if {[
string length $dest_noteb] == 1} {
459 if {$dest_noteb eq "s" || $dest_noteb eq "e"} {
462 set pw $::docking::tbs($src_noteb)
472 proc ::docking::orient_pw_ {tbn anchor} {
475 if {$anchor=="w" || $anchor=="e"} {
476 set orient "horizontal"
478 set orient "vertical"
482 set idx [lsearch -exact [$pw panes] $tbn]
484 if {[$pw cget -orient] ne $orient} {
488 ttk::panedwindow $pw -orient $orient
499 proc ::docking::insert_pane_ {pw idx wnd} {
500 if {$idx ne "end" && $idx >= [
llength [$pw panes]]} {
503 $pw insert $idx $wnd -weight 1
507 proc ::docking::insert_notebook_ {pw idx noteb} {
509 set ::docking::tbs($noteb) $pw
513 proc ::docking::create_notebook_ {path} {
514 set noteb [ttk::notebook $path -width 1 -height 1]
515 bind $noteb <B1-Motion> {
516 if {[info exists ::docking::motion_]} { continue }
517 set ::docking::motion_ [::docking::identify_tab_ %W %x %y]
518 if {[lindex $::docking::motion_ 0] eq ""} {
519 # Do nothing if motion started outside a tab
522 if {[lindex $::docking::motion_ 1]} {
523 # Not a motion event if it starts and ends over the icon
524 unset ::docking::motion_
526 %W configure -cursor hand2
529 bind $noteb <ButtonRelease-1> {
530 if {[info exists ::docking::motion_]} {
531 %W configure -cursor {}
532 ::docking::manage_motion_ %W %X %Y
534 ::docking::manage_click_ %W %X %Y %x %y
537 bind $noteb <ButtonRelease-$::MB3> {
538 ::docking::manage_rightclick_ %W %X %Y %x %y
545 proc ::docking::identify_tab_ {noteb localX localY} {
547 set tab [$noteb identify tab $localX $localY]
549 set icon [$noteb tab $tab -image]
551 set iconW [
expr { 4 + [image width $icon] }]
553 set isIcon [
expr {$localX < $iconW ? 1 : 0}]
555 set isIcon [
expr [$noteb identify tab [
expr $localX - $iconW] $localY] != $tab]
559 return [list $tab $isIcon]
563 proc ::docking::manage_motion_ {src_noteb x y} {
564 lassign $::docking::motion_ src_tab
565 unset ::docking::motion_
566 if {$src_tab eq ""} {
return}
568 set dest_noteb [
winfo containing $x $y]
569 if {![
info exists ::docking::tbs($dest_noteb)]} {
return}
571 set localX [
expr $x-[
winfo rootx $dest_noteb]]
572 set localY [
expr $y-[
winfo rooty $dest_noteb]]
573 set dest_pos [$dest_noteb identify tab $localX $localY]
574 if {$dest_pos eq ""} {
set dest_pos "end"}
576 set wnd [
lindex [$src_noteb tabs] $src_tab]
577 if {$src_noteb eq $dest_noteb} {
578 $dest_noteb insert $dest_pos $wnd
586 proc ::docking::manage_click_ {noteb x y localX localY} {
588 if {$tab eq "" || ! $isIcon} {
return}
590 set wnd [
lindex [$noteb tabs] $tab]
600 proc ::docking::manage_rightclick_ {noteb x y localX localY} {
602 if {$tab eq "" || $isIcon} {
return}
606 set noteb_tabs [$noteb tabs]
607 set state [
expr { [llength $noteb_tabs] > 1 ? "normal" : "disabled" }]
608 set wnd [
lindex $noteb_tabs $tab]
611 if { [
winfo exists $m] } {
destroy $m}
613 $m add command -label [
::tr DockTop] -state $state \
614 -command "::docking::move_tab_ $wnd $noteb n"
615 $m add command -label [
::tr DockBottom] -state $state \
616 -command "::docking::move_tab_ $wnd $noteb s"
617 $m add command -label [
::tr DockLeft] -state $state \
618 -command "::docking::move_tab_ $wnd $noteb w"
619 $m add command -label [
::tr DockRight] -state $state \
620 -command "::docking::move_tab_ $wnd $noteb e"
622 if { $wnd != ".fdockmain" } {
624 $m add command -label [
::tr Undock] -command "::win::undockWindow $wnd $noteb"
625 $m add command -label [
::tr Close] -command "::win::closeWindow $wnd"
637 proc ::docking::layout_save { slot } {
641 set geometry [
wm geometry .]
642 set ::docking::layout_list($slot) [list [list "MainWindowGeometry" $geometry]]
643 if {[
wm state .] == "zoomed"} {
644 if { [
scan $geometry "%dx%d+%d+%d" w h x y] == 4 } {
645 set geometry "${w}x${h}+0+0"
646 set ::docking::layout_list($slot) [list [list "MainWindowGeometry" $geometry "zoomed"]]
653 foreach wnd [
array names ::docking::notebook_name] {
654 if {[
winfo exists $wnd]} {
655 lappend ::docking::layout_list($slot) [list [list "Toplevel" $wnd]]
660 proc ::docking::layout_save_pw {pw} {
665 for {
set i 0} {$i < [
expr [
llength [$pw panes]] -1]} {
incr i} {
666 lappend sashpos [$pw sashpos $i]
668 lappend ret [list $pw [$pw cget -orient] $sashpos]
670 foreach p [$pw panes] {
671 if {[
winfo class $p] == "TNotebook"} {
674 set glistWins [lsearch -all -regexp $wins "\.(fdock)?glistWin\[0-9\]+"]
675 set i [
llength $glistWins]
678 set remove [
lindex $glistWins $i]
679 set wins [
lreplace $wins $remove $remove]
681 lappend ret [list "TNotebook" $p $wins]
683 }
elseif {[
winfo class $p] == "TPanedwindow"} {
693 proc ::docking::layout_restore_pw { data } {
695 lassign $elt type pathName
696 if {$type == "Toplevel"} {
697 lappend ::docking::restore_wnds [list "undocked" $pathName]
699 }
elseif {$type == "TPanedwindow"} {
702 }
elseif {$type == "TNotebook"} {
705 foreach wnd [
lindex $elt 2] {
706 lappend ::docking::restore_wnds [list $pathName $wnd]
710 lassign $elt pw orient sash_positions
711 if {$sash_positions ne ""} {
712 lappend ::docking::restore_sashpos [ list $pw $sash_positions]
715 ttk::panedwindow $pw -orient $orient
716 set parent [
string range $pw 0 [
expr [
string last "." $pw]-1]]
717 if { $parent eq "" } {
718 pack $pw -fill both -expand true
726 proc ::docking::create_window {wnd} {
727 switch -regexp -matchvar regmatch -- $wnd {
728 "\.(fdock)?main" {
::docking::insert_tab $wnd $::docking::layout_dest_notebook end [list -text $::tr(Board)]}
742 "\.(fdock)?treeWin([0-9]+)" {
::tree::make [
lindex $regmatch end]}
748 proc ::docking::layout_restore { slot } {
750 if { $::docking::layout_list($slot) == {} } {
759 foreach wnd [
winfo children .] {
760 if { [
winfo class $wnd] ne "Menu" } {
766 set restore_geometry {}
767 set ::docking::restore_sashpos {}
768 set ::docking::restore_wnds {}
769 foreach data $::docking::layout_list($slot) {
770 if {[
lindex $data 0] eq "MainWindowGeometry"} {
771 lappend restore_geometry [list "." [
lindex $data 1] [
lindex $data 2]]
778 foreach geom $restore_geometry {
779 lassign $geom wnd size_pos zoomed
780 wm geometry $wnd $size_pos
781 if {$zoomed eq "zoomed"} {
782 if { $::windowsOS || $::macOS } {
785 wm attributes $wnd -zoomed
791 foreach sashpos $::docking::restore_sashpos {
796 lassign $sashpos pw sash
803 unset -nocomplain ::docking::restore_sashpos
813 foreach pair $::docking::restore_wnds {
814 lassign $pair ::docking::layout_dest_notebook wnd
821 unset -nocomplain ::docking::layout_dest_notebook
822 unset -nocomplain ::docking::restore_wnds