mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
160 lines
3.8 KiB
C++
160 lines
3.8 KiB
C++
#include "CtrlLib.h"
|
|
|
|
namespace Upp {
|
|
|
|
Rect DisplayPopup::screen_rect;
|
|
Ptr<Ctrl> DisplayPopup::ctrl;
|
|
Ptr<DisplayPopup> DisplayPopup::owner;
|
|
Rect DisplayPopup::item;
|
|
Value DisplayPopup::value;
|
|
Color DisplayPopup::paper;
|
|
Color DisplayPopup::ink;
|
|
dword DisplayPopup::style;
|
|
const Display *DisplayPopup::display;
|
|
int DisplayPopup::margin;
|
|
bool DisplayPopup::usedisplaystdsize_s;
|
|
|
|
DisplayPopup::DisplayPopup()
|
|
{
|
|
ONCELOCK {
|
|
Ctrl::InstallStateHook(StateHook);
|
|
Ctrl::InstallMouseHook(MouseHook);
|
|
Ctrl::InstallPaintHook(PaintHook);
|
|
}
|
|
}
|
|
|
|
void DisplayPopup::PaintHook(Ctrl *tw, Draw& w, const Rect& clip)
|
|
{
|
|
if(ctrl && tw && !IsNull(screen_rect) && ctrl->HasMouseDeep() &&
|
|
(tw == ctrl->GetTopCtrl() || tw == ctrl->GetTopCtrl()->GetOwner())) {
|
|
Rect r = screen_rect - tw->GetScreenRect().TopLeft();
|
|
DrawFrame(w, r, SBlack());
|
|
r.Deflate(1, 1);
|
|
w.Clip(r);
|
|
w.DrawRect(r, SColorPaper);
|
|
if(display) {
|
|
display->PaintBackground(w, r, value, ink, paper, style);
|
|
r.left += margin;
|
|
if(usedisplaystdsize_s)
|
|
r.top += (r.Height() - display->GetStdSize(value).cy) / 2;
|
|
display->Paint(w, r, value, ink, paper, style);
|
|
}
|
|
w.End();
|
|
}
|
|
}
|
|
|
|
Rect DisplayPopup::Check(Ctrl *ctrl, const Rect& item, const Value& value, const Display *display, int margin)
|
|
{
|
|
if(display && ctrl && !ctrl->IsDragAndDropTarget() && !(GetMouseLeft() || GetMouseRight() || GetMouseMiddle())) {
|
|
Ctrl *top = ctrl->GetTopCtrl();
|
|
if(top && top->HasFocusDeep()) {
|
|
Size sz = display->GetStdSize(value);
|
|
if(sz.cx + 2 * margin > item.GetWidth() || sz.cy > item.GetHeight()) {
|
|
Rect vw = ctrl->GetScreenView();
|
|
Rect r = (item + vw.TopLeft()) & vw;
|
|
if(r.Contains(GetMousePos()))
|
|
return r;
|
|
}
|
|
}
|
|
}
|
|
return Null;
|
|
}
|
|
|
|
void DisplayPopup::RefreshRect()
|
|
{
|
|
if(ctrl && !IsNull(screen_rect)) {
|
|
Ctrl *top = ctrl->GetTopCtrl();
|
|
top->RefreshFrame(screen_rect - top->GetScreenRect().TopLeft());
|
|
Ctrl *owner = top->GetOwner();
|
|
if(owner)
|
|
owner->RefreshFrame(screen_rect - owner->GetScreenRect().TopLeft());
|
|
}
|
|
}
|
|
|
|
void DisplayPopup::Sync()
|
|
{
|
|
Rect r = Check(ctrl, item, value, display, margin);
|
|
RefreshRect();
|
|
if(IsNull(r))
|
|
screen_rect = Null;
|
|
else {
|
|
Ctrl *top = ctrl->GetTopCtrl();
|
|
Size sz = display->GetStdSize(value);
|
|
Rect wa = top->GetScreenRect();
|
|
r.right = min(wa.right, r.left + sz.cx + 2 * margin);
|
|
if(wa.bottom < r.top + sz.cy)
|
|
return;
|
|
r.bottom = max(r.bottom, r.top + sz.cy);
|
|
Ctrl *owner = top->GetOwner();
|
|
if(owner) {
|
|
Rect owa = owner->GetScreenRect();
|
|
if(owa.bottom >= r.bottom)
|
|
r.right = min(max(wa.right, owa.right), r.left + sz.cx + 2 * margin);
|
|
}
|
|
screen_rect = r.Inflated(1, 1);
|
|
RefreshRect();
|
|
}
|
|
}
|
|
|
|
bool DisplayPopup::StateHook(Ctrl *, int reason)
|
|
{
|
|
if(reason == Ctrl::FOCUS)
|
|
Sync();
|
|
return false;
|
|
}
|
|
|
|
|
|
bool DisplayPopup::MouseHook(Ctrl *, bool, int event, Point, int, dword)
|
|
{
|
|
Sync();
|
|
return false;
|
|
}
|
|
|
|
void DisplayPopup::Set(Ctrl *_ctrl, const Rect& _item,
|
|
const Value& _value, const Display *_display,
|
|
Color _ink, Color _paper, dword _style, int _margin)
|
|
{
|
|
if(!GUI_ToolTips())
|
|
return;
|
|
|
|
if(item != _item || ctrl != _ctrl || value != _value || display != _display || ink != _ink ||
|
|
paper != _paper || style != _style) {
|
|
RefreshRect();
|
|
item = _item;
|
|
ctrl = _ctrl;
|
|
owner = this;
|
|
value = _value;
|
|
display = _display;
|
|
ink = _ink;
|
|
paper = _paper;
|
|
style = _style;
|
|
margin = _margin;
|
|
usedisplaystdsize_s = usedisplaystdsize;
|
|
Sync();
|
|
}
|
|
}
|
|
|
|
void DisplayPopup::Cancel()
|
|
{
|
|
if(owner == this) {
|
|
screen_rect = Null;
|
|
Sync();
|
|
}
|
|
}
|
|
|
|
bool DisplayPopup::IsOpen()
|
|
{
|
|
return ctrl && !IsNull(screen_rect);
|
|
}
|
|
|
|
bool DisplayPopup::HasMouse()
|
|
{
|
|
return ctrl && !IsNull(screen_rect) && screen_rect.Contains(GetMousePos());
|
|
}
|
|
|
|
void DisplayPopup::UseDisplayStdSize()
|
|
{
|
|
usedisplaystdsize = true;
|
|
}
|
|
|
|
}
|