// @(#)root/gui:$Name: $:$Id: TGDockableFrame.cxx,v 1.9 2005/06/09 17:44:40 brun Exp $
// Author: Abdelhalim Ssadik 07/07/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. *
*************************************************************************/
/**************************************************************************
This source is based on Xclass95, a Win95-looking GUI toolkit.
Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
Xclass95 is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
**************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// A TGDockableFrame is a frame with handles that allow it to be //
// undocked (i.e. put in a transient frame of its own) and to be docked //
// again or hidden and shown again. It uses the TGDockButton, which is //
// a button with two vertical bars (||) and TGDockHideButton, which is //
// a button with a small triangle. The TGUndockedFrame is a transient //
// frame that on closure will put the frame back in the dock. //
// //
//////////////////////////////////////////////////////////////////////////
#include "TColor.h"
#include "TGFrame.h"
#include "TMessage.h"
#include "TGWidget.h"
#include "TGButton.h"
#include "TGDockableFrame.h"
#include "TGWindow.h"
#include "TVirtualX.h"
#include "Riostream.h"
ClassImp(TGDockButton)
ClassImp(TGDockHideButton)
ClassImp(TGUndockedFrame)
ClassImp(TGDockableFrame)
//______________________________________________________________________________
TGDockButton::TGDockButton(const TGCompositeFrame *p, int id) :
TGButton (p, id, GetDefaultGC()(), kChildFrame)
{
// Create a dock button (i.e. button with two vertical bars).
fWidgetFlags = kWidgetIsEnabled;
fMouseOn = kFALSE;
Resize(10, GetDefaultHeight());
fNormBg = fBackground;
Float_t r, g, b, h, l, s;
TColor::Pixel2RGB(fNormBg, r, g, b);
TColor::RGB2HLS(r, g, b, h, l, s);
l = l + (1. - l) * 45. / 100.;
TColor::HLS2RGB(h, l, s, r, g, b);
fHiBg = TColor::RGB2Pixel(r, g, b);
AddInput(kEnterWindowMask | kLeaveWindowMask);
SetWindowName();
}
//______________________________________________________________________________
TGDockButton::~TGDockButton()
{
// Delete dock button.
fClient->FreeColor(fHiBg);
}
//______________________________________________________________________________
Bool_t TGDockButton::HandleCrossing(Event_t *event)
{
// Handle dock button crossing events.
TGButton::HandleCrossing(event);
if (event->fType == kLeaveNotify) {
fMouseOn = kFALSE;
} else if (event->fType == kEnterNotify) {
fMouseOn = kTRUE;
}
if (IsEnabled())
fClient->NeedRedraw(this);
return kTRUE;
}
//______________________________________________________________________________
void TGDockButton::DrawBorder()
{
// Draw borders of dock button.
int options = GetOptions();
if (fState == kButtonDown || fState == kButtonEngaged)
;
else if (fMouseOn == kTRUE && IsEnabled()) {
SetBackgroundColor(fHiBg);
ChangeOptions(kChildFrame);
} else {
SetBackgroundColor(fNormBg);
ChangeOptions(kChildFrame);
}
gVirtualX->ClearWindow(fId);
TGFrame::DrawBorder();
ChangeOptions(options);
}
//______________________________________________________________________________
void TGDockButton::DoRedraw()
{
// Draw the dock button, i.e. two vertical lines.
int x = 1, y = 0;
DrawBorder();
if (fState == kButtonDown || fState == kButtonEngaged) { ++x; ++y; }
for (int i = 0; i < 5; i +=4) {
gVirtualX->DrawLine(fId, GetHilightGC()(), i+x, y+1, i+x, fHeight-y-3);
gVirtualX->DrawLine(fId, GetShadowGC()(), i+x+1, y+1, i+x+1, fHeight-y-3);
}
}
//______________________________________________________________________________
TGDockHideButton::TGDockHideButton(const TGCompositeFrame *p) :
TGDockButton (p, 2)
{
// Create a dock hide button (i.e. button with small triangle).
Resize(10, 8);
fAspectRatio = 0;
SetWindowName();
}
//______________________________________________________________________________
void TGDockHideButton::DoRedraw()
{
// Draw dock hide button.
int x = 1, y = 0;
DrawBorder();
if (fState == kButtonDown || fState == kButtonEngaged) { ++x; ++y; }
if (fAspectRatio) {
gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+1, x+5, y+3);
gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+5, x+5, y+3);
gVirtualX->DrawLine(fId, GetHilightGC()(), x, y+1, x, y+5);
} else {
gVirtualX->DrawLine(fId, GetHilightGC()(), x+5, y+1, x+1, y+3);
gVirtualX->DrawLine(fId, GetHilightGC()(), x+5, y+5, x+1, y+3);
gVirtualX->DrawLine(fId, GetBlackGC()(), x+6, y+1, x+6, y+5);
}
}
//______________________________________________________________________________
TGUndockedFrame::TGUndockedFrame(const TGWindow *p, TGDockableFrame *dockable) :
TGTransientFrame(p, dockable->GetMainFrame(), 10, 10)
{
// Create the undocked (transient) frame.
SetWindowName("");
fDockable = dockable;
SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
kMWMDecorMinimize | kMWMDecorMenu,
kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
kMWMFuncMinimize,
kMWMInputModeless);
SetWindowName();
}
//______________________________________________________________________________
TGUndockedFrame::~TGUndockedFrame()
{
// Delete undocked frame. Puts back dockable frame in its original container.
if (fDockable && !fDockable->fDeleted) {
fDockable->DockContainer(kFALSE);
}
}
//______________________________________________________________________________
void TGUndockedFrame::FixSize()
{
// Fix the size of the undocked frame so it cannot be changed via the WM.
SetWMSize(fWidth, fHeight);
SetWMSizeHints(fWidth, fHeight, fWidth, fHeight, 0, 0);
}
//______________________________________________________________________________
void TGUndockedFrame::CloseWindow()
{
// Close undocked frame (called via WM close button).
DeleteWindow();
}
//______________________________________________________________________________
TGDockableFrame::TGDockableFrame(const TGWindow *p, int id, UInt_t /*options*/)
: TGCompositeFrame(p, 10, 10, kHorizontalFrame), TGWidget(id)
{
// Create a dockable frame widget.
fMsgWindow = fParent;
fCl = new TGLayoutHints(kLHintsExpandY | kLHintsExpandX);
TGLayoutHints *l1 = new TGLayoutHints(kLHintsTop | kLHintsLeft);
TGLayoutHints *l2 = new TGLayoutHints(kLHintsExpandY | kLHintsLeft);
TGLayoutHints *lb = new TGLayoutHints(kLHintsExpandY | kLHintsLeft, 0, 2, 0, 0);
TGLayoutHints *lc = new TGLayoutHints(kLHintsExpandY | kLHintsExpandX);
fButtons = new TGCompositeFrame(this, 10, 10, kVerticalFrame);
fButtons->SetCleanup();
fHideButton = new TGDockHideButton(fButtons);
fButtons->AddFrame(fHideButton, l1);
fDockButton = new TGDockButton(fButtons);
fButtons->AddFrame(fDockButton, l2);
TGCompositeFrame::AddFrame(fButtons, lb);
fContainer = new TGCompositeFrame(this, 10, 10);
TGCompositeFrame::AddFrame(fContainer, lc);
fEnableHide = kTRUE;
fEnableUndock = kTRUE;
fHidden = kFALSE;
fFrame = 0;
fDeleted = kFALSE;
fDockButton->Associate(this);
fHideButton->Associate(this);
MapSubwindows();
Resize(GetDefaultSize());
TGFrame::SetWindowName();
}
//______________________________________________________________________________
TGDockableFrame::~TGDockableFrame()
{
// Cleanup dockable frame.
if (fFrame) {
fDeleted = kTRUE;
delete fFrame;
} else {
delete fContainer;
}
delete fCl;
delete fButtons;
}
//______________________________________________________________________________
void TGDockableFrame::AddFrame(TGFrame *f, TGLayoutHints *hints)
{
// Add frame to dockable frame container. Frame and hints are NOT adopted.
f->ReparentWindow(fContainer);
fContainer->AddFrame(f, fHints = hints);
fContainer->Layout();
}
//______________________________________________________________________________
void TGDockableFrame::UndockContainer()
{
// Undock container.
int ax, ay;
Window_t wdummy;
if (fFrame || !fEnableUndock) return;
fFrame = new TGUndockedFrame(fClient->GetDefaultRoot(), this);
fFrame->SetEditDisabled();
RemoveFrame(fContainer);
fContainer->ReparentWindow(fFrame);
fFrame->AddFrame(fContainer, fCl); // fHints
gVirtualX->TranslateCoordinates(GetId(), fClient->GetDefaultRoot()->GetId(), fX,
fY + fFrame->GetHeight(), ax, ay, wdummy);
if (fDockName) fFrame->SetWindowName(fDockName);
fFrame->MapSubwindows();
fFrame->Resize(fFrame->GetDefaultSize());
fFrame->FixSize();
fFrame->Move(ax, ay);
fFrame->SetWMPosition(ax, ay);
fFrame->MapWindow();
if (((TGFrame *)fParent)->IsComposite()) // paranoia check
((TGCompositeFrame *)fParent)->HideFrame(this);
Layout();
SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_UNDOCK), fWidgetId, 0);
Undocked();
}
//______________________________________________________________________________
void TGDockableFrame::DockContainer(Int_t del)
{
// Dock container back to TGDockableFrame.
if (!fFrame) return;
if (del) {
delete fFrame; // this will call DockContainer again with del = kFALSE
return;
}
fFrame->RemoveFrame(fContainer);
fContainer->ReparentWindow(this);
TGCompositeFrame::AddFrame(fContainer, fCl); // fHints
// kludge! (for special case)
fDockButton->Resize(fDockButton->GetDefaultWidth(), 1);
Layout();
if (((TGFrame *)fParent)->IsComposite()) // paranoia check
((TGCompositeFrame *)fParent)->ShowFrame(this);
// fFrame is just being deleted (we're here called by TGUndockedFrame's
// destructor) so just set it NULL below to avoid eventual problems in
// TGDockableFrame's destructor.
fFrame = 0;
SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_DOCK), fWidgetId, 0);
Docked();
}
//______________________________________________________________________________
void TGDockableFrame::ShowContainer()
{
// Show dock container.
if (!fHidden) return;
ShowFrame(fContainer);
if (fEnableUndock) fButtons->ShowFrame(fDockButton);
fHideButton->SetAspectRatio(0);
if (((TGFrame *)fParent)->IsComposite()) // paranoia check
((TGCompositeFrame *)fParent)->Layout();
fHidden = kFALSE;
SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_SHOW), fWidgetId, 0);
}
//______________________________________________________________________________
void TGDockableFrame::HideContainer()
{
// Hide dock container.
if (fHidden || !fEnableHide) return;
HideFrame(fContainer);
fButtons->HideFrame(fDockButton);
fHideButton->SetAspectRatio(1);
if (((TGFrame *)fParent)->IsComposite()) // paranoia check
((TGCompositeFrame *)fParent)->Layout();
fHidden = kTRUE;
SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_HIDE),fWidgetId, 0);
}
//______________________________________________________________________________
Bool_t TGDockableFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
{
// Process dockable frame messages.
switch (GET_MSG(msg)) {
case kC_COMMAND:
switch (GET_SUBMSG(msg)) {
case kCM_BUTTON:
switch (parm1) {
case 1:
if (!fHidden) UndockContainer();
break;
case 2:
if (!fHidden)
HideContainer();
else
ShowContainer();
break;
}
break;
}
break;
}
return kTRUE;
}
//______________________________________________________________________________
void TGDockableFrame::EnableUndock(Bool_t onoff)
{
// Enable undocking.
fEnableUndock = onoff;
if (onoff)
fButtons->ShowFrame(fDockButton);
else
fButtons->HideFrame(fDockButton);
Layout();
}
//______________________________________________________________________________
void TGDockableFrame::EnableHide(Bool_t onoff)
{
// Enable hiding.
fEnableHide = onoff;
if (onoff)
fButtons->ShowFrame(fHideButton);
else
fButtons->HideFrame(fHideButton);
Layout();
}
//______________________________________________________________________________
void TGDockableFrame::SetWindowName(const char *name)
{
// Set window name so it appear as title of the undock window.
fDockName = "";
if (name) {
fDockName = name;
if (fFrame) fFrame->SetWindowName(fDockName);
}
}
//______________________________________________________________________________
void TGDockableFrame::SavePrimitive(ofstream &out, Option_t *option)
{
// Save a dockable frame widget as a C++ statement(s) on output stream out.
char quote = '"';
out << endl << " // dockable frame" << endl;
out << " TGDockableFrame *";
out << GetName()<<" = new TGDockableFrame(" << fParent->GetName();
if (GetOptions() == kHorizontalFrame) {
if (fWidgetId == -1) {
out << ");" << endl;
} else {
out << "," << fWidgetId << ");" << endl;
}
} else {
out << "," << fWidgetId << "," << GetOptionString() << ");" << endl;
}
out << " TGCompositeFrame *" << GetContainer()->GetName() << " = "
<< GetName() << "->GetContainer();" << endl;
TGFrameElement *el;
TIter next(GetContainer()->GetList());
while ((el = (TGFrameElement *) next())) {
el->fFrame->SavePrimitive(out, option);
out << " " << GetName() << "->AddFrame(" << el->fFrame->GetName();
el->fLayout->SavePrimitive(out, option);
out << ");"<< endl;
}
out << endl << " // next lines belong to the dockable frame widget" << endl;
if (EnableUndock())
out << " " << GetName() << "->EnableUndock(kTRUE);" << endl;
else
out << " " << GetName() << "->EnableUndock(kFALSE);" << endl;
if (EnableHide())
out << " " << GetName() << "->EnableHide(kTRUE);" << endl;
else
out << " " << GetName() << "->EnableHide(kFALSE);" << endl;
if (fDockName != "")
out << " " << GetName() << "->SetWindowName(" << quote << fDockName
<< quote << ");" << endl;
if (IsUndocked())
out << " " << GetName() << "->UndockContainer();" << endl;
else
out << " " << GetName() << "->DockContainer();" << endl;
if (IsHidden())
out << " " << GetName() << "->HideContainer();" << endl;
out << endl;
}
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.