#include "TGToolTip.h"
#include "TGLabel.h"
#include "TGResourcePool.h"
#include "TTimer.h"
#include "TSystem.h"
#include "TVirtualPad.h"
#include "TBox.h"
ClassImp(TGToolTip)
class TTipDelayTimer : public TTimer {
private:
TGToolTip *fTip;
public:
TTipDelayTimer(TGToolTip *tip, Long_t ms) : TTimer(ms, kTRUE) { fTip = tip; }
Bool_t Notify();
};
Bool_t TTipDelayTimer::Notify()
{
fTip->HandleTimer(0);
Reset();
return kFALSE;
}
TGToolTip::TGToolTip(const TGWindow *p, const TGFrame *f, const char *text,
Long_t delayms)
: TGCompositeFrame(p, 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
{
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel = new TGLabel(this, text);
fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel->SetTextColor(fClient->GetResourcePool()->GetTipFgndColor());
AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
2, 3, 0, 0));
MapSubwindows();
Resize(GetDefaultSize());
fWindow = f;
fPad = 0;
fBox = 0;
fX = fY = -1;
fDelay = new TTipDelayTimer(this, delayms);
}
TGToolTip::TGToolTip(const TGWindow *p, const TBox *box, const char *text,
Long_t delayms)
: TGCompositeFrame(p, 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
{
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel = new TGLabel(this, text);
fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel->SetTextColor(fClient->GetResourcePool()->GetTipFgndColor());
AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
2, 3, 0, 0));
MapSubwindows();
Resize(GetDefaultSize());
fWindow = 0;
fPad = 0;
fBox = box;
fDelay = new TTipDelayTimer(this, delayms);
}
TGToolTip::TGToolTip(const TBox *box, const char *text,Long_t delayms)
: TGCompositeFrame(gClient->GetRoot(), 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
{
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel = new TGLabel(this, text);
fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel->SetTextColor(fClient->GetResourcePool()->GetTipFgndColor());
AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
2, 3, 0, 0));
MapSubwindows();
Resize(GetDefaultSize());
fWindow = 0;
fPad = 0;
fBox = box;
fDelay = new TTipDelayTimer(this, delayms);
}
TGToolTip::TGToolTip(Int_t x, Int_t y, const char *text, Long_t delayms)
: TGCompositeFrame(gClient->GetDefaultRoot(), 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
{
SetWindowAttributes_t attr;
attr.fMask = kWAOverrideRedirect | kWASaveUnder;
attr.fOverrideRedirect = kTRUE;
attr.fSaveUnder = kTRUE;
gVirtualX->ChangeWindowAttributes(fId, &attr);
SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel = new TGLabel(this, text);
fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
fLabel->SetTextColor(fClient->GetResourcePool()->GetTipFgndColor());
AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
2, 3, 0, 0));
MapSubwindows();
Resize(GetDefaultSize());
fWindow = 0;
fPad = 0;
fBox = 0;
fX = x;
fY = y;
fDelay = new TTipDelayTimer(this, delayms);
}
TGToolTip::~TGToolTip()
{
delete fDelay;
delete fLabel;
delete fL1;
}
void TGToolTip::DrawBorder()
{
gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
gVirtualX->DrawLine(fId, GetBlackGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
}
void TGToolTip::Show(Int_t x, Int_t y)
{
Move(x, y);
MapWindow();
RaiseWindow();
Long_t args[2];
args[0] = x;
args[1] = y;
Emit("Show(Int_t,Int_t)", args);
}
void TGToolTip::Hide()
{
UnmapWindow();
fDelay->Remove();
Emit("Hide()");
}
void TGToolTip::Reset()
{
fDelay->Reset();
gSystem->AddTimer(fDelay);
Emit("Reset()");
}
void TGToolTip::Reset(const TVirtualPad *parent)
{
fPad = parent;
fDelay->Reset();
gSystem->AddTimer(fDelay);
}
Bool_t TGToolTip::HandleTimer(TTimer *)
{
Int_t x = 0, y = 0, px1 = 0, px2 = 0, py1 = 0;
Window_t wtarget;
if (fWindow) {
gVirtualX->TranslateCoordinates(fWindow->GetId(), GetParent()->GetId(),
fX == -1 ? Int_t(fWindow->GetWidth() >> 1) : fX,
fY == -1 ? Int_t(fWindow->GetHeight()) : fY,
x, y, wtarget);
} else if(fPad) {
if (fBox) {
px1 = fPad->XtoAbsPixel(fBox->GetX1());
px2 = fPad->XtoAbsPixel(fBox->GetX2());
py1 = fPad->YtoAbsPixel(fBox->GetY1());
} else {
px1 = fPad->XtoAbsPixel(fPad->GetX1());
px2 = fPad->XtoAbsPixel(fPad->GetX2());
py1 = fPad->YtoAbsPixel(fPad->GetY1());
}
gVirtualX->TranslateCoordinates(gVirtualX->GetWindowID(fPad->GetCanvasID()),
GetParent()->GetId(),
px1 + ((px2-px1) >> 1), py1,
x, y, wtarget);
} else {
x = fX;
y = fY;
}
Int_t move = 0;
Window_t dum1, dum2;
UInt_t mask = 0;
Int_t mx, my;
UInt_t screenW = fClient->GetDisplayWidth();
UInt_t screenH = fClient->GetDisplayHeight();
gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(),
dum1, dum2, mx, my, mx, my, mask);
fLabel->SetWrapLength(-1);
Resize(GetDefaultSize());
if (fWidth > (screenW/2))
fLabel->SetWrapLength((screenW/2)-15);
Resize(GetDefaultSize());
if (x + fWidth > screenW) {
x = screenW - fWidth;
move += 1;
}
if (y+4 + GetHeight() > screenH) {
y = screenH - (fHeight + 25);
move += 2;
}
TGRectangle rect(x, y, x+fWidth, y+fHeight);
if (rect.Contains(mx, my)) {
if (move == 1) {
if (fWidth+15 < (UInt_t)mx)
x = mx - fWidth - 15;
else if (my + fHeight+15 < screenH)
y = my + 15;
else if (fHeight+15 < (UInt_t)my)
y = my - fHeight - 15;
}
else if (move == 2) {
if (mx + fWidth+15 < screenW)
x = mx + 15;
else if (fHeight+15 < (UInt_t)my)
y = my - fHeight - 15;
else if (fWidth+15 < (UInt_t)mx)
x = mx - fWidth - 15;
}
else {
if (my + fHeight+15 < screenH)
y = my + 15;
else if (mx + fWidth+15 < screenW)
x = mx + 15;
else if (fWidth+15 < (UInt_t)mx)
x = mx - fWidth - 15;
else if (fHeight+15 < (UInt_t)my)
y = my - fHeight - 15;
}
}
Show(x, y+4);
fDelay->Remove();
return kTRUE;
}
void TGToolTip::SetText(const char *new_text)
{
fLabel->SetText(new TGString(new_text));
Resize(GetDefaultSize());
}
void TGToolTip::SetDelay(Long_t delayms)
{
fDelay->SetTime(delayms);
}
void TGToolTip::SetPosition(Int_t x, Int_t y)
{
fX = x;
fY = y;
if (fX < -1)
fX = 0;
if (fY < -1)
fY = 0;
if (fWindow) {
if (fX > (Int_t) fWindow->GetWidth())
fX = fWindow->GetWidth();
if (fY > (Int_t) fWindow->GetHeight())
fY = fWindow->GetHeight();
}
}
const TGString *TGToolTip::GetText() const
{
return fLabel->GetText();
}