package Tk::TabBar; use vars qw($VERSION %TYPES); $VERSION = '0.7'; use Tk; require Tk::Frame; use Carp; use strict; use base qw(Tk::Frame); Construct Tk::Widget 'TabBar'; $TYPES{fixed} = 0; $TYPES{docked} = 1; $TYPES{undocked} = 2; $TYPES{0} = "fixed"; $TYPES{1} = "docked"; $TYPES{2} = "undocked"; sub Populate { my ($cw, $args) = @_; my %args = %{$args}; $cw->{args} = \%args; $args->{-height} = 30; $args->{-highlightthickness} = 0; $cw->{vars}->{Height} = 30; $cw->{vars}->{Tabs}->{DockableBG} = $cw->ParseArg($args,"-tabdockablebg","black"); $cw->{vars}->{Tabs}->{Background} = $cw->ParseArg($args,"-tabbackground","white"); $cw->{vars}->{Tabs}->{DisabledBackground} = $cw->ParseArg($args,"-tabdisabledbackground",$cw->{vars}->{Tabs}->{Background}); $cw->{vars}->{Tabs}->{Foreground} = $cw->ParseArg($args,"-tabforeground","black"); $cw->{vars}->{Tabs}->{Highlight}->{Low} = $cw->ParseArg($args,"-tabhighlightlow","red"); $cw->{vars}->{Tabs}->{Highlight}->{Medium} = $cw->ParseArg($args,"-tabhighlightmedium","purple"); $cw->{vars}->{Tabs}->{Highlight}->{High} = $cw->ParseArg($args,"-tabhighlighthigh","white"); $cw->{vars}->{Tabs}->{Fill} = $cw->ParseArg($args,"-tabfill","black"); $cw->{vars}->{Tabs}->{Font} = $cw->ParseArg($args,"-tabfont",""); $cw->{vars}->{Tabs}->{PadX} = $cw->ParseArg($args,"-tabpadx",0); $cw->{vars}->{Tabs}->{PadY} = $cw->ParseArg($args,"-tabpady",0); $cw->{vars}->{Tabs}->{Thickness} = $cw->ParseArg($args,"-tabthickness",1); $cw->{vars}->{Undocked} = $cw->ParseArg($args,"-undocked",0); $cw->{vars}->{UndockedTitlePrefix} = $cw->ParseArg($args,"-undockedtitleprefix","Undocked"); $cw->{vars}->{CurrentTab} = ""; $cw->{tabs}->{order} = []; $cw->{rows}->[0]->{width} = 0; $cw->{rows}->[0]->{count} = 0; $cw->{frame} = $cw-> Frame(-background=>$cw->{vars}->{Tabs}->{Background}, )->pack(-side=>'top', -padx=>0, -pady=>0, -fill=>'both', -expand=>1); $cw->{canvas} = $cw->{frame}-> Canvas(%{$args})->pack(-side=>'top', -fill=>'both'); $cw->{popup}->{menu} = $cw-> Menu(-tearoff=>0, -background=>$cw->{vars}->{Tabs}->{Background}, -foreground=>$cw->{vars}->{Tabs}->{Foreground}, ( (ref($cw->{vars}->{Tabs}->{Font}) eq "Tk::Font") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : ( ($cw->{vars}->{Tabs}->{Font} ne "") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : () ) ), ); $cw->{popup}->{menu}-> add("command", -label=>"Undock", -state=>"disabled", -background=>$cw->{vars}->{Tabs}->{Background}, -foreground=>$cw->{vars}->{Tabs}->{Foreground}, ( (ref($cw->{vars}->{Tabs}->{Font}) eq "Tk::Font") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : ( ($cw->{vars}->{Tabs}->{Font} ne "") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : () ) ), -command=>sub{ $cw->UnDockTab($cw->{vars}->{ActiveTab}); } ); $cw->{popup}->{menu}-> add("command", -label=>"Dock", -state=>"disabled", -background=>$cw->{vars}->{Tabs}->{Background}, -foreground=>$cw->{vars}->{Tabs}->{Foreground}, ( (ref($cw->{vars}->{Tabs}->{Font}) eq "Tk::Font") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : ( ($cw->{vars}->{Tabs}->{Font} ne "") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : () ) ), -command=>sub{ $cw->parent->parent->parent->DockTab($cw->{vars}->{ActiveTab}); } ); $cw->{canvas}->CanvasBind("", sub { $cw->Refresh(); } ); } sub ParseArg { my $cw = shift; my ($args,$arg,$default) = @_; return (exists($args->{$arg}) ? delete($args->{$arg}) : $default); } sub Refresh { my $cw = shift; #print "($cw) Refresh: start\n"; $cw->RecalculatePositions(); $cw->DrawTabs(); $cw->RaiseTab($cw->{vars}->{CurrentTab},1); #print "($cw) Refresh: finish\n"; } sub RecalculatePositions { my $cw= shift; my $row = 0; my $col = 0; my $x = 0; $cw->{rows} = (); my $canvasWidth = $cw->{canvas}->width(); $canvasWidth = $cw->{canvas}->reqwidth() if ($canvasWidth < 10); foreach my $index (0..$#{$cw->{tabs}->{order}}) { my $tag = $cw->{tabs}->{order}->[$index]; $cw->CharacterizeTab($tag); if ((($x + $cw->{tabs}->{tags}->{$tag}->{width}) > $canvasWidth) && ($col != 0)) { $col = 0; $row++; $x = 0; } $cw->{tabs}->{tags}->{$tag}->{row} = $row; $cw->{tabs}->{tags}->{$tag}->{realRow} = $row; $cw->{tabs}->{tags}->{$tag}->{col} = $col; $cw->{tabs}->{tags}->{$tag}->{x} = $x; $x += $cw->{tabs}->{tags}->{$tag}->{width}; $col++; $cw->{rows}->[$row]->{width} = $x; $cw->{rows}->[$row]->{count} = $col; } $cw->CharacterizeCanvas(); } sub CharacterizeTab { my ($cw,$tag) = @_; #print "($cw) CharacterizeTab: tag($tag)\n"; $cw->{canvas}-> createText(10000,10000, -text=>$cw->{tabs}->{tags}->{$tag}->{text}, ( (ref($cw->{vars}->{Tabs}->{Font}) eq "Tk::Font") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : ( ($cw->{vars}->{Tabs}->{Font} ne "") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : () ) ), -tags=>[ "tktabbartest" ]); my ($x1,$y1,$x2,$y2) = $cw->{canvas}->bbox("tktabbartest"); $cw->{canvas}->delete("tktabbartest"); $cw->{vars}->{Height} = $y2 - $y1 + 18; $cw->{tabs}->{tags}->{$tag}->{width} = $x2 - $x1 + 14; $cw->{tabs}->{tags}->{$tag}->{width} = 0 if ($cw->{tabs}->{tags}->{$tag}->{hidden} == 1); } sub CharacterizeCanvas { my $cw = shift; $cw->{canvas}->configure(-height=>(($#{$cw->{rows}}+1)*$cw->{vars}->{Height})); $cw->{vars}->{Width} = $cw->{canvas}->width(); } ########################################################################### # # # ########################################################################### sub DrawTabs { my ($cw) = @_; #print "($cw) DrawTabs: start\n"; $cw->{canvas}->delete("all"); $cw->{canvas}-> createRectangle(0,($cw->{vars}->{Height}-5), 10000,((($#{$cw->{rows}}+1)*$cw->{vars}->{Height})+5), -fill=>$cw->{vars}->{Tabs}->{DisabledBackground}, -outline=>$cw->{vars}->{Tabs}->{DisabledBackground}, -tags=>["disabledTabs"]); foreach my $index (0..($#{$cw->{rows}}-1)) { $cw->{canvas}-> createLine(0,((($#{$cw->{rows}}-$index)*$cw->{vars}->{Height})-6), 10000,((($#{$cw->{rows}}-$index)*$cw->{vars}->{Height})-6), -width=>$cw->{vars}->{Tabs}->{Thickness}, -fill=>$cw->{vars}->{Tabs}->{Fill}, -tags=>["disabledLines"]); } my @tabs; foreach my $index (0..$#{$cw->{tabs}->{order}}) { my $tag = $cw->{tabs}->{order}->[$index]; $cw->DrawTab($tag,$cw->{tabs}->{tags}->{$tag}->{text}) unless ($cw->{tabs}->{tags}->{$tag}->{hidden} == 1); push(@tabs,$tag) if (($cw->{tabs}->{tags}->{$tag}->{x} == 0) && ($cw->{tabs}->{tags}->{$tag}->{row} != 0)); } $cw->{canvas}-> createLine(0,((($#{$cw->{rows}}+1)*$cw->{vars}->{Height})-6), 10000,((($#{$cw->{rows}}+1)*$cw->{vars}->{Height})-6), -width=>$cw->{vars}->{Tabs}->{Thickness}, -fill=>$cw->{vars}->{Tabs}->{Fill}, -tags=>["line"]); $cw->{canvas}-> createRectangle(0,((($#{$cw->{rows}}+1)*$cw->{vars}->{Height})-5), 10000,((($#{$cw->{rows}}+1)*$cw->{vars}->{Height})+5), -fill=>$cw->{vars}->{Tabs}->{Background}, -outline=>$cw->{vars}->{Tabs}->{Background}, -tags=>["line"]); #print "($cw) DrawTabs: currentTab($cw->{vars}->{CurrentTab})\n"; foreach (@tabs) { $cw->{canvas}->raise("disabledLines","all"); $cw->{canvas}->raise($_,"disabledLines"); } $cw->RaiseTab($cw->{vars}->{CurrentTab},1) if !($cw->Raised("")); #print "($cw) DrawTabs: finish\n"; } ########################################################################### # # # ########################################################################### sub DrawTab { my($cw,$tag,$text) = @_; #print "($cw) DrawTab: start\n"; #print "($cw) DrawTab: tag($tag) text($text)\n"; my $openSpace = $cw->{tabs}->{tags}->{$tag}->{x}; my $row = $cw->{tabs}->{tags}->{$tag}->{row}; #print "($cw) DrawTab: openSpace($openSpace) row($row)\n"; my $baseY = ($#{$cw->{rows}} - $row) * $cw->{vars}->{Height}; #print "($cw) DrawTab: baseY($baseY)\n"; my $highlight = (exists($cw->{tabs}->{tags}->{$tag}->{highlight}) ? $cw->{tabs}->{tags}->{$tag}->{highlight} : 0 ); my $textFill = ($highlight == 0 ? $cw->{vars}->{Tabs}->{Foreground} : ( ($highlight == 1) ? $cw->{vars}->{Tabs}->{Highlight}->{Low} : ( ($highlight == 2) ? $cw->{vars}->{Tabs}->{Highlight}->{Medium} : $cw->{vars}->{Tabs}->{Highlight}->{High} ) ) ); $cw->{canvas}-> createPolygon((1+$openSpace),$baseY+($cw->{vars}->{Height}-6), (1+$openSpace),$baseY+5, (3+$openSpace),$baseY+3, (($cw->{tabs}->{tags}->{$tag}->{width}-2)+$openSpace),$baseY+3, (($cw->{tabs}->{tags}->{$tag}->{width})+$openSpace),$baseY+5, (($cw->{tabs}->{tags}->{$tag}->{width})+$openSpace),$baseY+($cw->{vars}->{Height}-6), -width=>$cw->{vars}->{Tabs}->{Thickness}, -fill=>$cw->{vars}->{Tabs}->{Background}, -outline=>$cw->{vars}->{Tabs}->{Fill}, -tags=>[ $tag , "tab-$tag" , "tabs" ]); $cw->{canvas}-> createLine((1+$openSpace),$baseY+($cw->{vars}->{Height}-6), (($cw->{tabs}->{tags}->{$tag}->{width})+$openSpace),$baseY+($cw->{vars}->{Height}-6), -fill=>$cw->{vars}->{Tabs}->{Background}, -tags=>[ $tag , "tab-$tag" , "tabs" ]); $cw->{canvas}-> createLine((0+$openSpace),$baseY+($cw->{vars}->{Height}-6), (2+$openSpace),$baseY+($cw->{vars}->{Height}-6), -fill=>$cw->{vars}->{Tabs}->{Fill}, -tags=>[ $tag ]); $cw->{canvas}-> createLine(($cw->{tabs}->{tags}->{$tag}->{width}+$openSpace),$baseY+5, ($cw->{tabs}->{tags}->{$tag}->{width}+$openSpace),$baseY+($cw->{vars}->{Height}-6), -fill=>"black", -tags=>[ $tag ]); $cw->{canvas}-> createLine(($cw->{tabs}->{tags}->{$tag}->{width}-1+$openSpace),$baseY+4, ($cw->{tabs}->{tags}->{$tag}->{width}+$openSpace),$baseY+5, -fill=>"black", -tags=>[ $tag ]); my $type = (exists($cw->{tabs}->{tags}->{$tag}->{type}) ? $cw->{tabs}->{tags}->{$tag}->{type} : $TYPES{fixed} ); if (($type eq $TYPES{docked}) || ($type eq $TYPES{undocked})) { $cw->{canvas}-> createPolygon((2+$openSpace),$baseY+8, (6+$openSpace),$baseY+4, (2+$openSpace),$baseY+4, -width=>0, -fill=>$cw->{vars}->{Tabs}->{DockableBG}, -tags=>[ $tag ]); $cw->{canvas}-> createLine((1+$openSpace),$baseY+5, (3+$openSpace),$baseY+3, -fill=>$cw->{vars}->{Tabs}->{Fill}, -tags=>[ $tag ]); } $cw->{canvas}-> createText((($cw->{tabs}->{tags}->{$tag}->{width}/2)+$openSpace),$baseY+(($cw->{vars}->{Height}-4)/2), -text=>$text, ( (ref($cw->{vars}->{Tabs}->{Font}) eq "Tk::Font") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : ( ($cw->{vars}->{Tabs}->{Font} ne "") ? (-font=>$cw->{vars}->{Tabs}->{Font}) : () ) ), -fill=>$textFill, -tags=>[ $tag , "text$tag" ]); $cw->{canvas}-> bind($tag,"",sub{ $cw->RaiseTab($tag); }); $cw->{canvas}-> bind($tag,"",sub{ $cw->{vars}->{ActiveTab} = $tag; $cw->{popup}->{menu}->entryconfigure(0,-state=>"disabled"); $cw->{popup}->{menu}->entryconfigure(1,-state=>"normal"); $cw->{popup}->{menu}-> Popup(-popover=>"cursor", -popanchor=>"nw"); }) if ($type eq $TYPES{undocked}); $cw->{canvas}-> bind($tag,"",sub{ $cw->{vars}->{ActiveTab} = $tag; $cw->{popup}->{menu}->entryconfigure(0,-state=>"normal"); $cw->{popup}->{menu}->entryconfigure(1,-state=>"disabled"); $cw->{popup}->{menu}-> Popup(-popover=>"cursor", -popanchor=>"nw"); }) if ($type eq $TYPES{docked}); #print "($cw) DrawTab: finish\n"; } ########################################################################### # # # ########################################################################### sub AddTab { my ($cw,@args) = @_; my %args; while($#args > -1) { my $key = shift(@args); $key =~ s/^\-//; $args{ lc($key) } = shift(@args); } $args{type} = "fixed" if !exists($args{type}); #print "($cw) AddTab: start\n"; #print "($cw) AddTab: type($args{type}) tag($args{tag}) text($args{text})\n"; if ((!exists($args{text}) && ($args{type} ne "docking")) || !exists($args{tag})) { croak("ERROR: AddTab: must set text and tag arguments"); } $args{text} = $cw->{tabs}->{tags}->{$args{tag}}->{text} if ($args{type} eq "docking"); if (($args{type} ne "fixed") && ($args{type} ne "docked") && ($args{type} ne "undocked") && ($args{type} ne "docking")) { croak("ERROR: type($args{type}) not correct in call to AddTab\n"); } splice(@{$cw->{tabs}->{order}},$#{$cw->{tabs}->{order}}+1,0,$args{tag}); ($cw->{tabs}->{tags}->{$args{tag}}->{type} = $TYPES{$args{type}}) unless ($args{type} eq "fixed"); ($cw->{tabs}->{tags}->{$args{tag}}->{type} = $TYPES{docked}) if ($args{type} eq "docking"); $cw->{tabs}->{tags}->{$args{tag}}->{text} = $args{text}; my $packframe; if ((($args{type} eq "docked") || ($args{type} eq "undocked")) && ($cw->{vars}->{Undocked} == 0)) { my $toplevel = $cw->{frame}->Toplevel(); $toplevel->withdraw() if ($args{type} eq "docked"); $cw->{tabs}->{tags}->{$args{tag}}->{tabbar} = $toplevel-> TabBar(%{$cw->{args}}, -undocked=>1 )->pack(-side=>"top", -fill=>"both", -expand=>1); $cw->{tabs}->{tags}->{$args{tag}}->{tabbar}->HideCanvas() if ($args{type} eq "docked"); $packframe = $cw->{tabs}->{tags}->{$args{tag}}->{tabbar}->AddTab(-type=>"undocked", -tag=>$args{tag}, -text=>$args{text}); $cw->{tabs}->{tags}->{$args{tag}}->{tabbar}->RaiseTab($args{tag}); $toplevel->wmCapture() if ($args{type} eq "docked"); $cw->{tabs}->{tags}->{$args{tag}}->{frame} = $toplevel; $cw->DeleteTab($args{tag},"undocked") if ($args{type} eq "undocked"); } if (($args{type} eq "fixed") || ($cw->{vars}->{Undocked} == 1)) { $packframe = $cw->{tabs}->{tags}->{$args{tag}}->{frame} = $cw->{frame}->Frame(-background=>$cw->{vars}->{Tabs}->{Background}); } #--------------------------------------------------------------------------- # Characterize the tab and get the height and width #--------------------------------------------------------------------------- $cw->CharacterizeTab($args{tag}); #--------------------------------------------------------------------------- # Now calculate the row and column number that the tab should have and # update the rows hash, and the tab info. #--------------------------------------------------------------------------- my $realRow; my $row; my $col; my $x; my $order = $cw->FindOrder($args{tag}); if ($order > 0) { $row = $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$order - 1]}->{row}; $realRow = $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$order - 1]}->{realRow}; } else { $row = 0; $realRow = 0; } my $rowWidth = $cw->{rows}->[$row]->{width}; my $canvasWidth = $cw->{canvas}->width(); $canvasWidth = $cw->{canvas}->reqwidth() if ($canvasWidth < 10); if (($rowWidth + $cw->{tabs}->{tags}->{$args{tag}}->{width}) > $canvasWidth) { $cw->{rows}->[$#{$cw->{rows}}+1]->{width} = $cw->{tabs}->{tags}->{$args{tag}}->{width}; $cw->{rows}->[$#{$cw->{rows}}]->{count} = 1; $row = $#{$cw->{rows}}; $realRow = $#{$cw->{rows}}; $col = 0; $x = 0; } else { $x = $cw->{rows}->[$row]->{width}; $cw->{rows}->[$row]->{width} += $cw->{tabs}->{tags}->{$args{tag}}->{width}; $cw->{rows}->[$row]->{count}++; $col = $cw->{rows}->[$row]->{count} - 1; } $cw->{tabs}->{tags}->{$args{tag}}->{row} = $row; $cw->{tabs}->{tags}->{$args{tag}}->{realRow} = $realRow; $cw->{tabs}->{tags}->{$args{tag}}->{col} = $col; $cw->{tabs}->{tags}->{$args{tag}}->{x} = $x; #print "($cw) AddTab: row($row) col($col) x($x)\n"; $cw->CharacterizeCanvas(); #--------------------------------------------------------------------------- # Draw the tabs if this is not an undocked window. #--------------------------------------------------------------------------- $cw->DrawTabs() if (($args{type} ne "undocked") || $cw->{vars}->{Undocked} == 1); #print "($cw) AddTab: finish\n"; #--------------------------------------------------------------------------- # Return the frame the user should use to pack everything into. #--------------------------------------------------------------------------- return $packframe; } sub RaiseFirstAvailable { my $cw = shift; my $tag = shift; if ($cw->FirstShown() eq $tag) { if ($#{$cw->{tabs}->{order}} == 0) { $cw->UnpackTab($tag); } else { $cw->RaiseTab($cw->SecondShown()) unless ($cw->SecondShown eq ""); } } else { $cw->RaiseTab($cw->FirstShown()); } } ########################################################################### # # # ########################################################################### sub DeleteTab { my($cw,$tag,$type) = @_; #print "($cw) DeleteTab: start\n"; #print "($cw) DeleteTab: tag($tag) type($type)\n"; $type = "" unless defined($type); return if !exists($cw->{tabs}->{tags}->{$tag}); if ($cw->Raised($tag)) { $cw->RaiseFirstAvailable($tag); } $cw->{canvas}->delete($tag); #--------------------------------------------------------------------------- # Now reposition the other tabs #--------------------------------------------------------------------------- #print "($cw) DeleteTab: from row($cw->{tabs}->{tags}->{$tag}->{row}) col($cw->{tabs}->{tags}->{$tag}->{col})\n"; my $canvasWidth = $cw->{canvas}->width(); $canvasWidth = $cw->{canvas}->reqwidth() if ($canvasWidth < 10); $cw->{rows}->[$cw->{tabs}->{tags}->{$tag}->{row}]->{count}--; $cw->{rows}->[$cw->{tabs}->{tags}->{$tag}->{row}]->{width} -= $cw->{tabs}->{tags}->{$tag}->{width}; my $order = $cw->FindOrder($tag); foreach my $index (($order+1)..$#{$cw->{tabs}->{order}}) { my $currTag = $cw->{tabs}->{order}->[$index]; my $oldRow = $cw->{tabs}->{tags}->{$currTag}->{row}; if ($oldRow == $cw->{tabs}->{tags}->{$tag}->{row}) { #print "($cw) DeleteTab: tag($currTag) is on the same row...\n"; #print "($cw) DeleteTab: moving tag($currTag) from col($cw->{tabs}->{tags}->{$currTag}->{col}) and x($cw->{tabs}->{tags}->{$currTag}->{x})\n"; $cw->{tabs}->{tags}->{$currTag}->{col}--; if ($index == ($order+1)) { $cw->{tabs}->{tags}->{$currTag}->{x} = $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$index-1]}->{x}; } else { $cw->{tabs}->{tags}->{$currTag}->{x} = $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$index-1]}->{x} + $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$index-1]}->{width}; } #print "($cw) to col($cw->{tabs}->{tags}->{$currTag}->{col}) and x($cw->{tabs}->{tags}->{$currTag}->{x})\n"; } else { #print "($cw) DeleteTab: tag($currTag) is not on the same row...\n"; #print "($cw) DeleteTab: tag($currTag) is in col($cw->{tabs}->{tags}->{$currTag}->{col})\n"; if ($cw->{tabs}->{tags}->{$currTag}->{col} == 0) { #print "($cw) DeleteTab: check if tag($currTag) can be moved to the previous row\n"; if (($cw->{rows}->[$oldRow-1]->{width} + $cw->{tabs}->{tags}->{$currTag}->{width}) < $canvasWidth) { #print "($cw) DeleteTab: it can...\n"; my $newRow = $oldRow - 1; #print "($cw) DeleteTab: moving tag($currTag) from row($oldRow) and col($cw->{tabs}->{tags}->{$currTag}->{col})\n"; $cw->{rows}->[$oldRow]->{count}--; $cw->{rows}->[$oldRow]->{width} -= $cw->{tabs}->{tags}->{$currTag}->{width}; $cw->{tabs}->{tags}->{$currTag}->{row}--; $cw->{tabs}->{tags}->{$currTag}->{realRow}--; $cw->{rows}->[$newRow]->{count}++; $cw->{tabs}->{tags}->{$currTag}->{col} = $cw->{rows}->[$newRow]->{count} - 1; $cw->{tabs}->{tags}->{$currTag}->{x} = $cw->{rows}->[$newRow]->{width}; $cw->{rows}->[$newRow]->{width} += $cw->{tabs}->{tags}->{$currTag}->{width}; #print "($cw) to row($newRow) and col($cw->{tabs}->{tags}->{$currTag}->{col})\n"; foreach my $i (($index+1)..$#{$cw->{tabs}->{order}}) { last if ($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{row} != $oldRow); #print "($cw) DeleteTab: moving tag($cw->{tabs}->{order}->[$i]) from col($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{col})\n"; $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{col}--; if ($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{col} == 0) { $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{x} = 0; } else { $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{x} = $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i-1]}->{x} + $cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i-1]}->{width}; } #print "($cw) to col($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$i]}->{col})\n"; } } } } } #--------------------------------------------------------------------------- # Clear out the emtpy rows and adjust the canvas settings #--------------------------------------------------------------------------- foreach my $j (reverse(0..$#{$cw->{rows}})) { splice(@{$cw->{rows}},$j,1) if ($cw->{rows}->[$j]->{count} == 0); } $cw->CharacterizeCanvas(); #--------------------------------------------------------------------------- # Remove this tag from the order #--------------------------------------------------------------------------- $order = $cw->FindOrder($tag); splice(@{$cw->{tabs}->{order}},$order,1); if ($type ne "undocked") { #print "($cw) DeleteTab: ok now let's free that memory...\n"; $cw->{tabs}->{tags}->{$tag}->{frame}->destroy(); #print "($cw) DeleteTab: killed the GUI...\n"; delete($cw->{tabs}->{tags}->{$tag}); #print "($cw) DeleteTab: killed the data...\n"; #print "($cw) DeleteTab: done freeing memory...\n"; } #--------------------------------------------------------------------------- # Redraw the tabs #--------------------------------------------------------------------------- $cw->DrawTabs(); #print "($cw) DeleteTab: finish\n"; } ########################################################################### # # # ########################################################################### sub RaiseTab { my ($cw,$tag,$raiseitanyway) = @_; return if ($tag eq ""); #print "($cw) RaiseTab: tag($tag) raiseitanyway($raiseitanyway)\n"; my $type = (exists($cw->{tabs}->{tags}->{$tag}->{type}) ? $cw->{tabs}->{tags}->{$tag}->{type} : $TYPES{fixed}); if ($type eq $TYPES{undocked}) { if ($#{$cw->{tabs}->{order}} > -1) { $tag = $cw->{tabs}->{order}->[0]; } else { $tag = ""; } } return if ($tag eq ""); $raiseitanyway = 0 if (!defined($raiseitanyway) || ($raiseitanyway eq "")); return if ($cw->Raised($tag) && ($raiseitanyway != 1)); $cw->{canvas}->itemconfigure("tabs",-fill=>$cw->{vars}->{Tabs}->{DisabledBackground}); $cw->{canvas}->itemconfigure("tab-$tag",-fill=>$cw->{vars}->{Tabs}->{Background}); $cw->{canvas}->raise("line"); $cw->{canvas}->raise($tag); #print "($cw) RaiseTab: before currentTab($cw->{vars}->{CurrentTab})\n"; $cw->UnpackTab($cw->{vars}->{CurrentTab}) if !($cw->Raised("")); $cw->{vars}->{CurrentTab} = $tag; $cw->PackTab($tag); #print "($cw) RaiseTab: after currentTab($cw->{vars}->{CurrentTab})\n"; $cw->UnhighlightTab($tag); if ($cw->{tabs}->{tags}->{$tag}->{row} != 0) { #print "($cw) RaiseTab: configure the positions...\n"; foreach my $tempTag (keys(%{$cw->{tabs}->{tags}})) { #print "($cw) RaiseTab: resetting tag($tempTag) from row($cw->{tabs}->{tags}->{$tempTag}->{row}) to row($cw->{tabs}->{tags}->{$tempTag}->{realRow})\n"; $cw->{tabs}->{tags}->{$tempTag}->{row} = $cw->{tabs}->{tags}->{$tempTag}->{realRow}; } my $row = $cw->{tabs}->{tags}->{$tag}->{row}; #print "($cw) RaiseTab: now raise the right row of tabs...\n"; foreach my $tempTag (keys(%{$cw->{tabs}->{tags}})) { if ($cw->{tabs}->{tags}->{$tempTag}->{row} < $row) { #print "($cw) RaiseTab: moving tag($tempTag) from row($cw->{tabs}->{tags}->{$tempTag}->{row})\n"; $cw->{tabs}->{tags}->{$tempTag}->{row} += 1; #print "($cw) to row($cw->{tabs}->{tags}->{$tempTag}->{row})\n"; } else { if ($cw->{tabs}->{tags}->{$tempTag}->{row} == $row) { #print "($cw) RaiseTab: moving tag($tempTag) from row($cw->{tabs}->{tags}->{$tempTag}->{row}) to row(0)\n"; $cw->{tabs}->{tags}->{$tempTag}->{row} = 0; } } } $cw->DrawTabs(0); } } sub Raised { my ($cw,$tag) = @_; return ($cw->{vars}->{CurrentTab} eq $tag); } sub ExistsTab { my ($cw,$tag) = @_; return exists($cw->{tabs}->{tags}->{$tag}); } ########################################################################### # # # ########################################################################### sub PackTab { my($cw,$tag) = @_; return if ($cw->{tabs}->{tags}->{$tag}->{hidden} == 1); $cw->{tabs}->{tags}->{$tag}->{frame}-> pack(-side=>'bottom', -padx=>0, -pady=>0, -ipadx=>$cw->{vars}->{Tabs}->{PadX}, -ipady=>$cw->{vars}->{Tabs}->{PadY}, -fill=>'both', -expand=>1); } ########################################################################### # # # ########################################################################### sub UnpackTab { my($cw,$tag) = @_; #print "($cw) UnpackTab: tag($tag)\n"; $cw->{tabs}->{tags}->{$tag}->{frame}->packForget(); } sub UnDockTab { my ($cw,$tag) = @_; #print "($cw) UnDockTab: tag($tag)\n"; $cw->{tabs}->{tags}->{$tag}->{frame}->wmRelease(); my $geom = $cw->geometry(); $geom =~ s/[\+\-]\d+[\+\-]\d+//; $cw->{tabs}->{tags}->{$tag}->{frame}->geometry($geom); $cw->{tabs}->{tags}->{$tag}->{frame}-> title($cw->{vars}->{UndockedTitlePrefix}." - ".$cw->{tabs}->{tags}->{$tag}->{text}); $cw->{tabs}->{tags}->{$tag}->{frame}->deiconify(); $cw->{tabs}->{tags}->{$tag}->{frame}->MapWindow(); $cw->{tabs}->{tags}->{$tag}->{tabbar}->ShowCanvas(); $cw->{tabs}->{tags}->{$tag}->{type} = $TYPES{undocked}; $cw->DeleteTab($tag,"undocked"); } sub DockTab { my ($cw,$tag) = @_; #print "($cw) DockTab: tag($tag)\n"; $cw->{tabs}->{tags}->{$tag}->{frame}->wmCapture(); $cw->{tabs}->{tags}->{$tag}->{tabbar}->HideCanvas(); $cw->AddTab(-type=>"docking", -tag=>$tag); $cw->RaiseTab($tag); } sub FirstShown { my ($cw) = @_; foreach my $index (0..$#{$cw->{tabs}->{order}}) { return $cw->{tabs}->{order}->[$index] if ($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$index]}->{hidden} == 0); } return 0; } sub SecondShown { my ($cw) = @_; my $count = 0; foreach my $index (0..$#{$cw->{tabs}->{order}}) { $count++ if ($cw->{tabs}->{tags}->{$cw->{tabs}->{order}->[$index]}->{hidden} == 0); return $cw->{tabs}->{order}->[$index] if ($count == 2); } return; } sub HideTab { my ($cw,$tag) = @_; # return if ($cw->{tabs}->{order}->[0] eq $tag); $cw->{tabs}->{tags}->{$tag}->{hidden} = 1; if ($cw->Raised($tag)) { $cw->RaiseTab($cw->FirstShown()); } $cw->Refresh(); } sub ShowTab { my ($cw,$tag) = @_; my $hidden = $cw->{tabs}->{tags}->{$tag}->{hidden}; $cw->{tabs}->{tags}->{$tag}->{hidden} = 0; $cw->Refresh(); $cw->RaiseTab($tag) if ($hidden == 1); } sub ShowCanvas { my ($cw) = @_; #print "($cw) ShowCanvas: showing\n"; $cw->{canvas}->pack(-side=>'top', -fill=>'both'); } sub HideCanvas { my ($cw) = @_; #print "($cw) HideCanvas: hiding\n"; $cw->{canvas}->packForget(); } sub HighlightTab { my ($cw,$tag,$priority) = @_; #print "($cw) HighlightTab: tag($tag) priority($priority)\n"; return if $cw->Raised($tag); #print "($cw) HighlightTab: tab is not raised... go ahead and highlight...\n"; $priority = "low" if (!defined($priority) || (($priority ne "low") && ($priority ne "medium") && ($priority ne "high")) ); my $priorityValue = $priority eq "low" ? 1 : ($priority eq "medium" ? 2 : 3); my $textFill = ($priority eq "low" ? $cw->{vars}->{Tabs}->{Highlight}->{Low} : ( $priority eq "medium" ? $cw->{vars}->{Tabs}->{Highlight}->{Medium} : $cw->{vars}->{Tabs}->{Highlight}->{High} ) ); my $highlight = (exists($cw->{tabs}->{tags}->{$tag}->{highlight}) ? $cw->{tabs}->{tags}->{$tag}->{highlight} : 0 ); if ($priorityValue > $highlight) { $cw->{canvas}->itemconfigure("text$tag",-fill=>$textFill); $cw->{tabs}->{tags}->{$tag}->{highlight} = $priorityValue; } } sub UnhighlightTab { my ($cw,$tag) = @_; $cw->{canvas}->itemconfigure("text$tag",-fill=>$cw->{vars}->{Tabs}->{Foreground}); delete($cw->{tabs}->{tags}->{$tag}->{highlight}); } sub FindOrder { my $cw = shift; my ($tag) = @_; foreach my $index (0..$#{$cw->{tabs}->{order}}) { return $index if ($cw->{tabs}->{order}->[$index] eq $tag); } } 1;