Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGButtonGroup.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Valeriy Onuchin & Fons Rademakers 16/10/2000
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // The TGButtonGroup widget organizes TGButton widgets in a group. //
15 // //
16 // A button group widget makes it easier to deal with groups of buttons.//
17 // A button in a button group is associated with a unique identifier. //
18 // The button group emits a Clicked() signal with this identifier when //
19 // the button is clicked. Thus, a button group is an ideal solution //
20 // when you have several similar buttons and want to connect all their //
21 // Clicked() signals, for example, to one slot. //
22 // //
23 // An exclusive button group switches off all toggle buttons except //
24 // the one that was clicked. A button group is by default non-exclusive.//
25 // All radio buttons that are inserted, will be mutually exclusive even //
26 // if the button group is non-exclusive. //
27 // //
28 // //
29 // There are two ways of using a button group: //
30 // //
31 // The button group is a parent widget of a number of buttons, //
32 // i.e. the button group is the parent argument in the button //
33 // constructor. The buttons are assigned identifiers 1, 2, 3 etc. //
34 // in the order they are created or you can specify button id in //
35 // the button constructor. A TGButtonGroup can display a frame and //
36 // a title because it inherits from TGGroupFrame. //
37 // //
38 // Example: //
39 // //
40 // // vertical frame without border and title //
41 // TGVButtonGroup *bg = new TGVButtonGroup(main_frame); //
42 // //
43 // // create text button with id=1 //
44 // TGTextButton *button1 = new TGTextButton(bg,"some text"); //
45 // //
46 // // create another text button with id=2 //
47 // TGTextButton *button2 = new TGTextButton(bg,"another text"); //
48 // //
49 // // map all buttons //
50 // bg->Show(); //
51 // //
52 // NOTE: there is no need to call AddFrame() since the buttons are //
53 // automatically added with a default layout hint to their parent, //
54 // i.e. the buttongroup. To override the default layout hints use the //
55 // SetLayoutHints() method. //
56 // //
57 // ButtonGroup Signals: //
58 // //
59 // Pressed(Int_t id) --> is emitted when a button in the group is //
60 // pressed down. The id argument is the //
61 // button's identifier. //
62 // Released(Int_t id) --> is emitted when a button in the group is //
63 // released. The id argument is the button's //
64 // identifier. //
65 // Clicked(Int_t id) --> is emitted when a button in the group is //
66 // clicked. The id argument is the button's //
67 // identifier. //
68 // //
69 // //
70 // The TGHButtonGroup widget organizes TGButton widgets in a group //
71 // with one horizontal row. TGHButtonGroup is a convenience class that //
72 // offers a thin layer on top of TGButtonGroup. It inherits from //
73 // TGButtonGroup. //
74 // //
75 // The TGVButtonGroup widget organizes TGButton widgets in a group //
76 // with one vertical column. TGVButtonGroup is a convenience class that //
77 // offers a thin layer on top of TGButtonGroup. It inherits from //
78 // TGButtonGroup. //
79 // //
80 //////////////////////////////////////////////////////////////////////////
81 
82 #include "TGButtonGroup.h"
83 #include "TGButton.h"
84 #include "TClass.h"
85 #include "TGLayout.h"
86 #include "TList.h"
87 #include "TGResourcePool.h"
88 #include "Riostream.h"
89 
90 
91 ClassImp(TGButtonGroup);
92 ClassImp(TGHButtonGroup);
93 ClassImp(TGVButtonGroup);
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Constructor. Layout 1 row or 1 column.
97 
98 TGButtonGroup::TGButtonGroup(const TGWindow *parent,
99  const TString &title,
100  UInt_t options,
101  GContext_t norm,
102  FontStruct_t font,
103  ULong_t back) :
104  TGGroupFrame(parent, new TGString(title), options, norm, font, back)
105 {
106  Init();
107  if (options & kVerticalFrame) {
108  SetLayoutManager(new TGVerticalLayout(this));
109  } else {
110  SetLayoutManager(new TGHorizontalLayout(this));
111  }
112 
113  fDrawBorder = !title.IsNull();
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Constructor. Layout defined by TGMatrixLayout:
118 /// r = number of rows
119 /// c = number of columns
120 /// s = interval between frames
121 /// h = layout hints
122 
123 TGButtonGroup::TGButtonGroup(const TGWindow *parent,
124  UInt_t r, UInt_t c,
125  Int_t s, Int_t h,
126  const TString &title,
127  GContext_t norm ,
128  FontStruct_t font ,
129  ULong_t back) :
130  TGGroupFrame(parent, new TGString(title), 0, norm, font, back)
131 {
132  Init();
133  fDrawBorder = !title.IsNull();
134  SetLayoutManager(new TGMatrixLayout(this,r,c,s,h));
135 }
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Default init.
139 
140 void TGButtonGroup::Init()
141 {
142  fState = kTRUE;
143  fMapOfButtons = new TMap(); // map of button/id pairs
144  fExclGroup = kFALSE;
145  fRadioExcl = kFALSE;
146  fDrawBorder = kTRUE;
147 
148  SetWindowName();
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Destructor, we do not delete the buttons.
153 
154 TGButtonGroup::~TGButtonGroup()
155 {
156  TIter next(fMapOfButtons);
157  TGButton *item = 0;
158 
159  while ((item = (TGButton*)next())) {
160  item->SetGroup(0);
161  }
162 
163  SafeDelete(fMapOfButtons);
164 }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Redraw the group frame. Need special DoRedraw() since we need to
168 /// redraw with fBorderWidth=0.
169 
170 void TGButtonGroup::DoRedraw()
171 {
172  gVirtualX->ClearArea(fId, 0, 0, fWidth, fHeight);
173 
174  DrawBorder();
175 }
176 
177 ////////////////////////////////////////////////////////////////////////////////
178 /// Draw border of around the group frame.
179 ///
180 /// if frame is kRaisedFrame - a frame border is of "wall style",
181 /// otherwise of "groove style".
182 
183 void TGButtonGroup::DrawBorder()
184 {
185  if (!fDrawBorder) return;
186 
187  Int_t x, y, l, t, r, b, gl, gr, sep, max_ascent, max_descent;
188 
189  UInt_t tw = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
190  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
191 
192  l = 0;
193  t = (max_ascent + max_descent + 2) >> 1;
194  r = fWidth - 1;
195  // next three lines are for backward compatibility in case of horizontal layout
196  TGLayoutManager * lm = GetLayoutManager();
197  // coverity[returned_null]
198  // coverity[dereference]
199  if ((lm->InheritsFrom(TGHorizontalLayout::Class())) ||
200  (lm->InheritsFrom(TGMatrixLayout::Class())))
201  b = fHeight - 1;
202  else
203  b = fHeight - t;
204 
205  sep = 3;
206  UInt_t rr = 5 + (sep << 1) + tw;
207 
208  switch (fTitlePos) {
209  case kRight:
210  gl = fWidth>rr ? Int_t(fWidth - rr) : 5 + sep;
211  break;
212  case kCenter:
213  gl = fWidth>tw ? Int_t((fWidth - tw)>>1) - sep : 5 + sep;
214  break;
215  case kLeft:
216  default:
217  gl = 5 + sep;
218  }
219  gr = gl + tw + (sep << 1);
220 
221  switch (fOptions & (kSunkenFrame | kRaisedFrame)) {
222  case kRaisedFrame:
223  gVirtualX->DrawLine(fId, GetHilightGC()(), l, t, gl, t);
224  gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, t+1, gl, t+1);
225 
226  gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t, r-1, t);
227  gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t+1, r-2, t+1);
228 
229  gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, t, r-1, b-1);
230  gVirtualX->DrawLine(fId, GetShadowGC()(), r, t, r, b);
231 
232  gVirtualX->DrawLine(fId, GetHilightGC()(), r-1, b-1, l, b-1);
233  gVirtualX->DrawLine(fId, GetShadowGC()(), r, b, l, b);
234 
235  gVirtualX->DrawLine(fId, GetHilightGC()(), l, b-1, l, t);
236  gVirtualX->DrawLine(fId, GetShadowGC()(), l+1, b-2, l+1, t+1);
237  break;
238  case kSunkenFrame:
239  default:
240  gVirtualX->DrawLine(fId, GetShadowGC()(), l, t, gl, t);
241  gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, t+1, gl, t+1);
242 
243  gVirtualX->DrawLine(fId, GetShadowGC()(), gr, t, r-1, t);
244  gVirtualX->DrawLine(fId, GetHilightGC()(), gr, t+1, r-2, t+1);
245 
246  gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, t, r-1, b-1);
247  gVirtualX->DrawLine(fId, GetHilightGC()(), r, t, r, b);
248 
249  gVirtualX->DrawLine(fId, GetShadowGC()(), r-1, b-1, l, b-1);
250  gVirtualX->DrawLine(fId, GetHilightGC()(), r, b, l, b);
251 
252  gVirtualX->DrawLine(fId, GetShadowGC()(), l, b-1, l, t);
253  gVirtualX->DrawLine(fId, GetHilightGC()(), l+1, b-2, l+1, t+1);
254  break;
255  }
256 
257  x = gl + sep;
258  y = 1;
259 
260  if (fState) {
261  fText->Draw(fId, fNormGC, x, y + max_ascent);
262  } else {
263  fText->Draw(fId, GetHilightGC()(), x, y + 1 + max_ascent);
264  fText->Draw(fId, GetShadowGC()(), x, y + max_ascent);
265  }
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Makes border to be visible/invisible.
270 
271 void TGButtonGroup::SetBorderDrawn(Bool_t enable)
272 {
273  if (enable != IsBorderDrawn()) {
274  fDrawBorder = enable;
275  ChangedBy("SetBorderDrawn"); // emit signal
276  }
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Sets the button group to be exclusive if enable is kTRUE,
281 /// or to be non-exclusive if enable is kFALSE.
282 /// An exclusive button group switches off all other toggle buttons when
283 /// one is switched on. This is ideal for groups of radio-buttons
284 /// A non-exclusive group allow many buttons to be switched on at the same
285 /// time. The default setting is kFALSE.
286 
287 void TGButtonGroup::SetExclusive(Bool_t enable)
288 {
289  if (enable != IsExclusive()) {
290  fExclGroup = enable;
291  ChangedBy("SetExclusive"); // emit signal
292  }
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 /// If enable is kTRUE, this button group will treat radio buttons as
297 /// mutually exclusive, and other buttons according to IsExclusive().
298 /// This function is called automatically whenever a TGRadioButton
299 /// is inserted, so you should normally never have to call it.
300 
301 void TGButtonGroup::SetRadioButtonExclusive(Bool_t enable)
302 {
303  if (enable != IsRadioButtonExclusive()) {
304  fRadioExcl = enable;
305  ChangedBy("SetRadioButtonExclusive"); // emit signal
306  }
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Sets the state of all the buttons in the group to enable or disable.
311 
312 void TGButtonGroup::SetState(Bool_t state)
313 {
314  fState = state;
315 
316  TIter next(fMapOfButtons);
317  TGButton *item = 0;
318 
319  while ((item = (TGButton*)next())) { // loop over all buttons
320  if (state) {
321  item->SetState(kButtonUp);
322  } else {
323  item->SetState(kButtonDisabled);
324  }
325  }
326  DoRedraw();
327 }
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Sets the button with id to be on/down, and if this is an
330 /// exclusive group, all other button in the group to be off/up.
331 
332 void TGButtonGroup::SetButton(Int_t id, Bool_t down)
333 {
334  TGButton *b = Find(id);
335 
336  if (b && (b->IsDown() != down)) {
337  b->SetState(kButtonDown, kTRUE);
338  }
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Inserts a button with the identifier id into the button group.
343 /// Returns the button identifier.
344 ///
345 /// It is not necessary to manually insert buttons that have this button
346 /// group as their parent widget. An exception is when you want custom
347 /// identifiers instead of the default 1, 2, 3 etc.
348 ///
349 /// The button is assigned the identifier id or an automatically
350 /// generated identifier. It works as follows: If id > 0, this
351 /// identifier is assigned. If id == -1 (default), the identifier is
352 /// equal to the number of buttons in the group+1. If id is any other
353 /// negative integer, for instance -2, a unique identifier (negative
354 /// integer <= -2) is generated.
355 ///
356 /// Inserting several buttons with id = -1 assigns the identifiers 1,
357 /// 2, 3, etc.
358 
359 Int_t TGButtonGroup::Insert(TGButton *button, Int_t id)
360 {
361  if (button->fGroup && button->fGroup != this)
362  button->fGroup->Remove(button);
363 
364  if (button->fGroup == this) {
365  if (id == -1)
366  return GetId(button); // the button is already in group
367  else
368  button->fGroup->Remove(button); // want to set a new id
369  }
370 
371  button->fGroup = this;
372  button->Associate(this);
373 
374  static Int_t seq_no = -2;
375  Long_t bid;
376 
377  if (id < -1) bid = seq_no--;
378  else if (id == -1) bid = GetCount()+1;
379  else bid = id;
380 
381  fMapOfButtons->Add(button, (TObject*)bid);
382  AddFrame(button);
383 
384  // coverity[returned_null]
385  // coverity[dereference]
386  SetRadioButtonExclusive(button->IsA()->InheritsFrom(TGRadioButton::Class()));
387 
388  Connect(button, "Clicked()" , "TGButtonGroup", this, "ReleaseButtons()");
389  Connect(button, "Pressed()" , "TGButtonGroup", this, "ButtonPressed()");
390  Connect(button, "Released()", "TGButtonGroup", this, "ButtonReleased()");
391  Connect(button, "Clicked()" , "TGButtonGroup", this, "ButtonClicked()");
392 
393  return (Int_t) bid;
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Removes a button from the button group.
398 
399 void TGButtonGroup::Remove(TGButton *button)
400 {
401  TGButton *item = (TGButton*) fMapOfButtons->Remove(button);
402  if (item) {
403  button->SetGroup(0);
404  button->Disconnect(this);
405  button->DestroyWindow();
406  }
407 
408  RemoveFrame(button);
409 }
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// Finds and returns a pointer to the button with the specified
413 /// identifier id. Returns null if the button was not found.
414 
415 TGButton *TGButtonGroup::Find(Int_t id) const
416 {
417  TIter next(fMapOfButtons);
418  TGButton *item = 0;
419 
420  while ((item = (TGButton*)next())) {
421  if ((Long_t)fMapOfButtons->GetValue(item) == id) break; // found
422  }
423 
424  return item;
425 }
426 
427 ////////////////////////////////////////////////////////////////////////////////
428 /// Finds and returns the id of the button.
429 /// Returns -1 if the button is not a member of this group.
430 
431 Int_t TGButtonGroup::GetId(TGButton *button) const
432 {
433  TPair *a = (TPair*) fMapOfButtons->FindObject(button);
434  if (a)
435  return (Int_t)Long_t(a->Value());
436  else
437  return -1;
438 }
439 
440 ////////////////////////////////////////////////////////////////////////////////
441 /// This slot is activated when one of the buttons in the group emits the
442 /// Pressed() signal.
443 
444 void TGButtonGroup::ButtonPressed()
445 {
446 #if 0
447  // Is here for historical purposes and example. Now this is not needed
448  // anymore since TGButton has has its own GetSender() method returning
449  // the TGButton proper.
450 
451  // This is needed since gTQSender points to TQObject part of TGButton
452  TGButton *btn = dynamic_cast<TGButton*>((TQObject*)gTQSender);
453 
454  if (!btn) {
455  Error("ButtonPressed", "gTQSender not a TGButton");
456  return;
457  }
458 #else
459  TGButton *btn = (TGButton*)gTQSender;
460 #endif
461 
462  TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
463  if (a) {
464  Int_t id = (Int_t)Long_t(a->Value());
465  Pressed(id);
466  }
467 }
468 
469 ////////////////////////////////////////////////////////////////////////////////
470 /// This slot is activated when one of the buttons in the group emits the
471 /// Released() signal.
472 
473 void TGButtonGroup::ButtonReleased()
474 {
475  TGButton *btn = (TGButton*)gTQSender;
476 
477  TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
478  if (a) {
479  Int_t id = (Int_t)Long_t(a->Value());
480  Released(id);
481  }
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// This slot is activated when one of the buttons in the group emits the
486 /// Clicked() signal.
487 
488 void TGButtonGroup::ButtonClicked()
489 {
490  TGButton *btn = (TGButton*)gTQSender;
491 
492  TPair *a = (TPair*) fMapOfButtons->FindObject(btn);
493  if (a) {
494  Int_t id = (Int_t)Long_t(a->Value());
495  Clicked(id);
496  }
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// This slot is activated when one of the buttons in the
501 /// exclusive group emits the Pressed() signal.
502 
503 void TGButtonGroup::ReleaseButtons()
504 {
505  if (!fExclGroup && !fRadioExcl) return;
506 
507  TGButton *btn = (TGButton*)gTQSender;
508 
509  if (!fExclGroup && !btn)
510  return;
511 
512  TIter next(fMapOfButtons);
513  TGButton *item = 0;
514 
515  while ((item = (TGButton*)next())) { // loop over all buttons
516  // coverity[returned_null]
517  // coverity[dereference]
518  if (btn != item && item->IsToggleButton() && item->IsOn() &&
519  (fExclGroup || (item->IsA()->InheritsFrom(TGRadioButton::Class())
520  && btn->IsA()->InheritsFrom(TGRadioButton::Class())))) {
521  item->SetOn(kFALSE);
522  }
523  }
524 }
525 
526 ////////////////////////////////////////////////////////////////////////////////
527 /// Show group of buttons.
528 
529 void TGButtonGroup::Show()
530 {
531  MapSubwindows();
532  Resize();
533  MapRaised();
534  fClient->NeedRedraw(this);
535 }
536 
537 ////////////////////////////////////////////////////////////////////////////////
538 /// Hide group of buttons.
539 
540 void TGButtonGroup::Hide()
541 {
542  UnmapWindow();
543 }
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Set or change title.
547 
548 void TGButtonGroup::SetTitle(TGString *title)
549 {
550  if (!title) {
551  Error("SetTitle", "title cannot be 0, try \"\"");
552  return;
553  }
554 
555  if (strcmp(fText->GetString(), title->GetString())) {
556  SetBorderDrawn(title->GetLength() ? kTRUE : kFALSE);
557  TGGroupFrame::SetTitle(title);
558  ChangedBy("SetTitle");
559  }
560 }
561 
562 ////////////////////////////////////////////////////////////////////////////////
563 /// Set or change title.
564 
565 void TGButtonGroup::SetTitle(const char *title)
566 {
567  if (!title) {
568  Error("SetTitle", "title cannot be 0, try \"\"");
569  return;
570  }
571 
572  if (strcmp(fText->GetString(), title)) {
573  SetBorderDrawn(title && strlen(title));
574  TGGroupFrame::SetTitle(title);
575  ChangedBy("SetTitle");
576  }
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// Set layout hints for the specified button or if button=0 for all
581 /// buttons.
582 
583 void TGButtonGroup::SetLayoutHints(TGLayoutHints *l, TGButton *button)
584 {
585  TGFrameElement *el;
586  TIter next(fList);
587 
588  while ((el = (TGFrameElement *)next())) {
589  if ((el->fFrame==(TGFrame*)button) || !button) {
590  el->fLayout = l ? l : fgDefaultHints;
591  }
592  }
593  Layout();
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////
597 /// Save a button group widget as a C++ statement(s) on output stream out.
598 
599 void TGButtonGroup::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
600 {
601  char quote ='"';
602 
603  // font + GC
604  option = GetName()+5; // unique digit id of the name
605  TString parGC, parFont;
606  // coverity[returned_null]
607  // coverity[dereference]
608  parFont.Form("%s::GetDefaultFontStruct()",IsA()->GetName());
609  // coverity[returned_null]
610  // coverity[dereference]
611  parGC.Form("%s::GetDefaultGC()()",IsA()->GetName());
612 
613  if ((GetDefaultFontStruct() != fFontStruct) || (GetDefaultGC()() != fNormGC)) {
614  TGFont *ufont = gClient->GetResourcePool()->GetFontPool()->FindFont(fFontStruct);
615  if (ufont) {
616  ufont->SavePrimitive(out, option);
617  parFont.Form("ufont->GetFontStruct()");
618  }
619 
620  TGGC *userGC = gClient->GetResourcePool()->GetGCPool()->FindGC(fNormGC);
621  if (userGC) {
622  userGC->SavePrimitive(out, option);
623  parGC.Form("uGC->GetGC()");
624  }
625  }
626 
627  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
628 
629  out << std::endl << " // buttongroup frame" << std::endl;
630 
631  out << " TGButtonGroup *";
632  out << GetName() << " = new TGButtonGroup(" << fParent->GetName()
633  << ","<< quote << fText->GetString() << quote;
634 
635  if (fBackground == GetDefaultFrameBackground()) {
636  if (fFontStruct == GetDefaultFontStruct()) {
637  if (fNormGC == GetDefaultGC()()) {
638  if (!GetOptions()) {
639  out <<");" << std::endl;
640  } else {
641  out << "," << GetOptionString() <<");" << std::endl;
642  }
643  } else {
644  out << "," << GetOptionString() << "," << parGC.Data() <<");" << std::endl;
645  }
646  } else {
647  out << "," << GetOptionString() << "," << parGC.Data() << "," << parFont.Data() <<");" << std::endl;
648  }
649  } else {
650  out << "," << GetOptionString() << "," << parGC.Data() << "," << parFont.Data() << ",ucolor);" << std::endl;
651  }
652  if (option && strstr(option, "keep_names"))
653  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
654 
655  // setting layout manager
656  out << " " << GetName() <<"->SetLayoutManager(";
657  // coverity[returned_null]
658  // coverity[dereference]
659  GetLayoutManager()->SavePrimitive(out, option);
660  out << ");"<< std::endl;
661 
662  TGFrameElement *f;
663  TIter next(GetList());
664  while ((f = (TGFrameElement *)next())) {
665  f->fFrame->SavePrimitive(out,option);
666  if (f->fFrame->InheritsFrom("TGButton")) continue;
667  else {
668  out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
669  f->fLayout->SavePrimitive(out, option);
670  out << ");"<< std::endl;
671  }
672  }
673 
674  if (IsExclusive())
675  out << " " << GetName() <<"->SetExclusive(kTRUE);" << std::endl;
676 
677  if (IsRadioButtonExclusive())
678  out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << std::endl;
679 
680  if (!IsBorderDrawn())
681  out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << std::endl;
682 
683 
684  out << " " << GetName() << "->Resize(" << GetWidth()
685  << "," << GetHeight() << ");" << std::endl;
686 
687  if (!IsEnabled())
688  out << " " << GetName() <<"->SetState(kFALSE);" << std::endl;
689 
690  out << " " << GetName() << "->Show();" << std::endl;
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Save a button group widget as a C++ statement(s) on output stream out.
695 
696 void TGHButtonGroup::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
697 {
698  char quote ='"';
699 
700  // font + GC
701  option = GetName()+5; // unique digit id of the name
702  TString parGC, parFont;
703  parFont.Form("%s::GetDefaultFontStruct()",IsA()->GetName());
704  parGC.Form("%s::GetDefaultGC()()",IsA()->GetName());
705 
706  if ((GetDefaultFontStruct() != fFontStruct) || (GetDefaultGC()() != fNormGC)) {
707  TGFont *ufont = gClient->GetResourcePool()->GetFontPool()->FindFont(fFontStruct);
708  if (ufont) {
709  ufont->SavePrimitive(out, option);
710  parFont.Form("ufont->GetFontStruct()");
711  }
712 
713  TGGC *userGC = gClient->GetResourcePool()->GetGCPool()->FindGC(fNormGC);
714  if (userGC) {
715  userGC->SavePrimitive(out, option);
716  parGC.Form("uGC->GetGC()");
717  }
718  }
719 
720  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
721 
722  out << std::endl << " // horizontal buttongroup frame" << std::endl;
723 
724  out << " TGHButtonGroup *";
725  out << GetName() << " = new TGHButtonGroup(" << fParent->GetName()
726  << "," << quote << fText->GetString() << quote;
727  if (fBackground == GetDefaultFrameBackground()) {
728 
729  if (fFontStruct == GetDefaultFontStruct()) {
730 
731  if (fNormGC == GetDefaultGC()()) {
732  out << ");" << std::endl;
733  } else {
734  out << "," << parGC.Data() <<");" << std::endl;
735  }
736  } else {
737  out << "," << parGC.Data() << "," << parFont.Data() <<");" << std::endl;
738  }
739  } else {
740  out << "," << parGC.Data() << "," << parFont.Data() << ",ucolor);" << std::endl;
741  }
742  if (option && strstr(option, "keep_names"))
743  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
744 
745  TGFrameElement *f;
746  TIter next(GetList());
747  while ((f = (TGFrameElement *)next())) {
748  f->fFrame->SavePrimitive(out,option);
749  if (f->fFrame->InheritsFrom("TGButton")){
750  out << " " << GetName() << "->SetLayoutHints(";
751  f->fLayout->SavePrimitive(out, "nocoma");
752  out << "," << f->fFrame->GetName();
753  out << ");"<< std::endl;
754  }
755  else {
756  out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
757  f->fLayout->SavePrimitive(out, option);
758  out << ");"<< std::endl;
759  }
760  }
761 
762  if (!IsEnabled())
763  out << " " << GetName() <<"->SetState(kFALSE);" << std::endl;
764 
765  if (IsExclusive())
766  out << " " << GetName() <<"->SetExclusive(kTRUE);" << std::endl;
767 
768  if (IsRadioButtonExclusive())
769  out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << std::endl;
770 
771  if (!IsBorderDrawn())
772  out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << std::endl;
773 
774  out << " " << GetName() <<"->Resize(" << GetWidth() << ","
775  << GetHeight() << ");" << std::endl;
776 
777  out << " " << GetName() << "->Show();" << std::endl;
778 }
779 
780 ////////////////////////////////////////////////////////////////////////////////
781 /// Save a button group widget as a C++ statement(s) on output stream out.
782 
783 void TGVButtonGroup::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
784 {
785  char quote ='"';
786 
787  // font + GC
788  option = GetName()+5; // unique digit id of the name
789  TString parGC, parFont;
790  parFont.Form("%s::GetDefaultFontStruct()",IsA()->GetName());
791  parGC.Form("%s::GetDefaultGC()()",IsA()->GetName());
792 
793  if ((GetDefaultFontStruct() != fFontStruct) || (GetDefaultGC()() != fNormGC)) {
794  TGFont *ufont = gClient->GetResourcePool()->GetFontPool()->FindFont(fFontStruct);
795  if (ufont) {
796  ufont->SavePrimitive(out, option);
797  parFont.Form("ufont->GetFontStruct()");
798  }
799 
800  TGGC *userGC = gClient->GetResourcePool()->GetGCPool()->FindGC(fNormGC);
801  if (userGC) {
802  userGC->SavePrimitive(out, option);
803  parGC.Form("uGC->GetGC()");
804  }
805  }
806 
807  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
808 
809  out << std::endl << " // vertical buttongroup frame" << std::endl;
810 
811  out << " TGVButtonGroup *";
812  out << GetName() << " = new TGVButtonGroup(" << fParent->GetName()
813  << "," << quote << fText->GetString() << quote;
814 
815  if (fBackground == GetDefaultFrameBackground()) {
816  if (fFontStruct == GetDefaultFontStruct()) {
817  if (fNormGC == GetDefaultGC()()) {
818  out <<");" << std::endl;
819  } else {
820  out << "," << parGC.Data() <<");" << std::endl;
821  }
822  } else {
823  out << "," << parGC.Data() << "," << parFont.Data() <<");" << std::endl;
824  }
825  } else {
826  out << "," << parGC.Data() << "," << parFont.Data() << ",ucolor);" << std::endl;
827  }
828  if (option && strstr(option, "keep_names"))
829  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
830 
831  TGFrameElement *f;
832  TIter next(GetList());
833  while ((f = (TGFrameElement *)next())) {
834  f->fFrame->SavePrimitive(out,option);
835  if (f->fFrame->InheritsFrom("TGButton")) continue;
836  else {
837  out << " " << GetName() << "->AddFrame(" << f->fFrame->GetName();
838  f->fLayout->SavePrimitive(out, option);
839  out << ");"<< std::endl;
840  }
841  }
842 
843  if (!IsEnabled())
844  out << " " << GetName() <<"->SetState(kFALSE);" << std::endl;
845 
846  if (IsExclusive())
847  out << " " << GetName() <<"->SetExclusive(kTRUE);" << std::endl;
848 
849  if (IsRadioButtonExclusive())
850  out << " " << GetName() <<"->SetRadioButtonExclusive(kTRUE);" << std::endl;
851 
852  if (!IsBorderDrawn())
853  out << " " << GetName() <<"->SetBorderDrawn(kFALSE);" << std::endl;
854 
855  out << " " << GetName() << "->Resize(" << GetWidth()
856  << "," << GetHeight() << ");"<< std::endl;
857 
858  out << " " << GetName() << "->Show();" << std::endl;
859 }