// @(#)root/guibuilder:$Name: $:$Id: TGuiBldDragManager.cxx,v 1.32 2005/02/18 11:22:28 rdm Exp $
// Author: Valeriy Onuchin 12/09/04
/*************************************************************************
* Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGuiBldDragManager.h"
#include "TGuiBldEditor.h"
#include "TRootGuiBuilder.h"
#include "TGuiBldQuickHandler.h"
#include "TTimer.h"
#include "TList.h"
#include "TSystem.h"
#include "TMath.h"
#include "TGResourcePool.h"
#include "TROOT.h"
#include "TColor.h"
#include "KeySymbols.h"
#include "TGMenu.h"
#include "TGFileDialog.h"
#include "TGMsgBox.h"
#include "TRandom.h"
#include "TGButton.h"
#include "TGMdi.h"
//////////////////////////////////////////////////////////////////////////
// //
// TGuiBldDragManager //
// //
//////////////////////////////////////////////////////////////////////////
ClassImp(TGuiBldDragManager)
static UInt_t gGridStep = 10;
static TGuiBldDragManager *gGuiBldDragManager = 0;
///////////////////////// auxilary static functions ///////////////////////////
//______________________________________________________________________________
static Window_t GetWindowFromPoint(Int_t x, Int_t y)
{
// returns a window located at point x,y (screen coordinates)
Window_t src, dst, child;
Window_t ret = 0;
Int_t xx = x;
Int_t yy = y;
dst = src = child = gVirtualX->GetDefaultRootWindow();
while (child && dst) {
src = dst;
dst = child;
gVirtualX->TranslateCoordinates(src, dst, xx, yy, xx, yy, child);
ret = dst;
}
return ret;
}
////////////////////////////////////////////////////////////////////////////////
class TGuiBldDragManagerGrid {
public:
static UInt_t fgStep;
static ULong_t fgPixel;
static TGGC *fgBgnd;
Pixmap_t fPixmap;
TGWindow *fWindow;
Int_t fWinId;
TGuiBldDragManagerGrid();
~TGuiBldDragManagerGrid();
void Draw();
void SetStep(UInt_t step);
void InitPixmap();
void InitBgnd();
};
UInt_t TGuiBldDragManagerGrid::fgStep = gGridStep;
ULong_t TGuiBldDragManagerGrid::fgPixel = 0;
TGGC *TGuiBldDragManagerGrid::fgBgnd = 0;
//______________________________________________________________________________
TGuiBldDragManagerGrid::TGuiBldDragManagerGrid()
{
//
fPixmap = 0;
fWindow = 0;
fWinId = 0;
if (!fgBgnd) InitBgnd();
SetStep(fgStep);
}
//______________________________________________________________________________
TGuiBldDragManagerGrid::~TGuiBldDragManagerGrid()
{
//
if (gClient && gClient->GetWindowById(fWinId)) {
fWindow->SetBackgroundPixmap(0);
fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
gClient->NeedRedraw(fWindow);
}
if (fPixmap) {
gVirtualX->DeletePixmap(fPixmap);
}
fPixmap = 0;
fWindow = 0;
fWinId = 0;
}
//______________________________________________________________________________
void TGuiBldDragManagerGrid::SetStep(UInt_t step)
{
//
if (!gClient || !gClient->IsEditable()) return;
fWindow = (TGWindow*)gClient->GetRoot();
fWinId = fWindow->GetId();
fgStep = step;
InitPixmap();
}
//______________________________________________________________________________
void TGuiBldDragManagerGrid::InitBgnd()
{
//
if (fgBgnd) return;
fgBgnd = new TGGC(TGFrame::GetBckgndGC());
fgPixel = fgBgnd->GetForeground();
Float_t r, g, b;
TColor::Pixel2RGB(fgPixel, r, g, b);
r = r * 0.9;
g = g * 0.9;
//b = b * 0.9;
fgPixel = TColor::RGB2Pixel(r, g, b);
fgBgnd->SetForeground(fgPixel);
}
//______________________________________________________________________________
void TGuiBldDragManagerGrid::InitPixmap()
{
//
if (fPixmap) {
gVirtualX->DeletePixmap(fPixmap);
}
fPixmap = gVirtualX->CreatePixmap(gClient->GetDefaultRoot()->GetId(), fgStep, fgStep);
gVirtualX->FillRectangle(fPixmap, fgBgnd->GetGC(), 0, 0, fgStep, fgStep);
if(fgStep > 2) {
gVirtualX->FillRectangle(fPixmap, TGFrame::GetShadowGC()(),
fgStep - 1, fgStep - 1, 1, 1);
}
}
//______________________________________________________________________________
void TGuiBldDragManagerGrid::Draw()
{
//
if (fWindow && (fWindow != gClient->GetRoot())) {
fWindow->SetBackgroundPixmap(0);
fWindow->SetBackgroundColor(((TGFrame*)fWindow)->GetBackground());
gClient->NeedRedraw(fWindow);
}
if (!gClient || !gClient->IsEditable()) return;
if (!fPixmap) InitPixmap();
fWindow = (TGWindow*)gClient->GetRoot();
fWinId = fWindow->GetId();
fWindow->SetBackgroundPixmap(fPixmap);
gClient->NeedRedraw(fWindow);
}
////////////////////////////////////////////////////////////////////////////////
class TGuiBldDragManagerRepeatTimer : public TTimer {
private:
TGuiBldDragManager *fManager; // back pointer
public:
TGuiBldDragManagerRepeatTimer(TGuiBldDragManager *m, Long_t ms) :
TTimer(ms, kTRUE) { fManager = m; }
Bool_t Notify() { fManager->HandleTimer(this); Reset(); return kFALSE; }
};
////////////////////////////////////////////////////////////////////////////////
class TGDragGrabber : public TGFrame {
private:
TGFrame *fFrame; //
Pixmap_t fPixmap; //
GContext_t fGC; //
public:
TGDragGrabber(TGFrame *src, Int_t x, Int_t y);
void DoRedraw();
};
//______________________________________________________________________________
TGDragGrabber::TGDragGrabber(TGFrame *src, Int_t x, Int_t y) :
TGFrame(gClient->GetDefaultRoot(), 20, 20)
{
//
fFrame = src;
fGC = gClient->GetResourcePool()->GetFrameGC()->GetGC();
Resize(fFrame->GetWidth(), fFrame->GetHeight());
fPixmap = gVirtualX->CreatePixmap(gVirtualX->GetDefaultRootWindow(), fWidth, fHeight);
gVirtualX->CopyArea(fFrame->GetId(), fPixmap, fGC, 0, 0, fWidth, fHeight, 0, 0);
gVirtualX->SetMWMHints(fId, 0, 0, 0);
Move(x, y);
}
//______________________________________________________________________________
void TGDragGrabber::DoRedraw()
{
//
gVirtualX->CopyArea(fPixmap, fId, fGC, 0, 0, fWidth, fHeight, 0, 0);
}
////////////////////////////////////////////////////////////////////////////////
class TGGrabRect : public TGFrame {
private:
Pixmap_t fPixmap;
ECursor fType;
public:
TGGrabRect(Int_t type);
~TGGrabRect() {}
Bool_t HandleButton(Event_t *ev);
ECursor GetType() const { return fType; }
};
//______________________________________________________________________________
TGGrabRect::TGGrabRect(Int_t type) : TGFrame(gClient->GetDefaultRoot(), 7, 7, kTempFrame)
{
//
switch (type) {
case 0:
fType = kTopLeft;
break;
case 1:
fType = kTopSide;
break;
case 2:
fType = kTopRight;
break;
case 3:
fType = kBottomLeft;
break;
case 4:
fType = kLeftSide;
break;
case 5:
fType = kRightSide;
break;
case 6:
fType = kBottomSide;
break;
case 7:
fType = kBottomRight;
break;
}
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
fPixmap = gVirtualX->CreatePixmap(gVirtualX->GetDefaultRootWindow(), 7, 7);
const TGGC *bgc = fClient->GetResourcePool()->GetSelectedBckgndGC();
const TGGC *gc = fClient->GetResourcePool()->GetSelectedGC();
gVirtualX->FillRectangle(fPixmap, bgc->GetGC(), 0, 0, 6, 6);
gVirtualX->DrawRectangle(fPixmap, gc->GetGC(), 0, 0, 6, 6);
AddInput(kButtonPressMask);
SetBackgroundPixmap(fPixmap);
gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(fType));
}
//______________________________________________________________________________
Bool_t TGGrabRect::HandleButton(Event_t *ev)
{
//
gGuiBldDragManager->CheckDragResize(ev);
return kTRUE;
}
////////////////////////////////////////////////////////////////////////////////
class TGAroundFrame : public TGFrame {
public:
TGAroundFrame();
~TGAroundFrame() {}
};
//______________________________________________________________________________
TGAroundFrame::TGAroundFrame() : TGFrame(gClient->GetDefaultRoot(), 1, 1,
kTempFrame | kOwnBackground)
{
//
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
ULong_t red;
fClient->GetColorByName("red", red);
SetBackgroundColor(red);
}
////////////////////////////////////////////////////////////////////////////////
class TGuiBldDragManagerPimpl {
friend class TGuiBldDragManager;
private:
TGuiBldDragManager *fManager; // dnd manager
TTimer *fRepeatTimer; // repeat rate timer (when mouse stays pressed)
TGFrame *fGrab; //
TGLayoutHints *fGrabLayout;
TGFrame *fSaveGrab; // used during context menu handling
TGFrame *fLastFrame; // last clicked frame
TGuiBldDragManagerGrid *fGrid; //
ECursor fResizeType; //
Int_t fX0, fY0; // initial drag position in pixels
Int_t fX, fY; // current drag position in pixels
Int_t fXf, fYf; // offset of inititial position inside frame
Int_t fGrabX, fGrabY; //
const TGWindow *fGrabParent; //
Int_t fLastPopupAction;//
Bool_t fReplaceOn;
TGGrabRect *fGrabRect[8]; //
TGFrame *fAroundFrame[4]; //
Bool_t fGrabRectHidden;
TGFrameElement *fGrabListPosition;
Bool_t fButtonPressed;
Bool_t fCompacted;
TGFrame *fPlane; //
public:
TGuiBldDragManagerPimpl(TGuiBldDragManager *m) {
fManager = m;
fRepeatTimer = new TGuiBldDragManagerRepeatTimer(m, 100);
int i = 0;
for (i = 0; i <8; i++) {
fGrabRect[i] = new TGGrabRect(i);
}
for (i = 0; i <4; i++) {
fAroundFrame[i] = new TGAroundFrame();
}
fPlane = 0;
ResetParams();
}
void ResetParams() {
fGrab = 0;
fSaveGrab = 0;
fLastFrame = 0;
fGrid = 0;
fX0 = fY0 = fX = fY = fXf = fYf = fGrabX = fGrabY = 0;
fGrabParent = 0;
fResizeType = kPointer;
fLastPopupAction = kNoneAct;
fReplaceOn = kFALSE;
fGrabLayout = 0;
fGrabRectHidden = kFALSE;
fGrabListPosition = 0;
fButtonPressed = kFALSE;
fCompacted = kFALSE;
}
~TGuiBldDragManagerPimpl() {
int i;
for (i = 0; i <8; i++) {
delete fGrabRect[i];
}
for (i = 0; i <4; i++) {
delete fAroundFrame[i];
}
delete fRepeatTimer;
delete fGrab;
if (fPlane) {
fPlane->ChangeOptions(fPlane->GetOptions() & ~kRaisedFrame);
gClient->NeedRedraw(fPlane, kTRUE);
fPlane = 0;
}
}
};
////////////////////////////////////////////////////////////////////////////////
TGuiBldDragManager::TGuiBldDragManager() : TVirtualDragManager() ,
TGFrame(gClient->GetDefaultRoot(), 1, 1)
{
// Constructor. Create "fantom window".
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
gGuiBldDragManager = this;
fPimpl = new TGuiBldDragManagerPimpl(this);
Init();
fSelectionIsOn = kFALSE;
fFrameMenu = 0;
fLassoMenu = 0;
fEditor = 0;
fBuilder = 0;
fQuickHandler = 0;
fLassoDrawn = kFALSE;
fDropStatus = kFALSE;
TString tmpfile = gSystem->TempDirectory();
fPasteFileName = gSystem->ConcatFileName(tmpfile.Data(),
Form("RootGuiBldClipboard%d.C", gSystem->GetPid()));
fName = "Gui Builder Drag Manager";
SetWindowName(fName.Data());
fClient->UnregisterWindow(this);
}
//______________________________________________________________________________
TGuiBldDragManager::~TGuiBldDragManager()
{
// Destructor
delete fPimpl;
delete fBuilder;
fBuilder = 0;
// delete fEditor;
// fEditor = 0;
delete fFrameMenu;
fFrameMenu =0;
delete fLassoMenu;
fLassoMenu = 0;
if (!gSystem->AccessPathName(fPasteFileName.Data())) {
gSystem->Unlink(fPasteFileName.Data());
}
gGuiBldDragManager = 0;
}
//______________________________________________________________________________
void TGuiBldDragManager::Init()
{
//
TVirtualDragManager::Init();
fTargetId = 0;
SetCursorType(kPointer);
}
//______________________________________________________________________________
void TGuiBldDragManager::Snap2Grid()
{
//
delete fPimpl->fGrid;
fPimpl->fGrid = new TGuiBldDragManagerGrid();
fPimpl->fGrid->Draw();
}
//______________________________________________________________________________
UInt_t TGuiBldDragManager::GetGridStep()
{
//
return fPimpl->fGrid ? fPimpl->fGrid->fgStep : 1;
}
//______________________________________________________________________________
void TGuiBldDragManager::SetGridStep(UInt_t step)
{
//
fPimpl->fGrid->SetStep(step);
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::IgnoreEvent(Event_t *event)
{
//
if (!fClient || !fClient->IsEditable()) return kTRUE;
if (event->fType == kClientMessage) return kFALSE;
const TGWindow *w = fClient->GetWindowById(event->fWindow);
return w ? w->IsEditDisabled() : kTRUE;
}
//______________________________________________________________________________
TGFrame* TGuiBldDragManager::InEditable(Window_t id)
{
//
if (!id) return 0;
Window_t preparent = id;
Window_t parent = (Window_t)gVirtualX->GetParent(id);
while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
if (parent == fClient->GetRoot()->GetId()) {
TGWindow *w = fClient->GetWindowById(preparent);
return (w ? (TGFrame*)w : 0);
}
preparent = parent;
parent = gVirtualX->GetParent(parent);
}
return 0;
}
//______________________________________________________________________________
TGCompositeFrame *TGuiBldDragManager::FindCompositeFrame(Window_t id)
{
//
if (!id) return 0;
Window_t parent = id;
while (!parent || (parent != fClient->GetDefaultRoot()->GetId())) {
TGWindow *w = fClient->GetWindowById(parent);
if (w) {
if (w->InheritsFrom(TGCompositeFrame::Class())) {
return (TGCompositeFrame*)w;
}
}
parent = gVirtualX->GetParent(parent);
}
return 0;
}
//______________________________________________________________________________
void TGuiBldDragManager::SetCursorType(Int_t cur)
{
// sets cursor
static UInt_t gid = 0;
static UInt_t rid = 0;
if (fPimpl->fGrab && (gid != fPimpl->fGrab->GetId())) {
gVirtualX->SetCursor(fPimpl->fGrab->GetId(),
gVirtualX->CreateCursor((ECursor)cur));
gid = fPimpl->fGrab->GetId();
}
if (fClient->IsEditable() && (rid != fClient->GetRoot()->GetId())) {
gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
gVirtualX->CreateCursor((ECursor)cur));
rid = fClient->GetRoot()->GetId();
}
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::CheckDragResize(Event_t *event)
{
// check resize type event
Bool_t ret = kFALSE;
fPimpl->fResizeType = kPointer;
for (int i = 0; i < 8; i++) {
if (fPimpl->fGrabRect[i]->GetId() == event->fWindow) {
fPimpl->fResizeType = fPimpl->fGrabRect[i]->GetType();
ret = kTRUE;
}
}
if ((event->fType == kButtonPress) && (fPimpl->fResizeType != kPointer)) {
fDragType = kDragResize;
ret = kTRUE;
}
SetCursorType(ret ? fPimpl->fResizeType : kPointer);
return ret;
}
//______________________________________________________________________________
void TGuiBldDragManager::DoRedraw()
{
//
if (!fClient || !fClient->IsEditable()) return;
TGWindow *root = (TGWindow*)fClient->GetRoot();
fClient->NeedRedraw(root, kTRUE);
fLassoDrawn = kFALSE;
}
//______________________________________________________________________________
void TGuiBldDragManager::SwitchEditable(TGFrame *frame)
{
//
if (!frame) return;
TGCompositeFrame *comp = 0;
if (frame->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame *)frame;
} else if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame *)frame->GetParent();
}
if (!comp) return;
comp->SetEditable(kTRUE);
if (fBuilder) {
TString str = comp->ClassName();
str += "::";
str += comp->GetName();
str += " set editable";
fBuilder->UpdateStatusBar(str.Data());
}
if (frame != comp) {
SelectFrame(frame);
}
}
//______________________________________________________________________________
void TGuiBldDragManager::SelectFrame(TGFrame *frame, Bool_t add)
{
//
if (!frame || frame->IsEditable()) return;
static Int_t x, x0, y, y0, xx, yy;
Window_t c;
frame->MapRaised();
if (!add) {
fDragType = kDragMove;
gVirtualX->TranslateCoordinates(frame->GetId(),
fClient->GetDefaultRoot()->GetId(),
0, 0, x0, y0, c);
x = x0 + frame->GetWidth();
y = y0 + frame->GetHeight();
Selected(frame);
DrawGrabRectangles(frame);
if (fBuilder) {
TString str = frame->ClassName();
str += "::";
str += frame->GetName();
str += " selected";
fBuilder->UpdateStatusBar(str.Data());
}
} else {
gVirtualX->TranslateCoordinates(frame->GetId(),
fClient->GetDefaultRoot()->GetId(),
0, 0, xx, yy, c);
fDragType = kDragLasso;
fPimpl->fX0 = x0 = TMath::Min(x0, xx);
fPimpl->fX = x = TMath::Max(x, xx + (Int_t)frame->GetWidth());
fPimpl->fY0 = y0 = TMath::Min(y0, yy);
fPimpl->fY = y = TMath::Max(y, yy + (Int_t)frame->GetHeight());
DrawLasso();
}
fFrameUnder = fPimpl->fGrab = frame;
SetCursorType(kMove);
if (fBuilder) fBuilder->Update();
}
//______________________________________________________________________________
void TGuiBldDragManager::Selected(TGFrame *frame)
{
//
if (!frame || (fPimpl->fGrab == frame)) return;
Emit("Selected(TGFrame*)", (Long_t)frame);
}
//______________________________________________________________________________
void TGuiBldDragManager::GrabFrame(TGFrame *frame)
{
//
if (!frame) return;
fPimpl->fGrabParent = frame->GetParent();
fPimpl->fGrabX = frame->GetX();
fPimpl->fGrabY = frame->GetY();
Window_t c;
gVirtualX->TranslateCoordinates(frame->GetId(),
fClient->GetDefaultRoot()->GetId(),
0, 0, fPimpl->fX0, fPimpl->fY0, c);
fPimpl->fX = fPimpl->fX0;
fPimpl->fY = fPimpl->fY0;
if (frame->GetFrameElement() && frame->GetFrameElement()->fLayout) {
fPimpl->fGrabLayout = frame->GetFrameElement()->fLayout;
}
if (fPimpl->fGrabParent && frame->GetFrameElement() &&
fPimpl->fGrabParent->InheritsFrom(TGCompositeFrame::Class())) {
TList *li = ((TGCompositeFrame*)fPimpl->fGrabParent)->GetList();
fPimpl->fGrabListPosition = (TGFrameElement*)li->Before(frame->GetFrameElement());
((TGCompositeFrame*)fPimpl->fGrabParent)->RemoveFrame(frame);
}
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(frame->GetId(), &attr);
frame->ReparentWindow(fClient->GetDefaultRoot(), fPimpl->fX0, fPimpl->fY0);
gVirtualX->Update(1);
if (fBuilder) {
fBuilder->Update();
TString str = frame->ClassName();
str += "::";
str += frame->GetName();
str += " is being dragged";
fBuilder->UpdateStatusBar(str.Data());
}
}
//______________________________________________________________________________
void TGuiBldDragManager::UngrabFrame()
{
//
if (!fPimpl->fGrab) return;
SetCursorType(kPointer);
HideGrabRectangles();
DoRedraw();
if (fBuilder) {
fBuilder->Update();
TString str = fPimpl->fGrab->ClassName();
str += "::";
str += fPimpl->fGrab->GetName();
str += " ungrabbed";
fBuilder->UpdateStatusBar(str.Data());
}
fPimpl->fGrab = 0;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::IsSelectedVisible()
{
//
if (!fPimpl->fGrab) return kFALSE;
Window_t w = gVirtualX->GetDefaultRootWindow();
Window_t src, dst, child;
Int_t x, y;
Bool_t ret = kFALSE;
gVirtualX->TranslateCoordinates(fPimpl->fGrab->GetId(), w,
fPimpl->fGrab->GetWidth()/2,
fPimpl->fGrab->GetHeight()/2, x, y, child);
dst = src = child = w;
while (child) {
src = dst;
dst = child;
gVirtualX->TranslateCoordinates(src, dst, x, y, x, y, child);
if (child == fPimpl->fGrab->GetId()) {
ret = kTRUE;
break;
}
}
return ret;
}
//______________________________________________________________________________
void TGuiBldDragManager::DrawGrabRectangles(TGWindow *win)
{
//
TGFrame *frame = win ? (TGFrame *)win : fPimpl->fGrab;
if (!frame) return;
Window_t w = gVirtualX->GetDefaultRootWindow();
Window_t c; Int_t x, y;
gVirtualX->TranslateCoordinates(frame->GetId(), w, 0, 0, x, y, c);
if (frame->InheritsFrom(TGCompositeFrame::Class()) && !frame->IsLayoutBroken()) {
fPimpl->fAroundFrame[0]->MoveResize(x-3, y-3, frame->GetWidth()+6, 2);
fPimpl->fAroundFrame[0]->MapRaised();
fPimpl->fAroundFrame[1]->MoveResize(x+frame->GetWidth()+3, y-3, 2, frame->GetHeight()+6);
fPimpl->fAroundFrame[1]->MapRaised();
fPimpl->fAroundFrame[2]->MoveResize(x-3, y+frame->GetHeight()+2, frame->GetWidth()+6, 2);
fPimpl->fAroundFrame[2]->MapRaised();
fPimpl->fAroundFrame[3]->MoveResize(x-3, y-3, 2, frame->GetHeight()+6);
fPimpl->fAroundFrame[3]->MapRaised();
} else {
for (int i=0; i<4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
}
// draw rectangles
DrawGrabRect(0, x - 6, y - 6);
DrawGrabRect(1, x + frame->GetWidth()/2 - 3, y - 6);
DrawGrabRect(2, x + frame->GetWidth(), y - 6);
DrawGrabRect(3, x - 6, y + frame->GetHeight());
DrawGrabRect(4, x - 6, y + frame->GetHeight()/2 - 3);
DrawGrabRect(5, x + frame->GetWidth(), y + frame->GetHeight()/2 - 3);
DrawGrabRect(6, x + frame->GetWidth()/2 - 3, y + frame->GetHeight());
DrawGrabRect(7, x + frame->GetWidth(), y + frame->GetHeight());
fPimpl->fGrabRectHidden = kFALSE;
}
//______________________________________________________________________________
void TGuiBldDragManager::DrawGrabRect(Int_t i, Int_t x, Int_t y)
{
//
fPimpl->fGrabRect[i]->Move(x, y);
fPimpl->fGrabRect[i]->MapRaised();
}
//______________________________________________________________________________
void TGuiBldDragManager::HighlightCompositeFrame(Window_t win)
{
//
static Window_t gw = 0;
if (!win || (win == gw)) return;
TGWindow *w = fClient->GetWindowById(win);
if (!w || (w == fPimpl->fPlane) || w->IsEditDisabled() || w->IsEditable() ||
!w->InheritsFrom(TGCompositeFrame::Class())) return;
TGFrame *frame = (TGFrame*)w;
UInt_t opt = frame->GetOptions();
if ((opt & kRaisedFrame) || (opt & kSunkenFrame)) return;
gw = win;
if (fPimpl->fPlane) {
fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
}
fPimpl->fPlane = frame;
fPimpl->fPlane->ChangeOptions(opt | kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
if (fBuilder) {
TString str = frame->ClassName();
str += "::";
str += frame->GetName();
fBuilder->UpdateStatusBar(str.Data());
}
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleTimer(TTimer *t)
{
// Handle repeat timer while dragging. Every time timer times out we move
// dragged frame set to another position.
// reset everything
if (!fClient || !fClient->IsEditable()) {
if (fPimpl->fRepeatTimer) fPimpl->fRepeatTimer->Remove();
Init();
if (fPimpl) fPimpl->ResetParams();
if (fBuilder) {
fBuilder->SetAction(0);
} else {
DeletePropertyEditor();
}
return kFALSE;
}
if (!IsSelectedVisible()) UngrabFrame();
Window_t dum;
Event_t ev;
ev.fCode = kButton1;
ev.fType = kMotionNotify;
ev.fState = 0;
gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(), dum, dum,
ev.fXRoot, ev.fYRoot, ev.fX, ev.fY, ev.fState);
static Int_t gy = 0;
static Int_t gx = 0;
static UInt_t gstate = 0;
static Window_t gw = 0;
ev.fWindow = GetWindowFromPoint(ev.fXRoot, ev.fYRoot);
if (ev.fWindow && (gw == ev.fWindow) && (gstate == ev.fState) &&
(ev.fYRoot == gy) && (ev.fXRoot == gx)) {
return kFALSE;
}
gw = ev.fWindow;
gstate = ev.fState;
if (!fDragging && !fMoveWaiting && !fPimpl->fButtonPressed &&
((ev.fState == kButton1Mask) || (ev.fState == kButton3Mask) ||
(ev.fState == (kButton1Mask | kKeyShiftMask)) ||
(ev.fState == (kButton1Mask | kKeyControlMask)))) {
if (ev.fState & kButton1Mask) ev.fCode = kButton1;
if (ev.fState & kButton3Mask) ev.fCode = kButton3;
ev.fType = kButtonPress;
t->SetTime(40);
if (fPimpl->fPlane && fClient->GetWindowById(fPimpl->fPlane->GetId())) {
fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
} else {
fPimpl->fPlane = 0;
}
return HandleButtonPress(&ev);
}
if ((fDragging || fMoveWaiting) && (!ev.fState || (ev.fState == kKeyShiftMask)) &&
fPimpl->fButtonPressed) {
ev.fType = kButtonRelease;
t->SetTime(100);
return HandleButtonRelease(&ev);
}
fPimpl->fButtonPressed = (ev.fState & kButton1Mask) ||
(ev.fState & kButton2Mask) ||
(ev.fState & kButton3Mask);
if ((ev.fYRoot == gy) && (ev.fXRoot == gx)) return kFALSE;
gy = ev.fYRoot;
gx = ev.fXRoot;
if (!fMoveWaiting && !fDragging && !ev.fState) {
if (!CheckDragResize(&ev) && fClient->GetWindowById(ev.fWindow)) {
HighlightCompositeFrame(ev.fWindow);
}
} else if (ev.fState & kButton1Mask) {
HandleMotion(&ev);
}
return kTRUE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::RecognizeGesture(Event_t *event, TGFrame *frame)
{
//
UInt_t estate = event->fState & 0xFF;
if (((event->fCode != kButton1) && (event->fCode != kButton3)) || !frame ||
(estate && !((estate & kKeyShiftMask) || (estate & kKeyControlMask)))) {
return kFALSE;
}
if (event->fCode == kButton3) {
SelectFrame(frame);
HandleButon3Pressed(event, frame);
return kTRUE;
} else if (((event->fCode == kButton1) && (event->fState & kKeyControlMask)) ||
((event->fCode == kButton1) && fBuilder && fBuilder->IsSelectMode())) {
SwitchEditable(frame);
return kTRUE;
} else if (!fSelectionIsOn) {
fPimpl->fX0 = event->fXRoot;
fPimpl->fY0 = event->fYRoot;
}
if (fPimpl->fLastFrame != frame) {
fPimpl->fLastFrame = frame;
if (fEditor && fPimpl->fLastFrame) {
if (!fEditor->IsEmbedded()) {
TGMainFrame *m = (TGMainFrame *)fEditor->GetMainFrame();
m->MapRaised();
}
fEditor->ChangeSelected(fPimpl->fLastFrame);
}
}
TGFrame *base = InEditable(frame->GetId());
HideGrabRectangles();
if (fBuilder && fBuilder->IsExecutalble() &&
frame->InheritsFrom(TGCompositeFrame::Class()) &&
!frame->IsEditable()) {
UngrabFrame();
frame->SetEditable(kTRUE);
fSource = 0;
fDragType = kDragLasso;
goto out;
}
if (event->fState & kKeyShiftMask) {
if (!fSelectionIsOn) {
fSelectionIsOn = kTRUE;
} else {
fPimpl->fX = event->fXRoot;
fPimpl->fY = event->fYRoot;
fDragType = kDragLasso;
DrawLasso();
return kTRUE;
}
}
if (frame->IsEditable()) {
fSource = 0;
CheckDragResize(event);
if (fDragType != kDragResize) {
fDragType = kDragLasso;
}
} else if (base) {
fSource = base;
SelectFrame(base, event->fState & kKeyShiftMask);
} else {
SwitchEditable(frame);
return kTRUE;
}
if (fDragType == kDragNone) return kFALSE;
out:
Window_t c;
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
base ? base->GetId() : frame->GetId(),
event->fXRoot, event->fYRoot,
fPimpl->fXf, fPimpl->fYf, c);
fPimpl->fX = event->fXRoot;
fPimpl->fY = event->fYRoot;
fMoveWaiting = kTRUE;
DoRedraw();
return kTRUE;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleButon3Pressed(Event_t *event, TGFrame *frame)
{
//
if (frame == fPimpl->fGrab) {
Menu4Frame(frame, event->fXRoot, event->fYRoot);
} else if (frame->IsEditable()) {
if (fLassoDrawn) {
Menu4Lasso(event->fXRoot, event->fYRoot);
} else {
Menu4Frame(frame, event->fXRoot, event->fYRoot);
}
} else {
TGFrame *base = InEditable(frame->GetId());
if (base) {
//SelectFrame(base);
Menu4Frame(base, event->fXRoot, event->fYRoot);
} else {
Menu4Frame(frame, event->fXRoot, event->fYRoot);
}
}
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleButton(Event_t *event)
{
// handle button event occured in some ROOT frame
if (event->fCode != kButton3) CloseMenus();
if (event->fType == kButtonPress) return HandleButtonPress(event);
else return HandleButtonRelease(event);
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleConfigureNotify(Event_t *event)
{
// resize events
TGWindow *w = fClient->GetWindowById(event->fWindow);
if (!w) return kFALSE;
fPimpl->fCompacted = kFALSE;
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleExpose(Event_t *event)
{
// repaint events
static Long_t was = gSystem->Now();
static Window_t win = 0;
Long_t now = (long)gSystem->Now();
if (event->fCount || (win == event->fWindow) || (now-was < 40) ||
fDragging) {
if (fDragging) HideGrabRectangles();
return kFALSE;
}
DrawGrabRectangles();
win = event->fWindow;
was = now;
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleEvent(Event_t *event)
{
// Handle all events.
if (IgnoreEvent(event)) return kFALSE;
switch (event->fType) {
case kExpose:
return HandleExpose(event);
case kConfigureNotify:
while (gVirtualX->CheckEvent(fId, kConfigureNotify, *event))
;
return HandleConfigureNotify(event);
case kGKeyPress:
case kKeyRelease:
return HandleKey(event);
case kFocusIn:
case kFocusOut:
//HandleFocusChange(event);
break;
case kButtonPress:
{
Int_t dbl_clk = kFALSE;
static Window_t gDbw = 0;
static Long_t gLastClick = 0;
static UInt_t gLastButton = 0;
static Int_t gDbx = 0;
static Int_t gDby = 0;
if ((event->fTime - gLastClick < 350) &&
(event->fCode == gLastButton) &&
(TMath::Abs(event->fXRoot - gDbx) < 6) &&
(TMath::Abs(event->fYRoot - gDby) < 6) &&
(event->fWindow == gDbw)) {
dbl_clk = kTRUE;
}
if (dbl_clk) {
if (event->fState & kKeyControlMask) {
TGWindow *root = (TGWindow *)fClient->GetRoot();
root->SetEditable(kFALSE);
SetEditable(kFALSE);
if (fBuilder) {
fBuilder->UpdateStatusBar("Edit is OFF");
}
return kTRUE;
} else if (!(event->fState & 0xFF)) {
ExecuteQuickAction(event);
return kTRUE;
}
} else {
gDbw = event->fWindow;
gLastClick = event->fTime;
gLastButton = event->fCode;
gDbx = event->fXRoot;
gDby = event->fYRoot;
return HandleButtonPress(event);
}
return kFALSE;
}
case kButtonRelease:
return HandleButtonRelease(event);
case kEnterNotify:
case kLeaveNotify:
//HandleCrossing(event);
break;
case kMotionNotify:
while (gVirtualX->CheckEvent(fId, kMotionNotify, *event))
;
return HandleMotion(event);
case kClientMessage:
HandleClientMessage(event);
break;
case kSelectionNotify:
//HandleSelection(event);
break;
case kSelectionRequest:
//HandleSelectionRequest(event);
break;
case kSelectionClear:
//HandleSelectionClear(event);
break;
case kColormapNotify:
//HandleColormapChange(event);
break;
default:
//Warning("HandleEvent", "unknown event (%#x) for (%#x)", event->fType, fId);
break;
}
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleDoubleClick(Event_t *)
{
//
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleButtonPress(Event_t *event)
{
// handle button press event
fPimpl->fButtonPressed = kTRUE;
if (fPimpl->fPlane) {
fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
}
if ( ((event->fCode != kButton1) && (event->fCode != kButton3)) ||
(event->fType != kButtonPress) || IgnoreEvent(event) ) return kFALSE;
Init();
HideGrabRectangles();
Window_t w = GetWindowFromPoint(event->fXRoot, event->fYRoot);
TGFrame *fr = 0;
if (w) {
fr = (TGFrame*)fClient->GetWindowById(w);
} else {
return kFALSE;
}
return RecognizeGesture(event, fr);
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleButtonRelease(Event_t *event)
{
// handle button release event
fPimpl->fButtonPressed = kFALSE;
gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kPointer));
EndDrag();
fSelectionIsOn &= (event->fState & kKeyShiftMask);
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleKey(Event_t *event)
{
// handle key event
static const char *gSaveMacroTypes[] = { "Macro files", "*.C",
"All files", "*",
0, 0 };
char tmp[10];
UInt_t keysym;
Bool_t ret = kFALSE;
TGFileInfo fi;
static TString dir(".");
static Bool_t overwr = kFALSE;
const char *fname;
if (event->fType != kGKeyPress) return kFALSE;
if (fPimpl->fPlane) {
fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
}
CloseMenus();
fi.fFileTypes = gSaveMacroTypes;
fi.fIniDir = StrDup(dir);
fi.fOverwrite = overwr;
gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
if (event->fState & kKeyControlMask) {
switch ((EKeySym)keysym & ~0x20) {
case kKey_Return:
case kKey_Enter:
HandleReturn(kTRUE);
ret = kTRUE;
break;
case kKey_X:
HandleCut();
ret = kTRUE;
break;
case kKey_C:
HandleCopy();
ret = kTRUE;
break;
case kKey_V:
if (fPimpl->fLastFrame && !fPimpl->fLastFrame->IsEditable()) {
fPimpl->fLastFrame->SetEditable(kTRUE);
}
HandlePaste();
ret = kTRUE;
break;
case kKey_B:
{
if (fPimpl->fGrab && (fPimpl->fLastFrame != fClient->GetRoot())) {
if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
BreakLayout();
}
}
ret = kTRUE;
break;
}
case kKey_L:
{
if (fPimpl->fGrab && (fPimpl->fLastFrame != fClient->GetRoot())) {
Compact(kFALSE);
} else {
Compact(kTRUE);
}
ret = kTRUE;
break;
}
case kKey_R:
HandleReplace();
ret = kTRUE;
break;
case kKey_S:
Save();
ret = kTRUE;
break;
case kKey_G:
HandleGrid();
ret = kTRUE;
break;
case kKey_H:
SwitchLayout();
ret = kTRUE;
break;
case kKey_N:
if (fBuilder) {
fBuilder->NewProject();
} else {
TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
main->MapRaised();
main->SetEditable(kTRUE);
}
ret = kTRUE;
break;
case kKey_O:
if (fBuilder) {
fBuilder->NewProject();
} else {
TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
main->MapRaised();
main->SetEditable(kTRUE);
}
new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
if (!fi.fFilename) return kTRUE;
dir = fi.fIniDir;
overwr = fi.fOverwrite;
fname = gSystem->BaseName(gSystem->UnixPathName(fi.fFilename));
if (strstr(fname, ".C")) {
gROOT->Macro(fname);
} else {
Int_t retval;
new TGMsgBox(fClient->GetDefaultRoot(), this, "Error...",
Form("file (%s) must have extension .C", fname),
kMBIconExclamation, kMBRetry | kMBCancel, &retval);
if (retval == kMBRetry) {
HandleKey(event);
}
}
ret = kTRUE;
break;
default:
break;
}
} else {
switch ((EKeySym)keysym ) {
case kKey_Delete:
case kKey_Backspace:
HandleDelete(event->fState & kKeyShiftMask);
ret = kTRUE;
break;
case kKey_Return:
case kKey_Enter:
HandleReturn(kFALSE);
ret = kTRUE;
break;
case kKey_Left:
case kKey_Right:
case kKey_Up:
case kKey_Down:
if (fLassoDrawn) {
HandleAlignment(keysym, event->fState & kKeyShiftMask);
} else if (fPimpl->fGrab) {
HandleLayoutOrder((keysym == kKey_Right) || (keysym == kKey_Down));
}
ret = kTRUE;
break;
case kKey_Space:
//Compact(kFALSE);
ret = kTRUE;
break;
default:
break;
}
}
if (fBuilder) {
fBuilder->SetAction(0);
fBuilder->Update();
}
return ret;
}
//______________________________________________________________________________
void TGuiBldDragManager::ReparentFrames(TGFrame *newfr, TGCompositeFrame *oldfr)
{
//
Int_t x0, y0, xx, yy;
Window_t c;
if (!newfr || !newfr->GetId() || !oldfr || !oldfr->GetId()) return;
gVirtualX->TranslateCoordinates(newfr->GetId(), oldfr->GetId(),
0, 0, x0, y0, c);
x0 = x0 < 0 ? 0 : x0;
y0 = y0 < 0 ? 0 : y0;
Int_t x = x0 + newfr->GetWidth();
Int_t y = y0 + newfr->GetHeight();
TGCompositeFrame *comp = 0;
if (newfr->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame*)newfr;
comp->SetLayoutBroken();
}
TIter next(oldfr->GetList());
TGFrameElement *el;
while ((el = (TGFrameElement*)next())) {
TGFrame *frame = el->fFrame;
if ((frame->GetX() >= x0) && (frame->GetY() >= y0) &&
(frame->GetX() + (Int_t)frame->GetWidth() <= x) &&
(frame->GetY() + (Int_t)frame->GetHeight() <= y)) {
if (frame == fPimpl->fGrab) UngrabFrame();
oldfr->RemoveFrame(frame);
gVirtualX->TranslateCoordinates(oldfr->GetId(), newfr->GetId(),
frame->GetX(), frame->GetY(), xx, yy, c);
frame->ReparentWindow(newfr, xx, yy);
if (comp) {
comp->AddFrame(frame, el->fLayout);
}
}
}
}
//______________________________________________________________________________
TList *TGuiBldDragManager::GetFramesInside(Int_t x0, Int_t y0, Int_t x, Int_t y)
{
//
Int_t xx, yy;
if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) return 0;
TList *list = new TList();
xx = x0; yy = y0;
x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
TIter next(((TGCompositeFrame*)fClient->GetRoot())->GetList());
TGFrameElement *el;
while ((el = (TGFrameElement*)next())) {
if ((el->fFrame->GetX() >= x0) && (el->fFrame->GetY() >= y0) &&
(el->fFrame->GetX() + (Int_t)el->fFrame->GetWidth() <= x) &&
(el->fFrame->GetY() + (Int_t)el->fFrame->GetHeight() <= y)) {
list->Add(el->fFrame);
}
}
if (list->IsEmpty()) {
delete list;
return 0;
}
return list;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleReturn(Bool_t on)
{
//
Int_t x0, y0, x, y, xx, yy;
Window_t c;
TGCompositeFrame *parent = 0;
TList *li = 0;
if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) return;
TGCompositeFrame *comp = (TGCompositeFrame*)fClient->GetRoot();
if (fLassoDrawn) {
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX, fPimpl->fY, x, y, c);
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0, fPimpl->fY0, x0, y0, c);
xx = x0; yy = y0;
x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
li = GetFramesInside(x0, y0, x, y);
if (!on && li) {
parent = new TGCompositeFrame(comp, x - x0, y - y0);
parent->MoveResize(x0, y0, x - x0, y - y0);
ReparentFrames(parent, comp);
comp->AddFrame(parent);
parent->MapWindow();
fLassoDrawn = kFALSE;
SelectFrame(parent);
if (fBuilder) {
fBuilder->UpdateStatusBar("Grab action performed");
}
}
} else if (on && fPimpl->fGrab) {
if (fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
parent = (TGCompositeFrame*)fPimpl->fGrab;
} else {
//parent = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
}
if (parent) {
ReparentFrames(comp, parent);
DeleteFrame(fPimpl->fGrab);
fPimpl->fGrab = 0;
if (fBuilder) {
fBuilder->UpdateStatusBar("Drop action performed");
}
}
}
delete li;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleAlignment(Int_t to, Bool_t lineup)
{
// align frames located inside lasso
Int_t x0, y0, x, y, xx, yy;
Window_t c;
TGCompositeFrame *comp = 0;
if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) return;
if (fLassoDrawn) {
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX, fPimpl->fY, x, y, c);
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0, fPimpl->fY0, x0, y0, c);
xx = x0; yy = y0;
x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
comp = (TGCompositeFrame*)fClient->GetRoot();
ToGrid(x, y);
ToGrid(x0, y0);
TIter next(comp->GetList());
TGFrameElement *el;
TGFrame *prev = 0;
while ((el = (TGFrameElement*)next())) {
TGFrame *fr = el->fFrame;
if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
(fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
(fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
switch ((EKeySym)to) {
case kKey_Left:
fr->Move(x0, fr->GetY());
if (lineup) {
if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
else fr->Move(x0, y0);
}
break;
case kKey_Right:
fr->Move(x - fr->GetWidth(), fr->GetY());
if (lineup) {
if (prev) fr->Move(fr->GetX(), prev->GetY() + prev->GetHeight());
else fr->Move(x - fr->GetWidth(), y0);
}
break;
case kKey_Up:
fr->Move(fr->GetX(), y0);
if (lineup) {
if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
else fr->Move(x0, y0);
}
break;
case kKey_Down:
fr->Move(fr->GetX(), y - fr->GetHeight());
if (lineup) {
if (prev) fr->Move(prev->GetX() + prev->GetWidth(), fr->GetY());
else fr->Move(x0, y - fr->GetHeight());
}
break;
default:
break;
}
prev = fr;
}
}
}
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleDelete(Bool_t crop)
{
//
Int_t x0, y0, x, y, xx, yy, w, h;
Window_t c;
if (!fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) return;
TGCompositeFrame *comp = 0;
Bool_t fromGrab = kFALSE;
if (fBuilder && crop) {
comp = fBuilder->FindEditableMdiFrame(fClient->GetRoot());
} else {
comp = (TGCompositeFrame*)fClient->GetRoot();
}
if (fPimpl->fGrab && !fLassoDrawn && crop &&
fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
ReparentFrames(comp, (TGCompositeFrame*)fPimpl->fGrab);
gVirtualX->TranslateCoordinates(fClient->GetRoot()->GetId(),
fClient->GetDefaultRoot()->GetId(),
fPimpl->fGrab->GetX(),
fPimpl->fGrab->GetY(),
fPimpl->fX0, fPimpl->fY0, c);
fPimpl->fX = fPimpl->fX0 + fPimpl->fGrab->GetWidth();
fPimpl->fY = fPimpl->fY0 + fPimpl->fGrab->GetHeight();
fromGrab = kTRUE;
}
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX, fPimpl->fY, x, y, c);
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0, fPimpl->fY0, x0, y0, c);
xx = x0; yy = y0;
x0 = TMath::Min(xx, x); x = TMath::Max(xx, x);
y0 = TMath::Min(yy, y); y = TMath::Max(yy, y);
w = x - x0;
h = y - y0;
if (fLassoDrawn || fromGrab) {
TIter next(comp->GetList());
TGFrameElement *el;
while ((el = (TGFrameElement*)next())) {
TGFrame *fr = el->fFrame;
if ((fr->GetX() >= x0) && (fr->GetY() >= y0) &&
(fr->GetX() + (Int_t)fr->GetWidth() <= x) &&
(fr->GetY() + (Int_t)fr->GetHeight() <= y)) {
if (!crop) {
DeleteFrame(fr);
} else {
fr->Move(fr->GetX() - x0, fr->GetY() - y0);
}
} else {
if (crop) {
DeleteFrame(fr);
}
}
}
if (crop && comp) {
gVirtualX->TranslateCoordinates(comp->GetId(), comp->GetParent()->GetId(),
x0, y0, xx, yy, c);
comp->MoveResize(xx, yy, w, h);
if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
gVirtualX->TranslateCoordinates(decor->GetId(), decor->GetParent()->GetId(),
xx, yy, xx, yy, c);
Int_t b = 2 * decor->GetBorderWidth();
decor->MoveResize(xx, yy, comp->GetWidth() + b,
comp->GetHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
}
}
if (fromGrab) {
DeleteFrame(fPimpl->fGrab);
fPimpl->fGrab = 0;
}
} else { // no lasso drawn
TString sav = fPasteFileName;
fPasteFileName = gSystem->ConcatFileName(gSystem->TempDirectory(),
Form("delete_RootGuiBldClipboard%d.C", gSystem->GetPid()));
HandleCut();
fPasteFileName = sav;
}
fLassoDrawn = kFALSE;
if (fBuilder) {
fBuilder->UpdateStatusBar(crop ? "Crop action performed" : "Delete action performed");
}
}
//______________________________________________________________________________
void TGuiBldDragManager::DeleteFrame(TGFrame *frame)
{
//
if (!frame) return;
frame->UnmapWindow();
TGCompositeFrame *comp = 0;
if (frame->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame*)frame->GetParent();
}
if (comp) comp->RemoveFrame(frame);
if (frame == fPimpl->fGrab) UngrabFrame();
fClient->UnregisterWindow(frame);
//frame->DeleteWindow();
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleCut()
{
//
if (!fPimpl->fGrab) return;
HandleCopy();
DeleteFrame(fPimpl->fGrab);
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleCopy()
{
//
if (!fPimpl->fGrab) return;
TGMainFrame *tmp = new TGMainFrame(fClient->GetDefaultRoot(),
fPimpl->fGrab->GetWidth(),
fPimpl->fGrab->GetHeight());
// save coordinates
Int_t x0 = fPimpl->fGrab->GetX();
Int_t y0 = fPimpl->fGrab->GetY();
// save parent name
TString name = fPimpl->fGrab->GetParent()->GetName();
((TGWindow*)fPimpl->fGrab->GetParent())->SetName(tmp->GetName());
fPimpl->fGrab->SetX(0);
fPimpl->fGrab->SetY(0);
TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
tmp->GetList()->Add(fe);
tmp->SetLayoutBroken();
tmp->SaveSource(fPasteFileName.Data(), "quiet");
tmp->GetList()->Remove(fe);
fPimpl->fGrab->SetX(x0);
fPimpl->fGrab->SetY(y0);
((TGWindow*)fPimpl->fGrab->GetParent())->SetName(name.Data());
if (fBuilder) {
TString str = fPimpl->fGrab->ClassName();
str += "::";
str += fPimpl->fGrab->GetName();
str += " copied to clipboard";
fBuilder->UpdateStatusBar(str.Data());
}
delete tmp;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandlePaste()
{
//
Int_t xp = 0;
Int_t yp = 0;
TGFrame *frame = 0;
if (gSystem->AccessPathName(fPasteFileName.Data())) return;
fPasting = kTRUE;
gROOT->Macro(fPasteFileName.Data());
Window_t c;
if (!fPimpl->fReplaceOn) {
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0, fPimpl->fY0, xp, yp, c);
ToGrid(xp, yp);
}
if (fPasteFrame) {
TGCompositeFrame *comp = 0;
comp = (TGCompositeFrame*)fPasteFrame;
TList *list = comp->GetList();
TGFrameElement *fe = 0;
fe = (TGFrameElement*)list->First();
comp = (TGCompositeFrame*)fClient->GetRoot();
if (fe) {
frame = fe->fFrame;
if (frame) frame->ReparentWindow(fClient->GetRoot(), xp, yp);
list->Remove(fe);
comp->GetList()->Add(fe);
}
comp->RemoveFrame(fPasteFrame);
fClient->UnregisterWindow(fPasteFrame);
fPasteFrame->DestroyWindow();
//delete fPasteFrame;
fPasteFrame = frame;
if (!fPimpl->fReplaceOn) {
SelectFrame(frame);
}
}
fPasting = kFALSE;
if (fBuilder) {
fBuilder->UpdateStatusBar("Paste action performed");
}
}
//______________________________________________________________________________
void TGuiBldDragManager::DoReplace(TGFrame *frame)
{
//
if (!frame || !fPimpl->fGrab || !fPimpl->fReplaceOn) return;
Int_t w = fPimpl->fGrab->GetWidth();
Int_t h = fPimpl->fGrab->GetHeight();
Int_t x = fPimpl->fGrab->GetX();
Int_t y = fPimpl->fGrab->GetY();
if (fBuilder) {
TString str = fPimpl->fGrab->ClassName();
str += "::";
str += fPimpl->fGrab->GetName();
str += " replaced by ";
str += frame->ClassName();
str += "::";
str += frame->GetName();
fBuilder->UpdateStatusBar(str.Data());
}
TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
fe->fFrame = 0;
fPimpl->fGrab->DestroyWindow();
delete fPimpl->fGrab;
fPimpl->fGrab = 0;
fe->fFrame = frame;
frame->MoveResize(x, y, w, h);
frame->MapRaised();
frame->SetFrameElement(fe);
SelectFrame(frame);
fPimpl->fReplaceOn = kFALSE;
TGWindow *root = (TGWindow *)fClient->GetRoot();
root->SetEditable(kFALSE);
DoRedraw();
root->SetEditable(kTRUE);
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleReplace()
{
//
if (!fPimpl->fGrab) return;
fPimpl->fReplaceOn = kTRUE;
TGFrame *frame = 0;
if (fBuilder && fBuilder->IsExecutalble()) {
frame = (TGFrame *)fBuilder->ExecuteAction();
} else {
HandlePaste();
frame = fPasteFrame;
}
DoReplace(frame);
fPimpl->fReplaceOn = kFALSE;
}
//______________________________________________________________________________
void TGuiBldDragManager::CloneEditable()
{
//
TString tmpfile = gSystem->TempDirectory();
tmpfile = gSystem->ConcatFileName(tmpfile.Data(),
Form("tmp%d.C", gRandom->Integer(100)));
Save(tmpfile.Data());
gROOT->Macro(tmpfile.Data());
gSystem->Unlink(tmpfile.Data());
if (fClient->GetRoot()->InheritsFrom(TGFrame::Class())) {
TGFrame *f = (TGFrame *)fClient->GetRoot();
f->Resize(f->GetWidth() + 10, f->GetHeight() + 10);
}
}
//______________________________________________________________________________
void TGuiBldDragManager::Save(const char *file)
{
//
if (!fClient->GetRoot() || !fClient->IsEditable()) return;
TGMainFrame *main = (TGMainFrame*)fClient->GetRoot()->GetMainFrame();
Bool_t lbrk = main->IsLayoutBroken();
main->SetLayoutBroken();
TGWindow *root = (TGWindow*)fClient->GetRoot();
TString fname = file;
root->SetEditable(kFALSE);
if (!file || !strlen(file)) {
static TString dir(".");
static Bool_t overwr = kFALSE;
static const char *gSaveMacroTypes[] = { "Macro files", "*.C",
"All files", "*",
0, 0 };
TGFileInfo fi;
fi.fFileTypes = gSaveMacroTypes;
fi.fIniDir = StrDup(dir);
fi.fOverwrite = overwr;
new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
if (!fi.fFilename) goto out;
dir = fi.fIniDir;
overwr = fi.fOverwrite;
fname = gSystem->BaseName(gSystem->UnixPathName(fi.fFilename));
}
if (strstr(fname.Data(), ".C")) {
main->SaveSource(fname.Data(), file ? "quiet" : "");
} else {
Int_t retval;
TString msg = Form("file (%s) must have extension .C", fname.Data());
new TGMsgBox(fClient->GetDefaultRoot(), main, "Error...", msg.Data(),
kMBIconExclamation, kMBRetry | kMBCancel, &retval);
if (retval == kMBRetry) {
Save();
}
}
out:
main->SetLayoutBroken(lbrk);
root->SetEditable(kTRUE);
}
//______________________________________________________________________________
void TGuiBldDragManager::DoResize()
{
// handle resize
if (!fPimpl->fGrab) return;
TGFrame *fr = fPimpl->fGrab;
Window_t c;
Int_t x = fPimpl->fX;
Int_t y = fPimpl->fY;
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fr->GetId(), x, y, x, y, c);
ToGrid(x, y);
switch (fPimpl->fResizeType) {
case kTopLeft:
if ((((int)fr->GetWidth() > x) || (x < 0)) &&
(((int)fr->GetHeight() > y) || (y < 0))) {
fr->MoveResize(fr->GetX() + x, fr->GetY() + y,
fr->GetWidth() - x, fr->GetHeight() - y);
}
break;
case kTopRight:
if ((x > 0) && (((int)fr->GetHeight() > y) || (y < 0))) {
fr->MoveResize(fr->GetX(), fr->GetY() + y,
x, fr->GetHeight() - y);
}
break;
case kTopSide:
if (((int)fr->GetHeight() > y) || (y < 0)) {
fr->MoveResize(fr->GetX(), fr->GetY() + y,
fr->GetWidth(), fr->GetHeight() - y);
}
break;
case kBottomLeft:
if ((((int)fr->GetWidth() > x) || (x < 0)) && (y > 0)) {
fr->MoveResize(fr->GetX() + x, fr->GetY(),
fr->GetWidth() - x, y);
}
break;
case kBottomRight:
if ((x > 0) && (y > 0)) {
fr->Resize(x, y);
}
break;
case kBottomSide:
if (y > 0) {
fr->Resize(fr->GetWidth(), y);
}
break;
case kLeftSide:
if ((int)fr->GetWidth() > x) {
fr->MoveResize(fr->GetX() + x, fr->GetY(),
fr->GetWidth() - x, fr->GetHeight());
}
break;
case kRightSide:
if (x > 0) {
fr->Resize(x, fr->GetHeight());
}
break;
default:
break;
}
gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
gVirtualX->CreateCursor(fPimpl->fResizeType));
fClient->NeedRedraw(fr, kTRUE);
DoRedraw();
}
//______________________________________________________________________________
void TGuiBldDragManager::DoMove()
{
//
if (!fPimpl->fGrab ) return;
Int_t x = fPimpl->fX - fPimpl->fXf;
Int_t y = fPimpl->fY - fPimpl->fYf;
fPimpl->fGrab->Move(x, y);
CheckTargetUnderGrab();
}
//______________________________________________________________________________
void TGuiBldDragManager::CheckTargetUnderGrab()
{
//
Window_t c;
TGWindow *win = 0;
if (!fPimpl->fGrab ) return;
Int_t x = fPimpl->fGrab->GetX();
Int_t y = fPimpl->fGrab->GetY();
Window_t w = GetWindowFromPoint(x - 1, y - 1);
if (w && (w != gVirtualX->GetDefaultRootWindow())) {
win = fClient->GetWindowById(w);
TGCompositeFrame *comp = 0;
if (!win) goto out;
if (win->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame *)win;
} else if (win->GetParent() != fClient->GetDefaultRoot()) {
comp = (TGCompositeFrame *)win->GetParent();
}
if (comp) {
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
comp->GetId(), x, y, x, y, c);
if ((comp != fPimpl->fGrab) && (x >= 0) && (y >= 0) &&
(x + fPimpl->fGrab->GetWidth() <= comp->GetWidth()) &&
(y + fPimpl->fGrab->GetHeight() <= comp->GetHeight())) {
if (comp != fTarget) {
comp->HandleDragEnter(fPimpl->fGrab);
if (fTarget) fTarget->HandleDragLeave(fPimpl->fGrab);
else Snap2Grid();
} else {
if (fTarget) fTarget->HandleDragMotion(fPimpl->fGrab);
}
fTarget = comp;
fTargetId = comp->GetId();
return;
} else {
if (fTarget) fTarget->HandleDragLeave(fPimpl->fGrab);
fTarget = 0;
fTargetId = 0;
}
}
}
out:
if (fTarget) fTarget->HandleDragLeave(fPimpl->fGrab);
if (!w || !win) {
fTarget = 0;
fTargetId = 0;
}
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleMotion(Event_t *event)
{
// handle motion event
static Long_t was = gSystem->Now();
static Int_t gy = event->fYRoot;
static Int_t gx = event->fXRoot;
Long_t now = (long)gSystem->Now();
if ((now-was < 100) || !(event->fState & kButton1Mask) ||
((event->fYRoot == gy) && (event->fXRoot == gx))) {
return kFALSE;
}
was = now;
gy = event->fYRoot;
gx = event->fXRoot;
if (!fDragging) {
if (fMoveWaiting && ((TMath::Abs(fPimpl->fX - event->fXRoot) > 10) ||
(TMath::Abs(fPimpl->fY - event->fYRoot) > 10))) {
return StartDrag(fSource, event->fXRoot, event->fYRoot);
}
} else {
fPimpl->fX = event->fXRoot;
fPimpl->fY = event->fYRoot;
switch (fDragType) {
case kDragLasso:
DrawLasso();
fSelectionIsOn = event->fState & kKeyShiftMask;
break;
case kDragMove:
case kDragCopy:
case kDragLink:
DoMove();
break;
case kDragResize:
DoResize();
break;
default:
break;
}
}
return kTRUE;
}
//______________________________________________________________________________
void TGuiBldDragManager::PlaceFrame(TGFrame *frame, TGLayoutHints *hints)
{
//
Int_t x0, y0, x, y;
Window_t c;
if (!frame || !fClient->IsEditable()) return;
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX , fPimpl->fY, x, y, c);
ToGrid(x, y);
ToGrid(x0, y0);
Int_t w = TMath::Abs(x - x0);
Int_t h = TMath::Abs(y - y0);
frame->Move(x > x0 ? x0 : x, y > y0 ? y0 : y);
frame->Resize(w, h);
frame->MapRaised();
frame->SetCleanup(kDeepCleanup);
frame->AddInput(kButtonPressMask);
if (fClient->GetRoot()->InheritsFrom(TGCompositeFrame::Class())) {
TGCompositeFrame *edit = (TGCompositeFrame*)fClient->GetRoot();
edit->SetCleanup(kDeepCleanup);
ReparentFrames(frame, edit);
frame->MapRaised();
edit->SetLayoutBroken();
UInt_t g = GetGridStep()/2;
edit->AddFrame(frame, hints ? hints : new TGLayoutHints(kLHintsNormal, g, g, g, g));
}
if (fBuilder) {
TString str = frame->ClassName();
str += "::";
str += frame->GetName();
str += " created";
fBuilder->UpdateStatusBar(str.Data());
}
}
//______________________________________________________________________________
void TGuiBldDragManager::DrawLasso()
{
// draw lasso for allocation new object
if (!fClient->IsEditable()) return;
UngrabFrame();
Int_t x0, y0, x, y;
Window_t c;
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX0 , fPimpl->fY0, x0, y0, c);
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fClient->GetRoot()->GetId(),
fPimpl->fX , fPimpl->fY, x, y, c);
ToGrid(x, y);
ToGrid(x0, y0);
Int_t w = TMath::Abs(x - x0);
Int_t h = TMath::Abs(y - y0);
DoRedraw();
gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
GetBlackGC()(), x > x0 ? x0 : x,
y > y0 ? y0 : y, w, h);
gVirtualX->DrawRectangle(fClient->GetRoot()->GetId(),
GetBlackGC()(), x > x0 ? x0-1 : x-1,
y > y0 ? y0-1 : y-1, w+2, h+2);
gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kCross));
gVirtualX->SetCursor(fClient->GetRoot()->GetId(), gVirtualX->CreateCursor(kCross));
fLassoDrawn = kTRUE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleClientMessage(Event_t *event)
{
//
if ((event->fFormat == 32) && ((Atom_t)event->fUser[0] == gWM_DELETE_WINDOW) &&
(event->fHandle != gROOT_MESSAGE)) {
TGMainFrame *main = (TGMainFrame*)fClient->GetRoot()->GetMainFrame();
if (event->fWindow == main->GetId()) {
fClient->SetRoot(0);
if (main != fBuilder) {
main->Cleanup();
if (fEditor && !fEditor->IsEmbedded()) {
delete fEditor;
fEditor = 0;
}
return kFALSE;
}
fBuilder->Hide();
delete fFrameMenu;
fFrameMenu =0;
delete fLassoMenu;
fLassoMenu = 0;
//delete fPimpl->fGrid;
fPimpl->fGrid = 0;
Init();
if (fPimpl) fPimpl->ResetParams();
} else if (fBuilder && (event->fWindow == fBuilder->GetId())) {
fBuilder->Hide();
} else if (fEditor && (event->fWindow == fEditor->GetMainFrame()->GetId())) {
TQObject::Disconnect(fEditor);
fEditor = 0;
}
}
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleSelection(Event_t *)
{
//
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::HandleSelectionRequest(Event_t *)
{
//
return kFALSE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::StartDrag(TGFrame *src, Int_t x, Int_t y)
{
// start dragging
if (fDragging) return kFALSE;
SetEditable(kTRUE); // grab server
fPimpl->fX = x;
fPimpl->fY = y;
fSelectionIsOn = kFALSE;
fPimpl->fRepeatTimer->Reset();
gSystem->AddTimer(fPimpl->fRepeatTimer);
fMoveWaiting = kFALSE;
fDragging = kTRUE;
switch (fDragType) {
case kDragCopy:
fPimpl->fGrab = new TGDragGrabber(src, x, y);
//GrabFrame(fPimpl->fGrab);
break;
case kDragMove:
fPimpl->fGrab = src;
GrabFrame(fPimpl->fGrab);
break;
default:
//fPimpl->fGrab = 0;
break;
}
return kTRUE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::EndDrag()
{
// end dragging
TGFrame *frame = 0;
Bool_t ret = kFALSE;
if (fPimpl->fGrab && (fDragType >= kDragMove) && (fDragType <= kDragLink)) {
ret = Drop();
} else if (fBuilder && fBuilder->IsExecutalble() &&
(fDragType == kDragLasso) && !fSelectionIsOn) {
frame = (TGFrame*)fBuilder->ExecuteAction();
PlaceFrame(frame, fBuilder->GetAction()->fHints);
ret = kTRUE;
} else if ((fDragType == kDragLasso) && fSelectionIsOn) {
HandleReturn(kFALSE);
ret = kTRUE;
}
if (!fLassoDrawn) DoRedraw();
Init();
if (fBuilder) {
fBuilder->SetAction(0);
fBuilder->Update();
if (fLassoDrawn) {
fBuilder->UpdateStatusBar("Lasso Drawn");
}
}
return ret;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::Cancel(Bool_t /*delSrc*/)
{
//
fTarget = 0;
EndDrag();
return kTRUE;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::Drop()
{
//
if (!fPimpl->fGrab && !fSelectionIsOn) return kFALSE;
fDropStatus = kFALSE;
TGFrame *frame = 0;
TGFrame *parent = 0;
Int_t x, y;
Window_t c;
switch (fDragType) {
case kDragCopy:
frame = (TGFrame*)fPimpl->fGrab->Clone();
break;
case kDragMove:
frame = fPimpl->fGrab;
break;
default:
break;
}
TGWindow *w = fClient->GetWindowById(fTargetId);
if (fTarget && fPimpl->fGrab && (w == fTarget) && w &&
(w != fClient->GetDefaultRoot())) {
parent = fTarget;
gVirtualX->TranslateCoordinates(fClient->GetDefaultRoot()->GetId(),
fTarget->GetId(),
fPimpl->fGrab->GetX(),
fPimpl->fGrab->GetY(), x, y, c);
fTarget->HandleDragLeave(fPimpl->fGrab);
} else {
parent = (TGFrame*)fPimpl->fGrabParent;
x = fPimpl->fGrabX;
y = fPimpl->fGrabY;
}
if (parent && frame) {
ToGrid(x, y);
fDropStatus = parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
if (!fDropStatus) {
parent = (TGFrame*)fPimpl->fGrabParent;
x = fPimpl->fGrabX;
y = fPimpl->fGrabY;
frame = fPimpl->fGrab;
parent->HandleDragDrop(frame, x, y, fPimpl->fGrabLayout);
fDropStatus = kTRUE;
}
}
if (fDropStatus) {
if (fBuilder) {
TString str = frame->ClassName();
str += "::";
str += frame->GetName();
str += " dropped into ";
str += parent->ClassName();
str += "::";
str += parent->GetName();
fBuilder->UpdateStatusBar(str.Data());
}
fTarget = 0;
fTargetId = 0;
if (parent && (parent == fPimpl->fGrabParent) && fPimpl->fGrabListPosition &&
frame && parent->InheritsFrom(TGCompositeFrame::Class())) {
TList *li = ((TGCompositeFrame*)parent)->GetList();
li->Remove(frame->GetFrameElement());
li->AddAfter(fPimpl->fGrabListPosition, frame->GetFrameElement());
}
}
fPimpl->fGrabParent = 0;
fPimpl->fGrabX = 0;
fPimpl->fGrabY = 0;
fPimpl->fGrabListPosition = 0;
return fDropStatus;
}
//______________________________________________________________________________
Bool_t TGuiBldDragManager::IsMoveWaiting() const
{
// Waits for either the mouse move from the given initial ButtonPress location
// or for the mouse button to be released. If mouse moves away from the initial
// ButtonPress location before the mouse button is released "IsMoveWaiting"
// returns kTRUE. If the mouse button released before the mose moved from the
// initial ButtonPress location, "IsMoveWaiting" returns kFALSE.
return fMoveWaiting;
}
//______________________________________________________________________________
void TGuiBldDragManager::Compact(Bool_t global)
{
// Layout and Resize frame.
// If global is kFALSE - compact selected frame
// If global is kFALSE - compact main frame of selected frame
TGCompositeFrame *comp = 0;
TGFrameElement *fe;
if (!fClient || !fClient->IsEditable()) return;
if (global) {
if (!fBuilder) comp = (TGCompositeFrame*)fClient->GetRoot()->GetMainFrame();
else comp = fBuilder->FindEditableMdiFrame(fClient->GetRoot());
} else {
if (fPimpl->fGrab &&
fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) {
comp = (TGCompositeFrame*)fPimpl->fGrab;
} else {
comp = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
}
}
if (!comp) return;
TIter next(comp->GetList());
TGFrame *root = (TGFrame *)fClient->GetRoot();
root->SetEditable(kFALSE);
if (global) {
while ((fe = (TGFrameElement*)next())) {
fe->fFrame->SetLayoutBroken(kFALSE);
fe->fFrame->Resize();
}
root->SetLayoutBroken(kFALSE);
fPimpl->fCompacted = kTRUE;
}
comp->SetLayoutBroken(kFALSE);
comp->Resize();
if (comp->GetParent()->InheritsFrom(TGMdiDecorFrame::Class())) {
TGMdiDecorFrame *decor = (TGMdiDecorFrame *)comp->GetParent();
Int_t b = 2 * decor->GetBorderWidth();
decor->MoveResize(decor->GetX(), decor->GetY(), comp->GetWidth() + b,
comp->GetHeight() + b + decor->GetTitleBar()->GetDefaultHeight());
}
root->SetEditable(kTRUE);
DoRedraw();
DrawGrabRectangles();
}
//______________________________________________________________________________
void TGuiBldDragManager::SetEditable(Bool_t on)
{
// grab server
static Bool_t gon = kFALSE;
static const TGWindow *gw = 0;
HideGrabRectangles();
if ((gon == on) && (fClient->GetRoot() == gw)) return;
gon = on; gw = fClient->GetRoot();
Snap2Grid();
if (on) {
if (!fClient->GetRoot()->InheritsFrom(TGFrame::Class())) return;
TGFrame *fr = (TGFrame*)fClient->GetRoot();
fEventMask = fr->GetEventMask(); //saved event mask
fr->AddInput(kKeyPressMask | kButtonPressMask);
if (fPimpl->fRepeatTimer) {
fPimpl->fRepeatTimer->Reset();
} else {
fPimpl->fRepeatTimer = new TGuiBldDragManagerRepeatTimer(this, 100);
}
gSystem->AddTimer(fPimpl->fRepeatTimer);
} else if (fClient->GetRoot()->IsEditable()) {
if (fPimpl->fRepeatTimer) fPimpl->fRepeatTimer->Remove();
UngrabFrame();
gVirtualX->SelectInput(fClient->GetRoot()->GetId(), fEventMask);
}
if (on && fClient->IsEditable()) {
gVirtualX->SetCursor(fClient->GetRoot()->GetId(),
gVirtualX->CreateCursor(kPointer));
}
if (!on && !gSystem->AccessPathName(fPasteFileName.Data())) {
gSystem->Unlink(fPasteFileName.Data());
}
}
//______________________________________________________________________________
void TGuiBldDragManager::ToGrid(Int_t &x, Int_t &y)
{
//
UInt_t step = GetGridStep();
x = x - x%step;
y = y - y%step;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleAction(Int_t act)
{
//
fPimpl->fLastPopupAction = act;
if (fPimpl->fPlane) {
fPimpl->fPlane->ChangeOptions(fPimpl->fPlane->GetOptions() & ~kRaisedFrame);
fClient->NeedRedraw(fPimpl->fPlane, kTRUE);
}
switch ((EActionType)act) {
case kPropertyAct:
CreatePropertyEditor();
break;
case kEditableAct:
if (fPimpl->fSaveGrab) fPimpl->fSaveGrab->SetEditable(kTRUE);
break;
case kCutAct:
HandleCut();
break;
case kCopyAct:
HandleCopy();
break;
case kPasteAct:
HandlePaste();
break;
case kCropAct:
HandleDelete(kTRUE);
break;
case kCompactAct:
Compact(kFALSE);
break;
case kCompactGlobalAct:
Compact(kTRUE);
break;
case kDropAct:
HandleReturn(kTRUE);
break;
case kLayUpAct:
HandleLayoutOrder(kFALSE);
break;
case kLayDownAct:
HandleLayoutOrder(kTRUE);
break;
case kCloneAct:
CloneEditable();
break;
case kGrabAct:
HandleReturn(fBuilder && !fBuilder->IsGrabButtonDown());
break;
case kDeleteAct:
HandleDelete(kFALSE);
break;
case kLeftAct:
HandleAlignment(kKey_Left);
break;
case kRightAct:
HandleAlignment(kKey_Right);
break;
case kUpAct:
HandleAlignment(kKey_Up);
break;
case kDownAct:
HandleAlignment(kKey_Down);
break;
case kEndEditAct:
SetEditable(kFALSE);
((TGWindow*)fClient->GetRoot())->SetEditable(kFALSE);
DeletePropertyEditor();
break;
case kReplaceAct:
HandleReplace();
break;
case kGridAct:
HandleGrid();
break;
case kBreakLayoutAct:
BreakLayout();
break;
case kSwitchLayoutAct:
case kLayoutVAct:
case kLayoutHAct:
SwitchLayout();
break;
case kNewAct:
if (fBuilder) {
fBuilder->NewProject();
} else {
TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
main->MapRaised();
main->SetEditable(kTRUE);
}
break;
case kOpenAct:
if (fBuilder) {
fBuilder->OpenProject();
} else {
TGMainFrame *main = new TGMainFrame(fClient->GetDefaultRoot(), 300, 300);
main->MapRaised();
main->SetEditable(kTRUE);
}
break;
case kSaveAct:
if (fBuilder) {
fBuilder->SaveProject();
} else {
Save();
}
break;
default:
break;
}
if (fBuilder) {
fBuilder->SetAction(0);
fBuilder->Update();
}
}
//______________________________________________________________________________
void TGuiBldDragManager::Menu4Frame(TGFrame *frame, Int_t x, Int_t y)
{
// create and place context menu for selected frame
fPimpl->fSaveGrab = fPimpl->fGrab;
fPimpl->fX0 = x;
fPimpl->fY0 = y;
fPimpl->fLastFrame = frame;
Bool_t composite = frame->InheritsFrom(TGCompositeFrame::Class());
Bool_t compar = frame->GetParent()->InheritsFrom(TGCompositeFrame::Class());
TGCompositeFrame *cfr = 0;
TGCompositeFrame *cfrp = 0;
TGLayoutManager *lm = 0;
if (composite) {
cfr = (TGCompositeFrame *)frame;
lm = cfr->GetLayoutManager();
}
if (compar) {
cfrp = (TGCompositeFrame *)frame->GetParent();
}
delete fFrameMenu;
fFrameMenu = new TGPopupMenu(fClient->GetDefaultRoot());
fFrameMenu->SetEditDisabled();
TString title = frame->ClassName();
title += "::";
title += frame->GetName();
fFrameMenu->AddLabel(title.Data());
fFrameMenu->AddSeparator();
if (!fBuilder) fFrameMenu->AddEntry("Gui Builder", kPropertyAct);
if (!frame->IsEditable() && !InEditable(frame->GetId())) {
fPimpl->fSaveGrab = frame;
goto out;
}
fFrameMenu->AddSeparator();
if (!frame->IsEditable()) {
if (composite) fFrameMenu->AddEntry("Drop Ctrl+Return", kDropAct);
fFrameMenu->AddSeparator();
fFrameMenu->AddEntry("Cut Ctrl+X", kCutAct);
fFrameMenu->AddEntry("Copy Ctrl+C", kCopyAct);
fFrameMenu->AddEntry("Delete Del", kDeleteAct);
if (composite) fFrameMenu->AddEntry("Crop Shift+Del", kCropAct);
fFrameMenu->AddEntry("Replace Ctrl+R", kReplaceAct);
} else {
if (!gSystem->AccessPathName(fPasteFileName.Data())) {
fFrameMenu->AddEntry("Paste Ctrl+V", kPasteAct);
}
if (frame->GetMainFrame() == frame) {
fFrameMenu->AddEntry("Clone Ctrl+A", kCloneAct);
}
}
fFrameMenu->AddSeparator();
if (composite && !cfr->GetList()->IsEmpty()) {
if (frame->IsLayoutBroken()) {
if (!frame->IsEditable()) {
fFrameMenu->AddEntry("Layout Ctrl+L", kCompactAct);
} else {
fFrameMenu->AddEntry("Layout Ctrl+L", kCompactGlobalAct);
}
} else {
fFrameMenu->AddEntry("Break Layout Ctrl+B", kBreakLayoutAct);
}
if (lm->InheritsFrom(TGVerticalLayout::Class()) ||
lm->InheritsFrom(TGHorizontalLayout::Class())) {
fFrameMenu->AddEntry("H/V Layout Ctrl+H", kSwitchLayoutAct);
}
}
if (compar && (cfrp->GetList()->GetSize() > 1) && !frame->IsEditable()) {
if (cfrp->GetList()->First() != frame->GetFrameElement()) {
fFrameMenu->AddEntry("Lay Up Up/Left", kLayUpAct);
}
if (cfrp->GetList()->Last() != frame->GetFrameElement()) {
fFrameMenu->AddEntry("Lay Down Down/Right", kLayDownAct);
}
}
fFrameMenu->AddSeparator();
fFrameMenu->AddEntry("Grid On/Off Ctrl+G", kGridAct);
if (frame->IsEditable()) {
fFrameMenu->AddSeparator();
fFrameMenu->AddEntry("Save As ... Ctrl+S", kSaveAct);
fFrameMenu->AddEntry("End Edit Ctrl+DblClick", kEndEditAct);
} else if (composite) {
fFrameMenu->AddSeparator();
fFrameMenu->AddEntry("Edit Ctrl+DblClick", kEditableAct);
}
out:
fFrameMenu->Connect("Activated(Int_t)", "TGuiBldDragManager", this, "HandleAction(Int_t)");
fPimpl->fLastPopupAction = kNoneAct;
fFrameMenu->PlaceMenu(x, y, kFALSE, kTRUE);
if (fLassoDrawn) DrawLasso();
}
//______________________________________________________________________________
void TGuiBldDragManager::Menu4Lasso(Int_t x, Int_t y)
{
//
if (!fLassoDrawn) return;
DrawLasso();
if (!fLassoMenu) {
fLassoMenu = new TGPopupMenu(fClient->GetDefaultRoot());
fLassoMenu->SetEditDisabled();
fLassoMenu->AddLabel("Edit actions");
fLassoMenu->AddSeparator();
fLassoMenu->AddEntry("Grab Return", kGrabAct);
fLassoMenu->AddSeparator();
fLassoMenu->AddEntry("Delete Delete", kDeleteAct);
fLassoMenu->AddEntry("Crop Shift+Delete", kCropAct);
fLassoMenu->AddSeparator();
fLassoMenu->AddEntry("Align Left Left(Shift+Left)", kLeftAct);
fLassoMenu->AddEntry("Align Right Right(Shift+Right)", kRightAct);
fLassoMenu->AddEntry("Align Up Up(Shift+Up)", kUpAct);
fLassoMenu->AddEntry("Align Down Down(Shift+Down)", kDownAct);
fLassoMenu->Connect("Activated(Int_t)", "TGuiBldDragManager", this, "HandleAction(Int_t)");
}
fPimpl->fLastPopupAction = kNoneAct;
fLassoMenu->PlaceMenu(x, y, kFALSE, kTRUE);
}
//______________________________________________________________________________
void TGuiBldDragManager::CreatePropertyEditor()
{
//
if (!fPimpl->fLastFrame) return;
TGWindow *root = (TGWindow*)fClient->GetRoot();
root->SetEditable(kFALSE);
fBuilder = (TRootGuiBuilder*)TRootGuiBuilder::Instance();
fBuilder->Move(fPimpl->fX0, fPimpl->fY0);
fBuilder->SetWMPosition(fPimpl->fX0, fPimpl->fY0);
SetPropertyEditor(fBuilder->GetEditor());
root->SetEditable(kTRUE);
}
//______________________________________________________________________________
void TGuiBldDragManager::SetPropertyEditor(TGuiBldEditor *e)
{
//
fEditor = e;
if (!fEditor) return;
fEditor->ChangeSelected(fPimpl->fLastFrame);
Connect("Selected(TGFrame*)", "TGuiBldEditor", fEditor, "ChangeSelected(TGFrame*)");
fEditor->Connect("UpdateSelected(TGFrame*)", "TGuiBldDragManager", this,
"HandleUpdateSelected(TGFrame*)");
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleLayoutOrder(Bool_t forward)
{
//
if (!fPimpl->fGrab || !fPimpl->fGrab->GetFrameElement() ||
!fPimpl->fGrab->GetParent()->InheritsFrom(TGCompositeFrame::Class())) {
return;
}
TGCompositeFrame *comp = (TGCompositeFrame*)fPimpl->fGrab->GetParent();
TList *li = comp->GetList();
TGFrameElement *fe = fPimpl->fGrab->GetFrameElement();
if (!fe) return;
TGFrame *frame;
TGFrameElement *el;
if (forward) {
el = (TGFrameElement *)li->After(fe);
if (!el) return;
frame = el->fFrame;
el->fFrame = fPimpl->fGrab;
fPimpl->fGrab->SetFrameElement(el);
fe->fFrame = frame;
frame->SetFrameElement(fe);
} else {
el = (TGFrameElement *)li->Before(fe);
if (!el) return;
frame = el->fFrame;
el->fFrame = fPimpl->fGrab;
fPimpl->fGrab->SetFrameElement(el);
fe->fFrame = frame;
frame->SetFrameElement(fe);
}
Bool_t sav = comp->IsLayoutBroken();
comp->SetLayoutBroken(kFALSE);
TGWindow *root = (TGWindow *)fClient->GetRoot();
root->SetEditable(kFALSE);
comp->Layout();
DoRedraw();
root->SetEditable(kTRUE);
if (sav) comp->SetLayoutBroken(kTRUE);
SelectFrame(el->fFrame);
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleGrid()
{
//
TGWindow *root = (TGWindow*)fClient->GetRoot();
if (fPimpl->fGrid->fgStep > 1) {
fPimpl->fGrid->SetStep(1);
if (fBuilder) {
fBuilder->UpdateStatusBar("Grid switched OFF");
}
} else {
fPimpl->fGrid->SetStep(gGridStep);
if (fBuilder) {
fBuilder->UpdateStatusBar("Grid switched ON");
}
if (root->InheritsFrom(TGCompositeFrame::Class())) {
TGCompositeFrame *comp = (TGCompositeFrame*)root;
TIter next(comp->GetList());
TGFrameElement *fe;
Int_t x, y, w, h;
while ((fe = (TGFrameElement*)next())) {
x = fe->fFrame->GetX();
y = fe->fFrame->GetY();
w = fe->fFrame->GetWidth();
h = fe->fFrame->GetHeight();
ToGrid(x, y);
ToGrid(w, h);
fe->fFrame->MoveResize(x, y, w, h);
}
}
}
root->SetEditable(kFALSE);
DoRedraw();
root->SetEditable(kTRUE);
DrawGrabRectangles();
}
//______________________________________________________________________________
TGCompositeFrame *TGuiBldDragManager::FindLayoutFrame(TGFrame *f)
{
//
if (!f) return 0;
const TGWindow *parent = f->GetParent();
TGCompositeFrame *ret = 0;
while (parent && (parent != fClient->GetDefaultRoot())) {
ret = (TGCompositeFrame*)parent;
if (parent->InheritsFrom(TGMdiFrame::Class())) return ret;
parent = parent->GetParent();
}
return ret;
}
//______________________________________________________________________________
void TGuiBldDragManager::HandleUpdateSelected(TGFrame *f)
{
//
if (!f) return;
TGCompositeFrame *main = FindLayoutFrame(f);
//Bool_t mainsav = main->IsLayoutBroken();
TGWindow *root = (TGWindow*)fClient->GetRoot();
root->SetEditable(kFALSE);
TGFrame *parent = 0;
if (f->GetParent()->InheritsFrom(TGFrame::Class())) {
parent = (TGFrame*)f->GetParent();
}
Bool_t sav = kFALSE;
if (parent && (parent != main)) {
sav = parent->IsLayoutBroken();
if (sav) {
parent->SetLayoutBroken(kFALSE);
}
}
main->SetLayoutBroken(kFALSE);
main->Layout();
fClient->NeedRedraw(f);
fClient->NeedRedraw(main);
if (sav) parent->SetLayoutBroken(kTRUE);
//if (mainsav) main->SetLayoutBroken(kTRUE);
root->SetEditable(kTRUE);
DrawGrabRectangles();
}
//______________________________________________________________________________
void TGuiBldDragManager::HideGrabRectangles()
{
//
if (fPimpl->fGrabRectHidden) return;
int i = 0;
for (i = 0; i < 8; i++) fPimpl->fGrabRect[i]->UnmapWindow();
for (i = 0; i < 4; i++) fPimpl->fAroundFrame[i]->UnmapWindow();
fPimpl->fGrabRectHidden = kTRUE;
}
//______________________________________________________________________________
void TGuiBldDragManager::DeletePropertyEditor()
{
if (!fEditor) return;
TQObject::Disconnect(fEditor);
delete fEditor;
fEditor = 0;
}
//______________________________________________________________________________
Int_t TGuiBldDragManager::GetStrartDragX() const
{
//
return fPimpl->fX0;
}
//______________________________________________________________________________
Int_t TGuiBldDragManager::GetStrartDragY() const
{
//
return fPimpl->fY0;
}
//______________________________________________________________________________
Int_t TGuiBldDragManager::GetEndDragX() const
{
//
return fPimpl->fY;
}
//______________________________________________________________________________
Int_t TGuiBldDragManager::GetEndDragY() const
{
//
return fPimpl->fY;
}
//______________________________________________________________________________
void TGuiBldDragManager::ExecuteQuickAction(Event_t *event)
{
//
TGWindow *win = gClient->GetWindowById(event->fWindow);
if (!win) return;
if (!fQuickHandler) fQuickHandler = new TGuiBldQuickHandler();
if (!fQuickHandler || !fQuickHandler->HandleEvent(win)) {
if (win->IsEditable()) {
TGFrame *f = (TGFrame*)win;
TGDimension sz = f->GetDefaultSize();
if ((sz.fWidth > 10) && (sz.fHeight > 10)) {
//Compact(kTRUE);
}
}
}
}
//______________________________________________________________________________
void TGuiBldDragManager::BreakLayout()
{
//
if (!fPimpl->fGrab) return;
fPimpl->fGrab->SetLayoutBroken(kTRUE);
if (fBuilder) {
TString str = fPimpl->fGrab->ClassName();
str += "::";
str += fPimpl->fGrab->GetName();
str += " Layout Broken";
fBuilder->UpdateStatusBar(str.Data());
}
Int_t x = fPimpl->fGrab->GetX();
Int_t y = fPimpl->fGrab->GetY();
UInt_t w = fPimpl->fGrab->GetWidth();
UInt_t h = fPimpl->fGrab->GetHeight();
const TGGC *gc = fClient->GetResourcePool()->GetSelectedBckgndGC();
DrawGrabRectangles();
gVirtualX->DrawRectangle(fPimpl->fGrab->GetParent()->GetId(),
gc->GetGC(), x, y, w, h);
gVirtualX->DrawRectangle(fPimpl->fGrab->GetParent()->GetId(),
gc->GetGC(), x-2, y-2, w+2, h+2);
TTimer::SingleShot(500, "TGuiBldDragManager", this, "DoRedraw()");
}
//______________________________________________________________________________
void TGuiBldDragManager::SwitchLayout()
{
//
if (!fPimpl->fGrab || !fPimpl->fGrab->InheritsFrom(TGCompositeFrame::Class())) return;
TGCompositeFrame *comp = (TGCompositeFrame*)fPimpl->fGrab;
comp->SetLayoutBroken(kFALSE);
UInt_t opt = comp->GetOptions();
TGLayoutManager *m = comp->GetLayoutManager();
if (m->InheritsFrom(TGHorizontalLayout::Class())) {
opt &= ~kHorizontalFrame;
opt |= kVerticalFrame;
if (fBuilder) {
TString str = comp->ClassName();
str += "::";
str += comp->GetName();
str += " Vertical Layout ON";
fBuilder->UpdateStatusBar(str.Data());
}
} else if (m->InheritsFrom(TGVerticalLayout::Class())) {
opt &= ~kVerticalFrame;
opt |= kHorizontalFrame;
if (fBuilder) {
TString str = comp->ClassName();
str += "::";
str += comp->GetName();
str += " Horizontal Layout ON";
fBuilder->UpdateStatusBar(str.Data());
}
}
comp->ChangeOptions(opt);
comp->Resize();
}
//______________________________________________________________________________
TGFrame *TGuiBldDragManager::GetSelected() const
{
//
return (fPimpl ? fPimpl->fGrab : 0);
}
//______________________________________________________________________________
void TGuiBldDragManager::CloseMenus()
{
//
void *ud;
if (fFrameMenu) fFrameMenu->EndMenu(ud);
if (fLassoMenu) fLassoMenu->EndMenu(ud);
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.