Logo ROOT  
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
65static UInt_t gGridStep = 8;
69
70static const char *gSaveMacroTypes[] = {
71 "Macro files", "*.C",
72 "All files", "*",
73 0, 0
74};
75
76static 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
102class TGuiBldMenuDialog : public TGTransientFrame {
103
104friend class TGuiBldDragManager;
105
106public:
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
116public:
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
136TGuiBldMenuDialog::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
165TGuiBldMenuDialog::~TGuiBldMenuDialog()
166{
167 fWidgets->Delete();
168 delete fWidgets;
169 delete fL1;
170 delete fL2;
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Connect buttons signals
175
176void 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
186void 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
279void 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
299void TGuiBldMenuDialog::CloseWindow()
300{
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// Build dialog
306
307void 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);
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
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Popup dialog.
428
429void 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
490static 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
517static void GuiBldErrorHandler(Int_t /*level*/, Bool_t /*abort*/,
518 const char * /*location*/, const char * /*msg*/)
519{
520}
521
522////////////////////////////////////////////////////////////////////////////////
523class TGuiBldDragManagerGrid {
524
525public:
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
542UInt_t TGuiBldDragManagerGrid::fgStep = gGridStep;
543ULong_t TGuiBldDragManagerGrid::fgPixel = 0;
544TGGC *TGuiBldDragManagerGrid::fgBgnd = 0;
545
546////////////////////////////////////////////////////////////////////////////////
547/// Create a grid background for the selected window
548
549TGuiBldDragManagerGrid::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
564TGuiBldDragManagerGrid::~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
585void 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
601void 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
622void 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////////////////////////////////////////////////////////////////////////////////
667class TGuiBldDragManagerRepeatTimer : public TTimer {
668
669private:
670 TGuiBldDragManager *fManager; // back pointer
671
672public:
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////////////////////////////////////////////////////////////////////////////////
680class TGGrabRect : public TGFrame {
681
682private:
683 Pixmap_t fPixmap;
685
686public:
687 TGGrabRect(Int_t type);
688 ~TGGrabRect() {}
689
691 ECursor GetType() const { return fType; }
692};
693
694////////////////////////////////////////////////////////////////////////////////
695/// ctor.
696
697TGGrabRect::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:
711 break;
712 case 3:
714 break;
715 case 4:
717 break;
718 case 5:
720 break;
721 case 6:
723 break;
724 case 7:
726 break;
727 }
728
732 attr.fSaveUnder = kTRUE;
733
734 gVirtualX->ChangeWindowAttributes(fId, &attr);
735
736 fPixmap = gVirtualX->CreatePixmap(gVirtualX->GetDefaultRootWindow(), 8, 8);
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
759Bool_t TGGrabRect::HandleButton(Event_t *ev)
760{
762 return kTRUE;
763}
764
765////////////////////////////////////////////////////////////////////////////////
766class TGAroundFrame : public TGFrame {
767
768public:
769 TGAroundFrame();
770 ~TGAroundFrame() {}
771};
772
773////////////////////////////////////////////////////////////////////////////////
774/// ctor.
775
776TGAroundFrame::TGAroundFrame() : TGFrame(gClient->GetDefaultRoot(), 1, 1,
778{
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////////////////////////////////////////////////////////////////////////////////
792class TGuiBldDragManagerPimpl {
793
794friend class TGuiBldDragManager;
795
796private:
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
824public:
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
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()));
920 delete [] s;
921
922 s = gSystem->ConcatFileName(tmpfile.Data(),
923 TString::Format("RootGuiBldTmpFile%d.C", gSystem->GetPid()));
925 delete [] s;
926
927 fName = "Gui Builder Drag Manager";
929
930 // let's try to solve the problems by myself
932
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
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.";
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";
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
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
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) {
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
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
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";
1412 }
1413 fSelected = fPimpl->fGrab = 0;
1414}
1415
1416////////////////////////////////////////////////////////////////////////////////
1417/// Helper for IsPointVisible
1418
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();
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
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
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;
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;
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
1863out:
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
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
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)) {
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
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.fIniDir = StrDup(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) {
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) {
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()),
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:
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
2613 Int_t x = canvas->GetX();
2614 Int_t y = canvas->GetY();
2615
2616 cont->SetEditDisabled(cont->GetEditDisabled() & ~kEditDisableGrab);
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.";
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
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";
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) {
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
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
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";
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();
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.fIniDir = StrDup(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(),
3340
3341 if (retval == kMBRetry) {
3342 return Save();
3343 }
3344 }
3345
3346out:
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.fIniDir = StrDup(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
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(),
3422
3423 if (retval == kMBRetry) {
3424 return SaveFrame();
3425 }
3426 }
3427
3428out:
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
3436static 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);
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);
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) {
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
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) {
3854 }
3855 }
3856
3857 fTarget = comp;
3858 fTargetId = comp->GetId();
3859 ret = kTRUE;
3860 return ret;
3861
3862 } else {
3863 if (fTarget) {
3865 }
3866 fTarget = 0;
3867 fTargetId = 0;
3868 }
3869 }
3870 }
3871
3872out:
3873 if (fTarget) {
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")) {
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";
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.";
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())) {
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) {
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
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() &&
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
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);
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);
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 }
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
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: