#include "TGTab.h"
#include "TGResourcePool.h"
#include "TList.h"
#include "Riostream.h"
#include "TClass.h"
#include "TGPicture.h"
const TGFont *TGTab::fgDefaultFont = 0;
const TGGC *TGTab::fgDefaultGC = 0;
ClassImp(TGTabElement)
ClassImp(TGTabLayout)
ClassImp(TGTab)
TGTabElement::TGTabElement(const TGWindow *p, TGString *text, UInt_t w, UInt_t h,
GContext_t norm, FontStruct_t font,
UInt_t options, ULong_t back) :
TGFrame(p, w, h, options, back)
{
fClosePic = 0;
fClosePicD = 0;
fShowClose = kFALSE;
fActive = kFALSE;
fText = text;
fBorderWidth = 0;
fNormGC = norm;
fFontStruct = font;
fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable;
fClosePic = fClient->GetPicture("closetab.png");
fClosePicD = fClient->GetPicture("closetab_d.png");
int max_ascent, max_descent;
if (fText)
fTWidth = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
fTHeight = max_ascent + max_descent;
Resize(TMath::Max(fTWidth+12, (UInt_t)45), fTHeight+6);
fEnabled = kTRUE;
gVirtualX->GrabButton(fId, kButton1, kAnyModifier, kButtonPressMask, kNone, kNone);
}
TGTabElement::~TGTabElement()
{
if (fClosePic) gClient->FreePicture(fClosePic);
if (fClosePicD) gClient->FreePicture(fClosePicD);
if (fText) delete fText;
}
void TGTabElement::DrawBorder()
{
gVirtualX->DrawLine(fId, GetHilightGC()(), 0, fHeight-1, 0, 2);
gVirtualX->DrawLine(fId, GetHilightGC()(), 0, 2, 2, 0);
gVirtualX->DrawLine(fId, GetHilightGC()(), 2, 0, fWidth-3, 0);
gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-2, 1, fWidth-2, fHeight-1);
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth-2, 1, fWidth-1, 2);
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth-1, 2, fWidth-1, fHeight-2);
gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-1, fHeight-1, fWidth-1, fHeight-1);
if (fText) {
int max_ascent, max_descent;
gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
if (fEnabled) {
fText->Draw(fId, fNormGC, 6, max_ascent+3);
} else {
fText->Draw(fId, GetHilightGC()(), 7, max_ascent + 1);
fText->Draw(fId, GetShadowGC()(), 6, max_ascent);
}
}
if (fShowClose && fClosePic && fClosePicD) {
if (fEnabled && fActive)
fClosePic->Draw(fId, fNormGC, fTWidth+12, fHeight/2-7);
else
fClosePicD->Draw(fId, fNormGC, fTWidth+12, fHeight/2-7);
}
}
Bool_t TGTabElement::HandleButton(Event_t *event)
{
if (event->fType == kButtonPress) {
TGTab* main = (TGTab*)fParent;
if (main) {
if (fShowClose && event->fWindow == GetId() &&
(UInt_t)event->fX > fTWidth+12 && (UInt_t)event->fX < fTWidth+26 &&
(UInt_t)event->fY > fHeight/2-7 && (UInt_t)event->fY < fHeight/2+7) {
if (main->GetTabTab(main->GetCurrent()) == this) {
main->CloseTab(main->GetCurrent());
return kTRUE;
}
}
TGFrameElement *el;
TIter next(main->GetList());
next();
Int_t i = 0;
Int_t c = main->GetCurrent();
while ((el = (TGFrameElement *) next())) {
if (el->fFrame->GetId() == (Window_t)event->fWindow)
c = i;
next(); i++;
}
main->SetTab(c);
}
}
return kTRUE;
}
TGDimension TGTabElement::GetDefaultSize() const
{
if (fShowClose && fClosePic && fClosePicD)
return TGDimension(TMath::Max(fTWidth+30, (UInt_t)45), fTHeight+6);
else
return TGDimension(TMath::Max(fTWidth+12, (UInt_t)45), fTHeight+6);
}
void TGTabElement::SetText(TGString *text)
{
if (fText) delete fText;
fText = text;
int max_ascent, max_descent;
fTWidth = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
fTHeight = max_ascent + max_descent;
fClient->NeedRedraw(this);
}
void TGTabElement::ShowClose(Bool_t show)
{
TGTab* main = (TGTab*)fParent;
fShowClose = show;
if (fShowClose && fClosePic && fClosePicD)
Resize(TMath::Max(fTWidth+30, (UInt_t)45), fTHeight+6);
else
Resize(TMath::Max(fTWidth+12, (UInt_t)45), fTHeight+6);
if (main)
main->GetLayoutManager()->Layout();
}
TGTabLayout::TGTabLayout(TGTab *main)
{
fMain = main;
fList = fMain->GetList();
}
void TGTabLayout::Layout()
{
Int_t i, xtab;
UInt_t tw;
UInt_t tabh = fMain->GetTabHeight(), bw = fMain->GetBorderWidth();
UInt_t w = fMain->GetWidth();
UInt_t h = fMain->GetHeight();
xtab = 2;
fMain->GetContainer()->MoveResize(0, tabh, w, h - tabh);
TGFrameElement *el, *elnxt;
TIter next(fList);
i = 0;
next();
while ((el = (TGFrameElement *) next())) {
elnxt = (TGFrameElement *) next();
tw = el->fFrame->GetDefaultWidth();
if (i == fMain->GetCurrent()) {
el->fFrame->MoveResize(xtab-2, 0, tw+3, tabh+1);
elnxt->fFrame->RaiseWindow();
el->fFrame->RaiseWindow();
} else {
el->fFrame->MoveResize(xtab, 2, tw, tabh-1);
el->fFrame->LowerWindow();
}
UInt_t nw = (w - (bw << 1));
if (nw > 32768) nw = 1;
UInt_t nh = (h - tabh - (bw << 1));
if (nh > 32768) nh = 1;
elnxt->fFrame->MoveResize(bw, tabh + bw, nw, nh);
elnxt->fFrame->Layout();
xtab += (Int_t)tw;
i++;
}
}
TGDimension TGTabLayout::GetDefaultSize() const
{
TGDimension dsize, dsize_te;
TGDimension size(0,0), size_te(0,0);
TGFrameElement *el, *elnxt;
TIter next(fList);
next();
while ((el = (TGFrameElement *)next())) {
dsize_te = el->fFrame->GetDefaultSize();
size_te.fWidth += dsize_te.fWidth;
elnxt = (TGFrameElement *) next();
dsize = elnxt->fFrame->GetDefaultSize();
if (size.fWidth < dsize.fWidth) size.fWidth = dsize.fWidth;
if (size.fHeight < dsize.fHeight) size.fHeight = dsize.fHeight;
}
if (size.fWidth < size_te.fWidth) size.fWidth = size_te.fWidth;
size.fWidth += fMain->GetBorderWidth() << 1;
size.fHeight += fMain->GetTabHeight() + (fMain->GetBorderWidth() << 1);
return size;
}
TGTab::TGTab(const TGWindow *p, UInt_t w, UInt_t h,
GContext_t norm, FontStruct_t font,
UInt_t options, ULong_t back) :
TGCompositeFrame(p, w, h, options, back)
{
fMsgWindow = p;
fBorderWidth = 2;
fCurrent = 0;
fRemoved = new TList;
fNormGC = norm;
fFontStruct = font;
int max_ascent, max_descent;
gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
fTabh = max_ascent + max_descent + 6;
SetLayoutManager(new TGTabLayout(this));
fContainer = new TGCompositeFrame(this, fWidth, fHeight - fTabh,
kVerticalFrame | kRaisedFrame | kDoubleBorder);
AddFrame(fContainer, 0);
fEditDisabled = kEditDisable | kEditDisableLayout;
fContainer->SetEditDisabled(kEditDisable | kEditDisableGrab);
}
TGTab::~TGTab()
{
Cleanup();
fRemoved->Delete();
delete fRemoved;
}
TGCompositeFrame *TGTab::AddTab(TGString *text)
{
TGTabElement *te = new TGTabElement(this, text, 50, 20, fNormGC, fFontStruct);
AddFrame(te, 0);
TGCompositeFrame* cf = new TGCompositeFrame(this, fWidth, fHeight-21);
AddFrame(cf, 0);
cf->SetEditDisabled(kEditDisableResize);
te->MapWindow();
cf->MapWindow();
return cf;
}
TGCompositeFrame *TGTab::AddTab(const char *text)
{
return AddTab(new TGString(text));
}
void TGTab::AddTab(const char *text, TGCompositeFrame *cf)
{
AddTab(new TGString(text), cf);
}
void TGTab::AddTab(TGString *text, TGCompositeFrame *cf)
{
TGTabElement *te = new TGTabElement(this, text, 50, 20, fNormGC, fFontStruct);
AddFrame(te, 0);
AddFrame(cf, 0);
cf->SetEditDisabled(kEditDisableResize);
te->MapWindow();
cf->MapWindow();
}
void TGTab::RemoveTab(Int_t tabIndex, Bool_t storeRemoved)
{
if (tabIndex < 0) {
tabIndex = fCurrent;
}
TGFrameElement *elTab, *elCont;
Int_t count = 0;
Removed(tabIndex);
TIter next(fList) ;
next() ;
while ((elTab = (TGFrameElement *) next())) {
elCont = (TGFrameElement *) next();
if (count == tabIndex) {
elCont->fFrame->UnmapWindow();
TGFrame *frame = elTab->fFrame;
RemoveFrame(elTab->fFrame);
frame->DestroyWindow();
delete frame;
if (storeRemoved)
fRemoved->Add(elCont->fFrame);
RemoveFrame(elCont->fFrame);
if (tabIndex == fCurrent) {
SetTab(0);
} else
fCurrent--;
break;
}
count++;
}
GetLayoutManager()->Layout();
}
void TGTab::SetEnabled(Int_t tabIndex, Bool_t on)
{
TGTabElement *te = GetTabTab(tabIndex);
if (te) {
te->SetEnabled(on);
fClient->NeedRedraw(te);
}
}
Bool_t TGTab::IsEnabled(Int_t tabIndex) const
{
TGTabElement *te = GetTabTab(tabIndex);
return te ? te->IsEnabled() : kFALSE;
}
void TGTab::ChangeTab(Int_t tabIndex, Bool_t emit)
{
TGTabElement *te = GetTabTab(tabIndex);
if (!te || !te->IsEnabled()) return;
if (tabIndex != fCurrent) {
if (GetTabTab(fCurrent)) {
GetTabTab(fCurrent)->SetActive(kFALSE);
fClient->NeedRedraw(GetTabTab(fCurrent));
}
TGFrameElement *el, *elnxt;
UInt_t tw;
Int_t xtab = 2;
Int_t count = 0;
TIter next(fList);
next();
fCurrent = tabIndex;
while ((el = (TGFrameElement *) next())) {
elnxt = (TGFrameElement *) next();
tw = el->fFrame->GetDefaultWidth();
if (count == fCurrent) {
el->fFrame->MoveResize(xtab-2, 0, tw+3, fTabh+1);
elnxt->fFrame->RaiseWindow();
el->fFrame->RaiseWindow();
} else {
el->fFrame->MoveResize(xtab, 2, tw, fTabh-1);
el->fFrame->LowerWindow();
}
xtab += tw;
count++;
}
if (emit) {
SendMessage(fMsgWindow, MK_MSG(kC_COMMAND, kCM_TAB), fCurrent, 0);
fClient->ProcessLine(fCommand, MK_MSG(kC_COMMAND, kCM_TAB), fCurrent, 0);
Selected(fCurrent);
}
GetTabTab(fCurrent)->SetActive(kTRUE);
fClient->NeedRedraw(GetTabTab(fCurrent));
}
}
Bool_t TGTab::SetTab(Int_t tabIndex, Bool_t emit)
{
if (tabIndex < 0)
return kFALSE;
TIter next(fList);
Int_t count = 0;
while (next())
count++;
count = count / 2 - 1;
if (tabIndex > count)
return kFALSE;
ChangeTab(tabIndex, emit);
return kTRUE;
}
Bool_t TGTab::SetTab(const char *name, Bool_t emit)
{
TGFrameElement *el;
Int_t count = 0;
TGTabElement *tab = 0;
TIter next(fList);
next();
while ((el = (TGFrameElement *) next())) {
next();
tab = (TGTabElement *)el->fFrame;
if (*(tab->GetText()) == name) {
ChangeTab(count, emit);
return kTRUE;
}
count++;
}
return kFALSE;
}
TGCompositeFrame *TGTab::GetTabContainer(Int_t tabIndex) const
{
if (tabIndex < 0) return 0;
TGFrameElement *el;
Int_t count = 0;
TIter next(fList);
next();
while (next()) {
el = (TGFrameElement *) next();
if (count == tabIndex)
return (TGCompositeFrame *) el->fFrame;
count++;
}
return 0;
}
TGCompositeFrame *TGTab::GetTabContainer(const char *name) const
{
TGFrameElement *el;
TGTabElement *tab = 0;
TGCompositeFrame *comp = 0;
TIter next(fList);
next();
while ((el = (TGFrameElement *) next())) {
tab = (TGTabElement *) el->fFrame;
el = (TGFrameElement *) next();
comp = (TGCompositeFrame *) el->fFrame;
if (*tab->GetText() == name){
return comp;
}
}
return 0;
}
TGTabElement *TGTab::GetTabTab(Int_t tabIndex) const
{
if (tabIndex < 0) return 0;
TGFrameElement *el;
Int_t count = 0;
TIter next(fList);
next();
while ((el = (TGFrameElement *) next())) {
next();
if (count == tabIndex)
return (TGTabElement *) el->fFrame;
count++;
}
return 0;
}
TGTabElement *TGTab::GetTabTab(const char *name) const
{
TGFrameElement *el;
TGTabElement *tab = 0;
TIter next(fList);
next();
while ((el = (TGFrameElement *) next())) {
tab = (TGTabElement *)el->fFrame;
if (name == *(tab->GetText())) {
return tab;
}
next();
}
return tab;
}
Int_t TGTab::GetNumberOfTabs() const
{
Int_t count = 0;
TIter next(fList);
next();
while (next()) {
next();
count++;
}
return count;
}
FontStruct_t TGTab::GetDefaultFontStruct()
{
if (!fgDefaultFont)
fgDefaultFont = gClient->GetResourcePool()->GetDefaultFont();
return fgDefaultFont->GetFontStruct();
}
const TGGC &TGTab::GetDefaultGC()
{
if (!fgDefaultGC)
fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
return *fgDefaultGC;
}
void TGTab::NewTab(const char *text)
{
TString name;
if (text)
name = text;
else
name = TString::Format("tab%d", GetNumberOfTabs()+1);
AddTab(name.Data());
GetLayoutManager()->Layout();
}
void TGTab::SetText(const char *text)
{
GetCurrentTab()->SetText(new TGString(text));
GetLayoutManager()->Layout();
}
TGLayoutManager *TGTab::GetLayoutManager() const
{
TGTab *tab = (TGTab*)this;
if (tab->fLayoutManager->IsA() != TGTabLayout::Class()) {
tab->SetLayoutManager(new TGTabLayout(tab));
}
return tab->fLayoutManager;
}
void TGTab::SavePrimitive(ostream &out, Option_t *option )
{
char quote = '"';
option = GetName()+5;
char parGC[50], parFont[50];
sprintf(parFont,"%s::GetDefaultFontStruct()",IsA()->GetName());
sprintf(parGC,"%s::GetDefaultGC()()",IsA()->GetName());
if ((GetDefaultFontStruct() != fFontStruct) || (GetDefaultGC()() != fNormGC)) {
TGFont *ufont = gClient->GetResourcePool()->GetFontPool()->FindFont(fFontStruct);
if (ufont) {
ufont->SavePrimitive(out, option);
sprintf(parFont,"ufont->GetFontStruct()");
}
TGGC *userGC = gClient->GetResourcePool()->GetGCPool()->FindGC(fNormGC);
if (userGC) {
userGC->SavePrimitive(out, option);
sprintf(parGC,"uGC->GetGC()");
}
}
if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
out << endl << " // tab widget" << endl;
out << " TGTab *";
out << GetName() << " = new TGTab(" << fParent->GetName()
<< "," << GetWidth() << "," << GetHeight();
if (fBackground == GetDefaultFrameBackground()) {
if (GetOptions() == kChildFrame) {
if (fFontStruct == GetDefaultFontStruct()) {
if (fNormGC == GetDefaultGC()()) {
out <<");" << endl;
} else {
out << "," << parGC <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont << "," << GetOptionString() <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont << "," << GetOptionString() << ",ucolor);" << endl;
}
TGCompositeFrame *cf;
TGLayoutManager * lm;
for (Int_t i=0; i<GetNumberOfTabs(); i++) {
cf = GetTabContainer(i);
out << endl << " // container of " << quote
<< GetTabTab(i)->GetString() << quote << endl;
out << " TGCompositeFrame *" << cf->GetName() << ";" << endl;
out << " " << cf->GetName() << " = " << GetName()
<< "->AddTab(" << quote << GetTabTab(i)->GetString()
<< quote << ");" << endl;
lm = cf->GetLayoutManager();
if (lm) {
if ((cf->GetOptions() & kHorizontalFrame) &&
(lm->InheritsFrom(TGHorizontalLayout::Class()))) {
;
} else if ((GetOptions() & kVerticalFrame) &&
(lm->InheritsFrom(TGVerticalLayout::Class()))) {
;
} else {
out << " " << cf->GetName() <<"->SetLayoutManager(";
lm->SavePrimitive(out, option);
out << ");" << endl;
}
if (!IsEnabled(i)) {
out << " " << GetName() << "->SetEnabled(" << i << ", kFALSE);" << endl;
}
}
cf->SavePrimitiveSubframes(out, option);
if (GetTabTab(i)->IsCloseShown()) {
out << " TGTabElement *tab" << i << " = "
<< GetName() << "->GetTabTab(" << i << ");" << endl;
out << " tab" << i << "->ShowClose(kTRUE);" << endl;
}
if (GetTabTab(i)->GetBackground() != GetTabTab(i)->GetDefaultFrameBackground()) {
GetTabTab(i)->SaveUserColor(out, option);
out << " TGTabElement *tab" << i << " = "
<< GetName() << "->GetTabTab(" << i << ");" << endl;
out << " tab" << i << "->ChangeBackground(ucolor);" << endl;
}
}
out << endl << " " << GetName() << "->SetTab(" << GetCurrent() << ");" << endl;
out << endl << " " << GetName() << "->Resize(" << GetName()
<< "->GetDefaultSize());" << endl;
}
void TGTabLayout::SavePrimitive(ostream &out, Option_t * )
{
out << "new TGTabLayout(" << fMain->GetName() << ")";
}