mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
244 lines
5.5 KiB
C++
244 lines
5.5 KiB
C++
#include "CtrlLib.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
#define LLOG(x) // DLOG(x)
|
|
|
|
ToolTip::ToolTip()
|
|
{
|
|
SetFrame(BlackFrame());
|
|
}
|
|
|
|
Size ToolTip::GetMinSize() const
|
|
{
|
|
return AddFrameSize(GetSmartTextSize(text, StdFont(), GetWorkArea().GetWidth() / 2) + 4);
|
|
}
|
|
|
|
void ToolTip::Paint(Draw& w)
|
|
{
|
|
Size sz = GetSize();
|
|
w.DrawRect(sz, SColorInfo);
|
|
DrawSmartText(w, 2, 2, sz.cx - 4, text, StdFont(), SColorInfoText());
|
|
}
|
|
|
|
void ToolTip::PopUp(Ctrl *owner, Point p, bool effect)
|
|
{
|
|
LLOG("ToolTip::PopUp" << Desc(owner) << " @ " << p);
|
|
Rect r = GetMouseWorkArea();
|
|
Size sz = GetMinSize();
|
|
p.x = max(p.x + sz.cx > r.right ? r.right - sz.cx : p.x, r.left);
|
|
p.y = max(p.y + sz.cy > r.bottom ? r.bottom - sz.cy : p.y, r.top);
|
|
if(GUI_PopUpEffect() == GUIEFFECT_SLIDE && effect)
|
|
SetRect(p.x, p.y, sz.cx, 1);
|
|
else
|
|
SetRect(p.x, p.y, sz.cx, sz.cy);
|
|
Ctrl::PopUp(owner, true, false, true);
|
|
if(effect)
|
|
Animate(*this, p.x, p.y, sz.cx, sz.cy);
|
|
}
|
|
|
|
Ptr<Ctrl> tipctrl;
|
|
bool showmode;
|
|
|
|
ToolTip& AppToolTip()
|
|
{
|
|
static ToolTip tip;
|
|
return tip;
|
|
}
|
|
|
|
void CloseToolTip()
|
|
{
|
|
ToolTip& q = AppToolTip();
|
|
if(q.IsOpen()) {
|
|
LLOG("CLOSE: CloseToolTip");
|
|
q.Close();
|
|
}
|
|
}
|
|
|
|
void EndShowMode()
|
|
{
|
|
showmode = false;
|
|
}
|
|
|
|
void ShowToolTip()
|
|
{
|
|
LLOG("ShowToolTip");
|
|
CloseToolTip();
|
|
if(tipctrl) {
|
|
String text = tipctrl->GetTip();
|
|
LLOG("-> showing tip: " << text << " tipctrl: " << UPP::Name(tipctrl));
|
|
Ctrl *top = tipctrl->GetTopCtrl();
|
|
ToolTip& q = AppToolTip();
|
|
q.Set(text);
|
|
if(text.GetCount() && top && (top->IsForeground() || top->IsPopUp())) {
|
|
LLOG("-> foreground");
|
|
Size sz = q.GetMinSize();
|
|
Rect r = Ctrl::GetMouseWorkArea();
|
|
Point p = GetMousePos() + Size(0, 22);
|
|
if(p.y + sz.cy > r.bottom)
|
|
p = GetMousePos() - Size(0, 6) - sz.cy;
|
|
q.PopUp(top, p, !showmode);
|
|
showmode = true;
|
|
KillTimeCallback((void *)EndShowMode);
|
|
return;
|
|
}
|
|
LLOG("-> background / empty text, top = " << UPP::Name(top));
|
|
}
|
|
SetTimeCallback(500, callback(EndShowMode), (void *)EndShowMode);
|
|
}
|
|
|
|
void SyncToolTip(Ctrl *ctrl)
|
|
{
|
|
if(ctrl != tipctrl || ctrl && ctrl->GetTip() != AppToolTip().Get()) {
|
|
LLOG("ToolTipHook / ctrl change " << UPP::Name(ctrl) << " -> " << UPP::Name(ctrl));
|
|
tipctrl = ctrl;
|
|
KillTimeCallback((void *)SyncToolTip);
|
|
if(showmode)
|
|
ShowToolTip();
|
|
else {
|
|
LLOG("ToolTipHook -> SetTimeCallback");
|
|
SetTimeCallback(GUI_ToolTipDelay(), callback(ShowToolTip), (void *)SyncToolTip);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ToolTipHook(Ctrl *ctrl, bool inframe, int event, Point p, int zdelta, dword keyflags)
|
|
{
|
|
if(event == Ctrl::MOUSEMOVE && ctrl != &AppToolTip())
|
|
{
|
|
SyncToolTip(Ctrl::GetVisibleChild(ctrl, p, inframe));
|
|
LLOG("ToolTipHook MOUSEMOVE " << UPP::Name(ctrl) << " inframe: " << inframe);
|
|
}
|
|
if(event == Ctrl::MOUSELEAVE) {
|
|
LLOG("ToolTipHook MOUSELEAVE " << UPP::Name(ctrl));
|
|
CloseToolTip();
|
|
KillTimeCallback((void *)EndShowMode);
|
|
SetTimeCallback(1000, callback(EndShowMode), (void *)EndShowMode);
|
|
}
|
|
if((event & Ctrl::ACTION) == Ctrl::DOWN) {
|
|
LLOG("ToolTipHook DOWN");
|
|
CloseToolTip();
|
|
EndShowMode();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ToolTipStateHook(Ctrl *ctrl, int reason)
|
|
{
|
|
if((reason == Ctrl::CLOSE || reason == Ctrl::ENABLE || reason == Ctrl::DEACTIVATE)
|
|
&& ctrl != &AppToolTip() && AppToolTip().IsOpen()) {
|
|
LLOG("ToolTipStateHook -> close, reason: " << reason);
|
|
CloseToolTip();
|
|
EndShowMode();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
INITBLOCK {
|
|
LLOG("Ctrl::InstallMouseHook(ToolTipHook)");
|
|
Ctrl::InstallMouseHook(ToolTipHook);
|
|
Ctrl::InstallStateHook(ToolTipStateHook);
|
|
}
|
|
|
|
void LinkToolTipIn__() {} // "Call" from elsewhere to force linking this module in...
|
|
|
|
class QTFPopUp : public RichTextCtrl {
|
|
public:
|
|
virtual void Deactivate();
|
|
virtual void CancelMode();
|
|
|
|
protected:
|
|
int width;
|
|
int maxheight;
|
|
bool open;
|
|
|
|
void DoClose();
|
|
|
|
public:
|
|
void PopUp(Ctrl *parent);
|
|
|
|
QTFPopUp& Width(int _width) { width = _width; return *this; }
|
|
QTFPopUp& MaxHeight(int _maxheight) { maxheight = _maxheight; return *this; }
|
|
|
|
QTFPopUp();
|
|
};
|
|
|
|
void QTFPopUp::Deactivate() {
|
|
if(open)
|
|
DoClose();
|
|
}
|
|
|
|
void QTFPopUp::CancelMode() {
|
|
DoClose();
|
|
}
|
|
|
|
void QTFPopUp::DoClose() {
|
|
if(open) {
|
|
open = false;
|
|
Close();
|
|
}
|
|
}
|
|
|
|
void QTFPopUp::PopUp(Ctrl *parent) {
|
|
Close();
|
|
Rect r = Rect(0, 0, width, maxheight);
|
|
GetFrame().FrameLayout(r);
|
|
int cy = min(maxheight, GetHeight(r.Width()) + maxheight - r.Height());
|
|
Rect area = GetMouseWorkArea();
|
|
Point p = GetMousePos();
|
|
r.top = max(area.top, p.y + 16);
|
|
r.bottom = r.top + cy;
|
|
if(r.bottom > area.bottom) {
|
|
r.bottom = area.bottom;
|
|
r.top = r.bottom - cy;
|
|
}
|
|
r.left = max(area.left, p.x - width / 2);
|
|
r.right = r.left + width;
|
|
if(r.right > area.right) {
|
|
r.right = area.right;
|
|
r.left = r.right - width;
|
|
}
|
|
open = false;
|
|
SetRect(r);
|
|
Ctrl::PopUp(parent);
|
|
SetFocus();
|
|
open = true;
|
|
}
|
|
|
|
QTFPopUp::QTFPopUp() {
|
|
static ColorF helpborder[] = {
|
|
(ColorF)2,
|
|
&SColorText, &SColorText, &SColorText, &SColorText,
|
|
&SColorFace, &SColorFace, &SColorFace, &SColorFace,
|
|
};
|
|
static BorderFrame helpframe(helpborder);
|
|
width = 250;
|
|
maxheight = 150;
|
|
Margins(5).Background(LtYellow).SetFrame(helpframe);
|
|
open = false;
|
|
}
|
|
|
|
void PerformDescription()
|
|
{
|
|
Ctrl *top = Ctrl::GetActiveWindow();
|
|
if(!top) return;
|
|
Vector<Image> vi;
|
|
vi.Add(CtrlImg::HelpCursor0());
|
|
vi.Add(CtrlImg::HelpCursor1());
|
|
if(PointLoop(*top, vi, 300)) {
|
|
Point p = GetMousePos();
|
|
Ctrl *ctrl = Ctrl::GetVisibleChild(top, p - top->GetRect().TopLeft(), true);
|
|
while(ctrl) {
|
|
String desc = ctrl->GetDescription();
|
|
if(!IsEmpty(desc)) {
|
|
static QTFPopUp qtf;
|
|
qtf.SetQTF(desc);
|
|
qtf.PopUp(top);
|
|
return;
|
|
}
|
|
ctrl = ctrl->GetParent();
|
|
}
|
|
}
|
|
}
|
|
|
|
END_UPP_NAMESPACE
|