/*
<img src="gif/TGedEditor.gif">
*/
//End_Html
#include "TGedEditor.h"
#include "TCanvas.h"
#include "TGCanvas.h"
#include "TGTab.h"
#include "TGedFrame.h"
#include "TGLabel.h"
#include "TROOT.h"
#include "TClass.h"
#include "TBaseClass.h"
class TGedTabInfo : public TObject {
public:
TGTabElement *fElement;
TGCompositeFrame *fContainer;
TGedTabInfo(TGTabElement* el, TGCompositeFrame* f) :
fElement(el), fContainer(f) {}
};
ClassImp(TGedEditor)
TGedEditor* TGedEditor::fgFrameCreator = 0;
TGedEditor* TGedEditor::GetFrameCreator()
{
return fgFrameCreator;
}
void TGedEditor::SetFrameCreator(TGedEditor* e)
{
fgFrameCreator = e;
}
TGedEditor::TGedEditor(TCanvas* canvas, UInt_t width, UInt_t height) :
TGMainFrame(gClient->GetRoot(), width, height),
fCan (0),
fTab (0),
fTabContainer (0),
fModel (0),
fPad (0),
fCanvas (0),
fClass (0),
fGlobal (kTRUE)
{
fCan = new TGCanvas(this, 170, 10, kFixedWidth);
AddFrame(fCan, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
fTab = new TGTab(fCan->GetViewPort(), 10, 10);
fTab->Associate(fCan);
fTab->SetCleanup(kDeepCleanup);
fCan->SetContainer(fTab);
fTabContainer = GetEditorTab("Style");
gROOT->GetListOfCleanups()->Add(this);
SetCanvas(canvas);
if (fCanvas) {
UInt_t ch = fCanvas->GetWindowHeight();
if (ch)
Resize(GetWidth(), ch > 700 ? 700 : ch);
else
Resize(GetWidth(), fCanvas->GetWh()<450 ? 450 : fCanvas->GetWh() + 4);
} else {
Resize(width, height);
}
MapSubwindows();
MapWindow();
}
TGedEditor::~TGedEditor()
{
Hide();
if(fGlobal){
TQObject::Disconnect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)");
TQObject::Disconnect("TCanvas", "Closed()");
}
TIter next(fFrameMap.GetTable());
TPair* pair;
while ((pair = (TPair*) next())) {
if (pair->Value() != 0) {
TGedFrame* frame = (TGedFrame*) pair->Value();
delete frame;
}
}
TGedTabInfo* ti;
TIter it1(&fCreatedTabs);
while ((ti = (TGedTabInfo*) it1())) {
fTab->AddFrame(ti->fElement,0);
fTab->AddFrame(ti->fContainer,0);
}
delete fTab;
delete ((TGFrameElement*)fList->First())->fLayout;
delete fCan;
}
void TGedEditor::Update(TGedFrame* )
{
if (fPad) {
fPad->Modified();
fPad->Update();
}
}
TGCompositeFrame* TGedEditor::GetEditorTab(const char* name)
{
return GetEditorTabInfo(name)->fContainer;
}
TGedTabInfo* TGedEditor::GetEditorTabInfo(const char* name)
{
if ( ! fCreatedTabs.IsEmpty()) {
TIter next(&fCreatedTabs);
TGedTabInfo* ti;
while ((ti = (TGedTabInfo *) next())) {
if (*ti->fElement->GetText() == name)
return ti;
}
}
TGCompositeFrame* tc = fTab->AddTab(new TGString(name));
TGTabElement *te = fTab->GetTabTab(fTab->GetNumberOfTabs() - 1);
fTab->RemoveFrame(tc);
fTab->RemoveFrame(te);
TGedFrame* nf = CreateNameFrame(tc, name);
nf->SetGedEditor(this);
nf->SetModelClass(0);
tc->AddFrame(nf, nf->GetLayoutHints());
TGedTabInfo* ti = new TGedTabInfo(te, tc);
fCreatedTabs.Add(ti);
return ti;
}
void TGedEditor::CloseWindow()
{
Hide();
}
void TGedEditor::ReinitWorkspace()
{
TIter next(&fVisibleTabs);
TGedTabInfo* ti;
while ((ti = (TGedTabInfo*)next())) {
TGTabElement *te = ti->fElement;
TGCompositeFrame *tc = ti->fContainer;
fTab->RemoveFrame(te);
fTab->RemoveFrame(tc);
TIter frames(tc->GetList());
frames();
TGFrameElement* fr;
while ((fr = (TGFrameElement *) frames()) != 0) {
TGFrame *f = fr->fFrame;
tc->RemoveFrame(f);
f->UnmapWindow();
te->UnmapWindow();
tc->UnmapWindow();
}
fVisibleTabs.Remove(ti);
}
}
void TGedEditor::SetGlobal(Bool_t global)
{
fGlobal = global;
if (fGlobal) {
TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
"TGedEditor", this, "GlobalSetModel(TVirtualPad *, TObject *, Int_t)");
TQObject::Connect("TCanvas", "Closed()",
"TGedEditor", this, "GlobalClosed()");
}
}
void TGedEditor::GlobalClosed()
{
if (gROOT->GetListOfCanvases()->IsEmpty())
TVirtualPadEditor::Terminate();
}
void TGedEditor::GlobalSetModel(TVirtualPad *pad, TObject * obj, Int_t ev)
{
if ((ev != kButton1Down) || !IsMapped() ||
(obj && obj->InheritsFrom("TColorWheel")))
return;
TCanvas* can = pad->GetCanvas();
if (can == fCanvas || can->GetShowEditor())
return;
Show();
}
void TGedEditor::ConnectToCanvas(TCanvas *c)
{
c->Connect("Selected(TVirtualPad*,TObject*,Int_t)", "TGedEditor",
this, "SetModel(TVirtualPad*,TObject*,Int_t)");
}
void TGedEditor::DisconnectFromCanvas()
{
if (fCanvas)
Disconnect(fCanvas, "Selected(TVirtualPad*,TObject*,Int_t)", this, "SetModel(TVirtualPad*,TObject*,Int_t)");
}
void TGedEditor::SetCanvas(TCanvas *newcan)
{
if (!newcan || (fCanvas == newcan)) return;
DisconnectFromCanvas();
fCanvas = newcan;
SetWindowName(Form("%s_Editor", fCanvas->GetName()));
fPad = fCanvas->GetSelectedPad();
if (fPad == 0) fPad = fCanvas;
ConnectToCanvas(fCanvas);
}
void TGedEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t event)
{
if ((event != kButton1Down) || (obj && obj->InheritsFrom("TColorWheel")))
return;
if (gPad) gPad->GetVirtCanvas()->SetCursor(kWatch);
gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
fPad = pad;
if (obj == 0) obj = fPad;
TGTabElement* seltab = fTab->GetCurrentTab();
Bool_t mapTabs = kFALSE;
if (fModel != obj) {
fModel = obj;
if (fModel == 0 || fModel->IsA() != fClass) {
ReinitWorkspace();
mapTabs = kTRUE;
fVisibleTabs.Add(fCreatedTabs.First());
if (fModel) {
fClass = fModel->IsA();
ActivateEditor(fClass, kTRUE);
} else {
fClass = 0;
}
TGedFrame* gfr;
TIter ngf(&fGedFrames);
while ((gfr = (TGedFrame*) ngf()))
fTabContainer->AddFrame(gfr, gfr->GetLayoutHints());
fExclMap.Clear();
fGedFrames.Clear();
TIter next(&fVisibleTabs);
TGedTabInfo* ti;
while ((ti = (TGedTabInfo *) next())) {
fTab->AddFrame(ti->fElement,0);
fTab->AddFrame(ti->fContainer,0);
}
}
ConfigureGedFrames(kTRUE);
} else {
ConfigureGedFrames(kFALSE);
}
if (mapTabs) {
TGedTabInfo* ti;
TIter next(&fVisibleTabs);
while ((ti = (TGedTabInfo *) next())) {
ti->fElement->MapWindow();
ti->fContainer->MapWindow();
}
if (seltab == 0 || fTab->SetTab(seltab->GetString(), kFALSE) == kFALSE)
fTab->SetTab(0, kFALSE);
}
if (fGlobal)
Layout();
else
((TGMainFrame*)GetMainFrame())->Layout();
if (gPad) gPad->GetVirtCanvas()->SetCursor(kPointer);
gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
}
void TGedEditor::Show()
{
SetCanvas(gPad->GetCanvas());
if (fGlobal) {
SetModel(fCanvas->GetClickSelectedPad(), fCanvas->GetClickSelected(), kButton1Down);
if (fCanvas->GetShowEditor())
fCanvas->ToggleEditor();
UInt_t dw = fClient->GetDisplayWidth();
UInt_t cw = fCanvas->GetWindowWidth();
UInt_t ch = fCanvas->GetWindowHeight();
UInt_t cx = (UInt_t)fCanvas->GetWindowTopX();
UInt_t cy = (UInt_t)fCanvas->GetWindowTopY();
if (!ch)
cy = cy + 20;
Int_t gedx = 0, gedy = 0;
if (cw + GetWidth() > dw) {
gedx = cx + cw - GetWidth();
gedy = ch - GetHeight();
} else {
if (cx > GetWidth())
gedx = cx - GetWidth() - 20;
else
gedx = cx + cw + 10;
gedy = cy - 20;
}
MoveResize(gedx, gedy, GetWidth(), ch > 700 ? 700 : ch);
SetWMPosition(gedx, gedy);
} else {
SetModel(fCanvas, fCanvas, kButton1Down);
}
MapWindow();
gVirtualX->RaiseWindow(GetId());
if (!gROOT->GetListOfCleanups()->FindObject(this))
gROOT->GetListOfCleanups()->Add(this);
}
void TGedEditor::Hide()
{
UnmapWindow();
ReinitWorkspace();
fModel = 0; fClass = 0;
DisconnectFromCanvas();
fCanvas = 0; fPad = 0;
gROOT->GetListOfCleanups()->Remove(this);
}
void TGedEditor::RecursiveRemove(TObject* obj)
{
if (obj == fPad) {
SetModel(fCanvas, fCanvas, kButton1Down);
return;
}
if (obj == fModel) {
SetModel(fPad, fPad, kButton1Down);
return;
}
}
void TGedEditor::ActivateEditor(TClass* cl, Bool_t recurse)
{
TPair *pair = (TPair*) fFrameMap.FindObject(cl);
TClass *edClass = 0;
TGedFrame *frame = 0;
if (pair == 0) {
edClass = TClass::GetClass(Form("%sEditor", cl->GetName()));
if (edClass && edClass->InheritsFrom(TGedFrame::Class())) {
TGWindow *exroot = (TGWindow*) fClient->GetRoot();
fClient->SetRoot(fTabContainer);
fgFrameCreator = this;
frame = reinterpret_cast<TGedFrame*>(edClass->New());
frame->SetModelClass(cl);
fgFrameCreator = 0;
fClient->SetRoot(exroot);
}
fFrameMap.Add(cl, frame);
} else {
frame = (TGedFrame*)pair->Value();
}
Bool_t exclfr = kFALSE;
Bool_t exclbases = kFALSE;
if (frame) {
TPair* exclpair = (TPair*) fExclMap.FindObject(cl);
if (exclpair) {
exclfr = kTRUE;
exclbases = (exclpair->Value() != 0);
}
if (!exclfr && frame->AcceptModel(fModel)){
if (frame->GetExtraTabs()) {
TIter next(frame->GetExtraTabs());
TGedFrame::TGedSubFrame* subf;
while ((subf = (TGedFrame::TGedSubFrame*)next())) {
TGedTabInfo* ti = GetEditorTabInfo(subf->fName);
ti->fContainer->AddFrame(subf->fFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
if (fVisibleTabs.FindObject(ti) == 0)
fVisibleTabs.Add(ti);
}
}
InsertGedFrame(frame);
}
}
if (recurse && !exclbases) {
if (frame)
frame->ActivateBaseClassEditors(cl);
else
ActivateEditors(cl->GetListOfBases(), recurse);
}
}
void TGedEditor::ActivateEditors(TList* bcl, Bool_t recurse)
{
TBaseClass *base;
TIter next(bcl);
while ((base = (TBaseClass*) next())) {
ActivateEditor(base->GetClassPointer(), recurse);
}
}
void TGedEditor::ExcludeClassEditor(TClass* cl, Bool_t recurse)
{
TPair* pair = (TPair*) fExclMap.FindObject(cl);
if (pair) {
if (recurse && pair->Value() == 0)
pair->SetValue((TObject*)(Long_t)1);
} else {
fExclMap.Add(cl, (TObject*)(Long_t)(recurse ? 1 : 0));
}
}
void TGedEditor::InsertGedFrame(TGedFrame* f)
{
TObjLink* lnk = fGedFrames.FirstLink();
if (lnk == 0) {
fGedFrames.Add(f);
return;
}
TGedFrame* cf;
while (lnk) {
cf = (TGedFrame*) lnk->GetObject();
if (f->GetPriority() < cf->GetPriority()) {
fGedFrames.AddBefore(lnk, f);
return;
}
lnk = lnk->Next();
}
fGedFrames.Add(f);
}
void TGedEditor::ConfigureGedFrames(Bool_t objChanged)
{
TGFrameElement *el;
TIter vistabs(&fVisibleTabs);
vistabs();
TGedTabInfo* ti;
while ((ti = (TGedTabInfo *) vistabs())) {
TIter fr(ti->fContainer->GetList());
el = (TGFrameElement*) fr();
((TGedFrame*) el->fFrame)->SetModel(fModel);
if(objChanged) {
do {
el->fFrame->MapSubwindows();
el->fFrame->Layout();
el->fFrame->MapWindow();
} while((el = (TGFrameElement *) fr()));
}
ti->fContainer->Layout();
}
TIter next(fTabContainer->GetList());
while ((el = (TGFrameElement *) next())) {
if ((el->fFrame)->InheritsFrom(TGedFrame::Class())) {
if (objChanged) {
el->fFrame->MapSubwindows();
((TGedFrame *)(el->fFrame))->SetModel(fModel);
el->fFrame->Layout();
el->fFrame->MapWindow();
} else {
((TGedFrame *)(el->fFrame))->SetModel(fModel);
}
}
}
fTabContainer->Layout();
}
TGedFrame* TGedEditor::CreateNameFrame(const TGWindow* parent, const char* )
{
return new TGedNameFrame(parent);
}
void TGedEditor::PrintFrameStat()
{
printf("TGedEditor::PrintFrameStat()\n");
Int_t sum = 0;
TIter next(fFrameMap.GetTable());
TPair* pair;
while ((pair = (TPair*) next())) {
if (pair->Value() != 0) {
TClass* cl = (TClass*) pair->Key();
printf("TGedFrame created for %s \n", cl->GetName());
sum ++;
}
}
printf("SUMMARY: %d editors stored in the local map.\n", sum);
}