source: trunk/Mars/mbase/MGList.cc@ 19669

Last change on this file since 19669 was 19240, checked in by tbretz, 6 years ago
Allow to link the marslogo into the shared object so that no path is required.
File size: 10.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 11/2001 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MGList //
28// //
29// This is a TList object which has some enhancements for GUI elements. //
30// Use GetWidget to search for a GUI element with a given widget id. //
31// Add checkes for the existances of a GUI element with the same widget //
32// id (for IDs>=0). //
33// //
34/////////////////////////////////////////////////////////////////////////////
35#include "MGList.h"
36
37#include <iostream>
38
39#include <TROOT.h>
40#include <TClass.h>
41#include <TImage.h>
42#include <TGClient.h>
43#include <TGWidget.h>
44#include <TGPicture.h>
45
46ClassImp(MGList);
47
48using namespace std;
49
50// --------------------------------------------------------------------------
51//
52// Add the list to the global list of cleanups
53// objects in the list.
54//
55MGList::MGList() : TList()
56{
57 // Make sure that all object deleted are also deleted from this list
58 gROOT->GetListOfCleanups()->Add(this);
59 // Make sure that this doesn't remain in ListOfCleanups after deletion
60 SetBit(kMustCleanup);
61}
62
63// --------------------------------------------------------------------------
64//
65// Before destroying the list with all its contents free all TGPicture
66// objects in the list.
67//
68MGList::~MGList()
69{
70 DeletePictures();
71}
72
73// --------------------------------------------------------------------------
74//
75// Free/Delete all TGPicture store in list.
76//
77void MGList::DeletePictures()
78{
79 TObject *obj;
80 TIter Next(this);
81 while ((obj=Next()))
82 {
83 if (!obj->InheritsFrom(TGPicture::Class()))
84 continue;
85
86 //
87 // Remove the object first. Otherwise we would remove
88 // a non existing object...
89 //
90 Remove(obj);
91 if (gClient)
92 gClient->FreePicture((TGPicture*)obj);
93 }
94}
95
96// --------------------------------------------------------------------------
97//
98// Delete all pictures. Call TList::Delete.
99//
100void MGList::Delete(Option_t *option)
101{
102 DeletePictures();
103 TList::Delete(option);
104}
105
106// --------------------------------------------------------------------------
107//
108// Does a dynamic cast from a TObject to a TGWidget. This is necesary
109// if a class derived from TObject inherits also from TGWidget and
110// you have only a pointer to the TObject available.
111//
112TGWidget *MGList::GetWidget(TObject *obj) const
113{
114 //
115 // - IsA gives a pointer to the parent class entry in the dictionary
116 // - DynamicCast tries to cast obj of class type obj->IsA to one
117 // of its base classes TGWidget
118 // - This method is ment for dynamic casts (multi inheritance)
119 //
120 // If this functions makes trouble check for the correct inheritance
121 // first via obj->InheritsFrom(TGWidget::Class())
122 //
123 // The root implementation is used, because for space reasons
124 // the C++ dynamic_cast<TGWidget*> is turned off by the option
125 // -fno-rtti, which could be used in 'plain' C++
126 //
127
128 //
129 // FIXME: This should not be necessary but it is, why??
130 //
131 // TRY: TGPicture *pic = gClient->GetPicture("pic");
132 // cout << pic->IsA()->DynamicCast(TGWidget::Class(), pic) << endl;
133 //
134 // Is this another bug in root?
135 //
136#if ROOT_VERSION_CODE < ROOT_VERSION(3,02,07)
137 if (!obj->InheritsFrom(TGWidget::Class()))
138 return NULL;
139#endif
140
141 return (TGWidget*)obj->IsA()->DynamicCast(TGWidget::Class(), obj);
142}
143
144// --------------------------------------------------------------------------
145//
146// Returns kTRUE if the object is derived from TGWidget and a widget
147// with the TGWidget id of this object is already in the list.
148// If the object is not derived from TGWidget or no TGWidget object
149// with the same widget id is existing in the list kFALSE is returned.
150// If the TGWidget has an object id < 0 kFALSE is always retuned.
151//
152Bool_t MGList::IsExisting(TObject *obj) const
153{
154 const TGWidget *wid = GetWidget(obj);
155
156 //
157 // check whether it is a TGWidget
158 //
159 if (!wid)
160 return kFALSE;
161
162 const Int_t id = wid->WidgetId();
163
164 //
165 // check whether is has a valid id
166 // (not id=-1, which is the standard id)
167 //
168 if (id < 0)
169 return kFALSE;
170
171 //
172 // check whether Widget id is already existing in the list
173 //
174 return FindWidget(id) ? kTRUE : kFALSE;
175}
176
177// --------------------------------------------------------------------------
178//
179// If the given object obj is derived from TGWidget and a TGWidget with
180// the same widget id is already existing in the list the object is
181// ignored, otherwise it is added to the list via TList::Add(TObject *)
182//
183void MGList::Add(TObject *obj)
184{
185 if (IsExisting(obj))
186 {
187 // FIXME: Replace by gLog
188 const Int_t id = GetWidget(obj)->WidgetId();
189 cout << "Widget with id #" << id << " (";
190 cout << FindWidget(id)->ClassName() << ") already in list... ";
191 cout << obj->GetName() << " ignored." << endl;
192 return;
193 }
194
195 TList::Add(obj);
196 obj->SetBit(kMustCleanup);
197}
198
199// --------------------------------------------------------------------------
200//
201// If the given object obj is derived from TGWidget and a TGWidget with
202// the same widget id is already existing in the list the object is
203// ignored, otherwise it is added to the list via
204// TList::Add(TObject *, Option_t *)
205//
206void MGList::Add(TObject *obj, Option_t *opt)
207{
208 if (IsExisting(obj))
209 {
210 Int_t id = GetWidget(obj)->WidgetId();
211 cout << "Widget with id #" << id << " (";
212 cout << FindWidget(id)->ClassName() << ") already in list... ";
213 cout << obj->GetName() << " ignored." << endl;
214 return;
215 }
216
217 TList::Add(obj, opt);
218 obj->SetBit(kMustCleanup);
219}
220
221// --------------------------------------------------------------------------
222//
223// Adds the picture physically to the list. The list takes care of that
224// - The picture is freed as often as it was retrieved from gClient
225//
226void MGList::AddPicture(TGPicture *pic, const char *name)
227{
228 //
229 // Check whether the picture exists
230 //
231 if (!pic)
232 {
233 cout << "Warning: Requested picture '" << name << "' not found... ignored." << endl;
234 cout << " Please copy " << name << " to $HOME or $HOME/icons or add" << endl;
235 cout << " Unix.*.Gui.IconPath: ~/Path/To/The/Picture" << endl;
236 cout << " to [$HOME/].rootrc." << endl;
237 return;
238 }
239
240 //
241 // Add the picture to the list
242 //
243 TList::Add(pic);
244 pic->SetBit(kMustCleanup);
245}
246
247// --------------------------------------------------------------------------
248//
249// This gets a picture from the picture pool of the TGClient-object.
250// The pictures are freed automatically in the dstructor of the list.
251// The picture counts itself how often it got used, so that only
252// the first call to GetPicture will craete it and the last call to
253// FreePicture will destroy it. If you access the picture only via
254// MGList::GetPicture you don't have to care about.
255//
256// Don't try to call FreePicture by yourself for a picture gotten by
257// GetPicture. This is independant of the kIsOwner bit.
258//
259const TGPicture *MGList::GetPicture(const char *name)
260{
261 if (!gClient)
262 return NULL;
263
264 TGPicture *pic = const_cast<TGPicture*>(gClient->GetPicture(name));
265 AddPicture(pic, name);
266 return pic;
267}
268
269// --------------------------------------------------------------------------
270//
271// This gets a picture from the picture pool of the TGClient-object.
272// The pictures are freed automatically in the dstructor of the list.
273// The picture counts itself how often it got used, so that only
274// the first call to GetPicture will craete it and the last call to
275// FreePicture will destroy it. If you access the picture only via
276// MGList::GetPicture you don't have to care about.
277//
278// Don't try to call FreePicture by yourself for a picture gotten by
279// GetPicture. This is independant of the kIsOwner bit.
280//
281const TGPicture *MGList::GetPicture(const char *name, Int_t width, Int_t height)
282{
283 if (!gClient)
284 return NULL;
285
286 TGPicture *pic = const_cast<TGPicture*>(gClient->GetPicture(name, width, height));
287 AddPicture(pic, name);
288 return pic;
289}
290
291const TGPicture *MGList::GetPicture(const char *name, const char *xpm[])
292{
293 struct MGPicture : public TGPicture
294 {
295 MGPicture (const char *_n, Pixmap_t _p, Pixmap_t _m) : TGPicture(_n, _p, _m) { }
296 };
297
298 // Add Mars logo picture
299 TImage *img = TImage::Open(const_cast<char **>(xpm));
300 if (!img)
301 return 0;
302
303 TGPicture *pic = new MGPicture(name, img->GetPixmap(), img->GetMask());
304 delete img;
305 AddPicture(pic, name);
306
307 return pic;
308}
309
310// --------------------------------------------------------------------------
311//
312// Search the list for a object derived from TGidget which has the given
313// widget id. Returns a pointer to this object otherwise NULL.
314// For IDs < 0 the function returns always NULL.
315//
316TObject *MGList::FindWidget(Int_t id) const
317{
318 if (id<0)
319 return NULL;
320
321 TObject *obj;
322 TIter Next(this);
323 while ((obj=Next()))
324 {
325 const TGWidget *wid = GetWidget(obj);
326
327 if (!wid)
328 continue;
329
330 if (id == wid->WidgetId())
331 return obj;
332 }
333 return NULL;
334}
Note: See TracBrowser for help on using the repository browser.