Logo ROOT   6.21/01
Reference Guide
TGuiBldDragManager.cxx
Go to the documentation of this file.
1 // @(#)root/guibuilder:$Id: 99541fed972db7e4279fadcd4c0a0f0ae28a0a4d $
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 #include "TGuiBldDragManager.h"
14 #include "TGuiBldEditor.h"
15 #include "TRootGuiBuilder.h"
16 
17 #include "TTimer.h"
18 #include "TList.h"
19 #include "TClass.h"
20 #include "TSystem.h"
21 #include "TROOT.h"
22 #include "TColor.h"
23 #include "TImage.h"
24 
25 #include "TError.h"
26 #include "TClassMenuItem.h"
27 #include "TMethod.h"
28 #include "TBaseClass.h"
29 #include "TMethodArg.h"
30 #include "TToggle.h"
31 #include "TDataType.h"
32 #include "TObjString.h"
33 #include "TInterpreter.h"
34 
35 #include "KeySymbols.h"
36 #include "TGResourcePool.h"
37 #include "TGMenu.h"
38 #include "TGFileDialog.h"
39 #include "TGMsgBox.h"
40 #include "TRandom.h"
41 #include "TGButton.h"
42 #include "TGMdi.h"
43 #include "TGTextEntry.h"
44 #include "TGDockableFrame.h"
45 #include "TGColorDialog.h"
46 #include "TGFontDialog.h"
47 #include "TGComboBox.h"
48 #include "TGCanvas.h"
49 #include "TGLabel.h"
50 #include "TGProgressBar.h"
51 #include "TGScrollBar.h"
52 #include "TGTextEntry.h"
53 
54 #undef DEBUG_LOCAL
55 
56 //_____________________________________________________________________________
57 //
58 // TGuiBldDragManager
59 //
60 // Drag and drop manager used by the ROOT GUI Builder.
61 //_____________________________________________________________________________
62 
64 
65 static UInt_t gGridStep = 8;
69 
70 static const char *gSaveMacroTypes[] = {
71  "Macro files", "*.C",
72  "All files", "*",
73  0, 0
74 };
75 
76 static const char *gImageTypes[] = {
77  "All files", "*",
78  "XPM", "*.xpm",
79  "GIF", "*.gif",
80  "PNG", "*.png",
81  "JPEG", "*.jpg",
82  "TARGA", "*.tga",
83  "BMP", "*.bmp",
84  "ICO", "*.ico",
85  "XCF", "*.xcf",
86  "CURSORS", "*.cur",
87  "PPM", "*.ppm",
88  "PNM", "*.pnm",
89  "XBM", "*.xbm",
90  "TIFF", "*.tiff",
91  "Enacapsulated PostScript", "*.eps",
92  "PostScript", "*.ps",
93  "PDF", "*.pdf",
94  "ASImage XML","*.xml",
95  0, 0
96 };
97 
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 
101 
102 class TGuiBldMenuDialog : public TGTransientFrame {
103 
104 friend class TGuiBldDragManager;
105 
106 public:
107  TGButton *fOK; // OK button
108  //TGButton *fApply; // apply button
109  TGButton *fCancel; // cancel button
110  TObject *fObject; // selected object/frame
111  TMethod *fMethod; // method to be applied
112  TGLayoutHints *fL1; // internally used layout hints
113  TGLayoutHints *fL2; // internally used layout hints
114  TList *fWidgets; // list of widgets
115 
116 public:
117  virtual ~TGuiBldMenuDialog();
118  TGuiBldMenuDialog(const TGWindow *main, TObject *obj, TMethod *method);
119 
120  const char *GetParameters();
121  void CloseWindow();
122  void ConnectButtonSignals();
123  void Build();
124  void Popup();
125  void ApplyMethod();
126  void Add(const char *argname, const char *value, const char *type);
127 
128 };
129 
131 
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 /// ctor.
135 
136 TGuiBldMenuDialog::TGuiBldMenuDialog(const TGWindow *main, TObject *obj, TMethod *method) :
137  TGTransientFrame(gClient->GetDefaultRoot(), main, 200, 100)
138 {
139  fObject = obj;
140  fMethod = method;
141  if (!obj) return; // zombie
142 
143  fWidgets = new TList();
144 
145  fL1 = new TGLayoutHints(kLHintsTop | kLHintsCenterX, 0, 0, 5, 0);
146  fL2 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5);
147 
148  TString title = obj->ClassName();
149  title += "::";
150  title += method->GetName();
151 
152  Build();
153  ConnectButtonSignals();
154 
155  SetWindowName(title);
156  SetIconName(title);
158 
159  //TRootGuiBuilder::PropagateBgndColor(this, TRootGuiBuilder::GetBgnd());
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// dtor.
164 
165 TGuiBldMenuDialog::~TGuiBldMenuDialog()
166 {
167  fWidgets->Delete();
168  delete fWidgets;
169  delete fL1;
170  delete fL2;
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Connect buttons signals
175 
176 void TGuiBldMenuDialog::ConnectButtonSignals()
177 {
178  fOK->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogOK()");
179  //fApply->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogApply()");
180  fCancel->Connect("Pressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogCancel()");
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// execute method for obejct with input args
185 
186 void TGuiBldMenuDialog::ApplyMethod()
187 {
188  const char *params = GetParameters();
189  fObject->Execute(fMethod->GetName(), params);
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Return input parameters as single string.
194 
196 {
197  static char params[1024];
198  char param[256];
199 
200  TObjString *str;
201  TObject *obj;
202 
203  Int_t selfobjpos;
204 // if (fMenu->GetContextMenu()->GetSelectedMenuItem())
205 // selfobjpos = fMenu->GetContextMenu()->GetSelectedMenuItem()->GetSelfObjectPos();
206 // else
207  selfobjpos = -1;
208 
209  params[0] = 0;
210  TIter next(fWidgets);
211  Int_t nparam = 0;
212 
213  while ((obj = next())) { // first element is label, skip...
214  if (obj->IsA() != TGLabel::Class()) break;
215  obj = next(); // get either TGTextEntry or TGComboBox
216  str = (TObjString *) next(); // get type string
217 
218  nparam++;
219 
220  const char *type = str->GetString().Data();
221  const char *data = 0;
222 
223  if (obj->IsA() == TGTextEntry::Class())
224  data = ((TGTextEntry *) obj)->GetBuffer()->GetString();
225 
226  // TODO: Combobox...
227 
228  // if necessary, replace the selected object by it's address
229  if (selfobjpos == nparam-1) {
230  if (params[0]) strlcat(params, ",", 1024-strlen(params));
231  snprintf(param, 255, "(TObject*)0x%lx", (Long_t)fObject);
232  strlcat(params, param, 1024-strlen(params));
233  }
234 
235  if (params[0]) strlcat(params, ",", 1024-strlen(params));
236  if (data) {
237  if (!strncmp(type, "char*", 5))
238  snprintf(param, 255, "\"%s\"", data);
239  else
240  strlcpy(param, data, sizeof(param));
241  } else
242  strlcpy(param, "0", sizeof(param));
243 
244  strlcat(params, param, 1024-strlen(params));
245  }
246 
247  // if selected object is the last argument, have to insert it here
248  if (selfobjpos == nparam) {
249  if (params[0]) strlcat(params, ",", 1024-strlen(params));
250  snprintf(param, 255, "(TObject*)0x%lx", (Long_t)fObject);
251  strlcat(params, param, 1024-strlen(params));
252  }
253 
254  return params;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Create a string describing method argument.
259 
261 {
262  static TString ret;
263 
264  if (argument) {
265  ret.Form("(%s) %s", argument->GetTitle(), argument->GetName());
266  if (argument->GetDefault() && *(argument->GetDefault())) {
267  ret += " [default: ";
268  ret += argument->GetDefault();
269  ret += "]";
270  }
271  }
272 
273  return ret;
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// Add a label and text input field.
278 
279 void TGuiBldMenuDialog::Add(const char *argname, const char *value, const char *type)
280 {
281  TGLabel *l = new TGLabel(this, argname);
282  TGTextBuffer *b = new TGTextBuffer(20);
283  b->AddText(0, value);
284  TGTextEntry *t = new TGTextEntry(this, b);
285 
286  t->Connect("ReturnPressed()", "TGuiBldDragManager", gGuiBldDragManager, "DoDialogOK()");
287  t->Resize(260, t->GetDefaultHeight());
288  AddFrame(l, fL1);
289  AddFrame(t, fL2);
290 
291  fWidgets->Add(l);
292  fWidgets->Add(t);
293  fWidgets->Add(new TObjString(type));
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Close window
298 
299 void TGuiBldMenuDialog::CloseWindow()
300 {
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// Build dialog
306 
307 void TGuiBldMenuDialog::Build()
308 {
309  TMethodArg *argument = 0;
310  Int_t selfobjpos = -1;
311 
312  TIter next(fMethod->GetListOfMethodArgs());
313  Int_t argpos = 0;
314 
315  while ((argument = (TMethodArg *) next())) {
316  // Do not input argument for self object
317  if (selfobjpos != argpos) {
318  TString arg_name = CreateArgumentTitle(argument);
319  const char *argname = arg_name.Data();
320  const char *type = argument->GetTypeName();
321  TDataType *datatype = gROOT->GetType(type);
322  const char *charstar = "char*";
323  char basictype[32];
324 
325  if (datatype) {
326  strlcpy(basictype, datatype->GetTypeName(), sizeof(basictype));
327  } else {
329  if (strncmp(type, "enum", 4) && (cl && !(cl->Property() & kIsEnum)))
330  Warning("Dialog", "data type is not basic type, assuming (int)");
331  strlcpy(basictype, "int", sizeof(basictype));
332  }
333 
334  if (strchr(argname, '*')) {
335  strlcat(basictype, "*", 32-strlen(basictype));
336  type = charstar;
337  }
338 
339  TDataMember *m = argument->GetDataMember();
340  if (m && m->GetterMethod(fObject->IsA())) {
341 
342  // Get the current value and form it as a text:
343  char val[256];
344 
345  if (!strncmp(basictype, "char*", 5)) {
346  char *tdefval = 0;
347  m->GetterMethod()->Execute(fObject, "", &tdefval);
348  if (tdefval && strlen(tdefval))
349  strlcpy(val, tdefval, sizeof(val));
350  } else if (!strncmp(basictype, "float", 5) ||
351  !strncmp(basictype, "double", 6)) {
352  Double_t ddefval = 0.0;
353  m->GetterMethod()->Execute(fObject, "", ddefval);
354  snprintf(val, 255, "%g", ddefval);
355  } else if (!strncmp(basictype, "char", 4) ||
356  !strncmp(basictype, "bool", 4) ||
357  !strncmp(basictype, "int", 3) ||
358  !strncmp(basictype, "long", 4) ||
359  !strncmp(basictype, "short", 5)) {
360  Long_t ldefval = 0L;
361  m->GetterMethod()->Execute(fObject, "", ldefval);
362  snprintf(val, 255, "%li", ldefval);
363  }
364 
365  // Find out whether we have options ...
366 
367  TList *opt;
368  // coverity[returned_pointer]: keep for later use
369  if ((opt = m->GetOptions())) {
370  Warning("Dialog", "option menu not yet implemented");
371 
372  } else {
373  // we haven't got options - textfield ...
374  Add(argname, val, type);
375  }
376  } else { // if m not found ...
377 
378  char val[256] = "";
379  const char *tval = argument->GetDefault();
380  if (tval) strlcpy(val, tval, sizeof(val));
381  Add(argname, val, type);
382  }
383  }
384  argpos++;
385  }
386 
387  // add OK, Apply, Cancel buttons
388  TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
389  TGLayoutHints *l1 = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0);
390  UInt_t width = 0, height = 0;
391 
392  fWidgets->Add(l1);
393 
394  fOK = new TGTextButton(hf, "&OK", 1);
395  hf->AddFrame(fOK, l1);
396  fWidgets->Add(fOK);
397  height = fOK->GetDefaultHeight();
398  width = TMath::Max(width, fOK->GetDefaultWidth());
399 
400 /*
401  fApply = new TGTextButton(hf, "&Apply", 2);
402  hf->AddFrame(fApply, l1);
403  fWidgets->Add(fApply);
404  height = fApply->GetDefaultHeight();
405  width = TMath::Max(width, fApply->GetDefaultWidth());
406 */
407 
408  fCancel = new TGTextButton(hf, "&Cancel", 3);
409  hf->AddFrame(fCancel, l1);
410  fWidgets->Add(fCancel);
411  height = fCancel->GetDefaultHeight();
412  width = TMath::Max(width, fCancel->GetDefaultWidth());
413 
414  // place buttons at the bottom
415  l1 = new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5);
416  AddFrame(hf, l1);
417  fWidgets->Add(l1);
418  fWidgets->Add(hf);
419 
420  hf->Resize((width + 20) * 3, height);
421 
422  // map all widgets and calculate size of dialog
423  MapSubwindows();
424 }
425 
426 ////////////////////////////////////////////////////////////////////////////////
427 /// Popup dialog.
428 
429 void TGuiBldMenuDialog::Popup()
430 {
432  UInt_t height = GetDefaultHeight();
433 
434  Resize(width, height);
435 
436  Window_t wdummy;
437  Int_t x = (Int_t)((TGFrame*)fMain)->GetWidth();
438  Int_t y = (Int_t)((TGFrame*)fMain)->GetHeight();
439  gVirtualX->TranslateCoordinates(fMain->GetId(), fClient->GetDefaultRoot()->GetId(),
440  x, y, x, y, wdummy);
441 
442  x += 10;
443  y += 10;
444 
445  // make the message box non-resizable
446  SetWMSize(width, height);
447  SetWMSizeHints(width, height, width, height, 0, 0);
448 
454 
455  Move(x, y);
456  SetWMPosition(x, y);
457  MapRaised();
458  fClient->WaitFor(this);
459 }
460 
461 
462 ///////////////////////// auxilary static functions ///////////////////////////
463 ////////////////////////////////////////////////////////////////////////////////
464 /// Helper. Return a window located at point x,y (in screen coordinates)
465 
467 {
468  Window_t src, dst, child;
469  Window_t ret = 0;
470  Int_t xx = x;
471  Int_t yy = y;
472 
474  !gClient->IsEditable()) return 0;
475 
476  dst = src = child = gVirtualX->GetDefaultRootWindow();
477 
478  while (child && dst) {
479  src = dst;
480  dst = child;
481  gVirtualX->TranslateCoordinates(src, dst, xx, yy, xx, yy, child);
482  ret = dst;
483  }
484  return ret;
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 /// Helper to layout
489 
490 static void layoutFrame(TGFrame *frame)
491 {
492  if (!frame || !frame->InheritsFrom(TGCompositeFrame::Class())) {
493  return;
494  }
495 
496  TGCompositeFrame *comp = (TGCompositeFrame*)frame;
497 
498  if (comp->GetLayoutManager()) {
499  comp->GetLayoutManager()->Layout();
500  } else {
501  comp->Layout();
502  }
503  gClient->NeedRedraw(comp);
504 
505  TIter next(comp->GetList());
506  TGFrameElement *fe;
507 
508  while ((fe = (TGFrameElement*)next())) {
509  layoutFrame(fe->fFrame);
510  gClient->NeedRedraw(fe->fFrame);
511  }
512 }
513 
514 ////////////////////////////////////////////////////////////////////////////////
515 /// Our own error handler (not used yet)
516 
517 static void GuiBldErrorHandler(Int_t /*level*/, Bool_t /*abort*/,
518  const char * /*location*/, const char * /*msg*/)
519 {
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 class TGuiBldDragManagerGrid {
524 
525 public:
526  static UInt_t fgStep;
527  static ULong_t fgPixel;
528  static TGGC *fgBgnd;
529 
530  Pixmap_t fPixmap;
531  TGWindow *fWindow;
532  Int_t fWinId;
533 
534  TGuiBldDragManagerGrid();
535  ~TGuiBldDragManagerGrid();
536  void Draw();
537  void SetStep(UInt_t step);
538  void InitPixmap();
539  void InitBgnd();
540 };
541 
542 UInt_t TGuiBldDragManagerGrid::fgStep = gGridStep;
543 ULong_t TGuiBldDragManagerGrid::fgPixel = 0;
544 TGGC *TGuiBldDragManagerGrid::fgBgnd = 0;
545 
546 ////////////////////////////////////////////////////////////////////////////////
547 /// Create a grid background for the selected window
548 
549 TGuiBldDragManagerGrid::TGuiBldDragManagerGrid()
550 {
551  fPixmap = 0;
552  fWindow = 0;
553  fWinId = 0;
554 
555  if (!fgBgnd) {
556  InitBgnd();
557  }
558  SetStep(fgStep);
559 }
560 
561 ////////////////////////////////////////////////////////////////////////////////
562 /// ctor.
563 
564 TGuiBldDragManagerGrid::~TGuiBldDragManagerGrid()
565 {
566  fWindow = gClient->GetWindowById(fWinId);
567 
568  if (fWindow) {
569  fWindow->SetBackgroundPixmap(0);
570  fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
571  gClient->NeedRedraw(fWindow, kTRUE);
572  }
573  if (fPixmap) {
574  gVirtualX->DeletePixmap(fPixmap);
575  }
576 
577  fPixmap = 0;
578  fWindow = 0;
579  fWinId = 0;
580 }
581 
582 ////////////////////////////////////////////////////////////////////////////////
583 /// Set the grid step
584 
585 void TGuiBldDragManagerGrid::SetStep(UInt_t step)
586 {
587  if (!gClient || !gClient->IsEditable()) {
588  return;
589  }
590 
591  fWindow = (TGWindow*)gClient->GetRoot();
592  fWinId = fWindow->GetId();
593  fgStep = step;
594  InitPixmap();
595 
596 }
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /// Create grid background.
600 
601 void TGuiBldDragManagerGrid::InitBgnd()
602 {
603  if (fgBgnd) {
604  return;
605  }
606 
607  fgBgnd = new TGGC(TGFrame::GetBckgndGC());
608 
609  Float_t r, g, b;
610 
611  r = 232./255;
612  g = 232./255;
613  b = 226./255;
614 
615  fgPixel = TColor::RGB2Pixel(r, g, b);
616  fgBgnd->SetForeground(fgPixel);
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// Create grid background pixmap
621 
622 void TGuiBldDragManagerGrid::InitPixmap()
623 {
624  if (fPixmap) {
625  gVirtualX->DeletePixmap(fPixmap);
626  }
627 
628  fPixmap = gVirtualX->CreatePixmap(gClient->GetDefaultRoot()->GetId(), fgStep, fgStep);
629  gVirtualX->FillRectangle(fPixmap, fgBgnd->GetGC(), 0, 0, fgStep, fgStep);
630 
631  if(fgStep > 2) {
632  gVirtualX->FillRectangle(fPixmap, TGFrame::GetShadowGC()(),
633  fgStep - 1, fgStep - 1, 1, 1);
634  }
635 }
636 
637 ////////////////////////////////////////////////////////////////////////////////
638 /// Draw grid over editted frame.
639 
641 {
642  if (!gClient || !gClient->IsEditable()) {
643  return;
644  }
645 
646  fWindow = gClient->GetWindowById(fWinId);
647 
648  if (fWindow && (fWindow != gClient->GetRoot())) {
649  fWindow->SetBackgroundPixmap(0);
650  fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
651  gClient->NeedRedraw(fWindow);
652  }
653 
654  if (!fPixmap) {
655  InitPixmap();
656  }
657 
658  fWindow = (TGWindow*)gClient->GetRoot();
659  fWinId = fWindow->GetId();
660  fWindow->SetBackgroundPixmap(fPixmap);
661 
662  gClient->NeedRedraw(fWindow);
663 }
664 
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 class TGuiBldDragManagerRepeatTimer : public TTimer {
668 
669 private:
670  TGuiBldDragManager *fManager; // back pointer
671 
672 public:
673  TGuiBldDragManagerRepeatTimer(TGuiBldDragManager *m, Long_t ms) :
674  TTimer(ms, kTRUE) { fManager = m; }
675  Bool_t Notify() { fManager->HandleTimer(this); Reset(); return kFALSE; }
676 };
677 
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 class TGGrabRect : public TGFrame {
681 
682 private:
683  Pixmap_t fPixmap;
684  ECursor fType;
685 
686 public:
687  TGGrabRect(Int_t type);
688  ~TGGrabRect() {}
689 
691  ECursor GetType() const { return fType; }
692 };
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 /// ctor.
696 
697 TGGrabRect::TGGrabRect(Int_t type) :
698  TGFrame(gClient->GetDefaultRoot(), 8, 8, kTempFrame)
699 {
700  fType = kTopLeft;
701 
702  switch (type) {
703  case 0:
704  fType = kTopLeft;
705  break;
706  case 1:
707  fType = kTopSide;
708  break;
709  case 2:
710  fType = kTopRight;
711  break;
712  case 3:
713  fType = kBottomLeft;
714  break;
715  case 4:
716  fType = kLeftSide;
717  break;
718  case 5:
719  fType = kRightSide;
720  break;
721  case 6:
722  fType = kBottomSide;
723  break;
724  case 7:
726  break;
727  }
728 
731  attr.fOverrideRedirect = kTRUE;
732  attr.fSaveUnder = kTRUE;
733 
734  gVirtualX->ChangeWindowAttributes(fId, &attr);
735 
736  fPixmap = gVirtualX->CreatePixmap(gVirtualX->GetDefaultRootWindow(), 8, 8);
737  const TGGC *bgc = TRootGuiBuilder::GetPopupHlghtGC();
738 //fClient->GetResourcePool()->GetSelectedBckgndGC();
739  TGGC *gc = new TGGC(TGFrame::GetBckgndGC());
740 
741  Pixel_t back;
742  fClient->GetColorByName("black", back);
743  gc->SetBackground(back);
744  gc->SetForeground(back);
745 
746  gVirtualX->FillRectangle(fPixmap, bgc->GetGC(), 0, 0, 7, 7);
747  gVirtualX->DrawRectangle(fPixmap, gc->GetGC(), 0, 0, 7, 7);
748 // gVirtualX->DrawRectangle(fPixmap, fClient->GetResourcePool()->GetSelectedBckgndGC()->GetGC(), 1, 1, 5, 5);
749 
750  AddInput(kButtonPressMask);
751  SetBackgroundPixmap(fPixmap);
752 
753  gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(fType));
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// Handle button press event.
758 
759 Bool_t TGGrabRect::HandleButton(Event_t *ev)
760 {
762  return kTRUE;
763 }
764 
765 ////////////////////////////////////////////////////////////////////////////////
766 class TGAroundFrame : public TGFrame {
767 
768 public:
769  TGAroundFrame();
770  ~TGAroundFrame() {}
771 };
772 
773 ////////////////////////////////////////////////////////////////////////////////
774 /// ctor.
775 
776 TGAroundFrame::TGAroundFrame() : TGFrame(gClient->GetDefaultRoot(), 1, 1,
778 {
781  attr.fOverrideRedirect = kTRUE;
782  attr.fSaveUnder = kTRUE;
783 
784  gVirtualX->ChangeWindowAttributes(fId, &attr);
785  ULong_t blue;
786  fClient->GetColorByName("blue", blue);
787  SetBackgroundColor(blue);
788 }
789 
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 class TGuiBldDragManagerPimpl {
793 
794 friend class TGuiBldDragManager;
795 
796 private:
797  TGuiBldDragManager *fManager; // drag and drop manager
798  TTimer *fRepeatTimer; // repeat rate timer (when mouse stays pressed)
799  TGFrame *fGrab; // grabbed/selected frame
800  TGLayoutHints *fGrabLayout; // layout of grabbed frame
801  TGFrame *fSaveGrab; // used during context menu handling
802  TGFrame *fClickFrame; // last clicked frame
803  TGuiBldDragManagerGrid *fGrid; //
804  ECursor fResizeType; // defines resize type
805  Int_t fX0, fY0; // initial drag position in pixels
806  Int_t fX, fY; // current drag position in pixels
807  Int_t fXf, fYf; // offset of inititial position inside frame
808  Int_t fGrabX, fGrabY; //
809  const TGWindow *fGrabParent; // parent of the grabbed/seleceted frame
810  Int_t fLastPopupAction;//
811  Bool_t fReplaceOn;
812  TGGrabRect *fGrabRect[8]; // small rectangles drawn over grabbed/selected frame
813  TGFrame *fAroundFrame[4]; // red lines drawn over layouted frame
814  Bool_t fGrabRectHidden;
815  TGFrameElement *fGrabListPosition;
816  Bool_t fButtonPressed; //
817  Bool_t fCompacted; //
818  TGFrame *fPlane; // highlighted plain composite frame when mose is moving
819  TGFrame *fSpacePressedFrame; // frame which was grabbed via spacebar pressed
820  Bool_t fPlacePopup; // kTRUE is menu fo frame was placed
821  TList *fFrameMenuTrash; // trash list
822  TGFrame *fMenuObject; // object/frame for which context menu is created
823 
824 public:
825  TGuiBldDragManagerPimpl(TGuiBldDragManager *m) {
826  fManager = m;
827  fRepeatTimer = new TGuiBldDragManagerRepeatTimer(m, 100);
828 
829  int i = 0;
830  for (i = 0; i <8; i++) {
831  fGrabRect[i] = new TGGrabRect(i);
832  }
833  for (i = 0; i <4; i++) {
834  fAroundFrame[i] = new TGAroundFrame();
835  }
836 
837  fFrameMenuTrash = new TList();
838 
839  ResetParams();
840  }
841  void ResetParams() {
842  fGrab = 0;
843  fSaveGrab = 0;
844  fClickFrame = 0;
845  fGrid = 0;
846  fX0 = fY0 = fX = fY = fXf = fYf = fGrabX = fGrabY = 0;
847  fGrabParent = 0;
848  fResizeType = kPointer;
849  fLastPopupAction = kNoneAct;
850  fReplaceOn = kFALSE;
851  fGrabLayout = 0;
852  fGrabRectHidden = kFALSE;
853  fGrabListPosition = 0;
854  fButtonPressed = kFALSE;
855  fCompacted = kFALSE;
856  fPlane = 0;
857  fSpacePressedFrame = 0;
858  fPlacePopup = kFALSE;
859  fFrameMenuTrash->Delete();
860  fMenuObject = 0;
861  }
862 
863  ~TGuiBldDragManagerPimpl() {
864  int i;
865  for (i = 0; i <8; i++) {
866  delete fGrabRect[i];
867  }
868  for (i = 0; i <4; i++) {
869  delete fAroundFrame[i];
870  }
871 
872  delete fRepeatTimer;
873  delete fGrab;
874  fFrameMenuTrash->Delete();
875  delete fFrameMenuTrash;
876 
877  if (fPlane) {
878  fPlane->ChangeOptions(fPlane->GetOptions() & ~kRaisedFrame);
879  gClient->NeedRedraw(fPlane, kTRUE);
880  fPlane = 0;
881  }
882  }
883 };
884 
885 
886 ////////////////////////////////////////////////////////////////////////////////
888  TGFrame(gClient->GetDefaultRoot(), 1, 1)
889 {
890  // Constructor. Create "fantom window".
891 
894  attr.fOverrideRedirect = kTRUE;
895  attr.fSaveUnder = kTRUE;
896 
897  gVirtualX->ChangeWindowAttributes(fId, &attr);
898 
899  gGuiBldDragManager = this;
900  fPimpl = new TGuiBldDragManagerPimpl(this);
901 
903  fFrameMenu = 0;
904  fLassoMenu = 0;
905  fEditor = 0;
906  fBuilder = 0;
909  fStop = kTRUE;
910  fSelected = 0;
911  fListOfDialogs = 0;
912 
913  Reset1();
915 
916  TString tmpfile = gSystem->TempDirectory();
917  char *s = gSystem->ConcatFileName(tmpfile.Data(),
918  TString::Format("RootGuiBldClipboard%d.C", gSystem->GetPid()));
919  fPasteFileName = s;
920  delete [] s;
921 
922  s = gSystem->ConcatFileName(tmpfile.Data(),
923  TString::Format("RootGuiBldTmpFile%d.C", gSystem->GetPid()));
924  fTmpBuildFile = s;
925  delete [] s;
926 
927  fName = "Gui Builder Drag Manager";
929 
930  // let's try to solve the problems by myself
932 
933  fClient->UnregisterWindow(this);
934 }
935 
936 ////////////////////////////////////////////////////////////////////////////////
937 /// Destructor
938 
940 {
942 
943  delete fPimpl;
944 
945  delete fBuilder;
946  fBuilder = 0;
947 
948 // delete fEditor;
949 // fEditor = 0;
950 
951  delete fFrameMenu;
952  fFrameMenu =0;
953 
954  delete fLassoMenu;
955  fLassoMenu = 0;
956 
959  }
960 
961  delete fListOfDialogs;
962 
963  gGuiBldDragManager = 0;
964 }
965 
966 ////////////////////////////////////////////////////////////////////////////////
967 /// Reset some parameters
968 
970 {
972  fTargetId = 0;
973  fPimpl->fPlacePopup = kFALSE;
975 }
976 
977 ////////////////////////////////////////////////////////////////////////////////
978 /// Create a list of dialog methods
979 
981 {
982  fListOfDialogs = new TList();
983 
984  TList *methodList = IsA()->GetListOfMethods();
985  TIter next(methodList);
986  TString str;
987  TMethod *method;
988 
989  while ((method = (TMethod*) next())) {
990  str = method->GetCommentString();
991  if (str.Contains("*DIALOG")) {
992  fListOfDialogs->Add(method);
993  }
994  }
995 }
996 
997 ////////////////////////////////////////////////////////////////////////////////
998 /// Draw grid on editable frame and restore background on previuosly editted one
999 
1001 {
1002  if (fStop) {
1003  return;
1004  }
1005 
1006  delete fPimpl->fGrid;
1007 
1008  fPimpl->fGrid = new TGuiBldDragManagerGrid();
1009  fPimpl->fGrid->Draw();
1010 }
1011 
1012 ////////////////////////////////////////////////////////////////////////////////
1013 /// Return the grid step
1014 
1016 {
1017  return fPimpl->fGrid ? fPimpl->fGrid->fgStep : 1;
1018 }
1019 
1020 ////////////////////////////////////////////////////////////////////////////////
1021 /// Set the grid step
1022 
1024 {
1025  fPimpl->fGrid->SetStep(step);
1026 }
1027 
1028 ////////////////////////////////////////////////////////////////////////////////
1029 /// Return kTRUE if event is rejected for processing by drag manager
1030 
1032 {
1033  if (fStop || !fClient || !fClient->IsEditable()) return kTRUE;
1034  if (event->fType == kClientMessage) return kFALSE;
1035  if (event->fType == kDestroyNotify) return kFALSE;
1036 
1037  TGWindow *w = fClient->GetWindowById(event->fWindow);
1038 
1039  if (w) {
1040  if (IsEditDisabled(w)) {
1041  w = GetEditableParent((TGFrame*)w);
1042  return !w;
1043  }
1044  } else {
1045  return kTRUE;
1046  }
1047  return kFALSE;
1048 }
1049 
1050 ////////////////////////////////////////////////////////////////////////////////
1051 /// Return a pointer to the parent window (which is being editted)
1052 
1054 {
1055  if (fStop || !id) {
1056  return 0;
1057  }
1058 
1059  Window_t preparent = id;
1060  Window_t parent = (Window_t)gVirtualX->GetParent(id);
1061 
1062  while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
1063  if (parent == fClient->GetRoot()->GetId()) {
1064  TGWindow *w = fClient->GetWindowById(preparent);
1065  return (w ? (TGFrame*)w : 0);
1066  }
1067  preparent = parent;
1068  parent = gVirtualX->GetParent(parent);
1069  }
1070  return 0;
1071 }
1072 
1073 ////////////////////////////////////////////////////////////////////////////////
1074 /// Find the first composite parent of window
1075 
1077 {
1078  if (fStop || !id) {
1079  return 0;
1080  }
1081 
1082  Window_t parent = id;
1083 
1084  while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
1085  TGWindow *w = fClient->GetWindowById(parent);
1086  if (w) {
1088  return (TGCompositeFrame*)w;
1089  }
1090  }
1091  parent = gVirtualX->GetParent(parent);
1092  }
1093  return 0;
1094 }
1095 
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// Set cursor for selcted/grabbed frame.
1098 
1100 {
1101  if (fStop) {
1102  return;
1103  }
1104 
1105  static UInt_t gid = 0;
1106  static UInt_t rid = 0;
1107 
1108  if (fPimpl->fGrab && (gid != fPimpl->fGrab->GetId())) {
1109  gVirtualX->SetCursor(fPimpl->fGrab->GetId(),
1110  gVirtualX->CreateCursor((ECursor)cur));
1111  gid = fPimpl->fGrab->GetId();
1112  }
1113  if (fClient->IsEditable() && (rid != fClient->GetRoot()->GetId())) {
1114  gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
1115  gVirtualX->CreateCursor((ECursor)cur));
1116  rid = fClient->GetRoot()->GetId();
1117  }
1118 }
1119 
1120 ////////////////////////////////////////////////////////////////////////////////
1121 /// Check resize type event.
1122 
1124 {
1125  if (fStop) {
1126  return kFALSE;
1127  }
1128 
1129  Bool_t ret = kFALSE;
1130  fPimpl->fResizeType = kPointer;
1131 
1132  for (int i = 0; i < 8; i++) {
1133  if (fPimpl->fGrabRect[i]->GetId() == event->fWindow) {
1134  fPimpl->fResizeType = fPimpl->fGrabRect[i]->GetType();
1135  ret = kTRUE;
1136  }
1137  }
1138 
1139  if ((event->fType == kButtonPress) && (fPimpl->fResizeType != kPointer)) {
1141  ret = kTRUE;
1142  }
1143 
1144  SetCursorType(ret ? fPimpl->fResizeType : kPointer);
1145  return ret;
1146 }
1147 
1148 ////////////////////////////////////////////////////////////////////////////////
1149 /// Redraw the editted window
1150 
1152 {
1153  if (fStop || !fClient || !fClient->IsEditable()) {
1154  return;
1155  }
1156 
1157  TGWindow *root = (TGWindow*)fClient->GetRoot();
1158 
1159  fClient->NeedRedraw(root, kTRUE);
1160 
1161  if (fBuilder) {
1163  }
1164 }
1165 
1166 ////////////////////////////////////////////////////////////////////////////////
1167 /// Switch editable
1168 
1170 {
1171  if (fStop || !frame) {
1172  return;
1173  }
1174 
1175  TGCompositeFrame *comp = 0;
1176 
1177  if (frame->InheritsFrom(TGCompositeFrame::Class()) && CanChangeLayout(frame)) {
1178  comp = (TGCompositeFrame *)frame;
1179  } else if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
1180  comp = (TGCompositeFrame *)frame->GetParent();
1181  }
1182 
1183  if (!comp) {
1184  return;
1185  }
1186 
1187  TString str = comp->ClassName();
1188  str += "::";
1189  str += comp->GetName();
1190 
1191  if (IsEditDisabled(comp)) {
1192  if (fBuilder) {
1193  str += " cannot be editted.";
1194  fBuilder->UpdateStatusBar(str.Data());
1195  }
1196  return;
1197  }
1198 
1199  if (frame != comp) {
1200  SelectFrame(frame);
1201  }
1202 
1203  if (comp->IsEditable()) {
1204  return;
1205  }
1206 
1207  RaiseMdiFrame(comp);
1208  comp->SetEditable(kTRUE);
1209 }
1210 
1211 ////////////////////////////////////////////////////////////////////////////////
1212 /// Grab/Select frame
1213 
1215 {
1216  if (fStop || !frame || (frame->GetParent() == fClient->GetDefaultRoot()) ||
1217  !fClient->IsEditable()) {
1218  return;
1219  }
1220 
1221  TString str = frame->ClassName();
1222  str += "::";
1223  str += frame->GetName();
1224 
1225  if (IsGrabDisabled(frame)) {
1226  if (fBuilder) {
1227  str += "can not be selected";
1228  fBuilder->UpdateStatusBar(str.Data());
1229  }
1230  return;
1231  }
1232 
1233  // do not grab mdi frames (quick hack)
1234  if (fBuilder && frame->InheritsFrom(TGMdiFrame::Class())) {
1235  return;
1236  }
1237 
1238 
1239  static Int_t x, x0, y, y0, xx, yy;
1240  Window_t c;
1241 
1242  RaiseMdiFrame(FindMdiFrame(frame));
1243  frame->MapRaised();
1244 
1245  if (!add) {
1246 
1248 
1249  gVirtualX->TranslateCoordinates(frame->GetId(),
1251  0, 0, x0, y0, c);
1252 
1253  x = x0 + frame->GetWidth();
1254  y = y0 + frame->GetHeight();
1255 
1256  if (fBuilder) {
1257  str += " selected";
1258  str += (IsEditDisabled(frame) || IsFixedLayout(frame) ? ". This frame cannot be editted." :
1259  " ");
1260  str += " Press SpaceBar to unselect the frame.";
1261  if (IsFixedSize(frame)) str += " This frame cannot be resized.";
1262 
1263  fBuilder->UpdateStatusBar(str.Data());
1264  }
1265 
1266  } else { //shift mask is on
1267 
1268  gVirtualX->TranslateCoordinates(frame->GetId(),
1270  0, 0, xx, yy, c);
1271 
1273  fPimpl->fX0 = x0 = TMath::Min(x0, xx);
1274  fPimpl->fX = x = TMath::Max(x, xx + (Int_t)frame->GetWidth());
1275  fPimpl->fY0 = y0 = TMath::Min(y0, yy);
1276  fPimpl->fY = y = TMath::Max(y, yy + (Int_t)frame->GetHeight());
1277 
1278  DrawLasso();
1279  }
1280 
1281  fFrameUnder = fPimpl->fGrab = frame;
1282  fPimpl->fGrab->RequestFocus();
1283 
1284  // quick hack. the special case for TGCanvases
1285  if (frame->InheritsFrom(TGCanvas::Class())) {
1286  fSelected = ((TGCanvas*)frame)->GetContainer();
1287 
1288  if (!IsEditDisabled(fSelected)) {
1290  if (fBuilder && fBuilder->GetAction()) {
1292  }
1293  }
1294  } else {
1295  fSelected = fPimpl->fGrab;
1296  }
1297  ChangeSelected(fPimpl->fGrab);
1298 
1300 
1302  DrawGrabRectangles(fPimpl->fGrab);
1303 }
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 /// Inform outside wold that selected frame was changed
1307 
1309 {
1310  if (fStop) {
1311  return;
1312  }
1313 
1314  TGFrame *sel = fr;
1315 
1316  if (fBuilder && (sel == fBuilder->GetMdiMain()->GetCurrent())) {
1317  sel = 0;
1318  }
1319 
1320  if (!fr) {
1321  UngrabFrame();
1322  }
1323 
1324  if (fEditor) {
1325  fEditor->ChangeSelected(sel);
1326  }
1327 
1328  if (fBuilder) {
1329  fBuilder->ChangeSelected(sel);
1330  //fBuilder->Update();
1331  }
1332 }
1333 
1334 ////////////////////////////////////////////////////////////////////////////////
1335 /// grab frame (see SelectFrame)
1336 
1338 {
1339  if (fStop || !frame || !fClient->IsEditable()) {
1340  return;
1341  }
1342 
1343  fPimpl->fGrabParent = frame->GetParent();
1344  fPimpl->fGrabX = frame->GetX();
1345  fPimpl->fGrabY = frame->GetY();
1346 
1347  Window_t c;
1348 
1349  gVirtualX->TranslateCoordinates(frame->GetId(),
1351  0, 0, fPimpl->fX0, fPimpl->fY0, c);
1352 
1353  fPimpl->fX = fPimpl->fX0;
1354  fPimpl->fY = fPimpl->fY0;
1355 
1356  if (frame->GetFrameElement() && frame->GetFrameElement()->fLayout) {
1357  fPimpl->fGrabLayout = frame->GetFrameElement()->fLayout;
1358  }
1359 
1360  if (fPimpl->fGrabParent && frame->GetFrameElement() &&
1361  fPimpl->fGrabParent->InheritsFrom(TGCompositeFrame::Class())) {
1362  TList *li = ((TGCompositeFrame*)fPimpl->fGrabParent)->GetList();
1363  fPimpl->fGrabListPosition = (TGFrameElement*)li->Before(frame->GetFrameElement());
1364  ((TGCompositeFrame*)fPimpl->fGrabParent)->RemoveFrame(frame);
1365  }
1366 
1367  SetWindowAttributes_t attr;
1369  attr.fOverrideRedirect = kTRUE;
1370  attr.fSaveUnder = kTRUE;
1371 
1372  gVirtualX->ChangeWindowAttributes(frame->GetId(), &attr);
1373 
1374  frame->UnmapWindow();
1375  frame->ReparentWindow(fClient->GetDefaultRoot(), fPimpl->fX0, fPimpl->fY0);
1376  gVirtualX->Update(1);
1377  frame->Move(fPimpl->fX0, fPimpl->fY0);
1378  frame->MapRaised();
1379 
1380  if (fBuilder) {
1381  //fBuilder->Update();
1382  TString str = frame->ClassName();
1383  str += "::";
1384  str += frame->GetName();
1385  str += " is grabbed";
1386 
1387  fBuilder->UpdateStatusBar(str.Data());
1388  }
1389 }
1390 
1391 ////////////////////////////////////////////////////////////////////////////////
1392 /// Ungrab/Unselect selected/grabbed frame.
1393 
1395 {
1396  if (fStop || !fPimpl->fGrab) {
1397  return;
1398  }
1399 
1402 
1403  DoRedraw();
1404 
1405  if (fBuilder) {
1406  //fBuilder->Update();
1407  TString str = fPimpl->fGrab->ClassName();
1408  str += "::";
1409  str += fPimpl->fGrab->GetName();
1410  str += " ungrabbed";
1411  fBuilder->UpdateStatusBar(str.Data());
1412  }
1413  fSelected = fPimpl->fGrab = 0;
1414 }
1415 
1416 ////////////////////////////////////////////////////////////////////////////////
1417 /// Helper for IsPointVisible
1418 
1419 static Bool_t IsParentOfGrab(Window_t id, const TGWindow *grab)
1420 {
1421  const TGWindow *parent = grab;
1422 
1423  while (parent && (parent != gClient->GetDefaultRoot())) {
1424  if (parent->GetId() == id) {
1425  return kTRUE;
1426  }
1427  parent = parent->GetParent();
1428  }
1429 
1430  return kFALSE;
1431 }
1432 
1433 ////////////////////////////////////////////////////////////////////////////////
1434 /// Helper function for IsSelectedWindow method
1435 
1437 {
1438  Window_t w = gVirtualX->GetDefaultRootWindow();
1439  Window_t src, dst, child;
1440  Int_t x = xi;
1441  Int_t y = yi;
1442  Bool_t ret = kFALSE;
1443 
1444  gVirtualX->TranslateCoordinates(fPimpl->fGrab->GetId(), w, x, y, x, y, child);
1445 
1446  dst = src = child = w;
1447 
1448  while (child) {
1449  src = dst;
1450  dst = child;
1451  gVirtualX->TranslateCoordinates(src, dst, x, y, x, y, child);
1452 
1453  if (IsParentOfGrab(child, fPimpl->fGrab)) {
1454  return kTRUE;
1455  }
1456  }
1457 
1458  return ret;
1459 }
1460 
1461 ////////////////////////////////////////////////////////////////////////////////
1462 /// Return kTRUE if grabbed/selected frame is not overlapped by other windows.
1463 
1465 {
1466  if (fStop || !fPimpl->fGrab || !fClient->IsEditable()) {
1467  return kFALSE;
1468  }
1469 
1470  if (fBuilder) {
1472  if (mdi && (mdi != fBuilder->GetMdiMain()->GetCurrent())) {
1473  return kFALSE;
1474  }
1475  }
1476 
1477  // popup menu was placed
1478  if (fPimpl->fPlacePopup) {
1479  return kTRUE;
1480  }
1481 
1482  static Long64_t was = gSystem->Now();
1483  static Bool_t visible = kFALSE;
1484 
1485  Long64_t now = gSystem->Now();
1486 
1487  if (now-was < 100) {
1488  return visible;
1489  }
1490  was = now;
1491 
1492  visible = kFALSE;
1493 
1494  if (!IsPointVisible(2, 2)) {
1495  return visible;
1496  }
1497 
1498  if (!IsPointVisible(2, fPimpl->fGrab->GetHeight()-2)) {
1499  return visible;
1500  }
1501 
1502  if (!IsPointVisible(fPimpl->fGrab->GetWidth()-2, 2)) {
1503  return visible;
1504  }
1505 
1506  if (!IsPointVisible(fPimpl->fGrab->GetWidth()-2,
1507  fPimpl->fGrab->GetHeight()-2)) {
1508  return visible;
1509  }
1510 
1511  visible = kTRUE;
1512 
1513  return visible;
1514 }
1515 
1516 ////////////////////////////////////////////////////////////////////////////////
1517 /// Draw small grab rectangles around grabbed/selected/frame
1518 
1520 {
1521  if (fStop) {
1522  return;
1523  }
1524 
1525  TGFrame *frame = win ? (TGFrame *)win : fPimpl->fGrab;
1526 
1527  if (!frame || !fClient->IsEditable() || fPimpl->fPlacePopup) {
1528  return;
1529  }
1530 
1531  Window_t w = gVirtualX->GetDefaultRootWindow();
1532  Window_t c; Int_t x, y;
1533 
1534  gVirtualX->TranslateCoordinates(frame->GetId(), w, 0, 0, x, y, c);
1535 
1536  if (frame->InheritsFrom(TGCompositeFrame::Class()) &&
1537  CanChangeLayout(frame) && !frame->IsLayoutBroken()) {
1538  fPimpl->fAroundFrame[0]->MoveResize(x-3, y-3, frame->GetWidth()+6, 2);
1539  fPimpl->fAroundFrame[0]->MapRaised();
1540  fPimpl->fAroundFrame[1]->MoveResize(x+frame->GetWidth()+3, y-3, 2, frame->GetHeight()+6);
1541  fPimpl->fAroundFrame[1]->MapRaised();
1542  fPimpl->fAroundFrame[2]->MoveResize(x-3, y+frame->GetHeight()+2, frame->GetWidth()+6, 2);
1543  fPimpl->fAroundFrame[2]->MapRaised();
1544  fPimpl->fAroundFrame[3]->MoveResize(x-3, y-3, 2, frame->GetHeight()+6);
1545  fPimpl->fAroundFrame[3]->MapRaised();
1546  } else {
1547  for (int i = 0; i < 4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
1548  }
1549 
1550  // draw rectangles
1551  DrawGrabRect(0, x - 6, y - 6);
1552  DrawGrabRect(1, x + frame->GetWidth()/2 - 3, y - 6);
1553  DrawGrabRect(2, x + frame->GetWidth(), y - 6);
1554  DrawGrabRect(3, x - 6, y + frame->GetHeight());
1555  DrawGrabRect(4, x - 6, y + frame->GetHeight()/2 - 3);
1556  DrawGrabRect(5, x + frame->GetWidth(), y + frame->GetHeight()/2 - 3);
1557  DrawGrabRect(6, x + frame->GetWidth()/2 - 3, y + frame->GetHeight());
1558  DrawGrabRect(7, x + frame->GetWidth(), y + frame->GetHeight());
1559 
1560  fPimpl->fGrabRectHidden = kFALSE;
1561 }
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// Helper method to draw grab rectangle at position x,y
1565 
1567 {
1568  if (fStop) {
1569  return;
1570  }
1571 
1572  fPimpl->fGrabRect[i]->Move(x, y);
1573  fPimpl->fGrabRect[i]->MapRaised();
1574 }
1575 
1576 ////////////////////////////////////////////////////////////////////////////////
1577 /// Raise composite frame when mouse is moving over it.
1578 /// That allows to highlight position of "plain" composite frames.
1579 
1581 {
1582  static Window_t gw = 0;
1583 
1584  if (fStop || !win || (win == gw)) {
1585  return;
1586  }
1587 
1588  TGWindow *w = fClient->GetWindowById(win);
1589 
1590  if (!w || (w == fPimpl->fPlane) || w->GetEditDisabled() || w->IsEditable() ||
1592  return;
1593  }
1594 
1595  TGFrame *frame = (TGFrame*)w;
1596  UInt_t opt = frame->GetOptions();
1597 
1598  if ((opt & kRaisedFrame) || (opt & kSunkenFrame)) {
1599  return;
1600  }
1601 
1602  gw = win;
1603  if (fPimpl->fPlane) {
1604  fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
1605  fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
1606  }
1607  fPimpl->fPlane = frame;
1608  fPimpl->fPlane->ChangeOptions(opt | kRaisedFrame);
1609  fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
1610 
1611  if (fBuilder) {
1612  TString str = frame->ClassName();
1613  str += "::";
1614  str += frame->GetName();
1615  fBuilder->UpdateStatusBar(str.Data());
1616  }
1617 }
1618 
1619 ////////////////////////////////////////////////////////////////////////////////
1620 /// The main event loop is originated here
1621 /// It repeadeatly queries pointer state and position on the screen.
1622 /// From this info an Event_t structure is built.
1623 
1625 {
1626  return HandleTimerEvent(0, t);
1627 }
1628 
1629 ////////////////////////////////////////////////////////////////////////////////
1630 /// Handle timer events or events coming from the recorder.
1631 
1633 {
1634  static Int_t gy = 0;
1635  static Int_t gx = 0;
1636  static UInt_t gstate = 0;
1637  static Window_t gw = 0;
1638 
1639  Bool_t ret = kTRUE;
1640 
1641  // if nothing is editted stop timer and reset everything
1642  if (!fClient || !fClient->IsEditable()) {
1644  return kFALSE;
1645  }
1646  if (!IsSelectedVisible()) {
1648  }
1649  if (e) {
1650  if (fPimpl->fRepeatTimer) {
1651  // we are replaying events from the recorder...
1652  fPimpl->fRepeatTimer->Reset();
1653  fPimpl->fRepeatTimer->Remove();
1654  }
1655  if (e->fType == kButtonPress)
1656  return HandleButtonPress(e);
1657  else if (e->fType == kButtonRelease)
1658  return HandleButtonRelease(e);
1659  else if (e->fState & kButton1Mask)
1660  return HandleMotion(e);
1661  return kTRUE;
1662  }
1663  Window_t dum;
1664  Event_t ev;
1665  ev.fCode = kButton1;
1666  ev.fType = kMotionNotify;
1667  ev.fState = 0;
1668 
1669  gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(), dum, dum,
1670  ev.fXRoot, ev.fYRoot, ev.fX, ev.fY, ev.fState);
1671 
1672  ev.fWindow = GetWindowFromPoint(ev.fXRoot, ev.fYRoot);
1673 
1674  if (ev.fWindow && (gw == ev.fWindow) && (gstate == ev.fState) &&
1675  (ev.fYRoot == gy) && (ev.fXRoot == gx)) {
1676  return kFALSE;
1677  }
1678 
1679  gw = ev.fWindow;
1680  gstate = ev.fState;
1681  ev.fState &= ~16; // ignore "num lock" pressed
1682  ev.fState &= ~2; // ignore "caps lock" pressed
1683 
1684  if (!fDragging && !fMoveWaiting && !fPimpl->fButtonPressed &&
1685  ((ev.fState == kButton1Mask) || (ev.fState == kButton3Mask) ||
1686  (ev.fState == (kButton1Mask | kKeyShiftMask)) ||
1687  (ev.fState == (kButton1Mask | kKeyControlMask)))) {
1688 
1689  if (ev.fState & kButton1Mask) ev.fCode = kButton1;
1690  if (ev.fState & kButton3Mask) ev.fCode = kButton3;
1691 
1692  ev.fType = kButtonPress;
1693  t->SetTime(40);
1694 
1695  if (fPimpl->fPlane && fClient->GetWindowById(fPimpl->fPlane->GetId())) {
1696  fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
1697  fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
1698  } else {
1699  fPimpl->fPlane = 0;
1700  }
1701 
1702  ret = HandleButtonPress(&ev);
1703  TimerEvent(&ev);
1704  return ret;
1705  }
1706 
1707  if ((fDragging || fMoveWaiting) && (!ev.fState || (ev.fState == kKeyShiftMask)) &&
1708  fPimpl->fButtonPressed) {
1709 
1710  ev.fType = kButtonRelease;
1711  t->SetTime(100);
1712 
1713  ret = HandleButtonRelease(&ev);
1714  TimerEvent(&ev);
1715  return ret;
1716  }
1717 
1718  fPimpl->fButtonPressed = (ev.fState & kButton1Mask) ||
1719  (ev.fState & kButton2Mask) ||
1720  (ev.fState & kButton3Mask);
1721 
1722  if ((ev.fYRoot == gy) && (ev.fXRoot == gx)) return kFALSE;
1723 
1724  gy = ev.fYRoot;
1725  gx = ev.fXRoot;
1726 
1727  if (!fMoveWaiting && !fDragging && !ev.fState) {
1728  if (!CheckDragResize(&ev) && fClient->GetWindowById(ev.fWindow)) {
1730  }
1731  } else if (ev.fState & kButton1Mask) {
1732  HandleMotion(&ev);
1733  TimerEvent(&ev);
1734  }
1735  return ret;
1736 }
1737 
1738 ////////////////////////////////////////////////////////////////////////////////
1739 /// Recognize what was done when mouse button pressed
1740 
1742 {
1743  if (fStop) {
1744  return kFALSE;
1745  }
1746 
1747  if (((event->fCode != kButton1) && (event->fCode != kButton3)) ||
1748  !frame || !fClient->IsEditable()) {
1749  return kFALSE;
1750  }
1751 
1752  TGFrame *context_fr = 0;
1753  Bool_t mdi = kFALSE;
1754 
1755  // hack for editable mdi frames
1756  if (frame->IsEditable() && frame->InheritsFrom(TGMdiFrame::Class())) {
1757  context_fr = frame;
1758  mdi = kTRUE;
1759  }
1760 
1761  // handle context menu
1762  if (event->fCode == kButton3) {
1763  if (!fPimpl->fSpacePressedFrame) {
1764  if (!mdi) {
1765  SelectFrame(frame);
1766  context_fr = fSelected;
1767  }
1768  } else {
1769  context_fr = fPimpl->fSpacePressedFrame;
1770  }
1771 
1772  HandleButon3Pressed(event, context_fr);
1773  return kTRUE;
1774  }
1775 
1776  fDragType = kDragNone;
1777 
1778  if (!fSelectionIsOn) {
1779  fPimpl->fX0 = event->fXRoot;
1780  fPimpl->fY0 = event->fYRoot;
1781  }
1782 
1783  //HideGrabRectangles();
1784  fPimpl->fClickFrame = frame;
1785 
1786  if (fBuilder && fBuilder->IsExecutable() &&
1788  UngrabFrame();
1789  frame->SetEditable(kTRUE);
1790  fSource = 0;
1792  goto out;
1793  }
1794 
1795  if (event->fState & kKeyShiftMask) {
1796  // drag grabbed frame with shift key pressed should create a copy of grabbed frame
1797  // move a copy of editable and selected frame
1798  if (frame == fPimpl->fGrab) {
1799  fSource = frame;
1800  fDragType = kDragCopy;
1801  gVirtualX->SetCursor(frame->GetId(), gVirtualX->CreateCursor(kMove));
1802  goto out;
1803  }
1804 
1805  // otherwise do lasso selection
1806  if (!fSelectionIsOn) {
1808  } else {
1809  fPimpl->fX = event->fXRoot;
1810  fPimpl->fY = event->fYRoot;
1812  DrawLasso();
1813  return kTRUE;
1814  }
1815  }
1816 
1817  CheckDragResize(event);
1818 
1819  if (frame->IsEditable()) {
1820  fSource = 0;
1821 
1822  if (fDragType != kDragResize) {
1823 
1824  // move editable and selected frame
1825  if (frame == fPimpl->fGrab) {
1826  fSource = frame;
1827  fDragType = kDragMove;
1828  gVirtualX->SetCursor(frame->GetId(), gVirtualX->CreateCursor(kMove));
1829  goto out;
1830  }
1831 
1833  }
1834  } else if ((fDragType != kDragResize) && !fPimpl->fSpacePressedFrame) {
1835 
1836  // special case of TGCanvas
1837  if (!fPimpl->fGrab && frame->InheritsFrom(TGCanvas::Class())) {
1838  TGFrame *cont = ((TGCanvas*)frame)->GetContainer();
1839 
1840  if (!cont->IsEditable()) {
1841  cont->SetEditable(kTRUE);
1843  goto out;
1844  }
1845  }
1846 
1847  fSource = frame;
1848  SelectFrame(frame, event->fState & kKeyShiftMask);
1849  }
1850 
1851  if ((fDragType == kDragNone) && !fPimpl->fSpacePressedFrame) {
1852  SwitchEditable(frame);
1853  fSource = 0;
1854 
1855  // try again
1856  CheckDragResize(event);
1857 
1858  if (fDragType == kDragNone) {
1859  return kFALSE;
1860  }
1861  }
1862 
1863 out:
1864  Window_t c;
1865 
1866  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
1867  frame->GetId(),
1868  event->fXRoot, event->fYRoot,
1869  fPimpl->fXf, fPimpl->fYf, c);
1870  fPimpl->fX = event->fXRoot;
1871  fPimpl->fY = event->fYRoot;
1872 
1873  fMoveWaiting = kTRUE;
1874  DoRedraw();
1875 
1876  return kTRUE;
1877 }
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// Handle 3d mouse pressed (popup context menu)
1881 
1883 {
1884  if (fStop || !frame) {
1885  return;
1886  }
1887 
1888  if (fClient->GetWaitForEvent() == kUnmapNotify) {
1889  return;
1890  }
1891 
1892  if (frame == fSelected) {
1893  Menu4Frame(frame, event->fXRoot, event->fYRoot);
1894  } else if (frame->IsEditable()) {
1895  if (fLassoDrawn) {
1896  Menu4Lasso(event->fXRoot, event->fYRoot);
1897  } else {
1898  Menu4Frame(frame, event->fXRoot, event->fYRoot);
1899  }
1900  } else {
1901  TGFrame *base = InEditable(frame->GetId());
1902  if (base) {
1903  //SelectFrame(base);
1904  Menu4Frame(base, event->fXRoot, event->fYRoot);
1905  } else {
1906  Menu4Frame(frame, event->fXRoot, event->fYRoot);
1907  }
1908  }
1909 }
1910 
1911 ////////////////////////////////////////////////////////////////////////////////
1912 /// Handle button event occured in some ROOT frame
1913 
1915 {
1916  if (fStop) {
1917  return kFALSE;
1918  }
1919 
1920  if (event->fCode != kButton3) {
1921  CloseMenus();
1922  }
1923 
1924  if (event->fType == kButtonPress) {
1925  return HandleButtonPress(event);
1926  } else {
1927  return HandleButtonRelease(event);
1928  }
1929 }
1930 
1931 ////////////////////////////////////////////////////////////////////////////////
1932 /// Resize events
1933 
1935 {
1936  if (fStop) {
1937  return kFALSE;
1938  }
1939 
1940  TGWindow *w = fClient->GetWindowById(event->fWindow);
1941 
1942  if (!w) {
1943  return kFALSE;
1944  }
1945 
1946  fPimpl->fCompacted = kFALSE;
1947  return kFALSE;
1948 }
1949 
1950 ////////////////////////////////////////////////////////////////////////////////
1951 /// Handle repaint event
1952 
1954 {
1955  if (fStop) {
1956  return kFALSE;
1957  }
1958 
1959  static Long64_t was = gSystem->Now();
1960  static Window_t win = 0;
1961  Long64_t now = gSystem->Now();
1962 
1963  if (event->fCount || (win == event->fWindow) || (now-was < 50) || fDragging) {
1964  if (fDragging) {
1966  }
1967  return kFALSE;
1968  }
1969 
1970  if (gMenuDialog) {
1972  gMenuDialog->RaiseWindow();
1973  return kFALSE;
1974  }
1975 
1976  if (fLassoDrawn) {
1977  DrawLasso();
1978  } else {
1979  if (IsSelectedVisible()) {
1981  }
1982  }
1983 
1984  win = event->fWindow;
1985  was = now;
1986 
1987  return kFALSE;
1988 }
1989 
1990 ////////////////////////////////////////////////////////////////////////////////
1991 /// Handle all events.
1992 
1994 {
1995  if (fStop) {
1996  return kFALSE;
1997  }
1998 
1999  if (IgnoreEvent(event)) {
2000  return kFALSE;
2001  }
2002 
2003  switch (event->fType) {
2004 
2005  case kExpose:
2006  return HandleExpose(event);
2007 
2008  case kConfigureNotify:
2009  while (gVirtualX->CheckEvent(fId, kConfigureNotify, *event))
2010  ;
2011  return HandleConfigureNotify(event);
2012 
2013  case kGKeyPress:
2014  case kKeyRelease:
2015  return HandleKey(event);
2016 
2017  case kFocusIn:
2018  case kFocusOut:
2019  //HandleFocusChange(event);
2020  break;
2021 
2022  case kButtonPress:
2023  {
2024  Int_t dbl_clk = kFALSE;
2025 
2026  static Window_t gDbw = 0;
2027  static Long_t gLastClick = 0;
2028  static UInt_t gLastButton = 0;
2029  static Int_t gDbx = 0;
2030  static Int_t gDby = 0;
2031 
2032  if ((event->fTime - gLastClick < 350) &&
2033  (event->fCode == gLastButton) &&
2034  (TMath::Abs(event->fXRoot - gDbx) < 6) &&
2035  (TMath::Abs(event->fYRoot - gDby) < 6) &&
2036  (event->fWindow == gDbw)) {
2037  dbl_clk = kTRUE;
2038  }
2039 
2040  if (dbl_clk) {
2041  if (event->fState & kKeyControlMask) {
2043  return kTRUE;
2044  } else if (!(event->fState & 0xFF)) {
2045  TGFrame *w = (TGFrame*)fClient->GetWindowById(event->fWindow);
2046 
2047  if (w && (w->GetEditDisabled() & kEditDisableBtnEnable)) {
2048  return w->HandleDoubleClick(event);
2049  }
2050  if (SaveFrame(fTmpBuildFile.Data())) {
2051  gROOT->Macro(fTmpBuildFile.Data());
2052  }
2053  // an easy way to start editting
2055  return kTRUE;
2056  }
2057  } else {
2058  gDbw = event->fWindow;
2059  gLastClick = event->fTime;
2060  gLastButton = event->fCode;
2061  gDbx = event->fXRoot;
2062  gDby = event->fYRoot;
2063 
2064  Bool_t ret = HandleButtonPress(event);
2065  return ret;
2066  }
2067 
2068  return kFALSE;
2069  }
2070 
2071  case kButtonRelease:
2072  return HandleButtonRelease(event);
2073 
2074  case kEnterNotify:
2075  case kLeaveNotify:
2076  //HandleCrossing(event);
2077  break;
2078 
2079  case kMotionNotify:
2080  while (gVirtualX->CheckEvent(fId, kMotionNotify, *event))
2081  ;
2082  return HandleMotion(event);
2083 
2084  case kClientMessage:
2085  return HandleClientMessage(event);
2086 
2087  case kDestroyNotify:
2088  return HandleDestroyNotify(event);
2089 
2090  case kSelectionNotify:
2091  //HandleSelection(event);
2092  break;
2093 
2094  case kSelectionRequest:
2095  //HandleSelectionRequest(event);
2096  break;
2097 
2098  case kSelectionClear:
2099  //HandleSelectionClear(event);
2100  break;
2101 
2102  case kColormapNotify:
2103  //HandleColormapChange(event);
2104  break;
2105 
2106  default:
2107  //Warning("HandleEvent", "unknown event (%#x) for (%#x)", event->fType, fId);
2108  break;
2109  }
2110 
2111  return kFALSE;
2112 }
2113 
2114 ////////////////////////////////////////////////////////////////////////////////
2115 /// Mouse double click handler (never should happen)
2116 
2118 {
2119  if (fStop) {
2120  return kFALSE;
2121  }
2122 
2123  return kFALSE;
2124 }
2125 
2126 ////////////////////////////////////////////////////////////////////////////////
2127 /// Return a parent which can handle button evevents.
2128 
2130 {
2131  TGWindow *parent = fr;
2132 
2133  while (parent && (parent != fClient->GetDefaultRoot())) {
2134  if (parent->GetEditDisabled() & kEditDisableBtnEnable) {
2135  return (TGFrame*)parent;
2136  }
2137  parent = (TGWindow*)parent->GetParent();
2138  }
2139  return 0;
2140 }
2141 
2142 ////////////////////////////////////////////////////////////////////////////////
2143 /// Unmap all popups
2144 
2146 {
2147  TList *li = fClient->GetListOfPopups();
2148  if (!li->GetEntries()) {
2149  return;
2150  }
2151 
2152  TGPopupMenu *pup;
2153  TIter next(li);
2154 
2155  while ((pup = (TGPopupMenu*)next())) {
2156  pup->UnmapWindow();
2157  fClient->ResetWaitFor(pup);
2158  }
2159  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
2160 }
2161 
2162 ////////////////////////////////////////////////////////////////////////////////
2163 /// Handle button press event
2164 
2166 {
2167  if (fStop) {
2168  return kFALSE;
2169  }
2170 
2171  fPimpl->fButtonPressed = kTRUE;
2172  fPimpl->fPlacePopup = kFALSE;
2173 
2174  if (fPimpl->fPlane) {
2175  fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
2176  fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
2177  }
2178 
2179  if (gMenuDialog) { // keep editor on the top
2180  gMenuDialog->RaiseWindow();
2181  }
2182 
2183  // keep undocked toolbar on the top
2184  //(but under win32 key handling will be broken : todo)
2185  if (gVirtualX->InheritsFrom("TGX11") && fBuilder &&
2188  }
2189 
2190  // keep color dialog on the top
2193  return kFALSE;
2194  }
2195 
2196  if ( ((event->fCode != kButton1) && (event->fCode != kButton3)) ||
2197  (event->fType != kButtonPress) || IgnoreEvent(event)) {
2198  return kFALSE;
2199  }
2200 
2201  Reset1();
2202  //HideGrabRectangles();
2203 
2204  Window_t w = GetWindowFromPoint(event->fXRoot, event->fYRoot);
2205  TGFrame *fr = 0;
2206 
2207  if (w) {
2208  fr = (TGFrame*)fClient->GetWindowById(w);
2209  if (!fr) {
2210  return kFALSE;
2211  }
2212 
2213  //fr->HandleButton(event);
2214  if (!IsEventsDisabled(fr)) {
2215  TGFrame *btnframe = GetBtnEnableParent(fr);
2216  if (btnframe) {
2217  event->fUser[0] = fr->GetId();
2218  btnframe->HandleButton(event);
2219  }
2220  }
2221 
2222  if (IsGrabDisabled(fr)) {
2223  fr = GetEditableParent(fr);
2224  }
2225 
2226  if (!fr) {
2227  return kFALSE;
2228  }
2229  } else {
2230  return kFALSE;
2231  }
2232 
2233  return RecognizeGesture(event, fr);
2234 }
2235 
2236 ////////////////////////////////////////////////////////////////////////////////
2237 /// Handle button release event
2238 
2240 {
2241  if (fStop) {
2242  return kFALSE;
2243  }
2244 
2245  // unmap all waiting popups
2246  if (fClient->GetWaitForEvent() == kUnmapNotify) {
2247  UnmapAllPopups();
2248  }
2249 
2250  TGWindow *w = fClient->GetWindowById(event->fWindow);
2251 
2252  if (w && !IsEventsDisabled(w)) {
2253  TGFrame *btnframe = GetBtnEnableParent((TGFrame*)w);
2254  if (btnframe) {
2255  event->fUser[0] = w->GetId();
2256  btnframe->HandleButton(event);
2257  }
2258  }
2259 
2260  fPimpl->fButtonPressed = kFALSE;
2261  gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kPointer));
2262  EndDrag();
2263  fSelectionIsOn &= (event->fState & kKeyShiftMask);
2264 
2265  if (fLassoDrawn) {
2266  DrawLasso();
2267  return kTRUE;
2268  }
2269 
2270  if (fPimpl->fClickFrame && !fSelectionIsOn) {
2271 
2272  // make editable the clicked frame if no lasso was drawn
2273  if ((fPimpl->fClickFrame == fPimpl->fGrab) && (fSelected == fPimpl->fGrab) &&
2274  !fPimpl->fGrab->IsEditable()) {
2275  SwitchEditable(fPimpl->fClickFrame);
2276  return kTRUE;
2277 
2278  // select/grab clicked frame if there was no grab frame
2279  } else if (!fPimpl->fGrab || ((fPimpl->fClickFrame != fPimpl->fGrab) &&
2280  (fPimpl->fClickFrame != fSelected))) {
2281  SelectFrame(fPimpl->fClickFrame);
2282  return kTRUE;
2283  }
2284 
2285  }
2286 
2287  SelectFrame(fPimpl->fGrab);
2288 
2289  return kTRUE;
2290 }
2291 
2292 ////////////////////////////////////////////////////////////////////////////////
2293 /// Handle key event
2294 
2296 {
2297  if (fStop) {
2298  return kFALSE;
2299  }
2300 
2301  char tmp[10];
2302  UInt_t keysym;
2303  Bool_t ret = kFALSE;
2304  TGFileInfo fi;
2305  static TString dir(".");
2306  static Bool_t overwr = kFALSE;
2307  TString fname;
2308 
2310 
2311  if (!w || !fPimpl) {
2312  return kFALSE;
2313  }
2314 
2316  return ((TGFrame*)w)->HandleKey(event);
2317  }
2318 
2319  if (event->fType != kGKeyPress) {
2320  return kFALSE;
2321  }
2322 
2323  if (IsEditDisabled(w)) {
2324  TGFrame *parent = GetEditableParent((TGFrame*)w);
2325  if (parent) {
2326  event->fWindow = parent->GetId();
2327  parent->HandleKey(event);
2328  } else {
2329  return ((TGFrame*)w)->HandleKey(event);
2330  }
2331  }
2332 
2333  fPimpl->fSpacePressedFrame = 0;
2334 
2335  if (fPimpl->fPlane) {
2336  fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
2337  fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
2338  }
2339 
2340  CloseMenus();
2341 
2343  fi.SetIniDir(dir);
2344  fi.fOverwrite = overwr;
2345 
2346  gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
2347 
2348  if (event->fState & kKeyControlMask) {
2349 
2350  switch ((EKeySym)keysym & ~0x20) {
2351  case kKey_Return:
2352  case kKey_Enter:
2354  ret = kTRUE;
2355  break;
2356  case kKey_X:
2357  HandleCut();
2358  ret = kTRUE;
2359  break;
2360  case kKey_C:
2361  HandleCopy();
2362  ret = kTRUE;
2363  break;
2364  case kKey_V:
2365  if (fPimpl->fClickFrame && !fPimpl->fClickFrame->IsEditable()) {
2366  fPimpl->fClickFrame->SetEditable(kTRUE);
2367  }
2368  HandlePaste();
2369  ret = kTRUE;
2370  break;
2371  case kKey_B:
2372  {
2373  if (fPimpl->fGrab ) {
2374  BreakLayout();
2375  }
2376  ret = kTRUE;
2377  break;
2378  }
2379  case kKey_L:
2380  {
2381  if (fPimpl->fGrab && (fPimpl->fClickFrame != fClient->GetRoot())) {
2382  Compact(kFALSE);
2383  } else {
2384  Compact(kTRUE);
2385  }
2386  ret = kTRUE;
2387  break;
2388  }
2389  case kKey_R:
2390  HandleReplace();
2391  ret = kTRUE;
2392  break;
2393  case kKey_S:
2394  Save();
2395  ret = kTRUE;
2396  break;
2397  case kKey_G:
2398  HandleGrid();
2399  ret = kTRUE;
2400  break;
2401  case kKey_H:
2402  SwitchLayout();
2403  ret = kTRUE;
2404  break;
2405  case kKey_N:
2406  if (fBuilder) {
2407  fBuilder->NewProject();
2408  } else {
2409  TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
2410  main->MapRaised();
2411  main->SetEditable(kTRUE);
2412  }
2413  ret = kTRUE;
2414  break;
2415  case kKey_O:
2416  if (fBuilder) {
2417  fBuilder->NewProject();
2418  } else {
2419  TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
2420  main->MapRaised();
2421  main->SetEditable(kTRUE);
2422  }
2423  new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
2424 
2425  if (!fi.fFilename) return kTRUE;
2426  dir = fi.fIniDir;
2427  overwr = fi.fOverwrite;
2429 
2430  if (fname.EndsWith(".C")) {
2431  gROOT->Macro(fname.Data());
2432  } else {
2433  Int_t retval;
2434  new TGMsgBox(fClient->GetDefaultRoot(), this, "Error...",
2435  TString::Format("file (%s) must have extension .C", fname.Data()),
2436  kMBIconExclamation, kMBRetry | kMBCancel, &retval);
2437  if (retval == kMBRetry) {
2438  HandleKey(event);
2439  }
2440  }
2441  ret = kTRUE;
2442  break;
2443  default:
2444  break;
2445  }
2446  } else {
2447  switch ((EKeySym)keysym) {
2448  case kKey_Delete:
2449  case kKey_Backspace:
2450  HandleDelete(event->fState & kKeyShiftMask);
2451  ret = kTRUE;
2452  break;
2453  case kKey_Return:
2454  case kKey_Enter:
2455  //UnmapAllPopups();
2457  ret = kTRUE;
2458  break;
2459  case kKey_Left:
2460  case kKey_Right:
2461  case kKey_Up:
2462  case kKey_Down:
2463  if (fLassoDrawn) {
2464  HandleAlignment(keysym, event->fState & kKeyShiftMask);
2465  } else if (fPimpl->fGrab) {
2466  HandleLayoutOrder((keysym == kKey_Right) || (keysym == kKey_Down));
2467  }
2468  ret = kTRUE;
2469  break;
2470  case kKey_Space:
2471  //UnmapAllPopups();
2472  if (fPimpl->fGrab) {
2473  SwitchEditable(fPimpl->fGrab);
2474 
2475  TGFrame *p = (TGFrame*)GetEditableParent(fPimpl->fGrab);
2476 
2477  if (p) {
2478  if (p == fBuilder->GetMdiMain()->GetCurrent()) {
2479  UngrabFrame();
2480  } else {
2481  SelectFrame(p);
2482  fSource = fPimpl->fSpacePressedFrame = p;
2483  }
2484  }
2485  }
2486  ret = kTRUE;
2487  break;
2488  default:
2489  break;
2490  }
2491  }
2492  if (fBuilder) {
2493  fBuilder->SetAction(0);
2494  //fBuilder->Update();
2495  }
2496 
2497  if (fLassoDrawn) {
2498  DrawLasso();
2499  }
2500 
2501  return ret;
2502 }
2503 
2504 ////////////////////////////////////////////////////////////////////////////////
2505 /// Reparent frames
2506 
2508 {
2509  if (fStop || !fClient->IsEditable() || (newfr == fClient->GetDefaultRoot())) {
2510  return;
2511  }
2512 
2513  Int_t x0, y0, xx, yy;
2514  Window_t c;
2515  static TGLayoutHints *hints = new TGLayoutHints(kLHintsNormal, 2, 2, 2, 2);
2516 
2517  if (!newfr || !newfr->GetId() || !oldfr || !oldfr->GetId()) return;
2518 
2519  gVirtualX->TranslateCoordinates(newfr->GetId(), oldfr->GetId(),
2520  0, 0, x0, y0, c);
2521 
2522  x0 = x0 < 0 ? 0 : x0;
2523  y0 = y0 < 0 ? 0 : y0;
2524  Int_t x = x0 + newfr->GetWidth();
2525  Int_t y = y0 + newfr->GetHeight();
2526 
2527  TGCompositeFrame *comp = 0;
2528 
2529  if (newfr->InheritsFrom(TGCompositeFrame::Class())) {
2530  comp = (TGCompositeFrame*)newfr;
2531  comp->SetLayoutBroken();
2532  }
2533 
2534  TIter next(oldfr->GetList());
2535  TGFrameElement *el;
2536 
2537  while ((el = (TGFrameElement*)next())) {
2538  TGFrame *frame = el->fFrame;
2539 
2540  if ((frame->GetX() >= x0) && (frame->GetY() >= y0) &&
2541  (frame->GetX() + (Int_t)frame->GetWidth() <= x) &&
2542  (frame->GetY() + (Int_t)frame->GetHeight() <= y)) {
2543 
2544  if (frame == fPimpl->fGrab) {
2545  UngrabFrame();
2546  }
2547 
2548  oldfr->RemoveFrame(frame);
2549 
2550  gVirtualX->TranslateCoordinates(oldfr->GetId(), newfr->GetId(),
2551  frame->GetX(), frame->GetY(), xx, yy, c);
2552 
2553  frame->ReparentWindow(newfr, xx, yy);
2554 
2555  if (comp) {
2556  comp->AddFrame(frame, hints); // el->fLayout);
2557  }
2558  }
2559  }
2560 }
2561 
2562 ////////////////////////////////////////////////////////////////////////////////
2563 /// Return the list of frames inside of some area
2564 
2566 {
2567  if (fStop) {
2568  return 0;
2569  }
2570 
2571  Int_t xx, yy;
2572 
2574  return 0;
2575  }
2576 
2577  TList *list = new TList();
2578 
2579  xx = x0; yy = y0;
2580  x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
2581  y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
2582 
2583  TIter next(((TGCompositeFrame*)fClient->GetRoot())->GetList());
2584  TGFrameElement *el;
2585 
2586  while ((el = (TGFrameElement*)next())) {
2587  if ((el->fFrame->GetX() >= x0) && (el->fFrame->GetY() >= y0) &&
2588  (el->fFrame->GetX() + (Int_t)el->fFrame->GetWidth() <= x) &&
2589  (el->fFrame->GetY() + (Int_t)el->fFrame->GetHeight() <= y)) {
2590  list->Add(el->fFrame);
2591  }
2592  }
2593  if (list->IsEmpty()) {
2594  delete list;
2595  return 0;
2596  }
2597  return list;
2598 }
2599 
2600 ////////////////////////////////////////////////////////////////////////////////
2601 /// Drop canvas container
2602 
2604 {
2605  if (fStop) {
2606  return;
2607  }
2608 
2609  TGCompositeFrame *comp = (TGCompositeFrame*)canvas->GetParent();
2610  comp->SetEditable(kTRUE);
2611 
2612  TGCompositeFrame *cont = (TGCompositeFrame*)canvas->GetContainer();
2613  Int_t x = canvas->GetX();
2614  Int_t y = canvas->GetY();
2615 
2617  cont->ReparentWindow(comp, x, y);
2618  canvas->SetContainer(0);
2619  comp->AddFrame(cont);
2620  DeleteFrame(canvas);
2621 
2622  if (fBuilder) {
2623  TString str = cont->ClassName();
2624  str += "::";
2625  str += cont->GetName();
2626  str += " dropped.";
2627  fBuilder->UpdateStatusBar(str.Data());
2628  }
2629  SelectFrame(cont);
2630 }
2631 
2632 ////////////////////////////////////////////////////////////////////////////////
2633 /// Create a new TGCanvas and place container into it
2634 
2636 {
2637  if (fStop || !cont) {
2638  return;
2639  }
2640 
2641  TGCompositeFrame *comp = (TGCompositeFrame*)cont->GetParent();
2642  comp->SetEditable(kTRUE);
2643 
2644  UInt_t w = cont->GetWidth()/2;
2645  UInt_t h = cont->GetHeight()/2;
2646 
2647  w = w < 100 ? 100 : w;
2648  h = h < 100 ? 100 : h;
2649 
2650  TGCanvas *canvas = new TGCanvas(comp, w, h);
2651  canvas->Move(cont->GetX(), cont->GetY());
2652  comp->RemoveFrame(cont);
2653  comp->AddFrame(canvas);
2654  cont->ReparentWindow(canvas->GetViewPort());
2655  canvas->SetContainer(cont);
2656  cont->SetCleanup(kDeepCleanup);
2657  canvas->MapSubwindows();
2658  canvas->MapWindow();
2659  SelectFrame(canvas);
2660 
2661  if (fBuilder) {
2662  fBuilder->UpdateStatusBar("Grab action performed. Presss Cntrl-Return to Drop grabbed frame.");
2663  }
2664 }
2665 
2666 ////////////////////////////////////////////////////////////////////////////////
2667 /// Handling of return/enter key pressing
2668 ///
2669 /// If on is kFALSE:
2670 /// If Return or Enter key was pressed - Grab Act
2671 /// If lasso is drawn - new composite frame is created and
2672 /// all frames inside lasso adopted as childrens.
2673 /// If lasso is not drawn and selected frame is composite one,
2674 /// - new TGCanvas widget is created and selcted frmae became
2675 /// container for this canvas.
2676 ///
2677 /// If on is kTRUE:
2678 /// If Return or Enter key was pressed with Control Key - Drop Act,
2679 /// The opposite action to the Grab Act.
2680 /// If selected/grabbed frame is not a TGCanvas widget -
2681 /// all frames inside the grabbed/selected frame are "dropped" into
2682 /// the underlying frame and the grabbed frame is deleted.
2683 ///
2684 /// If selected/grabbed frame is a TGCanvas widget -
2685 /// container frame "dropped" to editable frame
2686 
2688 {
2689  if (fStop) {
2690  return;
2691  }
2692 
2693  Int_t x0, y0, x, y, xx, yy;
2694  Window_t c;
2695  TGCompositeFrame *parent = 0;
2696  TList *li = 0;
2697 
2699  !fClient->IsEditable()) {
2700  return;
2701  }
2702 
2703  // if grabbed frame is editable - we need to switch edit to parent
2704  if (fPimpl->fGrab && fPimpl->fGrab->IsEditable()) {
2705  ((TGFrame*)fPimpl->fGrab->GetParent())->SetEditable(kTRUE);
2706  }
2707 
2708  if (fPimpl->fGrab && !fLassoDrawn) {
2709  if (!on) {
2710  if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class()) &&
2711  !fPimpl->fGrab->InheritsFrom(TGCanvas::Class()) &&
2712  !fPimpl->fGrab->InheritsFrom(TGContainer::Class()) &&
2713  CanChangeLayout(fPimpl->fGrab) &&
2714  CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
2716  return;
2717  }
2718  } else {
2719 
2720  if ((fPimpl->fGrab->IsA() == TGCanvas::Class()) &&
2721  !((TGCanvas*)fPimpl->fGrab)->GetContainer()->InheritsFrom(TGContainer::Class()) &&
2722  CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
2723  DropCanvas((TGCanvas*)fPimpl->fGrab);
2724  return;
2725  }
2726  }
2727  }
2728 
2730 
2731  if (fLassoDrawn) {
2732 
2733  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2734  fClient->GetRoot()->GetId(),
2735  fPimpl->fX, fPimpl->fY, x, y, c);
2736  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2737  fClient->GetRoot()->GetId(),
2738  fPimpl->fX0, fPimpl->fY0, x0, y0, c);
2739 
2740  xx = x0; yy = y0;
2741  x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
2742  y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
2743 
2744  li = GetFramesInside(x0, y0, x, y);
2745 
2746  if (!on && li) {
2747  parent = new TGCompositeFrame(comp, x - x0, y - y0);
2748  parent->MoveResize(x0, y0, x - x0, y - y0);
2749  ReparentFrames(parent, comp);
2750 
2751  comp->AddFrame(parent);
2752  parent->MapWindow();
2754  SelectFrame(parent);
2755 
2756  if (fBuilder) {
2757  TString str = "Grab action performed.";
2758  str += " Press Cntrl-Return to Drop grabbed frames.";
2759  str += " Presss Return for TCanvas Grab";
2760  fBuilder->UpdateStatusBar(str.Data());
2761  }
2762  }
2763  } else if (on && fPimpl->fGrab) {
2764 
2765  // check if it is forbidden
2766  if (!CanChangeLayout(fPimpl->fGrab) ||
2767  !CanChangeLayout((TGWindow*)fPimpl->fGrab->GetParent())) {
2768  if (fBuilder) {
2769  fBuilder->UpdateStatusBar("Drop action disabled");
2770  }
2771  return;
2772  }
2773 
2774  if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
2775  parent = (TGCompositeFrame*)fPimpl->fGrab;
2776  } else {
2777  //parent = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
2778  }
2779  if (parent) {
2780  ReparentFrames(comp, parent);
2781  DeleteFrame(fPimpl->fGrab);
2782  UngrabFrame();
2783  ChangeSelected(0); //update editors
2784 
2785  if (fBuilder) {
2786  fBuilder->UpdateStatusBar("Drop action performed");
2787  }
2788  }
2789  }
2790  delete li;
2791 }
2792 
2793 ////////////////////////////////////////////////////////////////////////////////
2794 /// Align frames located inside lasso area.
2795 
2797 {
2798  if (fStop) {
2799  return;
2800  }
2801 
2802  Int_t x0, y0, x, y, xx, yy;
2803  Window_t c;
2804  TGCompositeFrame *comp = 0;
2805 
2807  !fClient->IsEditable()) {
2808  return;
2809  }
2810 
2811  if (fLassoDrawn) {
2812  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2813  fClient->GetRoot()->GetId(),
2814  fPimpl->fX, fPimpl->fY, x, y, c);
2815  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2816  fClient->GetRoot()->GetId(),
2817  fPimpl->fX0, fPimpl->fY0, x0, y0, c);
2818 
2819  xx = x0; yy = y0;
2820  x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
2821  y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
2822 
2823  comp = (TGCompositeFrame*)fClient->GetRoot();
2824 
2825  ToGrid(x, y);
2826  ToGrid(x0, y0);
2827 
2828  TIter next(comp->GetList());
2829  TGFrameElement *el;
2830  TGFrame *prev = 0;
2831 
2832  while ((el = (TGFrameElement*)next())) {
2833  TGFrame *fr = el->fFrame;
2834 
2835  if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
2836  (fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
2837  (fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
2838 
2839  switch ((EKeySym)to) {
2840  case kKey_Left:
2841  fr->Move(x0, fr->GetY());
2842  if (lineup) {
2843  // coverity[dead_error_line]
2844  if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
2845  else fr->Move(x0, y0);
2846  }
2847  break;
2848  case kKey_Right:
2849  fr->Move(x - fr->GetWidth(), fr->GetY());
2850  if (lineup) {
2851  if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
2852  else fr->Move(x - fr->GetWidth(), y0);
2853  }
2854  break;
2855  case kKey_Up:
2856  fr->Move(fr->GetX(), y0);
2857  if (lineup) {
2858  if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
2859  else fr->Move(x0, y0);
2860  }
2861  break;
2862  case kKey_Down:
2863  fr->Move(fr->GetX(), y - fr->GetHeight());
2864  if (lineup) {
2865  if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
2866  else fr->Move(x0, y - fr->GetHeight());
2867  }
2868  break;
2869  default:
2870  break;
2871  }
2872  prev = fr;
2873  }
2874  }
2875  }
2876  if (fLassoDrawn) {
2877  DrawLasso();
2878  }
2879 }
2880 
2881 ////////////////////////////////////////////////////////////////////////////////
2882 /// Handle delete or crop action
2883 ///
2884 /// crop is kFALSE - delete action
2885 /// - if lasso is drawn -> all frames inside lasso area are deleted
2886 /// - if frame is grabbed/selected -> the frame is deleted
2887 /// crop is kTRUE - crop action
2888 /// - if lasso is drawn -> all frames outside of lasso area are deleted
2889 /// - if frame is grabbed/selected -> all frames except the grabbed frame are deleted
2890 /// In both cases the main frame is shrinked to the size of crop area.
2891 
2893 {
2894  if (fStop) {
2895  return;
2896  }
2897 
2898  Int_t x0, y0, x, y, xx, yy, w, h;
2899  Window_t c;
2900 
2902  !fClient->IsEditable()) {
2903  return;
2904  }
2905 
2906  TGCompositeFrame *comp = 0;
2907  Bool_t fromGrab = kFALSE;
2908  TGFrame *frame = fPimpl->fGrab;
2909 
2910  if (fBuilder && crop) {
2912  } else {
2913  comp = (TGCompositeFrame*)fClient->GetRoot();
2914  }
2915 
2916  if (frame && !CanChangeLayout((TGWindow*)frame->GetParent())) {
2917  frame = GetMovableParent(frame);
2918 
2919  if (!frame) {
2920  TString str = fPimpl->fGrab->ClassName();
2921  str += "::";
2922  str += fPimpl->fGrab->GetName();
2923  str += " cannot be deleted";
2924 
2925  if (fBuilder) {
2926  fBuilder->UpdateStatusBar(str.Data());
2927  }
2928  return;
2929  }
2930  }
2931 
2932  // prepare to crop grabbed frame
2933  if (frame && !fLassoDrawn && crop) {
2934  gVirtualX->TranslateCoordinates(frame->GetId(),
2936  -2, -2,
2937  fPimpl->fX0, fPimpl->fY0, c);
2938 
2939  fPimpl->fX = fPimpl->fX0 + frame->GetWidth()+4;
2940  fPimpl->fY = fPimpl->fY0 + frame->GetHeight()+4;
2941  fromGrab = kTRUE;
2942  }
2943 
2944  x0 = fPimpl->fX0; y0 = fPimpl->fY0;
2945  x = fPimpl->fX; y = fPimpl->fY;
2946  if (comp) {
2947  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2948  comp->GetId(),
2949  fPimpl->fX, fPimpl->fY, x, y, c);
2950  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
2951  comp->GetId(),
2952  fPimpl->fX0, fPimpl->fY0, x0, y0, c);
2953  }
2954 
2955  xx = x0; yy = y0;
2956  x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
2957  y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
2958  w = x - x0;
2959  h = y - y0;
2960 
2961  if (fLassoDrawn || fromGrab) {
2962  if (comp) {
2963  TIter next(comp->GetList());
2964  TGFrameElement *el;
2965 
2966  while ((el = (TGFrameElement*)next())) {
2967  TGFrame *fr = el->fFrame;
2968 
2969  if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
2970  (fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
2971  (fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
2972  if (!crop) {
2973  DeleteFrame(fr);
2974  } else {
2975  fr->Move(fr->GetX() - x0, fr->GetY() - y0);
2976  }
2977  } else {
2978  if (crop) {
2979  DeleteFrame(fr);
2980  }
2981  }
2982  }
2983  if (crop && comp) {
2984  gVirtualX->TranslateCoordinates(comp->GetId(), comp->GetParent()->GetId(),
2985  x0, y0, xx, yy, c);
2986 
2987  comp->MoveResize(xx, yy, w, h);
2988 
2989  if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
2990  TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
2991 
2992  gVirtualX->TranslateCoordinates(decor->GetId(), decor->GetParent()->GetId(),
2993  xx, yy, xx, yy, c);
2994 
2995  Int_t b = 2 * decor->GetBorderWidth();
2996  decor->MoveResize(xx, yy, comp->GetWidth() + b,
2997  comp->GetHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
2998  }
2999  }
3000  }
3001  } else { // no lasso drawn -> delete selected frame
3002  if (frame)
3003  DeleteFrame(frame);
3004  UngrabFrame();
3005  ChangeSelected(0); //update editors
3006  }
3008 
3009  if (fBuilder) {
3010  //fBuilder->Update();
3011  fBuilder->UpdateStatusBar(crop ? "Crop action performed" : "Delete action performed");
3012  }
3013 }
3014 
3015 ////////////////////////////////////////////////////////////////////////////////
3016 /// Delete frame
3017 
3019 {
3020  if (fStop || !frame) {
3021  return;
3022  }
3023 
3024  // remove the frame from the list tree and reset the editor...
3025  fEditor->RemoveFrame(frame);
3026 
3027  frame->UnmapWindow();
3028 
3029  TGCompositeFrame *comp = 0;
3030 
3031  if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
3032  comp = (TGCompositeFrame*)frame->GetParent();
3033  }
3034 
3035  if (comp) {
3036  comp->RemoveFrame(frame);
3037  }
3038 
3039  if (frame == fPimpl->fGrab) {
3040  UngrabFrame();
3041  }
3042 
3043  fClient->UnregisterWindow(frame);
3044 
3045  // mem.leak paid for robustness (with possibility "undelete")
3047 }
3048 
3049 ////////////////////////////////////////////////////////////////////////////////
3050 /// Handle cut action
3051 
3053 {
3054  if (fStop || !fPimpl->fGrab) {
3055  return;
3056  }
3057 
3058  //
3059  fPimpl->fGrab = GetMovableParent(fPimpl->fGrab);
3060  HandleCopy();
3061  DeleteFrame(fPimpl->fGrab);
3062  ChangeSelected(0); //update editors
3063 }
3064 
3065 ////////////////////////////////////////////////////////////////////////////////
3066 /// Handle copy. This method is also used by SaveFrame method.
3067 /// In later case brk_layout == kFALSE
3068 
3070 {
3071  if (fStop || !fPimpl->fGrab) {
3072  return;
3073  }
3074 
3076  fPimpl->fGrab->GetWidth(),
3077  fPimpl->fGrab->GetHeight());
3078 
3079  // save coordinates
3080  Int_t x0 = fPimpl->fGrab->GetX();
3081  Int_t y0 = fPimpl->fGrab->GetY();
3082 
3083  // save parent name
3084  TString name = fPimpl->fGrab->GetParent()->GetName();
3085 
3086  ((TGWindow*)fPimpl->fGrab->GetParent())->SetName(tmp->GetName());
3087 
3088  fPimpl->fGrab->SetX(0);
3089  fPimpl->fGrab->SetY(0);
3090 
3091  TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
3092 
3093  if (fe) {
3094  tmp->GetList()->Add(fe);
3095  }
3096 
3097  tmp->SetLayoutBroken(brk_layout);
3098 
3099  if (!brk_layout) { //save frame
3101  tmp->SetWMSize(tmp->GetWidth(), tmp->GetHeight());
3102  tmp->SetWMSizeHints(tmp->GetDefaultWidth(), tmp->GetDefaultHeight(), 10000, 10000, 0, 0);
3103  const char *short_name = gSystem->BaseName(fPasteFileName.Data());
3104  tmp->SetWindowName(short_name);
3105  tmp->SetIconName(short_name);
3106  tmp->SetClassHints(short_name, short_name);
3107  // some problems here under win32
3108  if (gVirtualX->InheritsFrom("TGX11")) tmp->SetIconPixmap("bld_rgb.xpm");
3109  }
3110  Bool_t quite = brk_layout || (fPasteFileName == fTmpBuildFile);
3111  tmp->SaveSource(fPasteFileName.Data(), quite ? "keep_names quiet" : "keep_names");
3112  tmp->GetList()->Remove(fe);
3113 
3114  fPimpl->fGrab->SetX(x0);
3115  fPimpl->fGrab->SetY(y0);
3116 
3117  ((TGWindow*)fPimpl->fGrab->GetParent())->SetName(name.Data());
3118 
3119  if (fBuilder) {
3120  TString str = fPimpl->fGrab->ClassName();
3121  str += "::";
3122  str += fPimpl->fGrab->GetName();
3123  str += " copied to clipboard";
3124  fBuilder->UpdateStatusBar(str.Data());
3125  }
3126 
3127  delete tmp;
3128 }
3129 
3130 ////////////////////////////////////////////////////////////////////////////////
3131 /// Handle paste action.
3132 
3134 {
3135  if (fStop) {
3136  return;
3137  }
3138 
3139  Int_t xp = 0;
3140  Int_t yp = 0;
3141 
3143  return;
3144  }
3145 
3146  fPasting = kTRUE;
3147  gROOT->Macro(fPasteFileName.Data());
3148 
3149  Window_t c;
3150  TGFrame *root = (TGFrame*)fClient->GetRoot();
3151 
3152  if (!fPimpl->fReplaceOn) {
3153  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
3154  root->GetId(),
3155  fPimpl->fX0, fPimpl->fY0, xp, yp, c);
3156  ToGrid(xp, yp);
3157 
3158  // fPasteFrame is defined in TVirtualDragManager.h
3159  // fPasteFrame is a TGMainFrame consisting "the frame to paste"
3160  // into the editable frame (aka fClient->GetRoot())
3161 
3162  if (fPasteFrame) {
3164  TGFrame *paste = ((TGFrameElement*)main->GetList()->First())->fFrame;
3165 
3166  UInt_t w = paste->GetWidth();
3167  UInt_t h = paste->GetHeight();
3168 
3169  if (xp + w > root->GetWidth()) {
3170  w = root->GetWidth() - xp -1;
3171  }
3172  if (yp + h > root->GetHeight()) {
3173  h = root->GetHeight() - yp -1;
3174  }
3175 
3176  paste->Resize(w, h);
3177  fPasteFrame->Move(xp, yp);
3178  fPimpl->fGrab = fPasteFrame;
3179  HandleReturn(1); // drop
3180  }
3181  }
3182 
3183  fPasting = kFALSE;
3184 
3185  if (fBuilder) {
3186  fBuilder->UpdateStatusBar("Paste action performed");
3187  }
3188 }
3189 
3190 ////////////////////////////////////////////////////////////////////////////////
3191 /// Replace frame (doesn't work yet properly)
3192 
3194 {
3195  if (fStop || !frame || !fPimpl->fGrab || !fPimpl->fReplaceOn) {
3196  return;
3197  }
3198 
3199  Int_t w = fPimpl->fGrab->GetWidth();
3200  Int_t h = fPimpl->fGrab->GetHeight();
3201  Int_t x = fPimpl->fGrab->GetX();
3202  Int_t y = fPimpl->fGrab->GetY();
3203 
3204  if (fBuilder) {
3205  TString str = fPimpl->fGrab->ClassName();
3206  str += "::";
3207  str += fPimpl->fGrab->GetName();
3208  str += " replaced by ";
3209  str += frame->ClassName();
3210  str += "::";
3211  str += frame->GetName();
3212  fBuilder->UpdateStatusBar(str.Data());
3213  }
3214 
3215  TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
3216 
3217  if (fe) {
3218  fe->fFrame = 0;
3219  fPimpl->fGrab->DestroyWindow();
3220  delete fPimpl->fGrab;
3221  fPimpl->fGrab = 0;
3222 
3223  fe->fFrame = frame;
3224  frame->MoveResize(x, y, w, h);
3225  frame->MapRaised();
3226  frame->SetFrameElement(fe);
3227  }
3228 
3229  SelectFrame(frame);
3230  fPimpl->fReplaceOn = kFALSE;
3231 
3232  TGWindow *root = (TGWindow *)fClient->GetRoot();
3233  root->SetEditable(kFALSE);
3234  DoRedraw();
3235  root->SetEditable(kTRUE);
3236 }
3237 
3238 ////////////////////////////////////////////////////////////////////////////////
3239 /// Handle replace
3240 
3242 {
3243  if (fStop || !fPimpl->fGrab) {
3244  return;
3245  }
3246 
3247  fPimpl->fReplaceOn = kTRUE;
3248  TGFrame *frame = 0;
3249 
3250  if (fBuilder && fBuilder->IsExecutable()) {
3251  frame = (TGFrame *)fBuilder->ExecuteAction();
3252  } else {
3253  HandlePaste();
3254  frame = fPasteFrame;
3255  }
3256  DoReplace(frame);
3257  fPimpl->fReplaceOn = kFALSE;
3258 }
3259 
3260 ////////////////////////////////////////////////////////////////////////////////
3261 /// Create a frame which is the same as currently editted frame
3262 
3264 {
3265  if (fStop) {
3266  return;
3267  }
3268 
3269  TString tmpfile = gSystem->TempDirectory();
3270  char *s = gSystem->ConcatFileName(tmpfile.Data(), TString::Format("tmp%d.C",
3271  gRandom->Integer(100)));
3272  Save(s);
3273  gROOT->Macro(s);
3274  gSystem->Unlink(s);
3275  delete [] s;
3276 
3278  TGFrame *f = (TGFrame *)fClient->GetRoot();
3279  f->Resize(f->GetWidth() + 10, f->GetHeight() + 10);
3280  }
3281 }
3282 
3283 ////////////////////////////////////////////////////////////////////////////////
3284 /// Save an editted frame to the file
3285 
3287 {
3288  if (fStop || !fClient->GetRoot() || !fClient->IsEditable()) {
3289  return kFALSE;
3290  }
3291 
3293  TGWindow *root = (TGWindow*)fClient->GetRoot();
3294  TString fname = file;
3295 
3296  root->SetEditable(kFALSE);
3297 
3298  static TImage *img = 0;
3299 
3300  if (!img) {
3301  img = TImage::Create();
3302  }
3303  img->FromWindow(main->GetId());
3304 
3305  if (!file || !file[0]) {
3306  static TString dir(".");
3307  static Bool_t overwr = kFALSE;
3308  TGFileInfo fi;
3309 
3311  fi.SetIniDir(dir);
3312  fi.fOverwrite = overwr;
3313  new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
3314 
3315  if (!fi.fFilename) goto out;
3316  dir = fi.fIniDir;
3317  overwr = fi.fOverwrite;
3319  }
3320 
3321  if (fname.EndsWith(".C")) {
3323  main->SetWMSize(main->GetWidth(), main->GetHeight());
3324  main->SetWMSizeHints(main->GetDefaultWidth(), main->GetDefaultHeight(), 10000, 10000, 0, 0);
3325  main->SetWindowName(fname.Data());
3326  main->SetIconName(fname.Data());
3327  main->SetClassHints(fname.Data(), fname.Data());
3328  // some problems here under win32
3329  if (gVirtualX->InheritsFrom("TGX11")) main->SetIconPixmap("bld_rgb.xpm");
3330  main->SaveSource(fname.Data(), file ? "keep_names quiet" : "keep_names");
3331 
3332  fBuilder->AddMacro(fname.Data(), img);
3333 
3334  } else {
3335  Int_t retval;
3336  TString msg = TString::Format("file (%s) must have extension .C", fname.Data());
3337 
3338  new TGMsgBox(fClient->GetDefaultRoot(), main, "Error...", msg.Data(),
3339  kMBIconExclamation, kMBRetry | kMBCancel, &retval);
3340 
3341  if (retval == kMBRetry) {
3342  return Save();
3343  }
3344  }
3345 
3346 out:
3347  main->RaiseWindow();
3348  return kTRUE;
3349 }
3350 
3351 ////////////////////////////////////////////////////////////////////////////////
3352 /// Save composite frame as macro
3353 
3355 {
3356  if (fStop || !fClient->GetRoot() || !fClient->IsEditable() ||
3357  !fPimpl->fGrab || !fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
3358  return kFALSE;
3359  }
3360 
3361  TString fname = file;
3362 
3363  TGFrame *frame = fPimpl->fGrab;
3365 
3366  static TImage *img = 0;
3367 
3368  if (!img) {
3369  img = TImage::Create();
3370  }
3371  img->FromWindow(frame->GetId());
3372 
3373  static TString dir(".");
3374  static Bool_t overwr = kFALSE;
3375 
3376  TString sav = fPasteFileName;
3377 
3378  if (!file) {
3379  TGFileInfo fi;
3380 
3382  fi.SetIniDir(dir);
3383  fi.fOverwrite = overwr;
3384  new TGFileDialog(fClient->GetDefaultRoot(), frame, kFDSave, &fi);
3385 
3386  if (!fi.fFilename) {
3387  goto out;
3388  }
3389 
3390  dir = fi.fIniDir;
3391  overwr = fi.fOverwrite;
3393  }
3394 
3395  if (fname.EndsWith(".C")) {
3396  fPasteFileName = fname;
3397  fPimpl->fGrab = frame;
3398  fStop = kFALSE;
3399  TGFrameElement *fe = frame->GetFrameElement();
3400 
3401  if (!fe) { // should never happen
3402  fe = new TGFrameElement();
3403  fe->fFrame = frame;
3404  fe->fState = kIsMapped;
3405  frame->SetFrameElement(fe);
3406  TGCompositeFrame *comp = (TGCompositeFrame*)frame->GetParent();
3407  comp->GetList()->Add(fe);
3408  }
3409  delete fe->fLayout;
3411 
3412  HandleCopy(kFALSE);
3413  fStop = kTRUE;
3414 
3415  fBuilder->AddMacro(fname.Data(), img);
3416  } else {
3417  Int_t retval;
3418  TString msg = TString::Format("file (%s) must have extension .C", fname.Data());
3419 
3420  new TGMsgBox(fClient->GetDefaultRoot(), frame, "Error...", msg.Data(),
3421  kMBIconExclamation, kMBRetry | kMBCancel, &retval);
3422 
3423  if (retval == kMBRetry) {
3424  return SaveFrame();
3425  }
3426  }
3427 
3428 out:
3429  fPasteFileName = sav;
3430  return kTRUE;
3431 }
3432 /*
3433 ////////////////////////////////////////////////////////////////////////////////
3434 /// Not used yet. Return 0 if all child frames are inside area x,y, w,h
3435 
3436 static Int_t canResize(TGFrame *frame, Int_t x, Int_t y, UInt_t &w, UInt_t &h)
3437 {
3438  if (frame->InheritsFrom(TGCompositeFrame::Class())) return 0;
3439 
3440  TGCompositeFrame *comp = (TGCompositeFrame*)frame;
3441 
3442  TIter next(comp->GetList());
3443  TGFrameElement *fe;
3444  Int_t d = gGuiBldDragManager->GetGridStep();
3445  Int_t ret = 0;
3446 
3447  while ((fe = (TGFrameElement*)next())) {
3448  if (x + fe->fFrame->GetX() + fe->fFrame->GetWidth() > w) {
3449  w = fe->fFrame->GetX() + x + fe->fFrame->GetWidth();
3450  ret |= 4;
3451  }
3452  if (y + fe->fFrame->GetY() + fe->fFrame->GetHeight() > h) {
3453  h = fe->fFrame->GetY() + y + fe->fFrame->GetHeight();
3454  ret |= 8;
3455  }
3456  }
3457  return ret;
3458 }
3459 */
3460 
3461 ////////////////////////////////////////////////////////////////////////////////
3462 /// handle resize
3463 
3465 {
3466  if (fStop || !fClient->IsEditable()) {
3467  return;
3468  }
3469 
3470  TGFrame *fr = fPimpl->fGrab;
3471 
3472  if (!fr || IsFixedSize(fr) ||
3473  IsFixedLayout((TGWindow*)fr->GetParent())) {
3474 
3475  fr = (TGFrame*)GetResizableParent(fr);
3476 
3477  if (!fr ) {
3478  return;
3479  }
3480  }
3481 
3482  TGCompositeFrame *comp = 0;
3483 
3485  comp = (TGCompositeFrame*)fr;
3486  }
3487 
3488  Window_t c;
3489  Int_t x = fPimpl->fX;
3490  Int_t y = fPimpl->fY;
3491  UInt_t w = 0;
3492  UInt_t h = 0;
3493  UInt_t wp = ((TGFrame*)fr->GetParent())->GetWidth() - 2;
3494  UInt_t hp = ((TGFrame*)fr->GetParent())->GetHeight() - 2;
3495 
3496  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
3497  fr->GetId(), x, y, x, y, c);
3498 
3499  ToGrid(x, y);
3501 
3502  switch (fPimpl->fResizeType) {
3503  case kTopLeft:
3504  if ((((int)fr->GetWidth() > x) || (x < 0)) &&
3505  (((int)fr->GetHeight() > y) || (y < 0))) {
3506 
3507  if (fr->GetY() + y < 2) {
3508  y = 2 - fr->GetY();
3509  }
3510  if (fr->GetX() + x < 2) {
3511  x = 2 - fr->GetX();
3512  }
3513  h = fr->GetHeight() - y;
3514  w = fr->GetWidth() - x;
3515  x = fr->GetX() + x;
3516  y = fr->GetY() + y;
3517 
3518  if (!IsFixedH(fr) && !IsFixedW(fr)) {
3519  fr->MoveResize(x, y, w, h);
3520  break;
3521  }
3522  if (IsFixedH(fr)) {
3523  fr->MoveResize(x, fr->GetY(), w, fr->GetDefaultHeight());
3524  break;
3525  }
3526  if (IsFixedW(fr)) {
3527  fr->MoveResize(fr->GetX(), y, fr->GetDefaultWidth(), h);
3528  break;
3529  }
3530  }
3531  break;
3532  case kTopRight:
3533  if ((x > 0) && (((int)fr->GetHeight() > y) || (y < 0))) {
3534 
3535  if (fr->GetY() + y < 2) {
3536  y = 2 - fr->GetY();
3537  }
3538  h = fr->GetHeight() - y;
3539 
3540  if (IsFixedW(fr)) {
3541  w = fr->GetDefaultWidth();
3542  } else {
3543  w = fr->GetX() + x > Int_t(wp) ? wp - fr->GetX() : UInt_t(x);
3544  }
3545  x = fr->GetX();
3546  y = fr->GetY() + y;
3547 
3548  if (!IsFixedH(fr)) {
3549  fr->MoveResize(x, y, w, h);
3550  } else {
3551  fr->Resize(x, fr->GetDefaultHeight());
3552  }
3553  }
3554  break;
3555  case kTopSide:
3556  if (((int)fr->GetHeight() > y) || (y < 0)) {
3557  if (IsFixedH(fr)) {
3558  break;
3559  }
3560 
3561  if (fr->GetY() + y < 2) {
3562  y = 2 - fr->GetY();
3563  }
3564  h = fr->GetHeight() - y;
3565  w = fr->GetWidth();
3566  x = fr->GetX();
3567  y = fr->GetY() + y;
3568 
3569  fr->MoveResize(x, y, w, h);
3570  }
3571  break;
3572  case kBottomLeft:
3573  if ((((int)fr->GetWidth() > x) || (x < 0)) && (y > 0)) {
3574 
3575  if (fr->GetX() + x < 2) {
3576  x = 2 - fr->GetX();
3577  }
3578  h = fr->GetY() + y > Int_t(hp) ? hp - fr->GetY() : UInt_t(y);
3579  w = fr->GetWidth() - x;
3580  x = fr->GetX() + x;
3581 
3582  if (!IsFixedH(fr) && !IsFixedW(fr)) {
3583  fr->MoveResize(x, fr->GetY(), w, h);
3584  break;
3585  }
3586  if (IsFixedH(fr)) {
3587  fr->MoveResize(x, fr->GetY(), w, fr->GetDefaultHeight());
3588  break;
3589  }
3590  if (IsFixedW(fr)) {
3591  fr->MoveResize(fr->GetX(), fr->GetY(),
3592  fr->GetDefaultWidth(), h);
3593  break;
3594  }
3595  }
3596  break;
3597  case kBottomRight:
3598  if ((x > 0) && (y > 0)) {
3599  w = !IsFixedW(fr) ? UInt_t(x) : fr->GetDefaultWidth();
3600  h = !IsFixedH(fr) ? UInt_t(y) : fr->GetDefaultHeight();
3601 
3602  h = fr->GetY() + h > hp ? hp - fr->GetY() : h;
3603  w = fr->GetX() + w > wp ? wp - fr->GetX() : w;
3604 
3605  //canResize(comp, 0, 0, w, h);
3606  fr->Resize(w, h);
3607  }
3608  break;
3609  case kBottomSide:
3610  if (y > 0) {
3611  if (IsFixedH(fr)) {
3612  break;
3613  }
3614 
3615  w = fr->GetWidth();
3616  h = fr->GetY() + y > (Int_t)hp ? hp - fr->GetY() : UInt_t(y);
3617 
3618  //canResize(comp, 0, 0, w, h);
3619  fr->Resize(w, h);
3620  }
3621  break;
3622  case kLeftSide:
3623  if ((int)fr->GetWidth() > x ) {
3624  if (IsFixedW(fr)) {
3625  break;
3626  }
3627 
3628  if (fr->GetX() + x < 2) {
3629  x = 2 - fr->GetX();
3630  }
3631  w = fr->GetWidth() - x;
3632  h = fr->GetHeight();
3633  y = fr->GetY();
3634  x = fr->GetX() + x;
3635 
3636  //canResize(comp, x, y, w, h);
3637  fr->MoveResize(x, y, w, h);
3638  }
3639  break;
3640  case kRightSide:
3641  if (x > 0) {
3642  if (IsFixedW(fr)) {
3643  break;
3644  }
3645 
3646  h = fr->GetHeight();
3647  w = fr->GetX() + x > (Int_t)wp ? wp - fr->GetX() : UInt_t(x);
3648  //canResize(comp, 0, 0, w, h);
3649  fr->Resize(w, h);
3650  }
3651  break;
3652  default:
3653  break;
3654  }
3655  if (comp && (!comp->IsLayoutBroken() || IsFixedLayout(comp))) {
3656  layoutFrame(comp);
3657  }
3658 
3659  gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
3660  gVirtualX->CreateCursor(fPimpl->fResizeType));
3661  w = fr->GetWidth();
3662  h = fr->GetHeight();
3663 
3664  if (fBuilder) {
3665  TString str = fr->ClassName();
3666  str += "::";
3667  str += fr->GetName();
3668  str += " resized ";
3669  str += TString::Format("(%d x %d)", w, h);
3670  fBuilder->UpdateStatusBar(str.Data());
3671  }
3672 
3673  fClient->NeedRedraw(fr, kTRUE);
3674  DoRedraw();
3675  fEditor->ChangeSelected(fr); //to update the geometry frame after drag resize
3676 }
3677 
3678 ////////////////////////////////////////////////////////////////////////////////
3679 /// Handle move
3680 
3682 {
3683  if (fStop || !fPimpl->fGrab || !fClient->IsEditable()) {
3684  return;
3685  }
3686 
3687  TGWindow *parent = (TGWindow*)fPimpl->fGrab->GetParent();
3688 
3689  // do not remove frame from fixed layout or non-editable parent
3690  if (IsFixedLayout(parent) || IsEditDisabled(parent)) {
3691  return;
3692  }
3693 
3694  Int_t x = fPimpl->fX - fPimpl->fXf;
3695  Int_t y = fPimpl->fY - fPimpl->fYf;
3696 
3697  static Int_t qq;
3698  static UInt_t w = 0;
3699  static UInt_t h = 0;
3700 
3701  if (w == 0) {
3702  gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), qq, qq, w, h);
3703  }
3704 
3705  //
3706  Bool_t move = (x > 0) && (y > 0) && ((x + fPimpl->fGrab->GetWidth()) < (w - 0)) &&
3707  ((y + fPimpl->fGrab->GetHeight()) < (h - 30));
3708 
3709 
3710  // we are out of "win32 world"
3711  if (!move && !gVirtualX->InheritsFrom("TGX11")) {
3712  EndDrag();
3713  return;
3714  }
3715 
3716  fPimpl->fGrab->Move(x, y);
3717 
3718  if (fBuilder) {
3719  //fBuilder->Update();
3720  TString str = fPimpl->fGrab->ClassName();
3721  str += "::";
3722  str += fPimpl->fGrab->GetName();
3723  str += " is moved to absolute position ";
3724  str += TString::Format("(%d , %d)", x, y);
3725  fBuilder->UpdateStatusBar(str.Data());
3726  }
3727 
3729 }
3730 
3731 ////////////////////////////////////////////////////////////////////////////////
3732 /// Return a pointer to the parent mdi frame
3733 
3735 {
3736  if (fStop || !in) {
3737  return 0;
3738  }
3739 
3740  TGFrame *p = in;
3741 
3742  while (p && (p != fClient->GetDefaultRoot()) &&
3744  if (p->InheritsFrom(TGMdiFrame::Class())) {
3745  return p;
3746  }
3747  p = (TGFrame*)p->GetParent();
3748  }
3749  return 0;
3750 }
3751 
3752 ////////////////////////////////////////////////////////////////////////////////
3753 /// Raise guibuilder's mdi frame.
3754 
3756 {
3757  if (fStop || !comp) {
3758  return;
3759  }
3760 
3761  if (comp && comp->InheritsFrom(TGMdiFrame::Class()) && fBuilder) {
3762  TGFrame *mdi = fBuilder->FindEditableMdiFrame(comp);
3763  if (mdi) {
3764  // dragged frame is taken from some main frame
3765  //if (fPimpl->fGrab && fClient->GetRoot()->InheritsFrom(TGMainFrame::Class())) {
3766  // fBuilder->MapRaised();
3767  //}
3768  }
3769  if (fBuilder->GetMdiMain()->GetCurrent() != comp) {
3771  }
3772  }
3773 }
3774 
3775 ////////////////////////////////////////////////////////////////////////////////
3776 /// Look for the drop target under grabbed/selected frame while moving
3777 
3779 {
3780  if (fStop || !fPimpl->fGrab ) {
3781  return;
3782  }
3783 
3784  Int_t x = fPimpl->fGrab->GetX();
3785  Int_t y = fPimpl->fGrab->GetY();
3786  UInt_t w = fPimpl->fGrab->GetWidth();
3787  UInt_t h = fPimpl->fGrab->GetHeight();
3788 
3789  Bool_t ok = CheckTargetAtPoint(x - 1, y - 1);
3790 
3791  if (!ok) {
3792  ok = CheckTargetAtPoint(x + w + 1, y + h + 1);
3793  }
3794 
3795  if (!ok) {
3796  ok = CheckTargetAtPoint(x + w + 1, y - 1);
3797  }
3798 
3799  if (!ok) {
3800  ok = CheckTargetAtPoint(x - 1, y + h + 1);
3801  }
3802 }
3803 
3804 ////////////////////////////////////////////////////////////////////////////////
3805 /// Helper. Look for the drop target under grabbed/selected frame while moving.
3806 
3808 {
3809  if (fStop || !fPimpl->fGrab) {
3810  return kFALSE;
3811  }
3812 
3813  UInt_t ww = fPimpl->fGrab->GetWidth();
3814  UInt_t hh = fPimpl->fGrab->GetHeight();
3815  Bool_t ret = kFALSE;
3816  Window_t c;
3817  TGWindow *win = 0;
3818 
3820 
3821  if (w && (w != gVirtualX->GetDefaultRootWindow())) {
3822  win = fClient->GetWindowById(w);
3823  TGCompositeFrame *comp = 0;
3824 
3825  if (!win) {
3826  goto out;
3827  }
3828 
3829  if (win->InheritsFrom(TGCompositeFrame::Class())) {
3830  comp = (TGCompositeFrame *)win;
3831  } else if (win->GetParent() != fClient->GetDefaultRoot()) {
3832  comp = (TGCompositeFrame *)win->GetParent();
3833  }
3834 
3835  if (comp) {
3836  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
3837  comp->GetId(), x, y, x, y, c);
3838 
3839  RaiseMdiFrame(comp);
3840 
3841  if ((comp != fPimpl->fGrab) && (x >= 0) && (y >= 0) &&
3842  (x + ww <= comp->GetWidth()) &&
3843  (y + hh <= comp->GetHeight())) {
3844 
3845  if (comp != fTarget) {
3846  comp->HandleDragEnter(fPimpl->fGrab);
3847 
3848  if (fTarget) fTarget->HandleDragLeave(fPimpl->fGrab);
3849 
3850  else Snap2Grid();
3851  } else {
3852  if (fTarget) {
3853  fTarget->HandleDragMotion(fPimpl->fGrab);
3854  }
3855  }
3856 
3857  fTarget = comp;
3858  fTargetId = comp->GetId();
3859  ret = kTRUE;
3860  return ret;
3861 
3862  } else {
3863  if (fTarget) {
3864  fTarget->HandleDragLeave(fPimpl->fGrab);
3865  }
3866  fTarget = 0;
3867  fTargetId = 0;
3868  }
3869  }
3870  }
3871 
3872 out:
3873  if (fTarget) {
3874  fTarget->HandleDragLeave(fPimpl->fGrab);
3875  }
3876 
3877  if (!w || !win) {
3878  fTarget = 0;
3879  fTargetId = 0;
3880  }
3881  return ret;
3882 }
3883 
3884 ////////////////////////////////////////////////////////////////////////////////
3885 /// Handle motion event
3886 
3888 {
3889  if (fStop) {
3890  return kFALSE;
3891  }
3892 
3893  static Long64_t was = gSystem->Now();
3894  static Int_t gy = event->fYRoot;
3895  static Int_t gx = event->fXRoot;
3896 
3897  Long64_t now = gSystem->Now();
3898 
3899  if ((now-was < 100) || !(event->fState & kButton1Mask) ||
3900  ((event->fYRoot == gy) && (event->fXRoot == gx))) {
3901  return kFALSE;
3902  }
3903 
3904  was = now;
3905  gy = event->fYRoot;
3906  gx = event->fXRoot;
3907 
3908  if (!fDragging) {
3909  if (fMoveWaiting && ((TMath::Abs(fPimpl->fX - event->fXRoot) > 10) ||
3910  (TMath::Abs(fPimpl->fY - event->fYRoot) > 10))) {
3911 
3912  return StartDrag(fSource, event->fXRoot, event->fYRoot);
3913  }
3914  } else {
3915  fPimpl->fX = event->fXRoot;
3916  fPimpl->fY = event->fYRoot;
3917 
3918  switch (fDragType) {
3919  case kDragLasso:
3920  DrawLasso();
3921  fSelectionIsOn = event->fState & kKeyShiftMask;
3922  break;
3923  case kDragMove:
3924  case kDragCopy:
3925  case kDragLink:
3926  DoMove();
3927  break;
3928  case kDragResize:
3929  DoResize();
3930  break;
3931  default:
3932  break;
3933  }
3934  }
3936  return kTRUE;
3937 }
3938 
3939 ////////////////////////////////////////////////////////////////////////////////
3940 /// Put created frame at position of the last mouse click
3941 
3943 {
3944  Int_t x0, y0, x, y;
3945  Window_t c;
3946 
3947  if (fStop || !frame || !fClient->IsEditable()) {
3948  return;
3949  }
3950 
3951  frame->MapSubwindows();
3952  TGFrame *root = (TGFrame*)fClient->GetRoot();
3953 
3954  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
3955  root->GetId(),
3956  fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
3957  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
3958  root->GetId(),
3959  fPimpl->fX , fPimpl->fY, x, y, c);
3960 
3961  ToGrid(x, y);
3962  ToGrid(x0, y0);
3963 
3964  UInt_t w = TMath::Abs(x - x0);
3965  UInt_t h = TMath::Abs(y - y0);
3966  x = x > x0 ? x0 : x;
3967  y = y > y0 ? y0 : y;
3968 
3969  // do not create frame with size smaller when default size
3970  w = w < frame->GetDefaultWidth() + 2 ? frame->GetDefaultWidth() + 2 : w;
3971  h = h < frame->GetDefaultHeight() + 2 ? frame->GetDefaultHeight() + 2 : h;
3972 
3973  // do not create frame out of editable space
3974  x = x + w > root->GetWidth() ? Int_t(root->GetWidth() - w) : x;
3975  y = y + h > root->GetHeight() ? Int_t(root->GetHeight() - h) : y;
3976 
3977  frame->Move(x, y);
3978 
3979  UInt_t grid = GetGridStep();
3980 
3981  if (IsFixedW(frame) || IsFixedH(frame) || IsFixedSize(frame)) {
3982  w = IsFixedW(frame) ? frame->GetDefaultWidth() : w;
3983  h = IsFixedH(frame) ? frame->GetDefaultHeight() : h;
3984  frame->Resize(w < grid ? grid : w, h < grid ? grid : h);
3985  } else {
3986  if (frame->InheritsFrom(TGVerticalFrame::Class())) {
3987  frame->Resize(w < grid ? 15*grid : w, h < grid ? 30*grid : h);
3988  } else if (frame->InheritsFrom(TGHorizontalFrame::Class())) {
3989  frame->Resize(w < grid ? 30*grid : w, h < grid ? 15*grid : h);
3990  }
3991  else frame->Resize(w < 2*grid ? 2*grid : w, h < 2*grid ? 2*grid : h);
3992  }
3993 
3994  frame->MapRaised();
3995  frame->SetCleanup(kDeepCleanup);
3996  frame->AddInput(kButtonPressMask);
3997 
4000  edit->SetCleanup(kDeepCleanup);
4001  ReparentFrames(frame, edit);
4002  frame->MapRaised();
4003  //edit->SetLayoutBroken();
4004  UInt_t g = 2;
4005  // temporary hack for status bar
4006  if (frame->InheritsFrom("TGStatusBar")) {
4007  edit->AddFrame(frame, new TGLayoutHints(kLHintsBottom | kLHintsExpandX));
4008  }
4009  else {
4010  edit->AddFrame(frame, hints ? hints : new TGLayoutHints(kLHintsNormal, g, g, g, g));
4011  }
4012 
4013  if (hints && !edit->IsLayoutBroken()) {
4014  edit->GetLayoutManager()->Layout();
4015  } else {
4016  edit->Layout();
4017  }
4018  }
4019  if (fBuilder) {
4020  TString str = frame->ClassName();
4021  str += "::";
4022  str += frame->GetName();
4023  str += " created";
4024  fBuilder->UpdateStatusBar(str.Data());
4025  }
4026 
4027  if (frame->InheritsFrom(TGCanvas::Class())) {
4028  frame = ((TGCanvas*)frame)->GetContainer();
4029  }
4030 
4031  SelectFrame(frame);
4032 
4033 }
4034 ////////////////////////////////////////////////////////////////////////////////
4035 /// Draw lasso for allocation new object
4036 
4038 {
4039  if (fStop || !fClient->IsEditable()) {
4040  return;
4041  }
4042 
4043  UngrabFrame();
4044 
4045  Int_t x0, y0, x, y;
4046  Window_t c;
4047  TGFrame *root = (TGFrame*)fClient->GetRoot();
4048 
4049  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(), root->GetId(),
4050  fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
4051  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(), root->GetId(),
4052  fPimpl->fX , fPimpl->fY, x, y, c);
4053 
4054  UInt_t w, h;
4055  Bool_t xswap = kFALSE;
4056  Bool_t yswap = kFALSE;
4057 
4058  // check limits
4059 
4060  if ((x == x0) || ( y==y0 )) return; //lasso is not rectangle -> do not draw it
4061 
4062  if (x > x0) {
4063  x0 = x0 < 0 ? 0 : x0;
4064  w = x - x0;
4065  } else {
4066  x = x < 0 ? 0 : x;
4067  w = x0 - x;
4068  x0 = x;
4069  xswap = kTRUE;
4070  }
4071 
4072  if (y > y0) {
4073  y0 = y0 < 0 ? 0 : y0;
4074  h = y - y0;
4075  } else {
4076  y = y < 0 ? 0 : y;
4077  h = y0 - y;
4078  y0 = y;
4079  yswap = kTRUE;
4080  }
4081 
4082  w = x0 + w > root->GetWidth() ? root->GetWidth() - x0 : w;
4083  h = y0 + h > root->GetHeight() ? root->GetHeight() - y0 : h;
4084  x = x0 + w;
4085  y = y0 + h;
4086 
4087  ToGrid(x, y);
4088  ToGrid(x0, y0);
4089 
4090  // correct fPimpl->fX0 , fPimpl->fY0 , fPimpl->fX , fPimpl->fY
4091  gVirtualX->TranslateCoordinates(root->GetId(), fClient->GetDefaultRoot()->GetId(),
4092  xswap ? x : x0, yswap ? y : y0,
4093  fPimpl->fX0 , fPimpl->fY0, c);
4094  gVirtualX->TranslateCoordinates(root->GetId(), fClient->GetDefaultRoot()->GetId(),
4095  xswap ? x0 : x, yswap ? y0 : y,
4096  fPimpl->fX , fPimpl->fY, c);
4097  DoRedraw();
4098 
4099  gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
4100  GetBlackGC()(), x0, y0, w, h);
4101  gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
4102  GetBlackGC()(), x0+1, y0+1, w-2, h-2);
4103 
4104  gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kCross));
4105  gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kCross));
4106 
4108  root->RequestFocus();
4109 
4110  if (fBuilder) {
4111  TString str = "Lasso drawn. Align frames inside or presss Return key to grab frames.";
4112  fBuilder->UpdateStatusBar(str.Data());
4113  }
4114 }
4115 
4116 ////////////////////////////////////////////////////////////////////////////////
4117 /// Handle client message
4118 
4120 {
4121  if (fStop) {
4122  return kFALSE;
4123  }
4124 
4125  if ((event->fFormat == 32) && ((Atom_t)event->fUser[0] == gWM_DELETE_WINDOW) &&
4126  (event->fHandle != gROOT_MESSAGE)) {
4127 
4128  if (fPimpl->fPlane && (fPimpl->fPlane->GetId() == event->fWindow)) {
4129  fPimpl->fPlane = 0;
4130  }
4131 
4132  TGWindow *root = (TGWindow*)fClient->GetRoot();
4133  if (!root || (root == fClient->GetDefaultRoot())) {
4135  return kTRUE;
4136  }
4138 
4139  if (event->fWindow == main->GetId()) {
4140  if (main != fBuilder) {
4141  if (fEditor && !fEditor->IsEmbedded()) {
4142  delete fEditor;
4143  fEditor = 0;
4144  }
4145 
4147  return kTRUE;
4148  }
4149 
4150  delete fFrameMenu;
4151  fFrameMenu =0;
4152 
4153  delete fLassoMenu;
4154  fLassoMenu = 0;
4155 
4156  delete fPimpl->fGrid;
4157  fPimpl->fGrid = 0;
4158  Reset1();
4159 
4160  } else if (fBuilder && (event->fWindow == fBuilder->GetId())) {
4161  fBuilder->CloseWindow();
4162 
4163  } else if (fEditor && (event->fWindow == fEditor->GetMainFrame()->GetId())) {
4165  fEditor = 0;
4166  }
4167 
4168  // to avoid segv. stop editting
4170  }
4171 
4172  return kFALSE;
4173 }
4174 
4175 ////////////////////////////////////////////////////////////////////////////////
4176 /// Handle destroy notify
4177 
4179 {
4180  if (fPimpl->fPlane && (fPimpl->fPlane->GetId() == event->fWindow)) {
4181  fPimpl->fPlane = 0;
4182  }
4183 
4184  return kFALSE;
4185 }
4186 
4187 
4188 ////////////////////////////////////////////////////////////////////////////////
4189 /// not used yet.
4190 
4192 {
4193  if (fStop) {
4194  return kFALSE;
4195  }
4196 
4197  return kFALSE;
4198 }
4199 
4200 ////////////////////////////////////////////////////////////////////////////////
4201 /// not used yet.
4202 
4204 {
4205  if (fStop) {
4206  return kFALSE;
4207  }
4208 
4209  return kFALSE;
4210 }
4211 
4212 ////////////////////////////////////////////////////////////////////////////////
4213 /// Find parent frame which can be dragged
4214 
4216 {
4217  if (fStop) {
4218  return 0;
4219  }
4220 
4221  TGFrame *ret = (TGFrame*)p;
4222  TGWindow *parent = (TGWindow*)ret->GetParent();
4223 
4224  while (parent && (parent != fClient->GetDefaultRoot())) {
4225  if (!IsFixedLayout(parent) && !IsEditDisabled(parent)) {
4226  return ret;
4227  }
4228  ret = (TGFrame*)parent;
4229  parent = (TGWindow*)ret->GetParent();
4230  }
4231 
4232  return 0;
4233 }
4234 
4235 ////////////////////////////////////////////////////////////////////////////////
4236 /// Find parent frame which can be resized
4237 
4239 {
4240  if (fStop) {
4241  return 0;
4242  }
4243 
4244  TGWindow *parent = p;
4245 
4246  while (parent && (parent != fClient->GetDefaultRoot())) {
4247  if (!IsFixedSize(parent) &&
4248  !IsFixedLayout((TGWindow*)parent->GetParent()) &&
4249  !IsEditDisabled((TGWindow*)parent->GetParent())) {
4250  return parent;
4251  }
4252  parent = (TGWindow*)parent->GetParent();
4253  }
4254 
4255  return 0;
4256 }
4257 
4258 ////////////////////////////////////////////////////////////////////////////////
4259 /// Start dragging.
4260 
4262 {
4263  if (fStop || fDragging) {
4264  return kFALSE;
4265  }
4266 
4267  TGFrame *mov = src;
4268 
4269  // special case when frame was grabbed via spacebar pressing
4270  if (fPimpl->fSpacePressedFrame) {
4271  if (fDragType == kDragNone) {
4272  fDragType = kDragMove;
4273  mov = fPimpl->fSpacePressedFrame;
4274  } else {
4275  fPimpl->fSpacePressedFrame = 0;
4276  }
4277  }
4278 
4279  TGWindow *parent = (TGWindow*)(mov ? mov->GetParent() : 0);
4280 
4281  // do not remove frame from fixed layout or non-editable parent
4282  // try to drag "draggable parent"
4283  if (parent && (IsFixedLayout(parent) || IsEditDisabled(parent))) {
4284  mov = GetMovableParent(parent);
4285  if (!mov) {
4286  return kFALSE;
4287  }
4288  }
4289 
4290  SetEditable(kTRUE); // grab server
4291 
4292  fPimpl->fX = x;
4293  fPimpl->fY = y;
4295 
4296  fPimpl->fRepeatTimer->Reset();
4297  gSystem->AddTimer(fPimpl->fRepeatTimer);
4298 
4299  fMoveWaiting = kFALSE;
4300  fDragging = kTRUE;
4301  if (src) gVirtualX->SetCursor(src->GetId(), gVirtualX->CreateCursor(kMove));
4302 
4303  switch (fDragType) {
4304  case kDragCopy:
4305  HandleCopy();
4306  HandlePaste();
4307  GrabFrame(fPimpl->fGrab);
4308  break;
4309  case kDragMove:
4310  fPimpl->fGrab = mov;
4311  GrabFrame(fPimpl->fGrab);
4312  break;
4313  default:
4314  //fPimpl->fGrab = 0;
4315  break;
4316  }
4317 
4318  return kTRUE;
4319 }
4320 
4321 ////////////////////////////////////////////////////////////////////////////////
4322 /// End dragging.
4323 
4325 {
4326  TGFrame *frame = 0;
4327  Bool_t ret = kFALSE;
4328 
4329  if (fStop) {
4330  return kFALSE;
4331  }
4332 
4333  fMoveWaiting = kFALSE; // for sanity check
4334 
4335  if (fPimpl->fGrab && (fDragType >= kDragMove) && (fDragType <= kDragLink)) {
4336 
4337  ret = Drop();
4338 
4339  } else if (fBuilder && fBuilder->IsExecutable() &&
4340  (fDragType == kDragLasso) && !fSelectionIsOn) {
4341 
4342  frame = (TGFrame*)fBuilder->ExecuteAction();
4343  PlaceFrame(frame, fBuilder->GetAction()->fHints);
4345  ret = kTRUE;
4346  //return ret;
4347  } else if ((fDragType == kDragLasso) && fSelectionIsOn) {
4348 
4350  ret = kTRUE;
4351  }
4352 
4353  if (!fLassoDrawn) {
4354  DoRedraw();
4355  }
4356 
4357  Reset1();
4358  fPimpl->fSpacePressedFrame = 0;
4359 
4360  if (fBuilder) {
4361  fBuilder->SetAction(0);
4362  }
4363 
4364  return ret;
4365 }
4366 
4367 ////////////////////////////////////////////////////////////////////////////////
4368 /// Do cancel action.
4369 
4371 {
4372  if (fStop) {
4373  return kFALSE;
4374  }
4375 
4376  fTarget = 0;
4377  EndDrag();
4378  return kTRUE;
4379 }
4380 
4381 ////////////////////////////////////////////////////////////////////////////////
4382 /// Drop grabbed frame
4383 
4385 {
4386  if (fStop || !fDragging || !fPimpl->fGrab ||
4387  !((fDragType >= kDragMove) && (fDragType <= kDragLink))) {
4388  return kFALSE;
4389  }
4390 
4391  fDropStatus = kFALSE;
4392  TGFrame *frame = 0;
4393  TGFrame *parent = 0;
4394  Int_t x, y;
4395  Window_t c;
4396 
4397  switch (fDragType) {
4398  case kDragCopy:
4399  case kDragMove:
4400  frame = (TGFrame*)fPimpl->fGrab;
4401  break;
4402  default:
4403  break;
4404  }
4405 
4407 
4408  if (fTarget && fPimpl->fGrab && (w == fTarget) && w &&
4409  (w != fClient->GetDefaultRoot())) {
4410  parent = fTarget;
4411 
4412  gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
4413  fTarget->GetId(),
4414  fPimpl->fGrab->GetX(),
4415  fPimpl->fGrab->GetY(), x, y, c);
4416  fTarget->HandleDragLeave(fPimpl->fGrab);
4417  } else {
4418  parent = (TGFrame*)fPimpl->fGrabParent;
4419  x = fPimpl->fGrabX;
4420  y = fPimpl->fGrabY;
4421  }
4422 
4423  //reject move if layout is on
4424  if (parent && !parent->IsLayoutBroken() && (parent == fPimpl->fGrabParent) ) {
4425  fDropStatus = 0;
4426  } else if (parent && frame && (parent != fClient->GetDefaultRoot()) ) {
4427  ToGrid(x, y);
4428  fDropStatus = parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
4429 
4430  // drop was rejected
4431  if (!fDropStatus) {
4432  if (fDragType == kDragMove) { // return dragged frame to initial position
4433  parent = (TGFrame*)fPimpl->fGrabParent;
4434  x = fPimpl->fGrabX;
4435  y = fPimpl->fGrabY;
4436  frame = fPimpl->fGrab;
4437 
4438  if (parent && frame && (parent != fClient->GetDefaultRoot())) {
4439  fDropStatus = parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
4440  }
4441  } else { // (fDragType == kDragCopy) - delete it
4442  DeleteFrame(frame);
4443  }
4444  }
4445  }
4446 
4447  if (fDropStatus) {
4448  //do not break layout of the new parent if layout there is enabled
4449  if (parent && !parent->IsLayoutBroken()) {
4450  parent->Layout();
4451  }
4452 
4453  if (fBuilder) {
4454  TString str = frame->ClassName();
4455  str += "::";
4456  str += frame->GetName();
4457  str += " dropped into ";
4458  str += parent->ClassName();
4459  str += "::";
4460  str += parent->GetName();
4461  str += " at position ";
4462  str += TString::Format("(%d , %d)", x, y);
4463  fBuilder->UpdateStatusBar(str.Data());
4464  }
4465  fTarget = 0;
4466  fTargetId = 0;
4467 
4468  if (parent && (parent == fPimpl->fGrabParent) && fPimpl->fGrabListPosition &&
4469  frame && parent->InheritsFrom(TGCompositeFrame::Class())) {
4470 
4471  TList *li = ((TGCompositeFrame*)parent)->GetList();
4472  li->Remove(frame->GetFrameElement());
4473  li->AddAfter(fPimpl->fGrabListPosition, frame->GetFrameElement());
4474  }
4475  } else { // grab frame cannot be dropped
4476 // if (fDragType == kDragCopy) { // dosn't work (point is not reached ???)
4477 // HandleDelete(kFALSE);
4478 // }
4479 
4480  if (fPimpl->fGrab && fPimpl->fGrabParent) {
4481  fPimpl->fGrab->ReparentWindow(fPimpl->fGrabParent, fPimpl->fGrabX, fPimpl->fGrabY);
4482  ((TGCompositeFrame*)fPimpl->fGrabParent)->AddFrame(fPimpl->fGrab);
4483  }
4484  }
4485 
4486  fPimpl->fGrabParent = 0;
4487  fPimpl->fGrabX = 0;
4488  fPimpl->fGrabY = 0;
4489  fPimpl->fGrabListPosition = 0;
4490 
4491  return fDropStatus;
4492 }
4493 
4494 ////////////////////////////////////////////////////////////////////////////////
4495 /// Waits for either the mouse move from the given initial ButtonPress location
4496 /// or for the mouse button to be released. If mouse moves away from the initial
4497 /// ButtonPress location before the mouse button is released "IsMoveWaiting"
4498 /// returns kTRUE. If the mouse button released before the mose moved from the
4499 /// initial ButtonPress location, "IsMoveWaiting" returns kFALSE.
4500 
4502 {
4503  return fMoveWaiting;
4504 }
4505 
4506 ////////////////////////////////////////////////////////////////////////////////
4507 /// Layout and Resize frame.
4508 /// If global is kFALSE - compact selected frame
4509 /// If global is kFALSE - compact main frame of selected frame
4510 
4512 {
4513  TGCompositeFrame *comp = 0;
4514  TGFrameElement *fe;
4515 
4516  if (fStop || !fClient || !fClient->IsEditable() || !fPimpl->fGrab) {
4517  return;
4518  }
4519 
4520  TGWindow *parent = (TGWindow*)fPimpl->fGrab->GetParent();
4521 
4522  if (global) {
4523  if (!fBuilder) {
4525  } else {
4527  if (!comp) {
4529  }
4530  }
4531  } else {
4532  if (fPimpl->fGrab &&
4533  fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
4534  comp = (TGCompositeFrame*)fPimpl->fGrab;
4535  } else {
4536  comp = (TGCompositeFrame*)parent;
4537  }
4538  }
4539 
4540  if (!comp || IsFixedLayout(comp) || IsFixedLayout(parent) ||
4541  IsFixedSize(comp) || IsFixedH(comp) || IsFixedW(comp)) return;
4542 
4543  comp->SetLayoutBroken(kFALSE);
4544 
4545  TIter next(comp->GetList());
4546 
4547  TGFrame *root = (TGFrame *)fClient->GetRoot();
4548  root->SetEditable(kFALSE);
4549 
4550  TGDimension d;
4551 
4552  if (global) {
4553  while ((fe = (TGFrameElement*)next())) {
4554  if (IsFixedLayout(fe->fFrame) || IsFixedSize(fe->fFrame) ||
4555  IsFixedH(fe->fFrame) || IsFixedW(fe->fFrame)) continue;
4556 
4558  d = fe->fFrame->GetDefaultSize();
4559 
4560  // avoid "to point" resizing
4561  if ((d.fWidth > 10) && (d.fHeight > 10)) {
4562  fe->fFrame->Resize();
4563  } else if (d.fWidth > 10) {
4564  fe->fFrame->Resize(d.fWidth, 10);
4565  } else if (d.fHeight > 10) {
4566  fe->fFrame->Resize(10, d.fHeight);
4567  } else {
4568  fe->fFrame->Resize(10, 10);
4569  }
4570  fClient->NeedRedraw(fe->fFrame);
4571  }
4572  if (!IsFixedLayout(root)) {
4573  root->SetLayoutBroken(kFALSE);
4574  }
4575  fPimpl->fCompacted = kTRUE;
4576  }
4577 
4578  if (!IsFixedLayout(comp)) {
4579  comp->SetLayoutBroken(kFALSE);
4580  d = comp->GetDefaultSize();
4581 
4582  // avoid "to point" resizing
4583  if ((d.fWidth > 10) && (d.fHeight > 10)) {
4584  comp->Resize();
4585  } else if (d.fWidth > 10) {
4586  comp->Resize(d.fWidth, 10);
4587  } else if (d.fHeight > 10) {
4588  comp->Resize(10, d.fHeight);
4589  } else {
4590  comp->Resize(10, 10);
4591  }
4592  layoutFrame(comp);
4593  }
4594 
4595  if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
4596  TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
4597  Int_t b = 2 * decor->GetBorderWidth();
4598  decor->MoveResize(decor->GetX(), decor->GetY(), comp->GetDefaultWidth() + b,
4599  comp->GetDefaultHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
4600  }
4601 
4602  root->SetEditable(kTRUE);
4603 
4604  fClient->NeedRedraw(comp);
4605  SelectFrame(comp);
4606  DoRedraw();
4607 }
4608 
4609 ////////////////////////////////////////////////////////////////////////////////
4610 /// Grab server.
4611 
4613 {
4614  static Bool_t gon = kFALSE;
4615  static const TGWindow *gw = 0;
4616 
4617  if ((gon == on) && (fClient->GetRoot() == gw)) {
4618  return;
4619  }
4620 
4621  gon = on; gw = fClient->GetRoot();
4622 
4623  if (on) {
4624  fStop = kFALSE;
4625 
4626  if (fPimpl->fRepeatTimer) {
4627  fPimpl->fRepeatTimer->Reset();
4628  } else {
4629  fPimpl->fRepeatTimer = new TGuiBldDragManagerRepeatTimer(this, 100);
4630  }
4631  gSystem->AddTimer(fPimpl->fRepeatTimer);
4633 
4634  Snap2Grid();
4635  } else {
4637 
4638  if (fPimpl->fRepeatTimer) {
4639  fPimpl->fRepeatTimer->Remove();
4640  }
4641 
4642  fSelected = fPimpl->fGrab = 0;
4643 
4644  delete fPimpl->fGrid;
4645  fPimpl->fGrid = 0;
4646 
4647  fPimpl->ResetParams();
4648 
4649  TGWindow *root = (TGWindow*)fClient->GetRoot();
4650  if (root) {
4651  fClient->SetRoot(0);
4652  }
4653 
4656  }
4657 
4660  }
4661 
4662  if (fBuilder) {
4663  fBuilder->Update();
4664  }
4665  //CloseMenus();
4666 
4667  fStop = kTRUE;
4668  }
4669 
4670  if (on && fClient->IsEditable()) {
4671  gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
4672  gVirtualX->CreateCursor(kPointer));
4673  }
4674 }
4675 
4676 ////////////////////////////////////////////////////////////////////////////////
4677 /// Return grid coordinates which are close to given
4678 
4680 {
4681  UInt_t step = GetGridStep();
4682  x = x - x%step;
4683  y = y - y%step;
4684 }
4685 
4686 ////////////////////////////////////////////////////////////////////////////////
4687 /// Main handler of actions
4688 
4690 {
4691  fPimpl->fLastPopupAction = act;
4692 
4693  switch ((EActionType)act) {
4694  case kPropertyAct:
4696  break;
4697  case kEditableAct:
4698  if (fPimpl->fSaveGrab) fPimpl->fSaveGrab->SetEditable(kTRUE);
4699  if (fBuilder) {
4701  }
4702  break;
4703  case kCutAct:
4704  HandleCut();
4705  break;
4706  case kCopyAct:
4707  HandleCopy();
4708  break;
4709  case kPasteAct:
4710  HandlePaste();
4711  break;
4712  case kCropAct:
4714  break;
4715  case kCompactAct:
4716  Compact(kFALSE);
4717  break;
4718  case kCompactGlobalAct:
4719  Compact(kTRUE);
4720  break;
4721  case kDropAct:
4723  break;
4724  case kLayUpAct:
4726  break;
4727  case kLayDownAct:
4729  break;
4730  case kCloneAct:
4731  CloneEditable();
4732  break;
4733  case kGrabAct:
4735  break;
4736  case kDeleteAct:
4738  break;
4739  case kLeftAct:
4741  break;
4742  case kRightAct:
4744  break;
4745  case kUpAct:
4747  break;
4748  case kDownAct:
4750  break;
4751  case kEndEditAct:
4752  if (fBuilder) {
4754  }
4756  break;
4757  case kReplaceAct:
4758  HandleReplace();
4759  break;
4760  case kGridAct:
4761  HandleGrid();
4762  break;
4763  case kBreakLayoutAct:
4764  BreakLayout();
4765  break;
4766  case kSwitchLayoutAct:
4767  case kLayoutVAct:
4768  case kLayoutHAct:
4769  SwitchLayout();
4770  break;
4771  case kNewAct:
4772  if (fBuilder) {
4773  fBuilder->NewProject();
4774  } else {
4775  TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
4776  main->MapRaised();
4777  main->SetEditable(kTRUE);
4778  }
4779  break;
4780  case kOpenAct:
4781  if (fBuilder) {
4782  fBuilder->OpenProject();
4783  } else {
4784  TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
4785  main->MapRaised();
4786  main->SetEditable(kTRUE);
4787  }
4788  break;
4789  case kSaveAct:
4790  if (fBuilder) {
4792  (!fClient->IsEditable() && fBuilder->GetMdiMain()->GetCurrent())) {
4793  fBuilder->SaveProject();
4794  } else {
4795  Save();
4796  }
4797  } else {
4798  Save();
4799  }
4800  break;
4801  case kSaveFrameAct:
4802  SaveFrame();
4803  break;
4804  default:
4805  break;
4806  }
4807 
4808  fPimpl->fPlacePopup = kFALSE;
4809 
4810  if (fBuilder) {
4811  fBuilder->SetAction(0);
4812  //fBuilder->Update();
4813  }
4814 
4815  if (fPimpl->fSaveGrab) {
4816  fClient->NeedRedraw(fPimpl->fSaveGrab, kTRUE);
4817  }
4818 
4819  DoRedraw();
4820 }
4821 
4822 ////////////////////////////////////////////////////////////////////////////////
4823 /// kTRUE - if it's possible to switch disable/enable layout
4824 
4826 {
4827  return (!(w->GetEditDisabled() & kEditDisable) &&
4829 }
4830 
4831 ////////////////////////////////////////////////////////////////////////////////
4832 /// kTRUE - if it's possible to change layout order in the parent's layout of window w
4833 
4835 {
4836  return (w->GetParent()->InheritsFrom(TGCompositeFrame::Class()) &&
4837  !((TGCompositeFrame*)w->GetParent())->IsLayoutBroken() &&
4838  !IsFixedLayout((TGWindow*)w->GetParent()));
4839 }
4840 
4841 ////////////////////////////////////////////////////////////////////////////////
4842 /// kTRUE is frame could be compacted/"layouted"
4843 
4845 {
4846  return CanChangeLayout(w);
4847 /*
4848  return (!IsFixedLayout(w) &&
4849  w->InheritsFrom(TGCompositeFrame::Class()) &&
4850  ((TGCompositeFrame*)w)->IsLayoutBroken() &&
4851  !IsEditDisabled((TGWindow*)w->GetParent()) &&
4852  !IsFixedLayout((TGWindow*)w->GetParent()));
4853 */
4854 }
4855 
4856 ////////////////////////////////////////////////////////////////////////////////
4857 /// Create widget property editor (it could be located outside of guibuilder)
4858 
4860 {
4861 // if (!fPimpl->fClickFrame) return;
4862 
4863  TGWindow *root = (TGWindow*)fClient->GetRoot();
4864  root->SetEditable(kFALSE);
4865 
4867 
4868  fBuilder->Move(fPimpl->fX0, fPimpl->fY0);
4869  fBuilder->SetWMPosition(fPimpl->fX0, fPimpl->fY0);
4871 
4872  root->SetEditable(kTRUE);
4873 }
4874 
4875 ////////////////////////////////////////////////////////////////////////////////
4876 /// Helper method
4877 
4879 {
4880  fEditor = e;
4881 
4882  if (!fEditor) {
4883  return;
4884  }
4885 
4886  ChangeSelected(fPimpl->fClickFrame);
4887  fEditor->Connect("UpdateSelected(TGFrame*)", "TGuiBldDragManager", this,
4888  "HandleUpdateSelected(TGFrame*)");
4889 }
4890 
4891 ////////////////////////////////////////////////////////////////////////////////
4892 /// Change layout order
4893 
4895 {
4896  if (fStop || !fPimpl->fGrab || !fPimpl->fGrab->GetFrameElement() ||
4897  !CanChangeLayoutOrder(fPimpl->fGrab)) {
4898  return;
4899  }
4900 
4901  TGCompositeFrame *comp = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
4902  TList *li = comp->GetList();
4903  TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
4904 
4905  if (!fe) { // sanity check
4906  return;
4907  }
4908 
4909  TGFrame *frame;
4910  TGFrameElement *el;
4911 
4912  if (forward) {
4913  el = (TGFrameElement *)li->After(fe);
4914  if (!el) return;
4915  frame = el->fFrame;
4916 
4917  el->fFrame = fPimpl->fGrab;
4918  fPimpl->fGrab->SetFrameElement(el);
4919  fe->fFrame = frame;
4920  frame->SetFrameElement(fe);
4921  } else {
4922  el = (TGFrameElement *)li->Before(fe);
4923 
4924  if (!el) {
4925  return;
4926  }
4927  frame = el->fFrame;
4928 
4929  el->fFrame = fPimpl->fGrab;
4930  fPimpl->fGrab->SetFrameElement(el);
4931  fe->fFrame = frame;
4932  frame->SetFrameElement(fe);
4933  }
4934 
4935  Bool_t sav = comp->IsLayoutBroken();
4936  comp->SetLayoutBroken(kFALSE);
4937  TGWindow *root = (TGWindow *)fClient->GetRoot();
4938  root->SetEditable(kFALSE);
4939  comp->Layout();
4940  DoRedraw();
4941  root->SetEditable(kTRUE);
4942 
4943  if (sav) {
4944  comp->SetLayoutBroken(kTRUE);
4945  }
4946  SelectFrame(el->fFrame);
4947 }
4948 
4949 ////////////////////////////////////////////////////////////////////////////////
4950 /// Switch on/of grid drawn.
4951 
4953 {
4954  if (fStop) {
4955  return;
4956  }
4957 
4958  TGWindow *root = (TGWindow*)fClient->GetRoot();
4959 
4960  if (!root || (root == fClient->GetDefaultRoot())) {
4961  return;
4962  }
4963 
4964  if (fPimpl->fGrid->fgStep > 1) {
4965  fPimpl->fGrid->SetStep(1);
4966  if (fBuilder) {
4967  fBuilder->UpdateStatusBar("Grid switched OFF");
4968  }
4969  } else {
4970  fPimpl->fGrid->SetStep(gGridStep);
4971 
4972  if (fBuilder) {
4973  fBuilder->UpdateStatusBar("Grid switched ON");
4974  }
4975 
4976  if (root->InheritsFrom(TGCompositeFrame::Class())) {
4977  TGCompositeFrame *comp = (TGCompositeFrame*)root;
4978  TIter next(comp->GetList());
4979  TGFrameElement *fe;
4980  Int_t x, y, w, h;
4981 
4982  while ((fe = (TGFrameElement*)next())) {
4983  x = fe->fFrame->GetX();
4984  y = fe->fFrame->GetY();
4985  w = fe->fFrame->GetWidth();
4986  h = fe->fFrame->GetHeight();
4987  ToGrid(x, y);
4988  ToGrid(w, h);
4989  fe->fFrame->MoveResize(x, y, w, h);
4990  }
4991  }
4992  }
4993 
4994  Snap2Grid();
4996 }
4997 
4998 ////////////////////////////////////////////////////////////////////////////////
4999 /// Helper to find a frame which can be layouted
5000 
5002 {
5003  if (fStop || !f) {
5004  return 0;
5005  }
5006 
5007  const TGWindow *parent = f->GetParent();
5008  TGCompositeFrame *ret = 0;
5009 
5010  while (parent && (parent != fClient->GetDefaultRoot())) {
5011  ret = (TGCompositeFrame*)parent;
5012  if (parent->InheritsFrom(TGMdiFrame::Class())) return ret;
5013  parent = parent->GetParent();
5014  }
5015  return ret;
5016 }
5017 
5018 ////////////////////////////////////////////////////////////////////////////////
5019 /// When selected frame was changed by guibuilder editor -> update its appearence
5020 
5022 {
5023  if (fStop || !f) {
5024  return;
5025  }
5026 
5027  TGCompositeFrame *parent = 0;
5028  if (f->GetParent() &&
5029  f->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
5030  parent = (TGCompositeFrame*)f->GetParent();
5031  }
5032 
5033  if (!parent || !CanChangeLayout(parent)) {
5034  return;
5035  }
5036 
5037  Bool_t sav = parent->IsLayoutBroken();
5038  parent->SetLayoutBroken(kFALSE);
5039 
5040  if ((parent->GetWidth() < parent->GetDefaultWidth()) ||
5041  (parent->GetHeight() < parent->GetDefaultHeight())) {
5042  parent->Resize(parent->GetDefaultSize());
5043  } else {
5044  parent->Layout();
5045  if (f->InheritsFrom(TGCompositeFrame::Class())) {
5046  layoutFrame(f);
5047  }
5048  }
5049  fClient->NeedRedraw(parent, kTRUE);
5050  fClient->NeedRedraw(f);
5051 
5052  if (sav) parent->SetLayoutBroken(kTRUE);
5053 
5054  SelectFrame(f);
5055 }
5056 
5057 ////////////////////////////////////////////////////////////////////////////////
5058 /// Hide/Unmap grab rectangles.
5059 
5061 {
5062  static Bool_t first = kFALSE;
5063 
5064  if (fPimpl->fGrabRectHidden) {
5065  return;
5066  }
5067  // skip very first event
5068  if (!first) {
5069  first = kTRUE;
5070  return;
5071  }
5072  int i = 0;
5073  for (i = 0; i < 8; i++) fPimpl->fGrabRect[i]->UnmapWindow();
5074  for (i = 0; i < 4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
5075  fPimpl->fGrabRectHidden = kTRUE;
5076 }
5077 
5078 ////////////////////////////////////////////////////////////////////////////////
5079 /// Delete widget property editor.
5080 
5082 {
5083  if (fStop || !fEditor) {
5084  return;
5085  }
5086 
5088 
5089  delete fEditor;
5090  fEditor = 0;
5091 }
5092 
5093 ////////////////////////////////////////////////////////////////////////////////
5094 /// Return the X coordinate where drag started
5095 
5097 {
5098  return fPimpl->fX0;
5099 }
5100 
5101 ////////////////////////////////////////////////////////////////////////////////
5102 /// Return the Y coordinate where drag started
5103 
5105 {
5106  return fPimpl->fY0;
5107 }
5108 
5109 ////////////////////////////////////////////////////////////////////////////////
5110 /// Return the current X coordinate of the dragged frame
5111 
5113 {
5114  return fPimpl->fY;
5115 }
5116 
5117 ////////////////////////////////////////////////////////////////////////////////
5118 /// Returns the current Y coordinate of the dragged frame
5119 
5121 {
5122  return fPimpl->fY;
5123 }
5124 
5125 ////////////////////////////////////////////////////////////////////////////////
5126 /// Disable/Enable layout for selected/grabbed composite frame.
5127 
5129 {
5130  if (fStop) {
5131  return;
5132  }
5133 
5134  TGFrame *frame = fSelected;
5135 
5136  if (!frame) {
5137  return;
5138  }
5139 
5140  TString str = frame->ClassName();
5141  str += "::";
5142  str += frame->GetName();
5143 
5144  if (IsFixedLayout(frame)) {
5145  if (fBuilder) {
5146  str += " layout cannot be broken";
5147  fBuilder->UpdateStatusBar(str.Data());
5148  }
5149  return;
5150  }
5151 
5152  frame->SetLayoutBroken(!frame->IsLayoutBroken());
5154 
5155  if (fBuilder) {
5156  str += (frame->IsLayoutBroken() ? " Disable Layout" : " Enable Layout");
5157  fBuilder->UpdateStatusBar(str.Data());
5158  }
5159  if (fPimpl->fGrab && (fPimpl->fGrab->IsA() == TGCanvas::Class())) {
5160  fPimpl->fGrab->Layout();
5161  }
5162 }
5163 
5164 ////////////////////////////////////////////////////////////////////////////////
5165 /// Switch Horizontal/Vertical layout of selected/grabbed composite frame
5166 
5168 {
5169  if (fStop || !fPimpl->fGrab) {
5170  return;
5171  }
5172 
5174 
5175  comp->SetLayoutBroken(kFALSE);
5176 
5177  UInt_t opt = comp->GetOptions();
5178  TGLayoutManager *m = comp->GetLayoutManager();