Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGStatusBar.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 23/01/98
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  This source is based on Xclass95, a Win95-looking GUI toolkit.
14  Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15 
16  Xclass95 is free software; you can redistribute it and/or
17  modify it under the terms of the GNU Library General Public
18  License as published by the Free Software Foundation; either
19  version 2 of the License, or (at your option) any later version.
20 
21 **************************************************************************/
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGStatusBar //
26 // //
27 // Provides a StatusBar widget. //
28 // //
29 //////////////////////////////////////////////////////////////////////////
30 
31 #include "TGStatusBar.h"
32 #include "TGResourcePool.h"
33 #include "TList.h"
34 #include "Riostream.h"
35 
36 
37 const TGFont *TGStatusBar::fgDefaultFont = 0;
38 TGGC *TGStatusBar::fgDefaultGC = 0;
39 
40 
41 class TGStatusBarPart : public TGHorizontalFrame {
42 friend class TGStatusBar;
43 private:
44  TGString *fStatusInfo; // status text to be displayed in this part
45  Int_t fYt; // y position of text in frame
46  virtual void DoRedraw();
47 
48 public:
49  TGStatusBarPart(const TGWindow *p, Int_t h, Int_t y, ULong_t back = GetDefaultFrameBackground());
50  ~TGStatusBarPart() { delete fStatusInfo; DestroyWindow(); }
51  void SetText(TGString *text);
52  const TGString *GetText() const { return fStatusInfo; }
53 };
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 /// Create statusbar part frame. This frame will contain the text for this
57 /// statusbar part.
58 
59 TGStatusBarPart::TGStatusBarPart(const TGWindow *p, Int_t h, Int_t y, ULong_t back)
60  : TGHorizontalFrame(p, 5, 5, kChildFrame | kHorizontalFrame, back)
61 {
62  fStatusInfo = 0;
63  fYt = y + 1;
64  fHeight = h;
65  MapWindow();
66 
67  fEditDisabled = kEditDisableGrab;
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Set text in this part of the statusbar.
72 
73 void TGStatusBarPart::SetText(TGString *text)
74 {
75  if (fStatusInfo) delete fStatusInfo;
76  fStatusInfo = text;
77  fClient->NeedRedraw(this);
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Draw string in statusbar part frame.
82 
83 void TGStatusBarPart::DoRedraw()
84 {
85  TGHorizontalFrame::DoRedraw();
86 
87  if (fStatusInfo)
88  fStatusInfo->Draw(fId, TGStatusBar::GetDefaultGC()(), 3, fYt);
89 }
90 
91 
92 ClassImp(TGStatusBar);
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Create a status bar widget. By default it consist of one part.
96 /// Multiple parts can be created using SetParts().
97 
98 TGStatusBar::TGStatusBar(const TGWindow *p, UInt_t w, UInt_t h,
99  UInt_t options, ULong_t back) :
100  TGHorizontalFrame(p, w, h, options, back)
101 {
102  fBorderWidth = 2;
103  fStatusPart = new TGStatusBarPart* [1];
104  fParts = new Int_t [1];
105  fXt = new Int_t [1];
106  fParts[0] = 100;
107  fNpart = 1;
108  f3DCorner = kTRUE;
109 
110  int max_ascent, max_descent;
111  gVirtualX->GetFontProperties(GetDefaultFontStruct(), max_ascent, max_descent);
112  int ht = max_ascent + max_descent;
113 
114  fYt = max_ascent;
115 
116  fStatusPart[0] = new TGStatusBarPart(this, ht, fYt);
117  AddFrame(fStatusPart[0]);
118  Resize(w, ht + 5);
119 
120  //fEditDisabled = kEditDisableLayout;
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Delete status bar widget.
125 
126 TGStatusBar::~TGStatusBar()
127 {
128  if (!MustCleanup()) {
129  for (int i = 0; i < fNpart; i++) {
130  delete fStatusPart[i];
131  }
132  }
133 
134  delete [] fStatusPart;
135  delete [] fParts;
136  delete [] fXt;
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Set text in partition partidx in status bar. The TGString is
141 /// adopted by the status bar.
142 
143 void TGStatusBar::SetText(TGString *text, Int_t partidx)
144 {
145  if (partidx < 0 || partidx >= fNpart) {
146  Error("SetText", "partidx out of range (0,%d)", fNpart-1);
147  return;
148  }
149 
150  fStatusPart[partidx]->SetText(text);
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Set text in partion partidx in status bar.
155 
156 void TGStatusBar::SetText(const char *text, Int_t partidx)
157 {
158  if ((partidx >= 0) && (partidx < fNpart))
159  SetText(new TGString(text), partidx);
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// return text in the part partidx
164 
165 const char *TGStatusBar::GetText(Int_t partidx) const
166 {
167  if (partidx < 0 || partidx >= fNpart) {
168  Error("GetText", "partidx out of range (0,%d)", fNpart-1);
169  return 0;
170  }
171 
172  const TGString *str = fStatusPart[partidx]->GetText();
173  return str->Data();
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Draw the status bar border (including cute 3d corner).
178 
179 void TGStatusBar::DrawBorder()
180 {
181  // Current width is known at this stage so calculate fXt's.
182  int i;
183  for (i = 0; i < fNpart; i++) {
184  if (i == 0)
185  fXt[i] = 0;
186  else
187  fXt[i] = fXt[i-1] + (fWidth * fParts[i-1] / 100);
188  }
189 
190  //TGFrame::DrawBorder();
191  for (i = 0; i < fNpart; i++) {
192  int xmax, xmin = fXt[i];
193  if (i == fNpart-1)
194  xmax = fWidth;
195  else
196  xmax = fXt[i+1] - 2;
197 
198  if (i == fNpart-1) {
199  if (f3DCorner)
200  fStatusPart[i]->MoveResize(fXt[i]+2, 1, xmax - fXt[i] - 15, fHeight - 2);
201  else
202  fStatusPart[i]->MoveResize(fXt[i]+2, 1, xmax - fXt[i], fHeight - 2);
203  } else
204  fStatusPart[i]->MoveResize(fXt[i]+2, 1, xmax - fXt[i] - 4, fHeight - 2);
205 
206  gVirtualX->DrawLine(fId, GetShadowGC()(), xmin, 0, xmax-2, 0);
207  gVirtualX->DrawLine(fId, GetShadowGC()(), xmin, 0, xmin, fHeight-2);
208  gVirtualX->DrawLine(fId, GetHilightGC()(), xmin, fHeight-1, xmax-1, fHeight-1);
209  if (i == fNpart-1)
210  gVirtualX->DrawLine(fId, GetHilightGC()(), xmax-1, fHeight-1, xmax-1, 0);
211  else
212  gVirtualX->DrawLine(fId, GetHilightGC()(), xmax-1, fHeight-1, xmax-1, 1);
213  }
214 
215  // 3d corner...
216  if (f3DCorner) {
217  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-3, fHeight-2, fWidth-2, fHeight-3);
218  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-4, fHeight-2, fWidth-2, fHeight-4);
219  gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-5, fHeight-2, fWidth-2, fHeight-5);
220 
221  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-7, fHeight-2, fWidth-2, fHeight-7);
222  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-8, fHeight-2, fWidth-2, fHeight-8);
223  gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-9, fHeight-2, fWidth-2, fHeight-9);
224 
225  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-11, fHeight-2, fWidth-2, fHeight-11);
226  gVirtualX->DrawLine(fId, GetShadowGC()(), fWidth-12, fHeight-2, fWidth-2, fHeight-12);
227  gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-13, fHeight-2, fWidth-2, fHeight-13);
228 
229  gVirtualX->DrawLine(fId, GetBckgndGC()(), fWidth-13, fHeight-1, fWidth-1, fHeight-1);
230  gVirtualX->DrawLine(fId, GetBckgndGC()(), fWidth-1, fHeight-1, fWidth-1, fHeight-13);
231  }
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Redraw status bar.
236 
237 void TGStatusBar::DoRedraw()
238 {
239  // calls DrawBorder()
240  TGFrame::DoRedraw();
241 
242  for (int i = 0; i < fNpart; i++)
243  fStatusPart[i]->DoRedraw();
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 /// Divide the status bar in nparts. Size of each part is given in parts
248 /// array (percentual).
249 
250 void TGStatusBar::SetParts(Int_t *parts, Int_t npart)
251 {
252  if (npart < 1) {
253  Warning("SetParts", "must be at least one part");
254  npart = 1;
255  }
256  if (npart > 15) {
257  Error("SetParts", "to many parts (limit is 15)");
258  return;
259  }
260 
261  int i;
262  for (i = 0; i < fNpart; i++)
263  delete fStatusPart[i];
264 
265  delete [] fStatusPart;
266  delete [] fParts;
267  delete [] fXt;
268  fList->Delete();
269 
270  fStatusPart = new TGStatusBarPart* [npart];
271  fParts = new Int_t [npart];
272  fXt = new Int_t [npart];
273 
274  int tot = 0;
275  for (i = 0; i < npart; i++) {
276  fStatusPart[i] = new TGStatusBarPart(this, fHeight, fYt);
277  AddFrame(fStatusPart[i]);
278  fParts[i] = parts[i];
279  tot += parts[i];
280  if (tot > 100)
281  Error("SetParts", "sum of part > 100");
282  }
283  if (tot < 100)
284  fParts[npart-1] += 100 - tot;
285  fNpart = npart;
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// Divide the status bar in npart equal sized parts.
290 
291 void TGStatusBar::SetParts(Int_t npart)
292 {
293  if (npart < 1) {
294  Warning("SetParts", "must be at least one part");
295  npart = 1;
296  }
297  if (npart > 40) {
298  Error("SetParts", "to many parts (limit is 40)");
299  return;
300  }
301 
302  int i;
303  for (i = 0; i < fNpart; i++)
304  delete fStatusPart[i];
305 
306  delete [] fStatusPart;
307  delete [] fParts;
308  delete [] fXt;
309  fList->Delete();
310 
311  fStatusPart = new TGStatusBarPart* [npart];
312  fParts = new Int_t [npart];
313  fXt = new Int_t [npart];
314 
315  int sz = 100/npart;
316  int tot = 0;
317  for (i = 0; i < npart; i++) {
318  fStatusPart[i] = new TGStatusBarPart(this, fHeight, fYt);
319  AddFrame(fStatusPart[i]);
320  fParts[i] = sz;
321  tot += sz;
322  }
323  if (tot < 100)
324  fParts[npart-1] += 100 - tot;
325  fNpart = npart;
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Return default font structure in use.
330 
331 FontStruct_t TGStatusBar::GetDefaultFontStruct()
332 {
333  if (!fgDefaultFont)
334  fgDefaultFont = gClient->GetResourcePool()->GetStatusFont();
335  return fgDefaultFont->GetFontStruct();
336 }
337 
338 ////////////////////////////////////////////////////////////////////////////////
339 /// Return default graphics context in use.
340 
341 const TGGC &TGStatusBar::GetDefaultGC()
342 {
343  if (!fgDefaultGC) {
344  fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
345  fgDefaultGC->SetFont(fgDefaultFont->GetFontHandle());
346  }
347  return *fgDefaultGC;
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////
351 /// Returns bar part. That allows to put in the bar part
352 /// something more interesting than text ;-)
353 
354 TGCompositeFrame *TGStatusBar::GetBarPart(Int_t npart) const
355 {
356  return ((npart<fNpart) && (npart>=0)) ? (TGCompositeFrame*)fStatusPart[npart] : 0;
357 }
358 
359 ////////////////////////////////////////////////////////////////////////////////
360 /// Return default size.
361 
362 TGDimension TGStatusBar::GetDefaultSize() const
363 {
364  UInt_t h = fHeight;
365 
366  for (int i = 0; i < fNpart; i++) {
367  h = TMath::Max(h,fStatusPart[i]->GetDefaultHeight()+1);
368  }
369  return TGDimension(fWidth, h);
370 }
371 
372 ////////////////////////////////////////////////////////////////////////////////
373 /// Save a status bar widget as a C++ statement(s) on output stream out.
374 
375 void TGStatusBar::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
376 {
377  if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
378 
379  out << std::endl;
380  out << " // status bar" << std::endl;
381 
382  out << " TGStatusBar *";
383  out << GetName() <<" = new TGStatusBar("<< fParent->GetName()
384  << "," << GetWidth() << "," << GetHeight();
385 
386  if (fBackground == GetDefaultFrameBackground()) {
387  if (GetOptions() == (kSunkenFrame | kHorizontalFrame)) {
388  out <<");" << std::endl;
389  } else {
390  out << "," << GetOptionString() <<");" << std::endl;
391  }
392  } else {
393  out << "," << GetOptionString() << ",ucolor);" << std::endl;
394  }
395  if (option && strstr(option, "keep_names"))
396  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
397 
398  int i; char quote = '"';
399 
400  if (fNpart > 1) {
401  out << " Int_t parts" << GetName()+5 << "[] = {" << fParts[0];
402 
403  for (i=1; i<fNpart; i++) {
404  out << "," << fParts[i];
405  }
406  out << "};" << std::endl;
407 
408  out << " " << GetName() << "->SetParts(parts" << GetName()+5
409  << "," << fNpart << ");" <<std::endl;
410  }
411  for (i=0; i<fNpart; i++) {
412  if (fStatusPart[i]->GetText()) {
413  out << " " << GetName() << "->SetText(" << quote
414  << fStatusPart[i]->GetText()->GetString()
415  << quote << "," << i << ");" << std::endl;
416  } else {
417  if (!fStatusPart[i]->GetList()->First()) continue;
418  out << " TGCompositeFrame *" << fStatusPart[i]->GetName()
419  << " = " << GetName() << "->GetBarPart(" << i << ");" << std::endl;
420 
421  TGFrameElement *el;
422  TIter next(fStatusPart[i]->GetList());
423 
424  while ((el = (TGFrameElement *) next())) {
425  el->fFrame->SavePrimitive(out, option);
426  out << " " << fStatusPart[i]->GetName() << "->AddFrame("
427  << el->fFrame->GetName();
428  el->fLayout->SavePrimitive(out, option);
429  out << ");" << std::endl;
430  }
431  }
432  }
433 }