Select a list tree item with a mouse press, drag it (move the mouse while keeping the mouse button pressed) and release the mouse button in any pad inside the canvas or in the top list tree item ("Base"). When the button is released, the selected data is "dropped" at that location, displaying the object in the canvas or adding (copying) it in the list tree.
#include <cmath>
const char gHelpDND[] = "\
Drag & Drop (DnD)\n\
Drag and Drop support is implemented on Linux via Xdnd, the\n\
drag and drop protocol for X window system, and on Windows\n\
via the Clipboard.\n\
Users can selects something in ROOT with a mouse press, drags\n\
it (moves the mouse while keeping the mouse button pressed) and\n\
releases the mouse button somewhere else. When the button is\n\
released the selected data is \"dropped\" at that location. This\n\
way, a histogram from an opened ROOT file in the browser can be\n\
dragged to any TCanvas. A script file from the browser can be\n\
dropped to a TGTextView or TGTextEdit widget in TGTextEditor.\n\
On Linux, it is possible to drag objects between ROOT and an\n\
external application. For example to drag a macro file from the\n\
ROOT browser to the Kate editor. On Windows, drag and drop works\n\
only within a single ROOT application, but it is possible to drag\n\
from the Windows Explorer to ROOT (e.g. a picture file to a canvas\n\
or a text file to a text editor).\n\
";
const char gReadyMsg[] = "Ready. You can drag list tree items to any \
pad in the canvas, or to the \"Base\" folder of the list tree itself...";
protected:
public:
virtual ~DNDMainFrame();
void DoCloseWindow();
TObject *GetObject(
const char *obj);
void ResetStatus();
};
M_FILE_OPEN,
M_FILE_BROWSE,
M_FILE_NEWCANVAS,
M_FILE_CLOSEWIN,
M_FILE_EXIT,
M_HELP_ABOUT
};
const char *dnd_types[] = {"ROOT files", "*.root", "ROOT macros", "*.C", "All files", "*", 0, 0};
{
fMenuFile->AddEntry(
" &Open...\tCtrl+O", M_FILE_OPEN, 0,
gClient->GetPicture(
"bld_open.png"));
fMenuFile->AddEntry(" &Browse...\tCtrl+B", M_FILE_BROWSE);
fMenuFile->AddEntry(" &New Canvas\tCtrl+N", M_FILE_NEWCANVAS);
fMenuFile->AddEntry(" &Close Window\tCtrl+W", M_FILE_CLOSEWIN);
fMenuFile->AddSeparator();
fMenuFile->AddEntry(
" E&xit\tCtrl+Q", M_FILE_EXIT, 0,
gClient->GetPicture(
"bld_exit.png"));
fMenuFile->Connect("Activated(Int_t)", "DNDMainFrame", this, "HandleMenu(Int_t)");
fMenuHelp->AddEntry(
" &About...", M_HELP_ABOUT, 0,
gClient->GetPicture(
"about.xpm"));
fMenuHelp->Connect("Activated(Int_t)", "DNDMainFrame", this, "HandleMenu(Int_t)");
fListTree->Associate(this);
fEc->SetDNDTarget(
kTRUE);
fCanvas = fEc->GetCanvas();
fCanvas->Divide(3, 2);
fCanvas->SetBorderMode(0);
fBaseLTI = fListTree->AddItem(0, "Base");
fStatus->SetTextColor(0x0000ff);
fButtonExit->Resize(fButtonExit->GetDefaultSize());
fButtonExit->SetToolTipText("Exit Application (ROOT)");
fButtonExit->Connect(
"Clicked()",
"TApplication",
gApplication,
"Terminate()");
item = fListTree->AddItem(fBaseLTI,
gr->
GetName(),
gr, pic, pic);
fListTree->SetToolTipItem(item, "Simple Graph");
TH1F *hpx = (
TH1F *)GetObject(
"1D Hist");
pic =
gClient->GetPicture(
"h1_t.xpm");
item = fListTree->AddItem(fBaseLTI, hpx->
GetName(), hpx, pic, pic);
fListTree->SetToolTipItem(item, "1D Histogram");
pic =
gClient->GetPicture(
"h2_t.xpm");
item = fListTree->AddItem(fBaseLTI,
h2->GetName(),
h2, pic, pic);
fListTree->SetToolTipItem(item, "2D Histogram");
#ifdef R__WIN32
if (rootsys[1] == ':' && rootsys[2] == '/')
rootsys.Remove(0, 3);
#endif
if (img) {
delete img;
} else
pic =
gClient->GetPicture(
"psp_t.xpm");
item = fListTree->AddItem(fBaseLTI, "Rose", ostr, pic, pic);
fListTree->SetToolTipItem(item, link.
Data());
}
fListTree->OpenItem(fBaseLTI);
fListTree->GetFirstItem()->SetDNDTarget(
kTRUE);
fListTree->Connect("DataDropped(TGListTreeItem*, TDNDData*)", "DNDMainFrame", this,
"DataDropped(TGListTreeItem*,TDNDData*)");
SetWindowName("ROOT DND Demo Application");
Resize(GetDefaultSize());
Connect("CloseWindow()", "DNDMainFrame", this, "DoCloseWindow()");
DontCallClose();
}
DNDMainFrame::~DNDMainFrame()
{
}
void DNDMainFrame::DoCloseWindow()
{
if (fGraph) {
delete fGraph;
fGraph = 0;
}
if (fHist1D) {
delete fHist1D;
fHist1D = 0;
}
if (fHist2D) {
delete fHist2D;
fHist2D = 0;
}
fMenuFile->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
fMenuHelp->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
fButtonExit->Disconnect("Clicked()", this, "CloseWindow()");
fListTree->Disconnect("DataDropped(TGListTreeItem*, TDNDData*)", this, "DataDropped(TGListTreeItem*,TDNDData*)");
delete fListTree;
CloseWindow();
}
{
fStatus->SetTextColor(0xff0000);
fStatus->ChangeText("I received data!!!");
if (
data->fDataType == gRootObj) {
buf.SetReadMode();
sprintf(tmp,
"Received DND data : Type = \"%s\"; Length = %d bytes;", obj->
ClassName(),
data->fDataLength);
itm = fListTree->AddItem(fBaseLTI, obj->
GetName(), obj, pic, pic);
fListTree->SetToolTipItem(itm, obj->
GetName());
} else {
sprintf(tmp,
"Received DND data: \"%s\"", (
char *)
data->fData);
if (img1 && img2) {
delete img2;
delete img1;
} else
itm = fListTree->AddItem(fBaseLTI, "Link...", ostr, pic, pic);
fListTree->SetToolTipItem(itm, (
const char *)
data->fData);
}
if (itm)
fStatus->ChangeText(tmp);
}
}
TObject *DNDMainFrame::GetObject(
const char *obj)
{
if (!strcmp(obj, "Graph")) {
if (fGraph == 0) {
for (
Int_t i = 0; i <
n; i++) {
y[i] = 10 *
sin(
x[i] + 0.2);
}
}
return fGraph;
} else if (!strcmp(obj, "1D Hist")) {
if (fHist1D == 0) {
fHist1D =
new TH1F(
"1D Hist",
"This is the px distribution", 100, -4, 4);
for (
Int_t i = 0; i < 10000; i++) {
fHist1D->Fill(px);
}
}
return fHist1D;
} else if (!strcmp(obj, "2D Hist")) {
if (fHist2D == 0) {
Double_t params[] = {130, -1.4, 1.8, 1.5, 1, 150, 2, 0.5, -2, 0.5, 3600, -2, 0.7, -3, 0.3};
TF2 *f2 =
new TF2(
"f2",
"xygaus + xygaus(5) + xylandau(10)", -4, 4, -4, 4);
fHist2D =
new TH2F(
"2D Hist",
"xygaus+xygaus(5)+xylandau(10)", 20, -4, 4, 20, -4, 4);
fHist2D->FillRandom("f2", 40000);
}
return fHist2D;
}
return 0;
}
void DNDMainFrame::HandleMenu(
Int_t menu_id)
{
switch (menu_id) {
case M_FILE_EXIT:
DoCloseWindow();
break;
case M_FILE_OPEN:
break;
case M_FILE_BROWSE:
break;
case M_FILE_NEWCANVAS:
break;
case M_FILE_CLOSEWIN: DoCloseWindow(); break;
case M_HELP_ABOUT:
break;
}
}
void DNDMainFrame::ResetStatus()
{
fStatus->SetTextColor(0x0000ff);
fStatus->ChangeText(gReadyMsg);
}
void drag_and_drop()
{
DNDMainFrame *mainWindow =
new DNDMainFrame(
gClient->GetRoot(), 700, 400);
mainWindow->MapWindow();
}
R__EXTERN TApplication * gApplication
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize MapSubwindows
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
virtual void Terminate(Int_t status=0)
Terminate the application by call TSystem::Exit() unless application has been told to return from Run...
Using a TBrowser one can browse all ROOT objects.
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Drag and drop data container.
virtual void SetParameters(const Double_t *params)
A 2-Dim function with parameters.
A frame containing two scrollbars (a horizontal and a vertical) and a viewport.
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
Add frame to the composite frame using the specified layout hints.
This class creates a file selection dialog.
const char ** fFileTypes
file types used to filter selectable files
char * fIniDir
on input: initial directory, on output: new directory
void SetIniDir(const char *inidir)
Set directory name.
A composite frame that layout their children in horizontal way.
TGHotString is a string with a "hot" character underlined.
This class handles GUI labels.
This class describes layout hints used by the layout classes.
void SetDNDSource(Bool_t onoff)
A list tree is a widget that can contain a number of items arranged in a tree structure.
Defines top level windows that interact with the system Window Manager.
The TGPicture class implements pictures and icons used in the different GUI elements and widgets.
Pixmap_t GetPicture() const
Yield an action as soon as it is clicked.
ROOT GUI Window base class.
A TGraph is an object made of two arrays X and Y with npoints each.
1-D histogram with a float per channel (see TH1 documentation)
2-D histogram with a float per channel (see TH1 documentation)
An abstract interface to image processing library.
static TImage * Open(const char *file, EImageFileTypes type=kUnknown)
Open a specified image file.
virtual void Scale(UInt_t, UInt_t)
virtual void Merge(const TImage *, const char *="alphablend", Int_t=0, Int_t=0)
virtual Pixmap_t GetPixmap()
virtual Pixmap_t GetMask()
const char * GetName() const override
Returns name of object.
Collectable string class.
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
This class creates a TGCanvas in which a TCanvas is created.
A TRootHelpDialog is used to display help text (or any text in a dialog window).
void SetText(const char *helpText)
Set help text from helpText buffer in TGTextView.
void Popup()
Show help dialog.
const char * Data() const
TString & Prepend(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
virtual const char * Getenv(const char *env)
Get environment variable.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
This static function calls a slot after a given time interval.
RVec< PromoteType< T > > sin(const RVec< T > &v)