#include "TGButtonGroup.h"
#include "TGButton.h"
#include "TClass.h"
#include "TGLayout.h"
#include "TList.h"
#include "TGResourcePool.h"
#include "Riostream.h"
ClassImp(TGButtonGroup)
ClassImp(TGHButtonGroup)
ClassImp(TGVButtonGroup)
TGButtonGroup::TGButtonGroup(const TGWindow *parent,
const TString &title,
UInt_t options,
GContext_t norm,
FontStruct_t font,
ULong_t back) :
TGGroupFrame(parent, new TGString(title), options, norm, font, back)
{
Init();
if (options & kVerticalFrame) {
SetLayoutManager(new TGVerticalLayout(this));
} else {
SetLayoutManager(new TGHorizontalLayout(this));
}
fDrawBorder = !title.IsNull();
}
TGButtonGroup::TGButtonGroup(const TGWindow *parent,
UInt_t r, UInt_t c,
Int_t s, Int_t h,
const TString &title,
GContext_t norm ,
FontStruct_t font ,
ULong_t back) :
TGGroupFrame(parent, new TGString(title), 0, norm, font, back)
{
Init();
fDrawBorder = !title.IsNull();
SetLayoutManager(new TGMatrixLayout(this,r,c,s,h));
}
void TGButtonGroup::Init()
{
fState = kTRUE;
fMapOfButtons = new TMap();
fExclGroup = kFALSE;
fRadioExcl = kFALSE;
fDrawBorder = kTRUE;
SetWindowName();
}
TGButtonGroup::~TGButtonGroup()
{
TIter next(fMapOfButtons);
register TGButton *item = 0;
while ((item = (TGButton*)next())) {
item->SetGroup(0);
}
SafeDelete(fMapOfButtons);
}
void TGButtonGroup::DoRedraw()
{
gVirtualX->ClearArea(fId, 0, 0, fWidth, fHeight);
DrawBorder();
}
void TGButtonGroup::DrawBorder()
{
if (!fDrawBorder) return;
Int_t x, y, l, t, r, b, gl, gr, sep, max_ascent, max_descent;
UInt_t tw = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
l = 0;
t = (max_ascent + max_descent + 2) >> 1;
r = fWidth - 1;
TGLayoutManager * lm = GetLayoutManager();
if ((lm->InheritsFrom(TGHorizontalLayout::Class())) ||
(lm->InheritsFrom(TGMatrixLayout::Class())))
b = fHeight - 1;
else
b = fHeight - t;
sep = 3;
UInt_t rr = 5 + (sep << 1) + tw;
switch (fTitlePos) {
case kRight:
gl = fWidth>rr ? fWidth - rr : 5 + sep;
break;
case kCenter:
gl = fWidth>tw ? ((fWidth - tw)>>1) - sep : 5 + sep;
break;
case kLeft:
default:
gl = 5 + sep;
}
gr = gl + tw + (sep << 1);
switch (fOptions & (kSunkenFrame | kRaisedFrame)) {
case kRaisedFrame:
gVirtualX->DrawLine(fId, GetHilightGC()(), l, t, gl, t);
gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, t+1, gl, t+1);
gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t, r-1, t);
gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t+1, r-2, t+1);
gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, t, r-1, b-1);
gVirtualX->DrawLine(fId, GetShadowGC()(), r, t, r, b);
gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, b-1, l, b-1);
gVirtualX->DrawLine(fId, GetShadowGC()(), r, b, l, b);
gVirtualX->DrawLine(fId, GetHilightGC()(), l, b-1, l, t);
gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, b-2, l+1, t+1);
break;
case kSunkenFrame:
default:
gVirtualX->DrawLine(fId, GetShadowGC()(), l, t, gl, t);
gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, t+1, gl, t+1);
gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t, r-1, t);
gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t+1, r-2, t+1);
gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, t, r-1, b-1);
gVirtualX->DrawLine(fId, GetHilightGC()(), r, t, r, b);
gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, b-1, l, b-1);
gVirtualX->DrawLine(fId, GetHilightGC()(), r, b, l, b);
gVirtualX->DrawLine(fId, GetShadowGC()(), l, b-1, l, t);
gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, b-2, l+1, t+1);
break;
}
x = gl + sep;
y = 1;
if (fState) {
fText->Draw(fId, fNormGC, x, y + max_ascent);
} else {
fText->Draw(fId, GetHilightGC()(), x, y + 1 + max_ascent);
fText->Draw(fId, GetShadowGC()(), x, y + max_ascent);
}
}
void TGButtonGroup::SetBorderDrawn(Bool_t enable)
{
if (enable != IsBorderDrawn()) {
fDrawBorder = enable;
ChangedBy("SetBorderDrawn");
}
}
void TGButtonGroup::SetExclusive(Bool_t enable)
{
if (enable != IsExclusive()) {
fExclGroup = enable;
ChangedBy("SetExclusive");
}
}
void TGButtonGroup::SetRadioButtonExclusive(Bool_t enable)
{
if (enable != IsRadioButtonExclusive()) {
fRadioExcl = enable;
ChangedBy("SetRadioButtonExclusive");
}
}
void TGButtonGroup::SetState(Bool_t state)
{
fState = state;
TIter next(fMapOfButtons);
register TGButton *item = 0;
while ((item = (TGButton*)next())) {
if (state) {
item->SetState(kButtonUp);
} else {
item->SetState(kButtonDisabled);
}
}
DoRedraw();
}
void TGButtonGroup::SetButton(Int_t id, Bool_t down)
{
TGButton *b = Find(id);
if (b && (b->IsDown() != down)) {
b->SetState(kButtonDown, kTRUE);
}
}
Int_t TGButtonGroup::Insert(TGButton *button, Int_t id)
{
if (button->fGroup && button->fGroup != this)
button->fGroup->Remove(button);
if (button->fGroup == this) {
if (id == -1)
return GetId(button);
else
button->fGroup->Remove(button);
}
button->fGroup = this;
button->Associate(this);
static Int_t seq_no = -2;
Long_t bid;
if (id < -1) bid = seq_no--;
else if (id == -1) bid = GetCount()+1;
else bid = id;
fMapOfButtons->Add(button, (TObject*)bid);
AddFrame(button);
SetRadioButtonExclusive(button->IsA()->InheritsFrom(TGRadioButton::Class()));
Connect(button, "Clicked()" , "TGButtonGroup", this, "ReleaseButtons()");
Connect(button, "Pressed()" , "TGButtonGroup", this, "ButtonPressed()");
Connect(button, "Released()", "TGButtonGroup", this, "ButtonReleased()");
Connect(button, "Clicked()" , "TGButtonGroup", this, "ButtonClicked()");
return (Int_t) bid;
}
void TGButtonGroup::Remove(TGButton *button)
{
TGButton *item = (TGButton*) fMapOfButtons->Remove(button);
if (item) {
button->SetGroup(0);
button->Disconnect(this);
button->DestroyWindow();
}
RemoveFrame(button);
}
TGButton *TGButtonGroup::Find(Int_t id) const
{
TIter next(fMapOfButtons);
register TGButton *item = 0;
while ((item = (TGButton*)next())) {
if ((Long_t)fMapOfButtons->GetValue(item) == id) break;
}
return item;
}
Int_t TGButtonGroup::GetId(TGButton *button) const
{
TPair *a = (TPair*) fMapOfButtons->FindObject(button);
if (a)
return (Int_t)Long_t(a->Value());
else
return -1;
}
void TGButtonGroup::ButtonPressed()
{
#if 0
TGButton *btn = dynamic_cast<TGButton*>((TQObject*)gTQSender);
if (!btn) {
Error("ButtonPressed", "gTQSender not a TGButton");
return;
}
#else
TGButton *btn = (TGButton*)gTQSender;
#endif
TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
if (a) {
Int_t id = (Int_t)Long_t(a->Value());
Pressed(id);
}
}
void TGButtonGroup::ButtonReleased()
{
TGButton *btn = (TGButton*)gTQSender;
TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
if (a) {
Int_t id = (Int_t)Long_t(a->Value());
Released(id);
}
}
void TGButtonGroup::ButtonClicked()
{
TGButton *btn = (TGButton*)gTQSender;
TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
if (a) {
Int_t id = (Int_t)Long_t(a->Value());
Clicked(id);
}
}
void TGButtonGroup::ReleaseButtons()
{
if (!fExclGroup && !fRadioExcl) return;
TGButton *btn = (TGButton*)gTQSender;
if (!fExclGroup && !btn)
return;
TIter next(fMapOfButtons);
register TGButton *item = 0;
while ((item = (TGButton*)next())) {
if (btn != item && item->IsToggleButton() && item->IsOn() &&
(fExclGroup || (item->IsA()->InheritsFrom(TGRadioButton::Class())
&& btn->IsA()->InheritsFrom(TGRadioButton::Class())))) {
item->SetOn(kFALSE);
}
}
}
void TGButtonGroup::Show()
{
MapSubwindows();
Resize();
MapRaised();
fClient->NeedRedraw(this);
}
void TGButtonGroup::Hide()
{
UnmapWindow();
}
void TGButtonGroup::SetTitle(TGString *title)
{
if (!title) {
Error("SetTitle", "title cannot be 0, try \"\"");
return;
}
if (strcmp(fText->GetString(), title->GetString())) {
SetBorderDrawn(title->GetLength() ? kTRUE : kFALSE);
TGGroupFrame::SetTitle(title);
ChangedBy("SetTitle");
}
}
void TGButtonGroup::SetTitle(const char *title)
{
if (!title) {
Error("SetTitle", "title cannot be 0, try \"\"");
return;
}
if (strcmp(fText->GetString(), title)) {
SetBorderDrawn(title && strlen(title));
TGGroupFrame::SetTitle(title);
ChangedBy("SetTitle");
}
}
void TGButtonGroup::SetLayoutHints(TGLayoutHints *l, TGButton *button)
{
TGFrameElement *el;
TIter next(fList);
while ((el = (TGFrameElement *)next())) {
if ((el->fFrame==(TGFrame*)button) || !button) {
el->fLayout = l ? l : fgDefaultHints;
}
}
Layout();
}
void TGButtonGroup::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 << " // buttongroup frame" << endl;
out << " TGButtonGroup *";
out << GetName() << " = new TGButtonGroup(" << fParent->GetName()
<< ","<< quote << fText->GetString() << quote;
if (fBackground == GetDefaultFrameBackground()) {
if (fFontStruct == GetDefaultFontStruct()) {
if (fNormGC == GetDefaultGC()()) {
if (!GetOptions()) {
out <<");" << endl;
} else {
out << "," << GetOptionString() <<");" << endl;
}
} else {
out << "," << GetOptionString() << "," << parGC <<");" << endl;
}
} else {
out << "," << GetOptionString() << "," << parGC << "," << parFont <<");" << endl;
}
} else {
out << "," << GetOptionString() << "," << parGC << "," << parFont << ",ucolor);" << endl;
}
out << " " << GetName() <<"->SetLayoutManager(";
GetLayoutManager()->SavePrimitive(out, option);
out << ");"<< endl;
TGFrameElement *f;
TIter next(GetList());
while ((f = (TGFrameElement *)next())) {
f->fFrame->SavePrimitive(out,option);
if (f->fFrame->InheritsFrom("TGButton")) continue;
else {
out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
f->fLayout->SavePrimitive(out, option);
out << ");"<< endl;
}
}
if (IsExclusive())
out << " " << GetName() <<"->SetExclusive(kTRUE);" << endl;
if (IsRadioButtonExclusive())
out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << endl;
if (!IsBorderDrawn())
out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << endl;
out << " " << GetName() << "->Resize(" << GetWidth()
<< "," << GetHeight() << ");" << endl;
if (!IsEnabled())
out << " " << GetName() <<"->SetState(kFALSE);" << endl;
out << " " << GetName() << "->Show();" << endl;
}
void TGHButtonGroup::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 << " // horizontal buttongroup frame" << endl;
out << " TGHButtonGroup *";
out << GetName() << " = new TGHButtonGroup(" << fParent->GetName()
<< "," << quote << fText->GetString() << quote;
if (fBackground == GetDefaultFrameBackground()) {
if (fFontStruct == GetDefaultFontStruct()) {
if (fNormGC == GetDefaultGC()()) {
out << ");" << endl;
} else {
out << "," << parGC <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont << ",ucolor);" << endl;
}
TGFrameElement *f;
TIter next(GetList());
while ((f = (TGFrameElement *)next())) {
f->fFrame->SavePrimitive(out,option);
if (f->fFrame->InheritsFrom("TGButton")){
out << " " << GetName() << "->SetLayoutHints(";
f->fLayout->SavePrimitive(out, "nocoma");
out << "," << f->fFrame->GetName();
out << ");"<< endl;
}
else {
out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
f->fLayout->SavePrimitive(out, option);
out << ");"<< endl;
}
}
if (!IsEnabled())
out << " " << GetName() <<"->SetState(kFALSE);" << endl;
if (IsExclusive())
out << " " << GetName() <<"->SetExclusive(kTRUE);" << endl;
if (IsRadioButtonExclusive())
out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << endl;
if (!IsBorderDrawn())
out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << endl;
out << " " << GetName() <<"->Resize(" << GetWidth() << ","
<< GetHeight() << ");" << endl;
out << " " << GetName() << "->Show();" << endl;
}
void TGVButtonGroup::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 << " // vertical buttongroup frame" << endl;
out << " TGVButtonGroup *";
out << GetName() << " = new TGVButtonGroup(" << fParent->GetName()
<< "," << quote << fText->GetString() << quote;
if (fBackground == GetDefaultFrameBackground()) {
if (fFontStruct == GetDefaultFontStruct()) {
if (fNormGC == GetDefaultGC()()) {
out <<");" << endl;
} else {
out << "," << parGC <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont <<");" << endl;
}
} else {
out << "," << parGC << "," << parFont << ",ucolor);" << endl;
}
TGFrameElement *f;
TIter next(GetList());
while ((f = (TGFrameElement *)next())) {
f->fFrame->SavePrimitive(out,option);
if (f->fFrame->InheritsFrom("TGButton")) continue;
else {
out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
f->fLayout->SavePrimitive(out, option);
out << ");"<< endl;
}
}
if (!IsEnabled())
out << " " << GetName() <<"->SetState(kFALSE);" << endl;
if (IsExclusive())
out << " " << GetName() <<"->SetExclusive(kTRUE);" << endl;
if (IsRadioButtonExclusive())
out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << endl;
if (!IsBorderDrawn())
out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << endl;
out << " " << GetName() << "->Resize(" << GetWidth()
<< "," << GetHeight() << ");"<< endl;
out << " " << GetName() << "->Show();" << endl;
}