Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGuiBldNameFrame.cxx
Go to the documentation of this file.
1 // @(#)root/guibuilder:$Id$
2 // Author: Valeriy Onuchin 12/09/04
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, 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 // TGuiNameFrame //
15 // //
16 //////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "TGuiBldNameFrame.h"
20 #include "TGLabel.h"
21 #include "TGTextEntry.h"
22 #include "TGuiBldEditor.h"
23 #include "TGLayout.h"
24 #include "TG3DLine.h"
25 #include "TColor.h"
26 #include "TROOT.h"
27 #include "TRootGuiBuilder.h"
28 #include "TGButton.h"
29 #include "TGFrame.h"
30 #include "TGMdiFrame.h"
31 #include "TGCanvas.h"
32 #include "TGListTree.h"
33 #include "TGuiBldDragManager.h"
34 #include "TGMsgBox.h"
35 #include "TGSplitter.h"
36 
37 ClassImp(TGuiBldNameFrame);
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 /// Constructor.
41 
42 TGuiBldNameFrame::TGuiBldNameFrame(const TGWindow *p, TGuiBldEditor *editor) :
43  TGCompositeFrame(p, 1, 1)
44 {
45  fEditor = editor;
46  fBuilder = (TRootGuiBuilder*)TRootGuiBuilder::Instance();
47  fManager = fBuilder->GetManager();
48  fEditDisabled = kEditDisable;
49  SetCleanup(kDeepCleanup);
50  TGFrame *frame = 0;
51  TGFrame *fSelected = fEditor->GetSelected();
52  if (fSelected) frame = fSelected;
53 
54  TGVerticalFrame *cf = new TGVerticalFrame(this, 180, 400);
55 
56  //list tree
57  TGHorizontalFrame *f = new TGHorizontalFrame(cf);
58  f->AddFrame(new TGLabel(f, "MDI Frame content"),
59  new TGLayoutHints(kLHintsLeft, 0, 1, 0, 0));
60  f->AddFrame(new TGHorizontal3DLine(f), new TGLayoutHints(kLHintsExpandX,
61  5, 5, 7, 7));
62  cf->AddFrame(f, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
63 
64  fCanvas = new TGCanvas(cf, 180, 110);
65  fListTree = new TGListTree(fCanvas, 0);
66  fCanvas->MapSubwindows();
67  cf->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
68 
69  //nameframe
70  fTitleFrame = new TGHorizontalFrame(cf, 100, 30);
71  fTitleFrame->AddFrame(new TGLabel(fTitleFrame, "Variable name"),
72  new TGLayoutHints(kLHintsLeft | kLHintsCenterY ,
73  0, 1, 0, 0));
74  fTitleFrame->AddFrame(new TGHorizontal3DLine(fTitleFrame),
75  new TGLayoutHints(kLHintsCenterY | kLHintsExpandX,
76  1, 1, 1, 1));
77  cf->AddFrame(fTitleFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop));
78 
79  TString name = "";
80  if (frame) {
81  name = frame->ClassName();
82  }
83  fLabel = new TGLabel(cf, name.Data());
84  cf->AddFrame(fLabel, new TGLayoutHints(kLHintsCenterX, 1, 1, 0, 0));
85 
86  TGCompositeFrame *sub = new TGHorizontalFrame(cf, 100, 30);
87  fFrameName = new TGTextEntry(sub, frame ? frame->GetName() : "noname");
88  fFrameName->SetAlignment(kTextLeft);
89  fFrameName->Resize(120, fFrameName->GetHeight());
90  sub->AddFrame(fFrameName, new TGLayoutHints(kLHintsTop | kLHintsCenterX,
91  2, 2, 0, 0));
92  fFrameName->SetEnabled(kTRUE);
93 
94  TGTextButton *btn = new TGTextButton(sub, " Set Name ");
95  sub->AddFrame(btn, new TGLayoutHints(kLHintsTop));
96  cf->AddFrame(sub, new TGLayoutHints(kLHintsTop | kLHintsCenterX,
97  2, 2, 0, 0));
98 
99  AddFrame(cf, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
100 
101  btn->Connect("Clicked()", "TGuiBldNameFrame", this, "UpdateName()");
102  btn->SetToolTipText("Set variable name");
103  fListTree->Connect("Clicked(TGListTreeItem*, Int_t)", "TGuiBldNameFrame",
104  this, "SelectFrameByItem(TGListTreeItem*, Int_t)");
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 /// Redraw frame (just a prototype).
109 
110 void TGuiBldNameFrame::DoRedraw()
111 {
112  //TColor *col = gROOT->GetColor(29);
113  //TRootGuiBuilder::SetBgndColor(fTitleFrame, col->GetPixel());
114  TGCompositeFrame::DoRedraw();
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Reset name frame.
119 
120 void TGuiBldNameFrame::Reset()
121 {
122  fFrameName->SetText("");
123  fLabel->SetText("");
124  DoRedraw();
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// Change selected frame.
129 
130 void TGuiBldNameFrame::ChangeSelected(TGFrame *frame)
131 {
132  fFrameName->Disconnect();
133 
134  if (!frame) {
135  Reset();
136  return;
137  }
138 
139  TString name = frame->ClassName();
140 
141  fLabel->SetText(name.Data());
142  fFrameName->SetText(frame->GetName());
143  Resize();
144 
145  TGCompositeFrame *main = GetMdi(frame);
146 
147  if (main) {
148  if (!fListTree->GetFirstItem())
149  MapItems(main);
150  else if ((fListTree->GetFirstItem()->GetUserData()) != main) {
151  //different MDI
152  //clear the list tree displayed
153  while (fListTree->GetFirstItem()) {
154  fListTree->DeleteItem(fListTree->GetFirstItem());
155  }
156  MapItems(main);
157  }
158  else // check if new items added or old ones reparented -> update tree
159  CheckItems(main);
160  }
161 
162  //highlight and open
163  TGListTreeItem *item = 0;
164  fListTree->OpenItem(fListTree->GetFirstItem()); //mdi
165  item = fListTree->FindItemByObj(fListTree->GetFirstItem(), frame);
166  if (item) {
167  fListTree->HighlightItem(item);
168  while (item->GetParent()) {
169  item = item->GetParent();
170  item->SetOpen(kTRUE);
171  }
172  }
173  fClient->NeedRedraw(fListTree, kTRUE);
174  fClient->NeedRedraw(fCanvas, kTRUE);
175  DoRedraw();
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// Set new name of frame, if it doesn't already exist in the same MDI frame.
180 
181 void TGuiBldNameFrame::UpdateName()
182 {
183  TGFrame *frame = fEditor->GetSelected();
184  TString ch = fFrameName->GetText();
185 
186  if (!frame) {
187  return;
188  }
189 
190  if (FindItemByName(fListTree, ch, fListTree->GetFirstItem())) {
191  fBuilder->UpdateStatusBar("Variable name already exists.");
192  TGCompositeFrame *cf = (TGCompositeFrame*)frame->GetParent();
193  int retval;
194  fBuilder->GetManager()->SetEditable(kFALSE);
195  new TGMsgBox(fClient->GetDefaultRoot(), fBuilder,
196  "Name conflict", "Variable name already exists.",
197  kMBIconExclamation, kMBOk, &retval);
198  cf->SetEditable(kTRUE);
199  // hack against selecting the message box itself
200  fBuilder->GetManager()->SelectFrame(frame);
201  frame->SetEditable(kTRUE);
202  }
203  else {
204  fBuilder->UpdateStatusBar("Variable name changed.");
205  frame->SetName(ch);
206  }
207 
208  //clear the list tree displayed
209  while (fListTree->GetFirstItem()) {
210  fListTree->DeleteItem(fListTree->GetFirstItem());
211  }
212 
213  TGCompositeFrame *main = GetMdi(frame);
214  MapItems(main);
215 
216  fClient->NeedRedraw(fListTree, kTRUE);
217  fClient->NeedRedraw(fFrameName);
218  DoRedraw();
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 /// Find the parent mdi frame
223 
224 TGCompositeFrame *TGuiBldNameFrame::GetMdi(TGFrame *frame)
225 {
226  TGFrame *p = frame;
227 
228  while (p && (p != fClient->GetDefaultRoot()) ) {
229  if (p->InheritsFrom(TGMdiFrame::Class())) {
230  return (TGCompositeFrame*)p;
231  }
232  else if (p->InheritsFrom(TGMainFrame::Class())) {
233  return (TGCompositeFrame*)p;
234  }
235  p = (TGFrame*)p->GetParent();
236  }
237  return 0;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 /// Map all the frames and subframes in mdi frame to the list tree.
242 
243 void TGuiBldNameFrame::MapItems(TGCompositeFrame *main)
244 {
245  if (!main) {
246  return;
247  }
248 
249  TList *list = main->GetList(); //list of all elements in the frame
250  TGFrameElement *el = 0;
251  TIter next(list);
252 
253  while ((el = (TGFrameElement *) next())) {
254  if (el->fFrame) {
255 
256  if (main->InheritsFrom(TGMdiFrame::Class()) ||
257  main->InheritsFrom(TGMainFrame::Class())) {
258 
259  // first loop, we're in the main frame -> add items directly
260  // to main frame folder of the tree list
261  if (!fListTree->FindChildByData(0, main)) {
262  // add main frame to root
263  fListTree->AddItem(0, main->GetName(), main);
264  }
265  //add other items to mainframe
266  fListTree->AddItem(fListTree->FindChildByData(0, main),
267  el->fFrame->GetName(), el->fFrame);
268 
269  } else { //means we're in recursion loop, browsing in subframe
270  // result is the name of the tree folder to which we want to
271  // place the element
272  TGListTreeItem *result = 0;
273  TGFrame *par = (TGFrame*)el->fFrame->GetParent();
274  result = fListTree->FindItemByObj(fListTree->GetFirstItem(), par);
275  if (result)
276  fListTree->AddItem(result, el->fFrame->GetName(), el->fFrame);
277  }
278 
279  if ( (el->fFrame->InheritsFrom(TGCompositeFrame::Class())) &&
280  (!(el->fFrame->InheritsFrom(TGMdiFrame::Class()))) ) {
281  //recursive call for composite subframes
282  main = (TGCompositeFrame*)(el->fFrame);
283  MapItems(main);
284  }
285  }
286  }
287 }
288 
289 ////////////////////////////////////////////////////////////////////////////////
290 /// Check if items are in the list tree and at the same place.
291 
292 Bool_t TGuiBldNameFrame::CheckItems(TGCompositeFrame *main)
293 {
294  TList *list = main->GetList(); //list of all elements in the frame
295 
296  TGFrameElement *el = 0;
297  TGListTreeItem *item = 0;
298  TIter next(list);
299  TGFrame *f = 0;
300  TGListTreeItem *par = 0;
301 
302  while ((el = (TGFrameElement *) next())) {
303  if (el && (el->fFrame)) {
304  item = fListTree->FindItemByObj(fListTree->GetFirstItem(),
305  el->fFrame);
306  if (!item) {
307  f = (TGFrame*)el->fFrame->GetParent();
308  if (f) {
309  par = fListTree->FindItemByObj(fListTree->GetFirstItem(), f);
310  if (par)
311  fListTree->AddItem(par, el->fFrame->GetName(), el->fFrame);
312  }
313  //return kTRUE; //selected item not found = is newly created
314  }
315  else if (item->GetParent() && item->GetParent()->GetUserData() !=
316  el->fFrame->GetParent()) {
317  f = (TGFrame*)el->fFrame->GetParent();
318  if (f) {
319  par = fListTree->FindItemByObj(fListTree->GetFirstItem(), f);
320  if (par)
321  fListTree->Reparent(item, par);
322  }
323  //return kTRUE; //parent of the item changed
324  }
325  if (el->fFrame->InheritsFrom(TGCompositeFrame::Class())) {
326  CheckItems((TGCompositeFrame*)el->fFrame);
327  }
328  }
329  }
330  return kFALSE; //treelist remains the same
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// Remove a frame.
335 
336 void TGuiBldNameFrame::RemoveFrame(TGFrame *frame)
337 {
338  TGListTreeItem *item;
339  item = fListTree->FindItemByObj(fListTree->GetFirstItem(), frame);
340  if (item) {
341  fListTree->DeleteItem(item);
342  }
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Find item with GetText == name. Search tree downwards starting at item.
347 
348 TGListTreeItem *TGuiBldNameFrame::FindItemByName(TGListTree *tree,
349  const char* name,
350  TGListTreeItem *item)
351 {
352  TGListTreeItem *fitem;
353  if (item && name) {
354  if (!strcmp(item->GetText(), name)) { //if names are equal
355  return item;
356  }
357  else {
358  if (item->GetFirstChild()) {
359  fitem = FindItemByName(tree, name, item->GetFirstChild());
360  if (fitem) return fitem;
361  }
362  return FindItemByName(tree, name, item->GetNextSibling());
363  }
364  }
365  return 0;
366 }
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// When list tree item is clicked, frame with that name is selected.
370 
371 void TGuiBldNameFrame::SelectFrameByItem(TGListTreeItem* item, Int_t)
372 {
373  TGFrame *frame = (TGFrame*)item->GetUserData();
374  if (frame) {
375  ((TGFrame*)frame->GetParent())->SetEditable(kTRUE);
376  fManager->SelectFrame(frame);
377  frame->SetEditable(kTRUE);
378  fClient->NeedRedraw(frame);
379  }
380 }
381 
382