OldDraw backup

git-svn-id: svn://ultimatepp.org/upp/trunk@1368 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-07-06 19:21:49 +00:00
parent 81c1f63db0
commit ef93369af8
114 changed files with 19381 additions and 0 deletions

953
olddraw/CtrlCore/Ctrl.cpp Normal file
View file

@ -0,0 +1,953 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
#define IMAGECLASS CtrlCoreImg
#define IMAGEFILE <CtrlCore/Ctrl.iml>
#include <Draw/iml_source.h>
static bool StdDisplayErrorFn(const Value& e)
{
GuiLock __;
if(!e.IsError())
return false;
String s = GetErrorText(e);
#ifdef PLATFORM_WIN32
#ifdef PLATFORM_WINCE
MessageBox(NULL, ToSystemCharset(s), ToSystemCharset(GetExeTitle()), MB_OK | MB_ICONQUESTION);
#else
MessageBox(NULL, s, GetExeTitle(), MB_OK | MB_ICONQUESTION);
#endif
#else
fputs(String().Cat() << GetExeTitle() << ": " << s << '\n', stderr);
#endif
return true;
}
bool (*&DisplayErrorFn())(const Value& v)
{
static bool (*errfn)(const Value& v) = &StdDisplayErrorFn;
return errfn;
}
Ctrl *Ctrl::LoopCtrl;
int Ctrl::LoopLevel;
bool Ctrl::MemoryCheck;
void Ctrl::SetData(const Value&) {}
Value Ctrl::GetData() const { return Value(); }
void Ctrl::Paint(Draw& draw) {}
int Ctrl::OverPaint() const { return 0; }
void Ctrl::Activate() {}
void Ctrl::Deactivate() {}
void Ctrl::CancelMode() {}
void Ctrl::MouseEnter(Point p, dword keyflags) {}
void Ctrl::LeftDown(Point p, dword keyflags) {}
void Ctrl::RightDown(Point p, dword keyflags) {}
void Ctrl::LeftRepeat(Point p, dword keyflags) {}
void Ctrl::RightRepeat(Point p, dword keyflags) {}
void Ctrl::MouseMove(Point p, dword keyflags) {}
void Ctrl::LeftUp(Point, dword keyflags) {}
void Ctrl::RightUp(Point p, dword keyflags) {}
void Ctrl::MouseLeave() {}
void Ctrl::MouseWheel(Point p, int zd, dword kf) {}
void Ctrl::LeftDrag(Point p, dword keyflags) {}
void Ctrl::LeftHold(Point p, dword keyflags) {}
void Ctrl::RightDrag(Point p, dword keyflags) {}
void Ctrl::RightHold(Point p, dword keyflags) {}
void Ctrl::MiddleDown(Point p, dword keyflags) {}
void Ctrl::MiddleDouble(Point p, dword keyflags) {}
void Ctrl::MiddleTriple(Point p, dword keyflags) {}
void Ctrl::MiddleRepeat(Point p, dword keyflags) {}
void Ctrl::MiddleDrag(Point p, dword keyflags) {}
void Ctrl::MiddleHold(Point p, dword keyflags) {}
void Ctrl::MiddleUp(Point p, dword keyflags) {}
void Ctrl::Layout() {}
void Ctrl::PostInput()
{
GuiLock __;
if(parent) parent->PostInput();
}
void Ctrl::LeftDouble(Point p, dword keyflags)
{
LeftDown(p, keyflags);
}
void Ctrl::LeftTriple(Point p, dword keyflags)
{
LeftDown(p, keyflags);
}
void Ctrl::RightDouble(Point p, dword keyflags)
{
RightDown(p, keyflags);
}
void Ctrl::RightTriple(Point p, dword keyflags)
{
RightDown(p, keyflags);
}
void Ctrl::ChildGotFocus()
{
GuiLock __;
if(parent) parent->ChildGotFocus();
}
void Ctrl::ChildLostFocus()
{
GuiLock __;
if(parent) parent->ChildLostFocus();
}
void Ctrl::ChildAdded(Ctrl *q)
{
GuiLock __;
if(parent) parent->ChildAdded(q);
}
void Ctrl::ChildRemoved(Ctrl *q)
{
GuiLock __;
if(parent) parent->ChildRemoved(q);
}
void Ctrl::ParentChange() {}
bool Ctrl::Key(dword key, int count)
{
return false;
}
void Ctrl::GotFocus() {}
void Ctrl::LostFocus() {}
dword Ctrl::AccessKeyBit(int accesskey)
{
accesskey &= 255;
if(accesskey >= 'A' && accesskey <= 'Z')
return (uint64)2 << (accesskey - 'A');
return !!accesskey;
}
dword Ctrl::GetAccessKeysDeep() const
{
GuiLock __;
dword used = GetAccessKeys();
for(Ctrl *ctrl = GetFirstChild(); ctrl; ctrl = ctrl->GetNext())
used |= ctrl->GetAccessKeysDeep();
return used;
}
void Ctrl::AssignAccessKeys(dword used)
{
GuiLock __;
for(Ctrl *ctrl = GetFirstChild(); ctrl; ctrl = ctrl->GetNext()) {
ctrl->AssignAccessKeys(used);
used |= ctrl->GetAccessKeys();
}
}
dword Ctrl::GetAccessKeys() const
{
return 0;
}
void Ctrl::DistributeAccessKeys()
{
AssignAccessKeys(GetAccessKeysDeep());
}
bool Ctrl::VisibleAccessKeys()
{
GuiLock __;
if(GUI_AltAccessKeys())
return GetAlt() && GetTopCtrl() == GetActiveCtrl();
return true;
}
void Ctrl::State(int) {}
void Ctrl::StateDeep(int reason)
{
GuiLock __;
if(destroying)
return;
State(reason);
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
q->StateDeep(reason);
}
void Ctrl::StateH(int reason)
{
GuiLock __;
for(int i = 0; i < statehook().GetCount(); i++)
if((*statehook()[i])(this, reason))
return;
if(reason == POSITION)
State(reason);
else
StateDeep(reason);
}
bool Ctrl::Accept()
{
GuiLock __;
if(!IsEnabled() || !IsShown())
return true;
if(DisplayError(GetData())) {
SetWantFocus();
return false;
}
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
if(!q->Accept()) return false;
return true;
}
void Ctrl::Reject()
{
GuiLock __;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
q->Reject();
}
void Ctrl::Serialize(Stream& s)
{
GuiLock __;
Value x;
if(s.IsStoring())
x = GetData();
s % x;
if(s.IsLoading())
SetData(x);
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
q->Serialize(s);
}
void Ctrl::Updated() {}
bool Ctrl::IsForeground() const
{
GuiLock __;
return GetTopCtrl()->IsWndForeground();
}
void Ctrl::SetForeground()
{
GuiLock __;
GetTopCtrl()->SetWndForeground();
}
bool Ctrl::IsOpen() const
{
GuiLock __;
const Ctrl *q = GetTopCtrl();
return q->IsWndOpen() && q->isopen;
}
void Ctrl::Show(bool ashow) {
GuiLock __;
if(visible != ashow) {
visible = true;
fullrefresh = false;
RefreshFrame();
visible = ashow;
fullrefresh = false;
RefreshFrame();
if(parent)
StateH(SHOW);
if(top)
WndShow(visible);
if(InFrame() && parent)
RefreshParentLayout();
}
}
bool Ctrl::IsVisible() const {
GuiLock __;
const Ctrl *q = this;
for(;;) {
if(!q->visible) return false;
if(!q->parent) break;
q = q->parent;
}
return q->visible;
}
void Ctrl::Enable(bool aenable) {
GuiLock __;
if(enabled != aenable) {
enabled = aenable;
// 01/12/2007 - mdelfede
// added support for windowed controls
// if(!parent) WndEnable(enabled);
if(top) WndEnable(enabled);
// 01/12/2007 - END
if(!enabled && parent && HasFocusDeep())
IterateFocusForward(this, GetTopCtrl());
RefreshFrame();
StateH(ENABLE);
SyncCaret();
}
}
bool Ctrl::IsShowEnabled() const {
GuiLock __;
return IsEnabled() && (!parent || parent->IsShowEnabled());
}
Ctrl& Ctrl::SetEditable(bool aeditable) {
GuiLock __;
if(editable != aeditable) {
editable = aeditable;
RefreshFrame();
StateH(EDITABLE);
}
return *this;
}
void Ctrl::SetModify()
{
modify = true;
}
void Ctrl::ClearModify()
{
GuiLock __;
modify = false;
for(Ctrl *q = firstchild; q; q = q->next)
q->ClearModify();
}
bool Ctrl::IsModified() const
{
GuiLock __;
if(IsModifySet()) return true;
for(Ctrl *q = firstchild; q; q = q->next)
if(q->IsModified()) return true;
return false;
}
void Ctrl::SetCaret(int x, int y, int cx, int cy)
{
GuiLock __;
#ifdef PLATFORM_X11
if(this == caretCtrl)
RefreshCaret();
#endif
caretx = x;
carety = y;
caretcx = cx;
caretcy = cy;
#ifdef PLATFORM_X11
WndCaretTime = GetTickCount();
if(this == caretCtrl)
RefreshCaret();
#endif
}
void Ctrl::SetCaret(const Rect& r)
{
SetCaret(r.left, r.top, r.GetWidth(), r.GetHeight());
}
Rect Ctrl::GetCaret() const
{
return RectC(caretx, carety, caretcx, caretcy);
}
void Ctrl::KillCaret()
{
SetCaret(0, 0, 0, 0);
}
void Ctrl::SetInfoPart(int i, const char *txt)
{
Vector<String> f = Split(info, '\x7f', false);
f.At(i) = txt;
info = Join(f, "\x7f");
}
Ctrl& Ctrl::Tip(const char *txt)
{
SetInfoPart(0, txt);
return *this;
}
Ctrl& Ctrl::HelpLine(const char *txt)
{
SetInfoPart(1, txt);
return *this;
}
Ctrl& Ctrl::Description(const char *txt)
{
SetInfoPart(2, txt);
return *this;
}
Ctrl& Ctrl::HelpTopic(const char *txt)
{
SetInfoPart(3, txt);
return *this;
}
Ctrl& Ctrl::LayoutId(const char *txt)
{
SetInfoPart(4, txt);
return *this;
}
String Ctrl::GetInfoPart(int i) const
{
Vector<String> f = Split(info, '\x7f', false);
return i < f.GetCount() ? f[i] : String();
}
String Ctrl::GetTip() const
{
return GetInfoPart(0);;
}
String Ctrl::GetHelpLine() const
{
return GetInfoPart(1);
}
String Ctrl::GetDescription() const
{
return GetInfoPart(2);
}
String Ctrl::GetHelpTopic() const
{
return GetInfoPart(3);
}
String Ctrl::GetLayoutId() const
{
return GetInfoPart(4);
}
bool Ctrl::SetWantFocus() {
GuiLock __;
if(IsWantFocus() && IsEnabled() && IsVisible() && IsOpen())
return SetFocus();
return false;
}
void Ctrl::UpdateRefresh() {
Update();
Refresh();
}
void Ctrl::Update() {
SetModify();
Updated();
}
void Ctrl::Action() {
WhenAction();
}
void Ctrl::UpdateAction() {
Update();
Action();
}
void Ctrl::UpdateActionRefresh() {
Update();
Action();
Refresh();
};
void Ctrl::CancelModeDeep() {
GuiLock __;
CancelMode();
for(Ctrl *q = firstchild; q; q = q->next)
q->CancelModeDeep();
}
String Ctrl::Name() const {
GuiLock __;
#ifdef CPU_64
String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this);
#else
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
#endif
if(IsChild())
s << "(parent " << String(typeid(*parent).name()) << ")";
else
#ifdef PLATFORM_WIN32
s << Format("(hwnd 0x%x)", (int)(intptr_t) GetHWND());
#endif
#ifdef PLATFORM_X11
s << Format("(window 0x%x)", (int)(intptr_t) GetWindow());
#endif
return s;
}
String Ctrl::GetDesc() const
{
return "";
}
String Name(const Ctrl *ctrl)
{
return ctrl ? ctrl->Name() : "NULL";
}
String Desc(const Ctrl *ctrl)
{
if(!ctrl)
return "NULL";
String s;
s << typeid(*ctrl).name();
String q = ctrl->GetDesc();
if(IsNull(q)) {
if(ctrl->GetPrev()) {
q = ctrl->GetPrev()->GetDesc();
if(!IsNull(q))
s << " <<\"" << q << "\">>";
}
}
else
s << " \"" << q << '\"';
const Ctrl *top = ctrl->GetTopWindow();
if(top && top != ctrl) {
String q = top->GetDesc();
if(IsNull(q))
s << " (" << typeid(*top).name() << ")";
else
s << " (\"" << q << "\")";
}
return s;
}
#ifdef _DEBUG
#define sFLAG(x) (x ? #x" " : "")
#define LG(x) s << x << '\n'
void Ctrl::Dump(Stream& s) const {
GuiLock __;
LG(Name());
LG(sFLAG(backpaint) << sFLAG(inframe) << sFLAG(visible) << sFLAG(enabled) <<
sFLAG(wantfocus) << sFLAG(editable) << sFLAG(IsModified()) << sFLAG(transparent));
LG("Rect: " << GetRect());
LG("View: " << GetView());
for(int i = 0; i < frame.GetCount(); i++)
LG("Frame " << i << ": " << typeid(*frame[i].frame).name() << " - " << frame[i].view);
LG("Data: " << GetData().ToString());
if(firstchild) {
LG("Children");
s << LOG_BEGIN;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) {
q->Dump(s);
LG("------");
}
s << LOG_END;
}
else
LG("No child");
}
void Ctrl::Dump() const {
Dump(VppLog());
}
void Dump(const Ctrl *ctrl)
{
if(ctrl)
ctrl->Dump();
else
LOG("NULL");
}
#endif
bool Ctrl::IsOcxChild()
{
return false;
}
Ctrl::Ctrl() {
GuiLock __;
LLOG("Ctrl::Ctrl");
destroying = false;
parent = prev = next = firstchild = lastchild = NULL;
top = NULL;
exitcode = 0;
frame.Add().frame = &NullFrame();
enabled = visible = wantfocus = initfocus = true;
editable = true;
// GLX = false;
#ifdef PLATFORM_WIN32
activex = false;
isdhctrl = false;
#endif
backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT;
inframe = false;
ignoremouse = transparent = false;
caretcx = caretcy = caretx = carety = 0;
SetRect(Rect(0, 0, 0, 0));
inloop = popup = isopen = false;
modify = false;
unicode = false;
popupgrab = false;
fullrefresh = false;
akv = false;
hasdhctrl = false;
}
void KillTimeCallbacks(void *id, void *idlim);
void Ctrl::DoRemove() {
GuiLock __;
if(!IsOpen()) return;
ReleaseCapture();
CancelModeDeep();
if(HasChildDeep(mouseCtrl) || mouseCtrl == this)
mouseCtrl = NULL;
LLOG("DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl));
#ifdef PLATFORM_X11
if(popupgrab) {
EndPopupGrab();
popupgrab = false;
}
#endif
if(HasFocusDeep()) {
LLOG("DoRemove - HasFocusDeep");
if(destroying) {
if(parent) {
LLOG("parent - deferred SetFocus / ChildLostFocus; parent = " << UPP::Name(parent));
defferedSetFocus = parent;
defferedChildLostFocus.Add(parent);
}
else
if(IsPopUp()) {
LLOG("Remove Popup");
Ctrl *owner = GetOwner();
if(owner && owner->IsEnabled())
owner->ActivateWnd();
}
NoWantFocus();
}
else {
Ptr<Ctrl> fc = focusCtrl;
focusCtrl = NULL;
DoKillFocus(fc, NULL);
if(parent) {
LLOG("DoRemove -> SetFocus(" << UPP::Name(parent) << "), focusCtrl = " << UPP::Name(focusCtrl) << ", fc = " << UPP::Name(fc));
bool b = IsWantFocus();
NoWantFocus();
parent->SetFocus0(false);
WantFocus(b);
}
else
if(IsPopUp()) {
LLOG("Remove Popup");
Ctrl *owner = GetOwner();
if(owner && owner->IsEnabled()) {
LLOG("Remove popup -> owner->ActivateWnd");
owner->ActivateWnd();
}
}
}
SyncCaret();
}
LLOG("//DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl));
}
void Ctrl::Close()
{
GuiLock __;
Ctrl *q = GetTopCtrl();
if(!q->top) return;
DoRemove();
if(parent) return;
StateH(CLOSE);
bool vis = visible;
UsrLogT(3, "CLOSE " + Desc(this));
WndDestroy();
visible = vis;
popup = false;
}
Ctrl::~Ctrl() {
GuiLock __;
LLOG("Ctrl::~Ctrl");
destroying = true;
while(GetFirstChild())
RemoveChild(GetFirstChild());
if(parent)
parent->RemoveChild(this);
Close();
KillTimeCallbacks(this, (byte *) this + sizeof(Ctrl));
}
GLOBAL_VAR(Vector<Ctrl::MouseHook>, Ctrl::mousehook);
GLOBAL_VAR(Vector<Ctrl::KeyHook>, Ctrl::keyhook);
GLOBAL_VAR(Vector<Ctrl::StateHook>, Ctrl::statehook);
void Ctrl::InstallMouseHook(MouseHook hook)
{
GuiLock __;
mousehook().Add(hook);
}
void Ctrl::DeinstallMouseHook(MouseHook hook)
{
GuiLock __;
int q = FindIndex(mousehook(), hook);
if(q >= 0) mousehook().Remove(q);
}
void Ctrl::InstallKeyHook(KeyHook hook)
{
GuiLock __;
keyhook().Add(hook);
}
void Ctrl::DeinstallKeyHook(KeyHook hook)
{
GuiLock __;
int q = FindIndex(keyhook(), hook);
if(q >= 0) keyhook().Remove(q);
}
void Ctrl::InstallStateHook(StateHook hook)
{
GuiLock __;
statehook().Add(hook);
}
void Ctrl::DeinstallStateHook(StateHook hook)
{
GuiLock __;
int q = FindIndex(statehook(), hook);
if(q >= 0) statehook().Remove(q);
}
static char sZoomText[] = "OK Cancel Exit Retry";
const char *Ctrl::GetZoomText()
{
GuiLock __;
return sZoomText;
}
Size Ctrl::Dsize;
Size Ctrl::Csize;
inline void Ctrl::Csizeinit()
{
GuiLock __;
if(Csize.cx == 0)
Csize = GetTextSize(sZoomText, StdFont());
if(Dsize.cx == 0)
Dsize = Size(99, 13);
Csize.cx = max(Csize.cx, Dsize.cx);
Csize.cy = max(Csize.cy, Dsize.cy);
}
void Ctrl::SetZoomSize(Size sz, Size bsz)
{
GuiLock __;
Csize = sz;
Dsize = bsz;
}
void Ctrl::NoLayoutZoom()
{
GuiLock __;
Csize = Dsize = Size(1, 1);
}
void Ctrl::GetZoomRatio(Size& m, Size& d)
{
GuiLock __;
m = Csize;
d = Dsize;
}
int Ctrl::HorzLayoutZoom(int cx)
{
Csizeinit();
return Csize.cx * cx / Dsize.cx;
}
int Ctrl::VertLayoutZoom(int cy)
{
Csizeinit();
return Csize.cy * cy / Dsize.cy;
}
Size Ctrl::LayoutZoom(int cx, int cy)
{
Csizeinit();
return Size(Csize.cx * cx / Dsize.cx, Csize.cy * cy / Dsize.cy);
}
Size Ctrl::LayoutZoom(Size sz)
{
Csizeinit();
return LayoutZoom(sz.cx, sz.cy);
}
Font FontZ(int face, int height)
{
return Font(face, Ctrl::VertLayoutZoom(height));
}
Font StdFontZ(int height) { return FontZ(Font::STDFONT, height); }
Font ScreenSansZ(int height) { return FontZ(Font::SCREEN_SANS, height); }
Font ScreenSerifZ(int height) { return FontZ(Font::SCREEN_SERIF, height); }
Font ScreenFixedZ(int height) { return FontZ(Font::SCREEN_FIXED, height); }
Font RomanZ(int height) { return FontZ(Font::ROMAN, height); }
Font ArialZ(int height) { return FontZ(Font::ARIAL, height); }
Font CourierZ(int height) { return FontZ(Font::COURIER, height); }
String Ctrl::appname;
void Ctrl::SetAppName(const String& nm)
{
GuiLock __;
appname = nm;
}
String Ctrl::GetAppName()
{
GuiLock __;
if(appname.IsEmpty())
appname = GetExeTitle();
return appname;
}
static bool _ClickFocus;
bool Ctrl::ClickFocus() { return _ClickFocus; }
void Ctrl::ClickFocus(bool cf) { _ClickFocus = cf; }
Vector<Ctrl *> Ctrl::GetTopWindows()
{
GuiLock __;
Vector<Ctrl *> c = GetTopCtrls();
Vector<Ctrl *> r;
for(int i = 0; i < c.GetCount(); i++)
if(!c[i]->IsPopUp())
r.Add(c[i]);
return r;
}
void Ctrl::CloseTopCtrls()
{
GuiLock __;
Vector<Ctrl *> tc = Ctrl::GetTopCtrls();
for(int i = 0; i < tc.GetCount(); i++)
tc[i]->Close();
}
bool xpstyle;
bool IsOrOwnedBy(Ctrl *q, Ctrl *window)
{
while(q) {
if(q == window)
return true;
q = q->GetOwner();
}
return false;
}
Vector< Ptr<Ctrl> > DisableCtrls(const Vector<Ctrl *>& ctrl, Ctrl *exclude)
{
Vector< Ptr<Ctrl> > disabled;
for(int i = 0; i < ctrl.GetCount(); i++) {
Ctrl *q = ctrl[i];
if(q && q->IsEnabled() && !IsOrOwnedBy(q, exclude)) {
q->Disable();
disabled.Add(q);
}
}
return disabled;
}
void EnableCtrls(const Vector< Ptr<Ctrl> >& ctrl)
{
for(int i = ctrl.GetCount(); --i >= 0;) {
Ctrl *q = ctrl[i];
if(q) q->Enable();
}
}
void Modality::Begin(Ctrl *modal, bool fo)
{
active = Ctrl::GetFocusCtrl();
fore_only = fo;
LLOG("Active " << Name(active));
enable = DisableCtrls(Ctrl::GetTopWindows(), modal);
}
void Modality::End()
{
EnableCtrls(enable);
if(active && (!fore_only || active->IsForeground()))
active->SetFocus();
enable.Clear();
active = NULL;
}
void (*s_chdefault)();
void (*Ctrl::skin)();
void CtrlSetDefaultSkin(void (*fn1)(), void (*fn2)())
{
GuiLock __;
s_chdefault = fn1;
Ctrl::skin = fn2;
}
void Ctrl::SetSkin(void (*_skin)())
{
GuiLock __;
skin = _skin;
ChSync();
Vector<Ctrl *> ctrl = GetTopCtrls();
for(int i = 0; i < ctrl.GetCount(); i++) {
ctrl[i]->RefreshLayoutDeep();
ctrl[i]->RefreshFrame();
}
}
void Ctrl::ChSync()
{
GuiLock __;
if(s_chdefault)
(*s_chdefault)();
if(skin)
(*skin)();
Csize.cx = Dsize.cx = 0;
ChFinish();
}
CH_INT(GUI_GlobalStyle, GUISTYLE_CLASSIC);
CH_INT(GUI_DragFullWindow, 1);
CH_INT(GUI_PopUpEffect, GUIEFFECT_SLIDE);
CH_INT(GUI_DropShadows, 1);
CH_INT(GUI_AltAccessKeys, 1);
CH_INT(GUI_AKD_Conservative, 0);
CH_INT(GUI_DragDistance, 4);
CH_INT(GUI_DblClickTime, 500);
END_UPP_NAMESPACE

79
olddraw/CtrlCore/Ctrl.iml Normal file
View file

@ -0,0 +1,79 @@
PREMULTIPLIED
IMAGE_ID(DndMoveX11)
IMAGE_ID(DndMove)
IMAGE_ID(DndMove98)
IMAGE_ID(DndNone)
IMAGE_ID(DndNone98)
IMAGE_ID(DndCopy)
IMAGE_ID(DndCopy98)
IMAGE_ID(DndData)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,154,91,136,13,113,28,199,191,110,43,81,238,47,10,39,181,158,36,145,7,235,206,150,187,8,41,183,245,66)
IMAGE_DATA(173,7,228,65,33,183,114,217,92,138,16,121,217,164,220,10,81,10,229,65,81,188,88,121,17,187,229,36,90,75,109,203)
IMAGE_DATA(38,235,210,142,239,239,156,153,115,206,206,252,231,204,204,158,253,255,231,60,204,175,190,205,153,255,206,153,207,247,247,251)
IMAGE_DATA(95,102,246,244,71,10,41,20,132,133,120,195,178,85,109,107,172,105,190,132,237,225,42,181,213,176,7,203,9,219,195,3)
IMAGE_DATA(195,30,172,194,136,193,131,229,14,195,30,60,124,195,30,148,124,131,30,124,249,134,60,20,229,27,240,16,200,215,236,33)
IMAGE_DATA(136,233,168,153,122,69,213,81,227,117,241,225,93,143,132,219,68,189,132,158,245,209,147,175,130,47,236,11,208,243,124,112)
IMAGE_DATA(179,154,21,30,132,127,72,3,27,200,247,239,99,100,235,252,64,193,151,118,169,125,181,38,126,13,117,3,249,241,61,67)
IMAGE_DATA(225,161,176,6,238,177,169,210,34,42,21,210,131,228,181,19,93,199,86,177,26,88,116,226,175,236,245,75,109,15,97,66)
IMAGE_DATA(152,227,225,237,95,191,26,100,218,234,158,213,89,53,119,107,50,127,147,163,156,23,92,43,227,181,54,36,223,47,252,106)
IMAGE_DATA(144,105,123,154,126,154,171,119,125,67,125,230,188,135,249,64,190,63,155,220,124,40,250,93,3,95,250,100,171,205,117,214)
IMAGE_DATA(159,12,167,245,87,107,142,251,241,251,199,204,185,6,190,227,161,240,253,52,195,233,248,215,97,181,255,110,207,240,228,40)
IMAGE_DATA(231,154,248,238,240,121,98,88,198,248,33,164,147,47,243,122,169,205,240,83,148,249,31,53,82,246,189,107,139,40,202,250)
IMAGE_DATA(151,68,18,241,68,153,254,24,80,105,107,136,105,126,193,2,42,15,154,42,195,30,220,139,248,110,195,30,84,15,18,147)
IMAGE_DATA(30,252,30,102,166,60,20,123,160,154,240,16,244,80,215,237,33,204,139,133,78,15,69,249,6,60,4,242,53,123,8,98)
IMAGE_DATA(58,186,79,157,161,86,82,35,116,241,225,93,143,132,123,133,58,9,61,235,163,39,95,5,95,216,235,161,231,249,224,102)
IMAGE_DATA(221,87,120,16,254,18,13,108,32,223,191,251,144,173,243,110,5,95,218,165,246,149,154,248,83,169,109,200,143,239,148,194)
IMAGE_DATA(131,206,26,72,94,115,208,117,108,153,172,129,48,71,192,155,155,201,26,168,194,100,13,124,61,20,176,227,224,75,173,171)
IMAGE_DATA(108,110,28,239,103,142,135,184,222,79,147,72,34,137,36,244,68,153,254,24,16,27,191,224,97,27,27,63,70,15,170,127)
IMAGE_DATA(64,98,227,199,224,193,195,55,236,65,201,55,232,193,151,111,200,67,81,190,1,15,129,124,205,30,130,152,70,243,135,249)
IMAGE_DATA(245,200,147,111,28,124,23,203,164,7,21,195,52,95,217,110,184,31,202,133,239,59,22,157,99,58,157,238,114,30,116,140)
IMAGE_DATA(10,119,223,195,237,167,27,199,238,228,159,59,143,154,131,59,23,221,223,9,184,93,169,249,151,4,71,146,127,146,191,230)
IMAGE_DATA(239,4,220,174,187,249,247,216,49,42,92,131,135,36,252,162,76,127,12,72,118,6,32,217,25,16,131,7,15,223,176,7)
IMAGE_DATA(37,223,160,7,95,190,33,15,69,249,6,60,4,242,53,123,8,98,58,74,118,6,148,215,206,128,138,94,192,186,185,64)
IMAGE_DATA(227,49,160,243,60,175,59,8,252,155,0,60,71,180,237,252,14,35,202,206,128,138,65,192,233,35,64,219,101,224,215,98)
IMAGE_DATA(224,211,84,224,221,38,224,243,109,122,217,1,52,247,7,118,241,186,222,33,249,145,118,6,244,97,222,231,200,222,15,180)
IMAGE_DATA(242,243,9,182,45,160,102,245,3,78,209,79,103,43,175,63,76,95,108,155,73,245,13,225,33,210,206,0,154,104,124,2)
IMAGE_DATA(252,29,8,92,228,57,187,0,19,153,239,97,26,249,209,64,62,39,72,243,27,126,103,52,112,151,127,27,69,245,10,224)
IMAGE_DATA(71,218,25,112,154,12,230,254,141,159,215,80,147,168,45,103,129,142,183,108,103,255,191,98,194,71,175,3,127,86,3,239)
IMAGE_DATA(249,183,249,84,69,136,26,168,66,89,3,25,107,181,192,23,126,158,199,188,143,10,251,53,217,149,217,177,39,235,67,237)
IMAGE_DATA(37,224,231,6,32,205,207,171,168,193,221,228,3,249,241,153,219,25,112,138,227,156,181,110,99,82,215,88,144,246,183,121)
IMAGE_DATA(54,145,152,206,252,55,222,97,255,172,202,230,47,126,134,149,192,247,236,12,224,96,125,254,130,76,154,233,108,176,107,110)
IMAGE_DATA(115,166,83,163,232,229,158,244,255,80,224,182,221,54,180,4,190,227,33,247,126,202,193,84,189,135,99,172,133,12,118,238)
IMAGE_DATA(103,182,29,160,214,82,203,70,2,245,55,129,223,155,129,175,114,78,77,161,6,148,200,247,4,107,191,107,59,231,216,67)
IMAGE_DATA(230,207,73,219,198,197,177,241,56,208,242,136,158,104,228,43,231,226,94,94,54,155,26,131,112,235,64,212,144,123,206,28)
IMAGE_DATA(206,57,182,156,253,76,254,135,133,92,131,56,39,111,177,157,75,18,102,81,227,168,254,26,216,78,200,218,34,243,91,230)
IMAGE_DATA(152,140,243,21,212,52,106,50,178,121,235,100,59,33,107,139,204,111,153,99,50,206,101,172,73,127,235,168,121,18,73,244)
IMAGE_DATA(104,252,7,44,92,244,185,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(1184, 4)
IMAGE_BEGIN_DATA
IMAGE_DATA(120,156,237,152,191,107,21,65,16,199,7,44,108,45,2,182,175,201,159,96,147,66,108,37,41,180,16,65,5,65,65,124)
IMAGE_DATA(41,69,210,4,130,54,70,144,136,198,31,77,8,18,181,139,4,12,54,41,132,88,90,8,81,17,212,66,196,128,18,33)
IMAGE_DATA(70,48,106,252,1,227,204,187,61,223,102,111,247,126,228,237,206,70,220,47,76,178,55,119,236,231,59,187,123,123,239,14)
IMAGE_DATA(90,208,2,77,8,113,133,145,61,32,43,162,7,204,21,201,3,234,138,224,1,77,9,123,40,240,133,61,88,249,130,30)
IMAGE_DATA(156,124,33,15,165,124,1,15,149,252,192,30,170,152,162,245,131,252,126,84,168,55,6,223,96,213,241,176,155,255,180,233)
IMAGE_DATA(252,56,197,117,138,243,20,39,155,123,182,49,170,248,29,246,4,157,187,69,209,214,98,142,98,180,153,7,215,181,165,30)
IMAGE_DATA(166,41,119,193,146,159,162,220,39,199,185,134,114,242,185,206,69,75,255,147,148,91,162,56,66,241,108,107,115,81,203,195)
IMAGE_DATA(101,106,95,52,250,190,73,199,47,21,155,143,103,3,242,121,173,157,213,142,153,253,84,99,179,242,117,209,35,31,192,178)
IMAGE_DATA(62,185,254,107,42,55,105,212,157,235,62,29,159,240,195,223,107,38,184,174,199,20,183,181,249,54,175,241,52,255,78,241)
IMAGE_DATA(250,94,161,24,180,48,230,252,141,125,169,206,16,99,129,98,140,98,88,237,65,124,124,188,200,222,25,202,3,143,241,49)
IMAGE_DATA(85,239,161,192,99,190,77,181,3,212,126,108,40,216,152,39,37,121,211,54,253,24,208,175,98,151,52,95,123,216,158,162)
IMAGE_DATA(24,16,246,96,62,240,71,132,61,216,94,64,36,61,184,94,130,164,60,20,248,194,30,172,124,65,15,78,190,144,135,82)
IMAGE_DATA(190,128,135,74,126,96,15,85,204,60,230,41,174,80,28,164,232,11,197,135,226,126,196,220,25,138,75,16,102,127,44,212)
IMAGE_DATA(107,225,51,251,40,132,121,62,152,172,121,139,7,230,15,6,96,3,116,231,151,222,225,59,227,60,98,225,115,158,199,190)
IMAGE_DATA(63,16,127,15,197,48,116,215,119,203,226,65,31,3,115,109,218,98,191,234,167,142,184,174,125,176,121,109,149,141,1,94)
IMAGE_DATA(189,135,120,122,2,241,240,57,196,3,163,89,112,155,115,234,250,33,229,161,142,152,217,7,197,249,117,141,1,62,90,66)
IMAGE_DATA(156,122,128,56,126,55,59,55,54,157,181,57,167,174,189,1,157,247,214,158,228,26,3,124,245,14,241,225,19,196,217,197)
IMAGE_DATA(236,220,157,133,172,205,57,143,124,128,238,124,206,232,252,15,171,133,253,169,19,207,223,120,231,243,156,12,40,110,190,255)
IMAGE_DATA(224,231,117,196,229,143,136,175,151,51,222,139,183,89,155,115,158,249,185,7,253,247,41,126,251,129,184,246,5,113,101,45)
IMAGE_DATA(227,189,95,205,218,156,11,192,55,133,191,126,35,110,252,68,252,186,129,184,254,61,11,110,115,78,130,95,35,66,242,249)
IMAGE_DATA(190,30,82,12,87,52,185,255,155,170,165,250,110,151,68,147,253,47,41,41,142,182,233,199,128,104,124,237,97,27,141,31)
IMAGE_DATA(209,131,237,5,36,26,63,130,135,2,95,216,131,149,47,232,193,201,23,242,80,202,23,240,80,201,15,236,161,138,41,90)
IMAGE_DATA(63,200,239,71,133,122,99,240,13,150,164,7,27,67,154,111,205,151,120,168,243,50,208,179,175,50,126,192,123,213,185,22)
IMAGE_DATA(109,121,243,158,49,175,105,234,197,100,185,250,172,226,27,255,183,82,255,223,99,75,13,155,60,233,161,215,220,75,253,117)
IMAGE_DATA(60,86,140,191,173,150,186,22,188,240,165,234,55,5,2,245,215,136,144,245,55,233,46,68,253,181,59,130,127,183,126,111)
IMAGE_DATA(255,155,194,3,120,72,114,169,149,62,88,37,37,37,37,37,37,37,37,233,250,223,127,12,123,251,1,221,75,253,62,248)
IMAGE_DATA(144,234,79,245,167,250,211,199,128,36,167,254,0,206,90,25,174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
IMAGE_END_DATA(864, 4)

View file

@ -0,0 +1,264 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
bool Ctrl::HasDHCtrl() const
{
GuiLock __;
if(dynamic_cast<const DHCtrl *>(this))
return true;
for(Ctrl *q = GetFirstChild(); q; q = q->next)
if(q->HasDHCtrl())
return true;
return false;
}
void Ctrl::SyncDHCtrl()
{
GuiLock __;
Ctrl *p = GetTopCtrl();
p->hasdhctrl = p->HasDHCtrl();
}
void Ctrl::AddChild(Ctrl *q, Ctrl *p)
{
GuiLock __;
ASSERT(q);
LLOG("Add " << UPP::Name(q) << " to: " << Name());
if(p == q) return;
bool updaterect = true;
if(q->parent) {
ASSERT(!q->inframe);
if(q->parent == this) {
RemoveChild0(q);
updaterect = false;
}
else
q->parent->RemoveChild(q);
}
q->parent = this;
if(p) {
ASSERT(p->parent == this);
q->prev = p;
q->next = p->next;
if(p == lastchild)
lastchild = q;
else
p->next->prev = q;
p->next = q;
}
else
if(firstchild) {
q->prev = NULL;
q->next = firstchild;
firstchild->prev = q;
firstchild = q;
}
else {
ASSERT(lastchild == NULL);
firstchild = lastchild = q;
q->prev = q->next = NULL;
}
q->CancelModeDeep();
if(updaterect)
q->UpdateRect();
ChildAdded(q);
q->ParentChange();
if(GetTopCtrl()->IsOpen())
q->StateH(OPEN);
if(dynamic_cast<DHCtrl *>(q))
SyncDHCtrl();
}
void Ctrl::AddChild(Ctrl *child)
{
AddChild(child, lastchild);
}
void Ctrl::AddChildBefore(Ctrl *child, Ctrl *insbefore)
{
if(insbefore)
AddChild(child, insbefore->prev);
else
AddChild(child);
}
void Ctrl::RemoveChild0(Ctrl *q)
{
GuiLock __;
ChildRemoved(q);
q->DoRemove();
q->parent = NULL;
if(q == firstchild)
firstchild = firstchild->next;
if(q == lastchild)
lastchild = lastchild->prev;
if(q->prev)
q->prev->next = q->next;
if(q->next)
q->next->prev = q->prev;
q->next = q->prev = NULL;
if(dynamic_cast<DHCtrl *>(q))
SyncDHCtrl();
}
void Ctrl::RemoveChild(Ctrl *q)
{
GuiLock __;
if(q->parent != this) return;
q->RefreshFrame();
RemoveChild0(q);
q->ParentChange();
if(GetTopCtrl()->IsOpen())
q->StateH(CLOSE);
}
void Ctrl::Remove()
{
GuiLock __;
if(parent)
parent->RemoveChild(this);
}
bool Ctrl::HasChild(Ctrl *q) const
{
GuiLock __;
return q && q->IsChild() && q->parent == this;
}
bool Ctrl::HasChildDeep(Ctrl *q) const
{
GuiLock __;
while(q && q->IsChild()) {
if(q->parent == this) return true;
q = q->parent;
}
return false;
}
static bool IterateFocusFw(Ctrl *ctrl, bool noframe, bool init, bool all)
{
LLOG("IterateFocusFw(" << UPP::Name(ctrl) << ")");
while(ctrl) {
if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled()) {
if(!(noframe && ctrl->InFrame())) {
if(all) {
ctrl->SetFocus();
return true;
}
if((!init || ctrl->IsInitFocus()) && ctrl->SetWantFocus())
return true;
}
if(IterateFocusFw(ctrl->GetFirstChild(), noframe, init, all))
return true;
}
ctrl = ctrl->GetNext();
}
return false;
}
bool Ctrl::IterateFocusForward(Ctrl *ctrl, Ctrl *top, bool noframe, bool init, bool all)
{
GuiLock __;
LLOG("IterateFocusForward(" << UPP::Name(ctrl) << ", top " << UPP::Name(top) << ", noframe " << noframe << ", init " << init << ")");
if(!ctrl) return false;
if(IterateFocusFw(ctrl->GetFirstChild(), noframe, init, all))
return true;
if(ctrl->GetNext() && IterateFocusFw(ctrl->GetNext(), noframe, init, all))
return true;
while(ctrl->GetParent() != top && (ctrl = ctrl->GetParent()) != NULL)
if(IterateFocusFw(ctrl->GetNext(), noframe, init, all))
return true;
return false;
}
static bool IterateFocusBw(Ctrl *ctrl, bool noframe, bool all)
{
while(ctrl) {
if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled()) {
if(IterateFocusBw(ctrl->GetLastChild(), noframe, all))
return true;
if(!(noframe && ctrl->InFrame())) {
if(all) {
ctrl->SetFocus();
return true;
}
if(ctrl->SetWantFocus())
return true;
}
}
ctrl = ctrl->GetPrev();
}
return false;
}
bool Ctrl::IterateFocusBackward(Ctrl *ctrl, Ctrl *top, bool noframe, bool all)
{
GuiLock __;
if(!ctrl || ctrl == top) return false;
if(IterateFocusBw(ctrl->GetPrev(), noframe, all))
return true;
while(ctrl->GetParent() != top) {
ctrl = ctrl->GetParent();
if(ctrl->SetWantFocus())
return true;
if(IterateFocusBw(ctrl->GetPrev(), noframe, all))
return true;
}
return false;
}
Ctrl *Ctrl::GetTopCtrl()
{
GuiLock __;
Ctrl *q = this;
while(q->parent)
q = q->parent;
return q;
}
const Ctrl *Ctrl::GetTopCtrl() const { return const_cast<Ctrl *>(this)->GetTopCtrl(); }
const Ctrl *Ctrl::GetOwner() const { return const_cast<Ctrl *>(this)->GetOwner(); }
Ctrl *Ctrl::GetTopCtrlOwner() { return GetTopCtrl()->GetOwner(); }
const Ctrl *Ctrl::GetTopCtrlOwner() const { return GetTopCtrl()->GetOwner(); }
Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top ? top->owner : NULL; }
const Ctrl *Ctrl::GetOwnerCtrl() const { return const_cast<Ctrl *>(this)->GetOwnerCtrl(); }
TopWindow *Ctrl::GetTopWindow()
{
GuiLock __;
Ctrl *q = GetTopCtrl();
while(q) {
TopWindow *w = dynamic_cast<TopWindow *>(q);
if(w) return w;
q = q->GetOwner();
}
return NULL;
}
const TopWindow *Ctrl::GetTopWindow() const
{
return const_cast<Ctrl *>(this)->GetTopWindow();
}
TopWindow *Ctrl::GetMainWindow()
{
GuiLock __;
Ctrl *q = GetTopCtrl();
for(;;) {
Ctrl *w = q->GetOwner();
if(!w)
return dynamic_cast<TopWindow *>(q);
q = w;
}
}
const TopWindow *Ctrl::GetMainWindow() const
{
return const_cast<Ctrl *>(this)->GetMainWindow();
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,311 @@
#include "CtrlCore.h"
NAMESPACE_UPP
ClipData::ClipData(const Value& data, String (*render)(const Value& data))
: data(data), render(render)
{}
String sRawClipData(const Value& data)
{
return data;
}
ClipData::ClipData(const String& data)
: data(data), render(sRawClipData)
{}
ClipData::ClipData()
: render(sRawClipData)
{}
void Ctrl::DragAndDrop(Point p, PasteClip& d) {}
void Ctrl::FrameDragAndDrop(Point p, PasteClip& d) {}
void Ctrl::DragEnter() {}
void Ctrl::DragRepeat(Point p) {}
void Ctrl::DragLeave() {}
PasteClip& Ctrl::Clipboard()
{
GuiLock __;
static PasteClip d;
d.fmt.Clear();
return d;
}
PasteClip& Ctrl::Selection()
{
GuiLock __;
static PasteClip d;
#ifdef PLATFORM_X11
d.fmt.Clear();
d.type = 2;
#endif
return d;
}
String Ctrl::GetDropData(const String& fmt) const
{
return GetSelectionData(fmt);
}
String Ctrl::GetSelectionData(const String& fmt) const
{
return Null;
}
#ifdef PLATFORM_WIN32
bool Has(UDropTarget *dt, const char *fmt);
String Get(UDropTarget *dt, const char *fmt);
bool PasteClip::IsAvailable(const char *fmt) const
{
if(this == &Ctrl::Selection())
return false;
return dt ? UPP::Has(dt, fmt) : IsClipboardAvailable(fmt);
}
String PasteClip::Get(const char *fmt) const
{
if(this == &Ctrl::Selection())
return Null;
return dt ? UPP::Get(dt, fmt) : ReadClipboard(fmt);
}
#endif
#ifdef PLATFORM_X11
bool PasteClip::IsAvailable(const char *fmt) const
{
return Ctrl::ClipHas(type, fmt);
}
String PasteClip::Get(const char *fmt) const
{
return Ctrl::ClipGet(type, fmt);
}
#endif
bool PasteClip::Accept()
{
accepted = true;
return paste;
}
bool PasteClip::Accept(const char *_fmt)
{
Vector<String> f = Split(_fmt, ';');
for(int i = 0; i < f.GetCount(); i++) {
if(IsAccepted() && fmt == _fmt)
return paste;
if(IsAvailable(f[i])) {
accepted = true;
if(paste) {
fmt = f[i];
data = Get(f[i]);
return true;
}
break;
}
}
return false;
}
PasteClip::PasteClip()
{
paste = true;
accepted = false;
#ifdef PLATFORM_WIN32
dt = NULL;
#else
type = 0;
#endif
}
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions)
{
VectorMap<String, ClipData> dummy;
return DoDragAndDrop(fmts, sample, actions, dummy);
}
int Ctrl::DoDragAndDrop(const VectorMap<String, ClipData>& data, const Image& sample, dword actions)
{
return DoDragAndDrop("", sample, actions, data);
}
Uuid sDndUuid;
const void *sInternalPtr;
String GetInternalDropId__(const char *type, const char *id)
{
return "U++ Internal clip:" + AsString(sDndUuid) + '-' + type + '-' + id;
}
void NewInternalDrop__(const void *ptr)
{
sDndUuid = Uuid::Create();
sInternalPtr = ptr;
}
const void *GetInternalDropPtr__()
{
return sInternalPtr;
}
String Unicode__(const WString& w)
{
return String((const char *)~w, 2 * w.GetLength());
}
WString Unicode__(const String& s)
{
return WString((const wchar *)~s, s.GetLength() / 2);
}
Image MakeDragImage(const Image& arrow, Image sample)
{
ImageBuffer b;
if(IsNull(sample)) {
sample = CtrlCoreImg::DndData();
b = sample;
Over(b, Point(0, 0), arrow, arrow.GetSize());
}
else {
b.Create(128, 128);
memset(~b, 0, sizeof(RGBA) * b.GetLength());
Size ssz = sample.GetSize();
Over(b, Point(2, 22), sample, sample.GetSize());
for(int y = 20; y < 96; y++) {
RGBA *s = b[y];
RGBA *e = s + 96;
while(s < e)
(s++)->a >>= 1;
e += 32;
int q = 128;
while(s < e) {
s->a = (s->a * q) >> 8;
q -= 4;
s++;
}
}
int qq = 128;
for(int y = 96; y < 128; y++) {
RGBA *s = b[y];
RGBA *e = s + 96;
while(s < e) {
s->a = (s->a * qq) >> 8;
s++;
}
e += 32;
int q = 255;
while(s < e) {
s->a = (s->a * q * qq) >> 16;
q -= 8;
s++;
}
qq -= 4;
}
RGBA *s = b[21] + 1;
RGBA c1 = Blue();
RGBA c2 = White();
for(int a = 255; a > 0; a -= 3) {
c1.a = c2.a = a;
*s++ = c1;
Swap(c1, c2);
}
s = b[21] + 1;
c1 = Black();
c2 = White();
for(int a = 255; a > 0; a -= 8) {
c1.a = c2.a = a;
*s = c1;
s += b.GetWidth();
Swap(c1, c2);
}
#ifdef PLATFORM_X11
if(Ctrl::IsCompositedGui()) {
Image h = Rescale(b, 64, 64);
b = h;
}
#endif
Over(b, Point(0, 0), arrow, arrow.GetSize());
}
return b;
}
Ptr<Ctrl> Ctrl::dndctrl;
Point Ctrl::dndpos;
bool Ctrl::dndframe;
PasteClip Ctrl::dndclip;
void Ctrl::DnDRepeat()
{
GuiLock __;
if(dndctrl) {
dndctrl->DragRepeat(dndpos);
if(dndctrl) {
PasteClip d = dndclip;
if(dndframe)
dndctrl->FrameDragAndDrop(dndpos, d);
else
dndctrl->DragAndDrop(dndpos, d);
}
}
else
UPP::KillTimeCallback(&dndpos);
}
void Ctrl::DnD(Point p, PasteClip& clip)
{
GuiLock __;
UPP::KillTimeCallback(&dndpos);
dndclip = clip;
Point hp = p - GetScreenRect().TopLeft();
Ptr<Ctrl> ctrl = this;
while(ctrl && ctrl->IsEnabled()) {
Rect view = ctrl->GetScreenView();
if(ctrl->IsMouseActive())
if(view.Contains(p)) {
dndpos = p - view.TopLeft();
dndframe = false;
ctrl->DragAndDrop(dndpos, clip);
if(clip.IsAccepted())
break;
}
else {
dndpos = p - ctrl->GetScreenRect().TopLeft();
dndframe = true;
ctrl->FrameDragAndDrop(dndpos, clip);
if(clip.IsAccepted())
break;
}
ctrl = ctrl->ChildFromPoint(hp);
}
if(ctrl != dndctrl) {
if(dndctrl)
dndctrl->DragLeave();
dndctrl = ctrl;
if(dndctrl)
dndctrl->DragEnter();
}
if(dndctrl)
UPP::SetTimeCallback(-40, callback(DnDRepeat), &dndpos);
}
void Ctrl::DnDLeave()
{
GuiLock __;
if(dndctrl) {
dndctrl->DragLeave();
UPP::KillTimeCallback(&dndpos);
dndctrl = NULL;
}
}
Ctrl *Ctrl::GetDragAndDropTarget()
{
GuiLock __;
return dndctrl;
}
END_UPP_NAMESPACE

1851
olddraw/CtrlCore/CtrlCore.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define TFILE <CtrlCore/CtrlCore.t>
#include <Core/t.h>
END_UPP_NAMESPACE

355
olddraw/CtrlCore/CtrlCore.t Normal file
View file

@ -0,0 +1,355 @@
#ifdef _MSC_VER
#pragma setlocale("C")
#endif
// CtrlKbd.cpp
T_("key\vCtrl+")
deDE("Strg+")
esES("Ctrl+")
fiFI("Ctrl+")
frFR("")
huHU("Ctrl+")
nlNL("Ctrl+")
roRO("tastă\vCtrl+")
ruRU("")
skSK("Ctrl+")
trTR("Ctrl+")
zhTW("Ctrl+")
T_("key\vAlt+")
deDE("Alt+")
esES("Alt+")
fiFI("Alt+")
frFR("")
huHU("Alt+")
nlNL("Alt+")
roRO("tastă\vAlt+")
ruRU("")
skSK("Alt+")
trTR("Alt+")
zhTW("Alt+")
T_("key\vShift+")
deDE("Umschalt+")
esES("May+")
fiFI("Shift+")
frFR("")
huHU("Shift+")
nlNL("Shift+")
roRO("tastă\vShift+")
ruRU("")
skSK("Shift+")
trTR("Shift+")
zhTW("Shift+")
T_("key\vTab")
deDE("Tab")
esES("Tab")
fiFI("Tabulaattori")
frFR("")
huHU("Tab")
nlNL("Tab")
roRO("tastă\vTab")
ruRU("")
skSK("Tab")
trTR("Tab")
zhTW("Tab")
T_("key\vSpace")
deDE("Leertaste")
esES("Espacio")
fiFI("Välilyönti")
frFR("")
huHU("Space")
nlNL("Spatie")
roRO("tastă\vSpațiu")
ruRU("")
skSK("Space")
trTR("Space")
zhTW("Space")
T_("key\vEnter")
deDE("Eingabetaste")
esES("Intro")
fiFI("Enter")
frFR("")
huHU("Enter")
nlNL("Enter")
roRO("tastă\vEnter")
ruRU("")
skSK("Enter")
trTR("Enter")
zhTW("Enter")
T_("key\vBackspace")
deDE("Rückschritt")
esES("Retroceso")
fiFI("Backspace")
frFR("")
huHU("Backspace")
nlNL("Backspace")
roRO("tastă\vBackspace")
ruRU("")
skSK("Backspace")
trTR("Backspace")
zhTW("Backspace")
T_("key\vCaps Lock")
deDE("Umschaltverriegelung")
esES("Bloq May")
fiFI("Caps Lock")
frFR("")
huHU("Caps Lock")
nlNL("Caps Lock")
roRO("tastă\vCaps Lock")
ruRU("")
skSK("Caps Lock")
trTR("Caps Lock")
zhTW("Caps Lock")
T_("key\vEsc")
deDE("Esc")
esES("Esc")
fiFI("Esc")
frFR("")
huHU("Esc")
nlNL("Escape")
roRO("tastă\vEsc")
ruRU("")
skSK("Esc")
trTR("Esc")
zhTW("Esc")
T_("key\vPage Up")
deDE("Bild hoch")
esES("Pág Arriba")
fiFI("Page Down")
frFR("")
huHU("Page Up")
nlNL("Page Up")
roRO("tastă\vPage Up")
ruRU("")
skSK("Page Up")
trTR("Page Up")
zhTW("Page Up")
T_("key\vPage Down")
deDE("Bild runter")
esES("Pág Abajo")
fiFI("Page Down")
frFR("")
huHU("Page Down")
nlNL("Page Down")
roRO("tastă\vPage Down")
ruRU("")
skSK("Page Down")
trTR("Page Down")
zhTW("Page Down")
T_("key\vEnd")
deDE("Ende")
esES("Fin")
fiFI("End")
frFR("")
huHU("End")
nlNL("Einde")
roRO("tastă\vEnd")
ruRU("")
skSK("End")
trTR("End")
zhTW("End")
T_("key\vHome")
deDE("Pos1")
esES("Inicio")
fiFI("Home")
frFR("")
huHU("Home")
nlNL("Begin")
roRO("tastă\vHome")
ruRU("")
skSK("Home")
trTR("Home")
zhTW("Home")
T_("key\vLeft")
deDE("Links")
esES("Izq")
fiFI("Vasen")
frFR("")
huHU("Bal")
nlNL("Links")
roRO("tastă\vStânga")
ruRU("")
skSK("Doľava")
trTR("Left")
zhTW("Left")
T_("key\vUp")
deDE("Hoch")
esES("Arriba")
fiFI("Ylös")
frFR("")
huHU("Up")
nlNL("Boven")
roRO("tastă\vSus")
ruRU("")
skSK("Hore")
trTR("Up")
zhTW("Up")
T_("key\vRight")
deDE("Rechts")
esES("Derecha")
fiFI("Oikea")
frFR("")
huHU("Jobb")
nlNL("Rechts")
roRO("tastă\vDreapta")
ruRU("")
skSK("Doprava")
trTR("Right")
zhTW("Right")
T_("key\vDown")
deDE("Runter")
esES("Abajo")
fiFI("Alas")
frFR("")
huHU("Down")
nlNL("Beneden")
roRO("tastă\vJos")
ruRU("")
skSK("Dole")
trTR("Down")
zhTW("Down")
T_("key\vInsert")
deDE("Einfg")
esES("Insertar")
fiFI("Insert")
frFR("")
huHU("Insert")
nlNL("Invoegen")
roRO("tastă\vInsert")
ruRU("")
skSK("Insert")
trTR("Insert")
zhTW("Insert")
T_("key\vDelete")
deDE("Entf")
esES("Borrar")
fiFI("Delete")
frFR("")
huHU("Delete")
nlNL("Verwijderen")
roRO("tastă\vDelete")
ruRU("")
skSK("Delete")
trTR("Delete")
zhTW("Delete")
T_("key\vBreak")
deDE("UntBr")
esES("Break")
fiFI("Break")
frFR("")
huHU("Break")
nlNL("Break")
roRO("tastă\vBreak")
ruRU("")
skSK("Break")
trTR("Break")
zhTW("Break")
T_("key\vNum[*]")
deDE("Num[*]")
esES("Num[*]")
fiFI("Num[*]")
frFR("")
huHU("Num[*]")
nlNL("Num[*]")
roRO("tastă\vNum[*]")
ruRU("")
skSK("Num[*]")
trTR("Num[*]")
zhTW("Num[*]")
T_("key\vNum[+]")
deDE("Num[+]")
esES("Num[+]")
fiFI("Num[+]")
frFR("")
huHU("Num[+]")
nlNL("Num[+]")
roRO("tastă\vNum[+]")
ruRU("")
skSK("Num[+]")
trTR("Num[+]")
zhTW("Num[+]")
T_("key\vNum[-]")
deDE("Num[-]")
esES("Num[-]")
fiFI("Num[-]")
frFR("")
huHU("Num[-]")
nlNL("Num[-]")
roRO("tastă\vNum[-]")
ruRU("")
skSK("Num[-]")
trTR("Num[-]")
zhTW("Num[-]")
T_("key\vNum[/]")
deDE("Num[/]")
esES("Num[/]")
fiFI("Num[/]")
frFR("")
huHU("Num[/]")
nlNL("Num[/]")
roRO("tastă\vNum[/]")
ruRU("")
skSK("Num[/]")
trTR("Num[/]")
zhTW("Num[/]")
T_("key\vAlt")
deDE("Alt")
esES("Alt")
fiFI("Alt")
frFR("")
huHU("Alt")
nlNL("Alt")
roRO("tastă\vAlt")
ruRU("")
skSK("Alt")
trTR("Alt")
zhTW("Alt")
T_("key\vShift")
deDE("Umschalt")
esES("May")
fiFI("Shift")
frFR("")
huHU("Shift")
nlNL("Shift")
roRO("tastă\vShift")
ruRU("")
skSK("Shift")
trTR("Shift")
zhTW("Shift")
T_("key\vCtrl")
deDE("Strg")
esES("Ctrl")
fiFI("Ctrl")
frFR("")
huHU("Ctrl")
nlNL("Ctrl")
roRO("tastă\vCtrl")
ruRU("")
skSK("Ctrl")
trTR("Ctrl")
zhTW("Ctrl")

View file

@ -0,0 +1,56 @@
description "GUI core system\377B0,0,255";
uses
Draw,
plugin\bmp;
library(WIN32 !MSC8ARM) "advapi32 comdlg32 comctl32";
file
Core readonly separator,
CtrlCore.h,
Win32Keys.i,
X11Keys.i,
MKeys.h,
Frame.cpp,
Ctrl.cpp,
CtrlChild.cpp,
CtrlPos.cpp,
CtrlDraw.cpp,
CtrlMouse.cpp,
CtrlKbd.cpp,
CtrlTimer.cpp,
CtrlClip.cpp,
LocalLoop.cpp,
CtrlCore.icpp,
Ctrl.iml,
CtrlCore.t,
TopWindow readonly separator,
TopWindow.h,
TopWindow.cpp,
lay.h,
llay.h,
Win32 readonly separator,
MultiMon.dli,
Win32Wnd.cpp,
Win32Clip.cpp,
Win32DnD.cpp,
Win32Proc.cpp,
TopWin32.cpp,
DHCtrl.cpp,
Win32Msg.i,
X11 readonly separator,
X11Wnd.cpp,
X11Proc.cpp,
TopWinX11.cpp,
X11Clip.cpp,
X11DnD.cpp,
X11ImgClip.cpp,
X11App.cpp,
X11DHCtrl.cpp,
X11Event.i,
Info readonly separator,
src.tpp,
srcdoc.tpp,
Copying;

View file

@ -0,0 +1,662 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
#define LTIMING(x) // TIMING(x)
bool Ctrl::globalbackpaint;
void Ctrl::RefreshFrame(const Rect& r) {
GuiLock __;
if(!IsOpen() || !IsVisible() || r.IsEmpty()) return;
LTIMING("RefreshFrame");
LLOG("RefreshRect " << Name() << ' ' << r);
#ifdef PLATFORM_WIN32
if(isdhctrl) {
InvalidateRect(((DHCtrl *)this)->GetHWND(), r, false);
return;
}
#endif
if(!top) {
if(InFrame())
parent->RefreshFrame(r + GetRect().TopLeft());
else
parent->Refresh(r + GetRect().TopLeft());
}
else {
LLOG("WndInvalidateRect: " << r << ' ' << Name());
LTIMING("RefreshFrame InvalidateRect");
WndInvalidateRect(r);
#ifdef PLATFORM_WIN32
LLOG("UpdateRect: " << GetWndUpdateRect() << ' ' << Name());
#endif
}
}
void Ctrl::Refresh(const Rect& area) {
GuiLock __;
if(fullrefresh || !IsVisible() || !IsOpen()) return;
LLOG("Refresh " << Name() << ' ' << area);
RefreshFrame((area + GetView().TopLeft()) & GetView().Inflated(OverPaint()));
}
void Ctrl::Refresh() {
GuiLock __;
if(fullrefresh || !IsVisible() || !IsOpen()) return;
LLOG("Refresh " << Name() << " full:" << fullrefresh);
Refresh(Rect(GetSize()).Inflated(OverPaint()));
#ifdef PLATFORM_WIN32
if(!isdhctrl)
#endif
fullrefresh = true;
}
void Ctrl::Refresh(int x, int y, int cx, int cy) {
Refresh(RectC(x, y, cx, cy));
}
void Ctrl::RefreshFrame(int x, int y, int cx, int cy) {
RefreshFrame(RectC(x, y, cx, cy));
}
void Ctrl::RefreshFrame() {
LLOG("RefreshFrame " << Name());
RefreshFrame(Rect(GetRect().Size()).Inflated(overpaint));
}
void Ctrl::ScrollRefresh(const Rect& r, int dx, int dy)
{
GuiLock __;
if(!IsOpen() || !IsVisible() || r.IsEmpty()) return;
int tdx = tabs(dx), tdy = tabs(dy);
if(dx) WndInvalidateRect(RectC(dx >= 0 ? r.left : r.right - tdx, r.top - tdy, tdx, r.Height()));
if(dy) WndInvalidateRect(RectC(r.left - tdx, dy >= 0 ? r.top : r.bottom - tdy, r.Width(), tdy));
}
bool Ctrl::AddScroll(const Rect& sr, int dx, int dy)
{
GuiLock __;
if(!top)
return true;
for(int i = 0; i < top->scroll.GetCount(); i++) {
Scroll& sc = top->scroll[i];
if(sc.rect == sr && sgn(dx) == sgn(sc.dx) && sgn(dy) == sgn(sc.dy)) {
sc.dx += dx;
sc.dy += dy;
ScrollRefresh(sc.rect, sc.dx, sc.dy);
return false;
}
if(sc.rect.Intersects(sr)) {
sc.rect |= sr;
sc.dx = sc.dy = 0;
WndInvalidateRect(sc.rect);
return true;
}
}
Scroll& sc = top->scroll.Add();
sc.rect = sr;
sc.dx = dx;
sc.dy = dy;
ScrollRefresh(sc.rect, sc.dx, sc.dy);
return false;
}
Rect Ctrl::GetClippedView()
{
GuiLock __;
Rect sv = GetScreenView();
Rect view = sv;
Ctrl *q = parent;
Ctrl *w = this;
while(q) {
view &= w->InFrame() ? q->GetScreenRect() : q->GetScreenView();
w = q;
q = q->parent;
}
return view - GetScreenRect().TopLeft();
}
void Ctrl::ScrollView(const Rect& _r, int dx, int dy)
{
GuiLock __;
if(IsFullRefresh() || !IsVisible())
return;
Size vsz = GetSize();
dx = sgn(dx) * min(abs(dx), vsz.cx);
dy = sgn(dy) * min(abs(dy), vsz.cy);
Rect r = _r & vsz;
Ctrl *w;
for(w = this; w->parent; w = w->parent)
if(w->InFrame()) {
Refresh();
return;
}
if(!w || !w->top) return;
Rect view = InFrame() ? GetView() : GetClippedView();
Rect sr = (r + view.TopLeft()) & view;
sr += GetScreenRect().TopLeft() - w->GetScreenRect().TopLeft();
if(w->AddScroll(sr, dx, dy))
Refresh();
else {
LTIMING("ScrollCtrls1");
Top *top = GetTopCtrl()->top;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
if(q->InView()) {
Rect cr = q->GetRect();
if(top && r.Intersects(cr)) { // Uno: Contains -> Intersetcs
Rect to = cr;
GetTopRect(to, false);
if(r.Intersects(cr.Offseted(-dx, -dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs
Rect from = cr.Offseted(-dx, -dy);
GetTopRect(from, false);
MoveCtrl *m = FindMoveCtrlPtr(top->move, q);
if(m && m->from == from && m->to == to) {
LLOG("ScrollView Matched " << from << " -> " << to);
m->ctrl = NULL;
goto done;
}
}
if(r.Intersects(cr.Offseted(dx, dy))) { // Uno's suggestion 06/11/26 Contains -> Intersetcs
Rect from = to;
to = cr.Offseted(dx, dy);
GetTopRect(to, false);
MoveCtrl& m = top->scroll_move.Add(q);
m.from = from;
m.to = to;
m.ctrl = q;
LLOG("ScrollView Add " << UPP::Name(q) << from << " -> " << to);
goto done;
}
cr &= r;
if(!cr.IsEmpty()) {
Refresh(cr);
Refresh(cr + Point(dx, dy));
}
done:;
}
}
}
}
void Ctrl::ScrollView(int x, int y, int cx, int cy, int dx, int dy) {
ScrollView(RectC(x, y, cx, cy), dx, dy);
}
void Ctrl::ScrollView(int dx, int dy) {
ScrollView(Rect(GetSize()), dx, dy);
}
void Ctrl::SyncScroll()
{
GuiLock __;
if(!top)
return;
Vector<Scroll> scroll = top->scroll;
top->scroll.Clear();
if(IsFullRefresh())
return;
for(int i = 0; i < scroll.GetCount(); i++) {
Scroll& sc = scroll[i];
if(abs(sc.dx) > 3 * sc.rect.Width() / 4 || abs(sc.dy) > 3 * sc.rect.Height() / 4) {
LLOG("Sync scroll Invalidate rect" << sc.rect);
WndInvalidateRect(sc.rect);
}
else
if(sc.dx || sc.dy) {
LLOG("WndScrollView " << sc.rect);
WndScrollView(sc.rect, sc.dx, sc.dy);
}
}
}
Rect Ctrl::GetOpaqueRect()
{
return IsTransparent() ? Rect(0, 0, 0, 0) : GetSize();
}
Rect Ctrl::GetVoidRect()
{
return Rect(0, 0, 0, 0);
}
#ifdef _DEBUG
struct sDrawLevelCheck {
Draw& w;
int lvl;
const Ctrl *q;
void Check() {
ASSERT_(lvl == w.GetCloffLevel(), "Draw::Begin/End mismatch for " + UPP::Name(q));
}
sDrawLevelCheck(Draw& w, const Ctrl *q) : w(w), lvl(w.GetCloffLevel()), q(q) {}
~sDrawLevelCheck() { Check(); }
};
#define LEVELCHECK(w, q) sDrawLevelCheck _x_(w, q)
#define DOLEVELCHECK _x_.Check();
#else
#define LEVELCHECK(w, q)
#define DOLEVELCHECK
#endif
void Ctrl::PaintCaret(SystemDraw& w)
{
GuiLock __;
#ifdef PLATFORM_X11
if(this == caretCtrl && WndCaretVisible)
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
#endif
}
void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
GuiLock __;
LEVELCHECK(w, this);
LTIMING("CtrlPaint");
Rect rect = GetRect().GetSize();
Rect orect = rect.Inflated(overpaint);
if(!IsShown() || orect.IsEmpty() || clip.IsEmpty() || !clip.Intersects(orect))
return;
Ctrl *q;
Rect view = rect;
for(int i = 0; i < frame.GetCount(); i++) {
LEVELCHECK(w, NULL);
frame[i].frame->FramePaint(w, view);
view = frame[i].view;
}
Rect oview = view.Inflated(overpaint);
bool hasviewctrls = false;
bool viewexcluded = false;
for(q = firstchild; q; q = q->next)
if(q->IsShown())
if(q->InFrame()) {
if(!viewexcluded && IsTransparent() && q->GetRect().Intersects(view)) {
w.Begin();
w.ExcludeClip(view);
viewexcluded = true;
}
LEVELCHECK(w, q);
Point off = q->GetRect().TopLeft();
w.Offset(off);
q->CtrlPaint(w, clip - off);
w.End();
}
else
hasviewctrls = true;
if(viewexcluded)
w.End();
DOLEVELCHECK;
if(!oview.IsEmpty()) {
if(oview.Intersects(clip) && w.IsPainting(oview)) {
LEVELCHECK(w, this);
if(overpaint) {
w.Clip(oview);
w.Offset(view.left, view.top);
Paint(w);
PaintCaret(w);
w.End();
w.End();
}
else {
w.Clipoff(view);
Paint(w);
PaintCaret(w);
w.End();
}
}
}
if(hasviewctrls && !view.IsEmpty()) {
Rect cl = clip & view;
w.Clip(cl);
for(q = firstchild; q; q = q->next)
if(q->IsShown() && q->InView()) {
LEVELCHECK(w, q);
Rect qr = q->GetRect();
Point off = qr.TopLeft() + view.TopLeft();
Rect ocl = cl - off;
if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) {
w.Offset(off);
q->CtrlPaint(w, cl - off);
w.End();
}
}
w.End();
}
}
int sShowRepaint;
void Ctrl::ShowRepaint(int q)
{
sShowRepaint = q;
}
void ShowRepaintRect(SystemDraw& w, const Rect& r, Color c)
{
if(sShowRepaint) {
w.DrawRect(r, c);
SystemDraw::Flush();
Sleep(sShowRepaint);
}
}
bool Ctrl::PaintOpaqueAreas(SystemDraw& w, const Rect& r, const Rect& clip, bool nochild)
{
GuiLock __;
LTIMING("PaintOpaqueAreas");
if(!IsShown() || r.IsEmpty() || !r.Intersects(clip) || !w.IsPainting(r))
return true;
Point off = r.TopLeft();
Point viewpos = off + GetView().TopLeft();
if(backpaint == EXCLUDEPAINT)
return w.ExcludeClip(r);
Rect cview = clip & (GetView() + off);
for(Ctrl *q = lastchild; q; q = q->prev)
if(!q->PaintOpaqueAreas(w, q->GetRect() + (q->InView() ? viewpos : off),
q->InView() ? cview : clip))
return false;
if(nochild && (lastchild || GetNext()))
return true;
Rect opaque = (GetOpaqueRect() + viewpos) & clip;
if(opaque.IsEmpty())
return true;
#ifdef SYSTEMDRAW
if(backpaint == FULLBACKPAINT && !dynamic_cast<BackDraw *>(&w))
#else
if(backpaint == FULLBACKPAINT && !w.IsBack())
#endif
{
ShowRepaintRect(w, opaque, LtRed());
BackDraw bw;
bw.Create(w, opaque.GetSize());
bw.Offset(viewpos - opaque.TopLeft());
bw.SetPaintingDraw(w, opaque.TopLeft());
{
LEVELCHECK(bw, this);
Paint(bw);
PaintCaret(bw);
}
bw.Put(w, opaque.TopLeft());
}
else {
w.Clip(opaque);
ShowRepaintRect(w, opaque, Green());
w.Offset(viewpos);
{
LEVELCHECK(w, this);
Paint(w);
PaintCaret(w);
}
w.End();
w.End();
}
LLOG("Exclude " << opaque);
return w.ExcludeClip(opaque);
}
inline int Area(const Rect& r)
{
return r.GetHeight() * r.GetWidth();
}
void CombineArea(Vector<Rect>& area, const Rect& r)
{
LTIMING("CombineArea");
if(r.IsEmpty()) return;
int ra = Area(r);
for(int i = 0; i < area.GetCount(); i++) {
Rect ur = r | area[i];
int a = Area(ur);
if(a < 2 * (ra + Area(area[i])) || a < 16000) {
area[i] = ur;
return;
}
}
area.Add(r);
}
void Ctrl::GatherTransparentAreas(Vector<Rect>& area, SystemDraw& w, Rect r, const Rect& clip)
{
GuiLock __;
LTIMING("GatherTransparentAreas");
Point off = r.TopLeft();
Point viewpos = off + GetView().TopLeft();
r.Inflate(overpaint);
Rect notr = GetVoidRect();
if(notr.IsEmpty())
notr = GetOpaqueRect();
notr += viewpos;
if(!IsShown() || r.IsEmpty() || !clip.Intersects(r) || !w.IsPainting(r))
return;
if(notr.IsEmpty())
CombineArea(area, r & clip);
else {
if(notr != r) {
CombineArea(area, clip & Rect(r.left, r.top, notr.left, r.bottom));
CombineArea(area, clip & Rect(notr.right, r.top, r.right, r.bottom));
CombineArea(area, clip & Rect(notr.left, r.top, notr.right, notr.top));
CombineArea(area, clip & Rect(notr.left, notr.bottom, notr.right, r.bottom));
}
for(Ctrl *q = firstchild; q; q = q->next) {
Point qoff = q->InView() ? viewpos : off;
Rect qr = q->GetRect() + qoff;
if(clip.Intersects(qr))
q->GatherTransparentAreas(area, w, qr, clip);
}
}
}
Ctrl *Ctrl::FindBestOpaque(const Rect& clip)
{
GuiLock __;
Ctrl *w = NULL;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) {
if(q->IsVisible() && GetScreenView().Contains(q->GetScreenRect())) {
Rect sw = q->GetScreenView();
if((q->GetOpaqueRect() + sw.TopLeft()).Contains(clip)) {
w = q;
Ctrl *h = q->FindBestOpaque(clip);
if(h) w = h;
}
else
if(q->GetScreenView().Contains(clip))
w = q->FindBestOpaque(clip);
else
if(q->GetScreenRect().Intersects(clip))
w = NULL;
}
}
return w;
}
void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint)
{
GuiLock __;
LTIMING("UpdateArea");
LLOG("========== UPDATE AREA " << UPP::Name(this) << " ==========");
if(backpaint == FULLBACKPAINT || globalbackpaint && !hasdhctrl && !dynamic_cast<DHCtrl *>(this)) {
ShowRepaintRect(draw, clip, LtRed());
BackDraw bw;
bw.Create(draw, clip.GetSize());
bw.Offset(-clip.TopLeft());
bw.SetPaintingDraw(draw, clip.TopLeft());
CtrlPaint(bw, clip);
bw.Put(draw, clip.TopLeft());
LLOG("========== END (FULLBACKPAINT)");
return;
}
if(backpaint == TRANSPARENTBACKPAINT) {
LLOG("TransparentBackpaint");
Vector<Rect> area;
GatherTransparentAreas(area, draw, GetRect().GetSize(), clip);
for(int i = 0; i < area.GetCount(); i++) {
Rect ar = area[i];
LLOG("Painting area: " << ar);
ShowRepaintRect(draw, ar, LtBlue());
BackDraw bw;
bw.Create(draw, ar.GetSize());
bw.Offset(-ar.TopLeft());
bw.SetPaintingDraw(draw, ar.TopLeft());
CtrlPaint(bw, ar);
bw.Put(draw, ar.TopLeft());
if(!draw.ExcludeClip(ar)) {
LLOG("========== END");
return;
}
}
PaintOpaqueAreas(draw, GetRect().GetSize(), clip);
LLOG("========== END");
return;
}
CtrlPaint(draw, clip);
LLOG("========== END");
}
void Ctrl::UpdateArea(SystemDraw& draw, const Rect& clip)
{
GuiLock __;
if(IsPanicMode())
return;
RemoveFullRefresh();
Point sp = GetScreenRect().TopLeft();
Ctrl *b = FindBestOpaque(clip + sp);
if(b) {
Point p = b->GetScreenRect().TopLeft() - sp;
draw.Offset(p);
b->UpdateArea0(draw, clip.Offseted(-p), backpaint);
draw.End();
}
else
UpdateArea0(draw, clip, backpaint);
}
void Ctrl::RemoveFullRefresh()
{
GuiLock __;
fullrefresh = false;
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
q->RemoveFullRefresh();
}
Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe)
{
GuiLock __;
if(!inframe) {
r &= Rect(GetSize());
r.Offset(GetView().TopLeft());
}
if(parent) {
r.Offset(GetRect().TopLeft());
return parent->GetTopRect(r, InFrame());
}
return this;
}
void Ctrl::DoSync(Ctrl *q, Rect r, bool inframe)
{
GuiLock __;
ASSERT(q);
LLOG("DoSync " << UPP::Name(q) << " " << r);
Ctrl *top = q->GetTopRect(r, inframe);
top->SyncScroll();
top->WndUpdate(r);
}
void Ctrl::Sync()
{
GuiLock __;
LLOG("Sync " << Name());
if(top && IsOpen()) {
LLOG("Sync UpdateWindow " << Name());
SyncScroll();
WndUpdate();
}
else
if(parent)
DoSync(parent, GetRect(), inframe);
SyncCaret();
}
void Ctrl::Sync(const Rect& sr)
{
GuiLock __;
LLOG("Sync " << Name() << " " << sr);
DoSync(this, sr, true);
SyncCaret();
}
void Ctrl::DrawCtrlWithParent(Draw& w, int x, int y)
{
GuiLock __;
if(parent) {
Rect r = GetRect();
Ctrl *top = parent->GetTopRect(r, inframe);
w.Clip(x, y, r.Width(), r.Height());
w.Offset(x - r.left, y - r.top);
SystemDraw *ws = dynamic_cast<SystemDraw *>(&w);
if(ws)
top->UpdateArea(*ws, r);
w.End();
w.End();
}
else
DrawCtrl(w, x, y);
}
void Ctrl::DrawCtrl(Draw& w, int x, int y)
{
GuiLock __;
w.Offset(x, y);
SystemDraw *ws = dynamic_cast<SystemDraw *>(&w);
if(ws)
UpdateArea(*ws, GetRect().GetSize());
w.End();
}
void Ctrl::SyncMoves()
{
GuiLock __;
if(!top)
return;
for(int i = 0; i < top->move.GetCount(); i++) {
MoveCtrl& m = top->move[i];
if(m.ctrl) {
RefreshFrame(m.from);
RefreshFrame(m.to);
}
}
for(int i = 0; i < top->scroll_move.GetCount(); i++) {
MoveCtrl& s = top->scroll_move[i];
if(s.ctrl) {
RefreshFrame(s.from);
RefreshFrame(s.to);
}
}
top->move.Clear();
top->scroll_move.Clear();
}
Ctrl& Ctrl::BackPaintHint()
{
GuiLock __;
if(IsDecentMachine())
BackPaint();
return *this;
}
void Ctrl::GlobalBackPaint(bool b)
{
GuiLock __;
globalbackpaint = b;
}
void Ctrl::GlobalBackPaintHint()
{
if(IsDecentMachine())
GlobalBackPaint();
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,417 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
Ptr<Ctrl> Ctrl::focusCtrl;
Ptr<Ctrl> Ctrl::focusCtrlWnd;
Ptr<Ctrl> Ctrl::lastActiveWnd;
Ptr<Ctrl> Ctrl::caretCtrl;
Rect Ctrl::caretRect;
bool Ctrl::ignorekeyup;
Ptr<Ctrl> Ctrl::defferedSetFocus;
Vector< Ptr<Ctrl> > Ctrl::defferedChildLostFocus;
#ifdef flagSO
Ptr<Ctrl> Ctrl::FocusCtrl() { return focusCtrl; }
void Ctrl::FocusCtrl(Ptr<Ctrl> fc) { focusCtrl = fc; }
#endif
static bool s_hotkey;
void Ctrl::RefreshAccessKeys()
{
GuiLock __;
if(GetAccessKeys())
Refresh();
for(Ctrl *ctrl = GetFirstChild(); ctrl; ctrl = ctrl->GetNext())
ctrl->RefreshAccessKeys();
}
void Ctrl::RefreshAccessKeysDo(bool vis)
{
GuiLock __;
if(GUI_AltAccessKeys() && vis != akv) {
akv = vis;
RefreshAccessKeys();
}
}
bool Ctrl::DispatchKey(dword keycode, int count)
{
GuiLock __;
if(GUI_AltAccessKeys()) {
bool alt = GetAlt();
Ctrl *c = GetActiveCtrl();
if(c)
c->RefreshAccessKeysDo(alt);
}
// RLOGBLOCK("Ctrl::DispatchKey");
// RLOG("DispatchKey: focusCtrl = " << FormatIntHex((int)~focusCtrl) << ", wnd = " << FormatIntHex((int)~focusCtrlWnd) << ")");
LLOG("DispatchKey " << keycode << " (0x" << Sprintf("%08x", keycode)
<< ", " << GetKeyDesc(keycode) << "), count:" << count
<< " focusCtrl:" << UPP::Name(focusCtrl) << " focusCtrlWnd:" << UPP::Name(focusCtrlWnd));
if((keycode & K_KEYUP) && ignorekeyup)
{
ignorekeyup = false;
return true;
}
for(int i = 0; i < keyhook().GetCount(); i++)
if((*keyhook()[i])(focusCtrl, keycode, count))
return true;
dword k = keycode;
word l = LOWORD(keycode);
if(!(k & K_DELTA) && l >= 32 && l != 127 && GetDefaultCharset() != CHARSET_UNICODE)
k = MAKELONG((word)FromUnicode(l, CHARSET_DEFAULT), HIWORD(keycode));
if(!focusCtrl)
return false;
Ptr<Ctrl> p = focusCtrl;
if(IsUsrLog()) {
String kl;
dword k = keycode;
int l = 0;
if(k < 65536) {
kl << "CHAR \'" << ToUtf8((wchar)keycode) << "\' (" << keycode << ')';
l = 2;
}
else {
kl << "KEY";
if(k & K_KEYUP) {
kl << "UP";
k &= ~K_KEYUP;
l = 2;
}
kl << " " << GetKeyDesc(k);
}
UsrLogT(l, kl);
}
for(;;) {
LLOG("Trying to DispatchKey: p = " << Desc(p));
if(p->IsEnabled() && p->Key(p->unicode ? keycode : k, count))
{
LLOG("Ctrl::DispatchKey(" << FormatIntHex(keycode) << ", " << GetKeyDesc(keycode)
<< "): eaten in " << Desc(p));
if(IsUsrLog())
UsrLogT(2, String().Cat() << "-> " << Desc(p));
eventCtrl = focusCtrl;
return true;
}
s_hotkey = true;
if(!p->GetParent()) {
if(p->HotKey(keycode)) {
eventCtrl = focusCtrl;
return true;
}
return false;
}
p = p->GetParent();
}
UsrLogT(2, "key was ignored");
return false;
}
bool Ctrl::HotKey(dword key)
{
GuiLock __;
if(!IsEnabled() || !IsVisible()) return false;
for(Ptr<Ctrl> ctrl = firstchild; ctrl; ctrl = ctrl->next)
{
if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled() && ctrl->HotKey(key))
{
if(IsUsrLog() && s_hotkey) {
UsrLogT(2, String().Cat() << "HOT-> " << UPP::Name(ctrl));
s_hotkey = false;
}
return true;
}
}
return false;
}
void Ctrl::DoDeactivate(Ptr<Ctrl> pfocusCtrl, Ptr<Ctrl> nfocusCtrl)
{
GuiLock __;
if(pfocusCtrl) {
Ctrl *ptop = pfocusCtrl->GetTopCtrl();
Ctrl *ntop = nfocusCtrl ? nfocusCtrl->GetTopCtrl() : NULL;
LLOG("DoDeactivate " << UPP::Name(ptop) << " in favor of " << UPP::Name(ntop));
if(ntop != ptop && !ptop->destroying) {
ptop->Deactivate();
ptop->StateH(DEACTIVATE);
ptop->RefreshAccessKeysDo(false);
}
}
}
void Ctrl::DoKillFocus(Ptr<Ctrl> pfocusCtrl, Ptr<Ctrl> nfocusCtrl)
{
GuiLock __;
if(pfocusCtrl && !pfocusCtrl->destroying) {
pfocusCtrl->StateH(FOCUS);
LLOG("LostFocus: " << Desc(pfocusCtrl));
pfocusCtrl->LostFocus();
}
if(pfocusCtrl && pfocusCtrl->parent && !pfocusCtrl->parent->destroying)
pfocusCtrl->parent->ChildLostFocus();
SyncCaret();
}
void Ctrl::DoSetFocus(Ptr<Ctrl> pfocusCtrl, Ptr<Ctrl> nfocusCtrl, bool activate)
{
GuiLock __;
if(activate && focusCtrl == nfocusCtrl && nfocusCtrl) {
Ctrl *top = nfocusCtrl->GetTopCtrl();
if((!pfocusCtrl || pfocusCtrl->GetTopCtrl() != top) && !top->destroying) {
top->StateH(ACTIVATE);
top->Activate();
top->RefreshAccessKeysDo(top->VisibleAccessKeys());
}
}
if(focusCtrl == nfocusCtrl && nfocusCtrl && !nfocusCtrl->destroying) {
nfocusCtrl->GotFocus();
nfocusCtrl->StateH(FOCUS);
}
if(focusCtrl == nfocusCtrl && nfocusCtrl && nfocusCtrl->parent &&
!nfocusCtrl->parent->destroying)
nfocusCtrl->parent->ChildGotFocus();
SyncCaret();
}
bool Ctrl::SetFocus0(bool activate)
{
GuiLock __;
if(IsUsrLog())
UsrLogT(6, String().Cat() << "SETFOCUS " << Desc(this));
LLOG("Ctrl::SetFocus " << Desc(this));
LLOG("focusCtrlWnd " << UPP::Name(focusCtrlWnd));
LLOG("Ctrl::SetFocus0 -> deferredSetFocus = NULL; was: " << UPP::Name(defferedSetFocus));
defferedSetFocus = NULL;
if(focusCtrl == this) return true;
if(!IsOpen() || !IsEnabled() || !IsVisible()) return false;
Ptr<Ctrl> pfocusCtrl = focusCtrl;
Ptr<Ctrl> topwindow = GetTopWindow();
Ptr<Ctrl> topctrl = GetTopCtrl();
Ptr<Ctrl> _this = this;
if(!topwindow) topwindow = topctrl;
LLOG("SetFocus -> SetWndFocus: topwindow = " << UPP::Name(topwindow) << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd));
if(!topwindow->HasWndFocus() && !topwindow->SetWndFocus()) return false;// cxl 31.1.2004
topwindow->SetWndForeground(); // cxl 2007-4-27
LLOG("SetFocus -> focusCtrl = this: " << FormatIntHex(this) << ", _this = " << FormatIntHex(~_this) << ", " << UPP::Name(_this));
focusCtrl = _this;
focusCtrlWnd = topwindow;
DoKillFocus(pfocusCtrl, _this);
LLOG("SetFocus 2");
DoDeactivate(pfocusCtrl, _this);
DoSetFocus(pfocusCtrl, _this, activate);
if(topwindow)
lastActiveWnd = topwindow;
return true;
}
bool Ctrl::SetFocus()
{
GuiLock __;
LLOG("Ctrl::SetFocus(" << Name() << ")");
return SetFocus0(true);
}
void Ctrl::ActivateWnd()
{
GuiLock __;
// notification, don't set physical focus here
LLOG("ActivateWnd " << Name());
Ptr<Ctrl> nfocusCtrl = this;
Ptr<Ctrl> pfocusCtrl = focusCtrl;
LLOG("About to set focus: " << UPP::Name(nfocusCtrl));
DoDeactivate(pfocusCtrl, nfocusCtrl);
focusCtrl = nfocusCtrl;
focusCtrlWnd = this;
DoKillFocus(pfocusCtrl, nfocusCtrl);
DoSetFocus(pfocusCtrl, nfocusCtrl, true);
LLOG("Focus: " << UPP::Name(focusCtrl) << " FocusWnd:" << UPP::Name(focusCtrlWnd));
}
void Ctrl::SetFocusWnd()
{
GuiLock __;
// notification, don't set physical focus here
LLOG("Ctrl::SetFocusWnd");
if(focusCtrlWnd != this) {
LLOG("Ctrl::SetFocusWnd->ActivateWnd");
ActivateWnd();
}
}
void Ctrl::KillFocusWnd()
{
GuiLock __;
// notification, don't set physical focus here
LLOG("KillFocusWnd " << Name());
if(this == ~focusCtrlWnd) {
Ptr<Ctrl> pfocusCtrl = focusCtrl;
DoDeactivate(pfocusCtrl, NULL);
focusCtrl = focusCtrlWnd = NULL;
DoKillFocus(pfocusCtrl, NULL);
}
}
void Ctrl::ClickActivateWnd()
{
GuiLock __;
LLOG("Ctrl::ClickActivateWnd");
if(this == ~focusCtrlWnd && focusCtrl && focusCtrl->GetTopCtrl() != this) {
LLOG("Ctrl::ClickActivateWnd -> ActivateWnd");
ActivateWnd();
}
}
void Ctrl::DefferedFocusSync()
{
GuiLock __;
while(defferedChildLostFocus.GetCount() || defferedSetFocus) {
LLOG("Ctrl::DeferredFocusSync, defferedSetFocus = " << UPP::Name(defferedSetFocus));
Vector< Ptr<Ctrl> > b = defferedChildLostFocus;
defferedChildLostFocus.Clear();
for(int i = 0; i < b.GetCount(); i++)
if(b[i]) {
LLOG("Ctrl::DeferredFocusSync -> ChildLostFocus " << UPP::Name(b[i]));
b[i]->ChildLostFocus();
}
if(defferedSetFocus) {
LLOG("Ctrl::DeferredFocusSync -> SetFocus " << UPP::Name(defferedSetFocus));
defferedSetFocus->SetFocus();
}
defferedSetFocus = NULL;
SyncCaret();
}
}
void Ctrl::RefreshCaret()
{
GuiLock __;
if(caretCtrl)
caretCtrl->Refresh(caretCtrl->caretx, caretCtrl->carety,
caretCtrl->caretcx, caretCtrl->caretcy);
}
void Ctrl::SyncCaret() {
GuiLock __;
#ifdef PLATFORM_X11
if(focusCtrl != caretCtrl) {
RefreshCaret();
caretCtrl = focusCtrl;
RefreshCaret();
}
#else
Rect cr;
cr.Clear();
if(focusCtrl && focusCtrl->IsVisible()) {
bool inframe = focusCtrl->InFrame();
cr = focusCtrl->GetScreenView();
cr = RectC(focusCtrl->caretx + cr.left, focusCtrl->carety + cr.top,
focusCtrl->caretcx, focusCtrl->caretcy) & cr;
for(Ctrl *q = focusCtrl->GetParent(); q; q = q->GetParent()) {
cr &= inframe ? q->GetScreenRect() : q->GetScreenView();
inframe = q->InFrame();
}
}
if(focusCtrl != caretCtrl || cr != caretRect) {
LLOG("Do SyncCaret focusCtrl: " << UPP::Name(focusCtrl)
<< ", caretCtrl: " << UPP::Name(caretCtrl)
<< ", cr: " << cr);
WndDestroyCaret();
if(focusCtrl && !cr.IsEmpty())
focusCtrl->GetTopCtrl()->WndCreateCaret(cr);
caretCtrl = focusCtrl;
caretRect = cr;
}
#endif
}
Ctrl *Ctrl::GetActiveWindow()
{
GuiLock __;
Ctrl *q = GetActiveCtrl();
return q ? q->GetTopWindow() : NULL;
}
bool Ctrl::HasFocusDeep() const
{
GuiLock __;
if(HasFocus() || HasChildDeep(FocusCtrl())) return true;
Ctrl *a = GetActiveCtrl();
if(!a || !a->IsPopUp()) return false;
a = a->GetOwnerCtrl();
return a && HasChildDeep(a);
}
String GetKeyDesc(dword key)
{
String desc;
// key &= 0xFFFF;
if(key == 0)
return desc;
if(key & K_CTRL) desc << t_("key\vCtrl+");
if(key & K_ALT) desc << t_("key\vAlt+");
if(key & K_SHIFT) desc << t_("key\vShift+");
key &= ~(K_CTRL | K_ALT | K_SHIFT);
if(key < K_DELTA && key > 32 && key != K_DELETE)
return desc + String(key, 1);
if(key >= K_NUMPAD0 && key <= K_NUMPAD9)
desc << "Num " << (char)(key - K_NUMPAD0 + '0');
else if(key >= K_0 && key <= K_9)
desc << (char)('0' + key - K_0);
else if(key >= K_A && key <= K_Z)
desc << (char)('A' + key - K_A);
else if(key >= K_F1 && key <= K_F12)
desc << Format("F%d", (int)key - K_F1 + 1);
else {
static struct {
dword key;
const char *name;
} nkey[] = {
{ K_TAB, tt_("key\vTab") }, { K_SPACE, tt_("key\vSpace") },
{ K_RETURN, tt_("key\vEnter") }, { K_BACKSPACE, tt_("key\vBackspace") },
{ K_CAPSLOCK, tt_("key\vCaps Lock") }, { K_ESCAPE, tt_("key\vEsc") },
{ K_PAGEUP, tt_("key\vPage Up") }, { K_PAGEDOWN, tt_("key\vPage Down") },
{ K_END, tt_("key\vEnd") }, { K_HOME, tt_("key\vHome") },
{ K_LEFT, tt_("key\vLeft") }, { K_UP, tt_("key\vUp") },
{ K_RIGHT, tt_("key\vRight") }, { K_DOWN, tt_("key\vDown") },
{ K_INSERT, tt_("key\vInsert") }, { K_DELETE, tt_("key\vDelete") },{ K_BREAK, tt_("key\vBreak") },
{ K_MULTIPLY, tt_("key\vNum[*]") }, { K_ADD, tt_("key\vNum[+]") }, { K_SUBTRACT, tt_("key\vNum[-]") }, { K_DIVIDE, tt_("key\vNum[/]") },
{ K_ALT_KEY, tt_("key\vAlt") }, { K_SHIFT_KEY, tt_("key\vShift") }, { K_CTRL_KEY, tt_("key\vCtrl") },
#ifdef PLATFORM_X11
{ 0x10060, "[`]" }, { 0x1002d, "[-]" }, { 0x1003d, "[=]" }, { 0x1005c, "[\\]" },
{ 0x1005b, "[[]" }, { 0x1005d, "[]]" },
{ 0x1003b, "[;]" }, { 0x10027, "[']" },
{ 0x1002c, "[,]" }, { 0x1002e, "[.]" }, { 0x1005f, "[/]" },
#endif
#ifdef PLATFORM_WIN32
{ 0x100c0, "[`]" }, { 0x100bd, "[-]" }, { 0x100bb, "[=]" }, { 0x100dc, "[\\]" },
{ 0x100db, "[[]" }, { 0x100dd, "[]]" },
{ 0x100ba, "[;]" }, { 0x100de, "[']" },
{ 0x100bc, "[,]" }, { 0x100be, "[.]" }, { 0x100bf, "[/]" },
#endif
{ 0, NULL }
};
for(int i = 0; nkey[i].key; i++)
if(nkey[i].key == key) {
desc << GetLngString(nkey[i].name);
return desc;
}
desc << Format("%04x", (int)key);
}
return desc;
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,660 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
Ptr<Ctrl> Ctrl::eventCtrl;
Ptr<Ctrl> Ctrl::mouseCtrl;
Ptr<Ctrl> Ctrl::captureCtrl;
Ptr<Ctrl> Ctrl::repeatTopCtrl;
Point Ctrl::repeatMousePos;
bool Ctrl::ignoreclick;
bool Ctrl::mouseinframe;
bool Ctrl::mouseinview;
Point Ctrl::mousepos;
Point Ctrl::leftmousepos = Null;
Point Ctrl::rightmousepos = Null;
Point Ctrl::middlemousepos = Null;
dword GetMouseFlags() {
dword style = 0;
if(GetAlt()) style |= K_ALT;
if(GetCtrl()) style |= K_CTRL;
if(GetShift()) style |= K_SHIFT;
if(GetMouseLeft()) style |= K_MOUSELEFT;
if(GetMouseRight()) style |= K_MOUSERIGHT;
if(GetMouseMiddle()) style |= K_MOUSEMIDDLE;
return style;
}
void Ctrl::LogMouseEvent(const char *f, const Ctrl *ctrl, int event, Point p, int zdelta, dword keyflags)
{
if(!IsUsrLog())
return;
String txt = f;
txt += (event & BUTTON) == RIGHT ? "RIGHT" : (event & BUTTON) == MIDDLE ? "MIDDLE" : "LEFT";
switch(event & ACTION) {
case DOWN: txt << "DOWN"; break;
case UP: txt << "UP"; break;
case DOUBLE: txt << "DOUBLE"; break;
case MOUSEWHEEL: txt << "WHEEL"; break;
default:
return;
}
txt << ' ' << p << " (";
if(keyflags & K_ALT)
txt << " ALT";
if(keyflags & K_CTRL)
txt << " CTRL";
if(keyflags & K_SHIFT)
txt << " SHIFT";
if(keyflags & K_MOUSELEFT)
txt << " LEFT";
if(keyflags & K_MOUSERIGHT)
txt << " RIGHT";
if(keyflags & K_MOUSEMIDDLE)
txt << " MIDDLE";
txt << " ) " << Desc(ctrl);
UsrLogT(txt);
}
Image Ctrl::FrameMouseEventH(int event, Point p, int zdelta, dword keyflags)
{
GuiLock __;
for(int i = 0; i < mousehook().GetCount(); i++)
if((*mousehook()[i])(this, true, event, p, zdelta, keyflags))
return Image::Arrow();
LogMouseEvent("FRAME ", this, event, p, zdelta, keyflags);
eventCtrl = this;
if(parent)
parent->ChildFrameMouseEvent(this, event, p, zdelta, keyflags);
return FrameMouseEvent(event, p, zdelta, keyflags);
}
Image Ctrl::FrameMouseEvent(int event, Point p, int zdelta, dword keyflags)
{
return Image::Arrow();
}
Image Ctrl::MouseEventH(int event, Point p, int zdelta, dword keyflags)
{
GuiLock __;
for(int i = 0; i < mousehook().GetCount(); i++)
if((*mousehook()[i])(this, false, event, p, zdelta, keyflags))
return Image::Arrow();
LogMouseEvent(NULL, this, event, p, zdelta, keyflags);
if(parent)
parent->ChildMouseEvent(this, event, p, zdelta, keyflags);
return MouseEvent(event, p, zdelta, keyflags);
}
void Ctrl::ChildFrameMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
{
GuiLock __;
if(parent)
parent->ChildFrameMouseEvent(child, event, p, zdelta, keyflags);
}
void Ctrl::ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
{
GuiLock __;
if(parent)
parent->ChildMouseEvent(child, event, p, zdelta, keyflags);
}
Image Ctrl::MouseEvent(int event, Point p, int zdelta, dword keyflags)
{
LLOG("MouseEvent " << UPP::Name(this) << " " << FormatIntHex(event));
switch(event) {
case MOUSEENTER:
MouseEnter(p, keyflags);
break;
case MOUSEMOVE:
MouseMove(p, keyflags);
break;
case LEFTDOWN:
LeftDown(p, keyflags);
break;
case LEFTDOUBLE:
LeftDouble(p, keyflags);
break;
case LEFTDRAG:
LeftDrag(p, keyflags);
break;
case LEFTHOLD:
LeftHold(p, keyflags);
break;
case LEFTTRIPLE:
LeftTriple(p, keyflags);
break;
case LEFTREPEAT:
LeftRepeat(p, keyflags);
break;
case LEFTUP:
LeftUp(p, keyflags);
break;
case RIGHTDRAG:
RightDrag(p, keyflags);
break;
case RIGHTHOLD:
RightHold(p, keyflags);
break;
case RIGHTTRIPLE:
RightTriple(p, keyflags);
break;
case RIGHTDOWN:
RightDown(p, keyflags);
break;
case RIGHTDOUBLE:
RightDouble(p, keyflags);
break;
case RIGHTREPEAT:
RightRepeat(p, keyflags);
break;
case RIGHTUP:
RightUp(p, keyflags);
break;
case MIDDLEDRAG:
MiddleDrag(p, keyflags);
break;
case MIDDLEHOLD:
MiddleHold(p, keyflags);
break;
case MIDDLETRIPLE:
MiddleTriple(p, keyflags);
break;
case MIDDLEDOWN:
MiddleDown(p, keyflags);
break;
case MIDDLEDOUBLE:
MiddleDouble(p, keyflags);
break;
case MIDDLEREPEAT:
MiddleRepeat(p, keyflags);
break;
case MIDDLEUP:
MiddleUp(p, keyflags);
break;
case MOUSELEAVE:
MouseLeave();
break;
case MOUSEWHEEL:
MouseWheel(p, zdelta, keyflags);
break;
case CURSORIMAGE:
return CursorImage(p, keyflags);
}
return Image::Arrow();
}
Image Ctrl::CursorImage(Point p, dword keyflags)
{
return Image::Arrow();
}
void Ctrl::IgnoreMouseClick()
{
GuiLock __;
LLOG("IgnoreMouseClick");
ignoreclick = true;
KillRepeat();
}
void Ctrl::IgnoreMouseUp()
{
GuiLock __;
LLOG("Ctrl::IgnoreMouseUp");
if(GetMouseLeft() || GetMouseRight() || GetMouseMiddle())
IgnoreMouseClick();
}
void Ctrl::EndIgnore()
{
GuiLock __;
LLOG("Ctrl::EndIgnore");
if(GetMouseLeft() || GetMouseRight() || GetMouseMiddle()) return;
KillRepeat();
ignoreclick = false;
}
bool Ctrl::IsMouseActive() const
{
GuiLock __;
return IsVisible() && IsEnabled() && IsOpen() && !ignoremouse;
}
Ctrl *Ctrl::ChildFromPoint(Point& pt) const
{
GuiLock __;
Ctrl *q;
Point p = pt;
Rect rect = GetRect();
Rect view = GetView();
if(view.Contains(p)) {
Point vp = p - view.TopLeft();
for(q = GetLastChild(); q; q = q->prev) {
if(q->InView() && q->IsMouseActive()) {
Rect r = q->GetRect();
if(r.Contains(vp)) {
pt = vp - r.TopLeft();
return q;
}
}
}
return NULL;
}
for(q = GetLastChild(); q; q = q->prev) {
if(q->InFrame() && q->IsMouseActive()) {
Rect r = q->GetRect();
if(r.Contains(p)) {
pt = p - r.TopLeft();
return q;
}
}
}
return NULL;
}
Image Ctrl::MEvent0(int e, Point p, int zd)
{
GuiLock __;
LLOG("MEvent0 " << Name() << " event: " << FormatIntHex(e, 0) << " point:" << p);
Ptr<Ctrl> _this = this;
mousepos = p;
dword mm = 0;
if((e & ACTION) == DOUBLE)
mm |= K_MOUSEDOUBLE;
if((e & ACTION) == TRIPLE)
mm |= K_MOUSETRIPLE;
Rect view = GetView();
if(mouseCtrl != this) {
if(mouseCtrl) {
Ptr<Ctrl> mousectrl = mouseCtrl;
mousectrl->MouseEventH(MOUSELEAVE, Point(0, 0), zd, GetMouseFlags() | mm);
if(mousectrl)
mousectrl->FrameMouseEventH(MOUSELEAVE, Point(0, 0), zd, GetMouseFlags() | mm);
}
mouseinframe = mouseinview = false;
if(_this) {
mouseCtrl = _this;
mouseinframe = true;
FrameMouseEventH(MOUSEENTER, p, zd, GetMouseFlags() | mm);
}
}
bool inview = view.Contains(p);
if(inview != mouseinview && _this) {
mouseinview = inview;
MouseEventH(inview ? MOUSEENTER : MOUSELEAVE, p, zd, GetMouseFlags() | mm);
}
if(_this)
if(view.Contains(p) || HasCapture()) {
p -= view.TopLeft();
return MouseEventH(e, p, zd, GetMouseFlags() | mm);
}
else
return FrameMouseEventH(e, p, zd, GetMouseFlags() | mm);
return Image::Arrow();
}
void Ctrl::LRepeat() {
GuiLock __;
if(repeatTopCtrl && repeatTopCtrl->HasFocusDeep() && GetMouseLeft()) // 4.7.2004 cxl, IsForeground...
repeatTopCtrl->DispatchMouseEvent(LEFTREPEAT, repeatMousePos, 0);
else
KillRepeat();
LLOG("LRepeat " << UPP::Name(mouseCtrl));
}
static int sDistMax(Point a, Point b)
{
return IsNull(a) ? INT_MAX : max(abs(a.x - b.x), abs(a.y - b.y));
}
static int sDistMin(Point a, Point b)
{
return IsNull(a) ? -1 : max(abs(a.x - b.x), abs(a.y - b.y));
}
void Ctrl::LRep() {
LLOG("LRep");
UPP::SetTimeCallback(-GetKbdSpeed(), callback(&Ctrl::LRepeat), &mousepos);
}
void Ctrl::LHold() {
GuiLock __;
if(sDistMax(leftmousepos, mousepos) < GUI_DragDistance() && repeatTopCtrl && GetMouseLeft())
repeatTopCtrl->DispatchMouseEvent(LEFTHOLD, repeatMousePos, 0);
}
void Ctrl::RRepeat() {
GuiLock __;
if(repeatTopCtrl && repeatTopCtrl->IsForeground() && GetMouseRight())
repeatTopCtrl->DispatchMouseEvent(RIGHTREPEAT, repeatMousePos, 0);
else
KillRepeat();
}
void Ctrl::RRep() {
UPP::SetTimeCallback(-GetKbdSpeed(), callback(&Ctrl::RRepeat), &mousepos);
}
void Ctrl::RHold() {
GuiLock __;
if(sDistMax(rightmousepos, mousepos) < GUI_DragDistance() && repeatTopCtrl && GetMouseRight())
repeatTopCtrl->DispatchMouseEvent(RIGHTHOLD, repeatMousePos, 0);
}
void Ctrl::MRepeat() {
GuiLock __;
if(repeatTopCtrl && repeatTopCtrl->IsForeground() && GetMouseMiddle())
repeatTopCtrl->DispatchMouseEvent(MIDDLEREPEAT, repeatMousePos, 0);
else
KillRepeat();
}
void Ctrl::MRep() {
GuiLock __;
UPP::SetTimeCallback(-GetKbdSpeed(), callback(&Ctrl::MRepeat), &mousepos);
}
void Ctrl::MHold() {
GuiLock __;
if(sDistMax(middlemousepos, mousepos) < GUI_DragDistance() && repeatTopCtrl && GetMouseMiddle())
repeatTopCtrl->DispatchMouseEvent(MIDDLEHOLD, repeatMousePos, 0);
}
void Ctrl::KillRepeat() {
GuiLock __;
LLOG("Ctrl::KillRepeat");
UPP::KillTimeCallback(&mousepos);
repeatTopCtrl = NULL;
leftmousepos = Null;
rightmousepos = Null;
middlemousepos = Null;
}
bool Ctrl::HasMouse() const
{
GuiLock __;
return mouseCtrl == this;
}
bool Ctrl::HasMouseDeep() const
{
GuiLock __;
return mouseCtrl == this || HasChildDeep(mouseCtrl);
}
Ctrl *Ctrl::GetMouseCtrl()
{
GuiLock __;
return mouseCtrl;
}
bool Ctrl::HasMouseInFrame(const Rect& r)
{
GuiLock __;
if(!HasMouse())
return false;
Rect q = GetVisibleScreenRect();
q = r.Offseted(q.TopLeft()) & q;
return q.Contains(GetMousePos());
}
bool Ctrl::HasMouseIn(const Rect& r) const
{
GuiLock __;
if(!HasMouse())
return false;
Rect q = GetVisibleScreenView();
q = r.Offseted(q.TopLeft()) & q;
return q.Contains(GetMousePos());
}
Point Ctrl::GetMouseViewPos() const
{
GuiLock __;
return GetMousePos() - GetVisibleScreenView().TopLeft();
}
void Ctrl::DoCursorShape() {
GuiLock __;
Image m = CursorOverride();
if(IsNull(m))
if(mouseCtrl)
SetMouseCursor(mouseCtrl->MEvent0(CURSORIMAGE, mousepos, 0));
else
SetMouseCursor(Image::Arrow());
else
SetMouseCursor(m);
}
void Ctrl::CheckMouseCtrl() {
GuiLock __;
Point p = GetMousePos();
if(mouseCtrl) {
Rect r = mouseCtrl->GetScreenRect();
LLOG("CheckMouseCtrl mouseCtrl " << UPP::Name(mouseCtrl) << " " << r);
if(!mouseCtrl->HasCapture() && !r.Contains(p)) {
Ptr<Ctrl> mousectrl = mouseCtrl;
if(mouseinview)
mousectrl->MouseEventH(MOUSELEAVE, p - mousectrl->GetScreenView().TopLeft(),
0, GetMouseFlags());
if(mouseinframe && mousectrl)
mousectrl->FrameMouseEventH(MOUSELEAVE, p - r.TopLeft(),
0, GetMouseFlags());
mouseinview = mouseinframe = false;
mouseCtrl = NULL;
leftmousepos = rightmousepos = middlemousepos = Null;
KillRepeat();
}
}
DoCursorShape();
}
Point leftdblpos = Null, rightdblpos = Null, middledblpos = Null;
int leftdbltime = Null, rightdbltime = Null, middledbltime = Null;
bool sDblTime(int time)
{
return !IsNull(time) && (int)GetTickCount() - time < GUI_DblClickTime();
}
Image Ctrl::DispatchMouse(int e, Point p, int zd) {
GuiLock __;
if(e == MOUSEMOVE) {
if(sDistMin(leftmousepos, p) > GUI_DragDistance() && repeatTopCtrl == this) {
DispatchMouseEvent(LEFTDRAG, leftmousepos, 0);
leftmousepos = Null;
}
if(sDistMin(rightmousepos, p) > GUI_DragDistance() && repeatTopCtrl == this) {
DispatchMouseEvent(RIGHTDRAG, rightmousepos, 0);
rightmousepos = Null;
}
if(sDistMin(middlemousepos, p) > GUI_DragDistance() && repeatTopCtrl == this) {
DispatchMouseEvent(MIDDLEDRAG, middlemousepos, 0);
middlemousepos = Null;
}
}
repeatMousePos = p;
if(e == LEFTDOUBLE) {
leftdbltime = GetTickCount();
leftdblpos = p;
}
if(e == RIGHTDOUBLE) {
rightdbltime = GetTickCount();
rightdblpos = p;
}
if(e == MIDDLEDOUBLE) {
middledbltime = GetTickCount();
middledblpos = p;
}
if(e == LEFTDOWN) {
LLOG("Ctrl::DispatchMouse: init left repeat for " << UPP::Name(this) << " at " << p);
UPP::SetTimeCallback(GetKbdDelay(), callback(&Ctrl::LRep), &mousepos);
UPP::SetTimeCallback(2 * GetKbdDelay(), callback(&Ctrl::LHold), &mousepos);
leftmousepos = p;
if(sDistMax(leftdblpos, p) < GUI_DragDistance() && sDblTime(leftdbltime))
e = LEFTTRIPLE;
repeatTopCtrl = this;
}
if(e == RIGHTDOWN) {
LLOG("Ctrl::DispatchMouse: init right repeat for " << UPP::Name(this) << " at " << p);
UPP::SetTimeCallback(GetKbdDelay(), callback(&Ctrl::RRep), &mousepos);
UPP::SetTimeCallback(2 * GetKbdDelay(), callback(&Ctrl::RHold), &mousepos);
rightmousepos = p;
if(sDistMax(rightdblpos, p) < GUI_DragDistance() && sDblTime(rightdbltime))
e = RIGHTTRIPLE;
repeatTopCtrl = this;
}
if(e == MIDDLEDOWN) {
LLOG("Ctrl::DispatchMouse: init middle repeat for " << UPP::Name(this) << " at " << p);
UPP::SetTimeCallback(GetKbdDelay(), callback(&Ctrl::MRep), &mousepos);
UPP::SetTimeCallback(2 * GetKbdDelay(), callback(&Ctrl::MHold), &mousepos);
middlemousepos = p;
if(sDistMax(middledblpos, p) < GUI_DragDistance() && sDblTime(middledbltime))
e = MIDDLETRIPLE;
repeatTopCtrl = this;
}
if(repeatTopCtrl != this)
repeatTopCtrl = NULL;
if(e == LEFTUP)
leftmousepos = Null;
if(e == RIGHTUP)
rightmousepos = Null;
if(e == MIDDLEUP)
rightmousepos = Null;
if(e == LEFTUP || e == RIGHTUP || e == MIDDLEUP)
KillRepeat();
Image result = DispatchMouseEvent(e, p, zd);
if(!GetMouseRight() && !GetMouseMiddle() && !GetMouseLeft())
ReleaseCtrlCapture();
return result;
}
Image Ctrl::DispatchMouseEvent(int e, Point p, int zd) {
GuiLock __;
if(!IsEnabled())
return Image::Arrow();
if(captureCtrl && captureCtrl != this && captureCtrl->IsMouseActive())
return captureCtrl->MEvent0(e, p + GetScreenRect().TopLeft() -
captureCtrl->GetScreenRect().TopLeft(), zd);
Ctrl *top = this;
if(e == MOUSEWHEEL && !GetParent()) {
Ctrl *w = GetFocusCtrl();
if(w) {
top = w->GetTopCtrl();
p = GetMousePos() - top->GetScreenRect().TopLeft();
}
}
Ctrl *q = top->ChildFromPoint(p);
return q ? q->DispatchMouseEvent(e, p, zd) : top->MEvent0(e, p, zd);
}
bool Ctrl::SetCapture() {
GuiLock __;
ReleaseCtrlCapture();
if(!GetTopCtrl()->SetWndCapture()) return false;
captureCtrl = mouseCtrl = this;
return true;
}
bool Ctrl::ReleaseCapture() {
GuiLock __;
return this == captureCtrl && ReleaseCtrlCapture();
}
bool Ctrl::ReleaseCtrlCapture() {
GuiLock __;
if(captureCtrl) {
captureCtrl->CancelMode();
Ctrl *w = captureCtrl->GetTopCtrl();
captureCtrl = NULL;
if(w->HasWndCapture()) {
w->ReleaseWndCapture();
return true;
}
}
captureCtrl = NULL;
return false;
}
bool Ctrl::HasCapture() const {
GuiLock __;
return captureCtrl == this && GetTopCtrl()->HasWndCapture();
}
Ctrl *Ctrl::GetVisibleChild(Ctrl *ctrl, Point p, bool pointinframe)
{
GuiLock __;
if(!pointinframe)
p += ctrl->GetView().TopLeft();
Ctrl *q;
Rect rect = ctrl->GetRect();
for(q = ctrl->GetLastChild(); q; q = q->GetPrev()) {
if(q->InFrame() && q->IsVisible()) {
Rect r = q->GetRect();
if(r.Contains(p))
return GetVisibleChild(q, p - r.TopLeft(), true);
}
}
Rect view = ctrl->GetView();
if(view.Contains(p)) {
p -= view.TopLeft();
for(q = ctrl->GetLastChild(); q; q = q->GetPrev()) {
if(q->InView() && q->IsVisible()) {
Rect r = q->GetRect();
if(r.Contains(p))
return GetVisibleChild(q, p - r.TopLeft(), true);
}
}
}
return ctrl;
}
AutoWaitCursor::AutoWaitCursor(int& avg) : WaitCursor(avg >= 0), avg(avg) {
time0 = GetTickCount();
}
AutoWaitCursor::~AutoWaitCursor() {
if(time0) avg = GetTickCount() - time0 - 500;
if(avg < -10000) avg = -10000;
if(avg > 10000) avg = 10000;
}
Image& Ctrl::CursorOverride()
{
GuiLock __;
static Image m;
return m;
}
Image Ctrl::OverrideCursor(const Image& m)
{
GuiLock __;
Image om = CursorOverride();
CursorOverride() = m;
DoCursorShape();
if(!mouseCtrl)
SetMouseCursor(IsNull(m) ? Image::Arrow() : m);
return om;
}
void WaitCursor::Show() {
if(flag)
prev = Ctrl::OverrideCursor(Image::Wait());
flag = false;
}
WaitCursor::WaitCursor(bool show) {
flag = true;
if(show) Show();
}
WaitCursor::~WaitCursor() {
if(!flag)
Ctrl::OverrideCursor(prev);
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,486 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#define LTIMING(x) // RTIMING(x)
bool Ctrl::Logc::IsEmpty() const {
return GetAlign() == SIZE ? GetB() <= GetA() : GetB() <= 0;
}
Size Ctrl::PosVal(int v) const {
switch(v) {
case MINSIZE: return GetMinSize();
case STDSIZE: return GetStdSize();
case MAXSIZE: return GetMaxSize();
}
return Size(v, v);
}
void Ctrl::Lay1(int& pos, int& r, int align, int a, int b, int sz) const
{
pos = a;
int size = b;
switch(align) {
case CENTER:
pos = (sz - b) / 2 + a;
break;
case RIGHT:
pos = sz - (a + b);
break;
case SIZE:
size = sz - (a + b);
break;
}
r = pos + max(size, 0);
}
Rect Ctrl::CalcRect(LogPos pos, const Rect& prect, const Rect& pview) const
{
Rect r;
Size sz = InFrame() ? prect.Size() : pview.Size();
Lay1(r.left, r.right, pos.x.GetAlign(),
PosVal(pos.x.GetA()).cx, PosVal(pos.x.GetB()).cx, sz.cx);
Lay1(r.top, r.bottom, pos.y.GetAlign(),
PosVal(pos.y.GetA()).cy, PosVal(pos.y.GetB()).cy, sz.cy);
return r;
}
Rect Ctrl::CalcRect(const Rect& prect, const Rect& pview) const
{
return CalcRect(pos, prect, pview);
}
Rect Ctrl::GetRect() const
{
return rect;
}
Rect Ctrl::GetView() const
{
GuiLock __;
return frame.GetCount() == 0 ? Rect(Size(rect.Size())) : Rect(frame[frame.GetCount() - 1].view);
}
Size Ctrl::GetSize() const
{
return GetView().GetSize();
}
Rect Ctrl::GetScreenRect() const
{
GuiLock __;
Rect r = GetRect();
if(parent) {
Rect pr = inframe ? parent->GetScreenRect() : parent->GetScreenView();
r = r + pr.TopLeft();
}
#ifdef PLATFORM_WIN32
else if(activex)
r = GetWndScreenRect();
#endif
return r;
}
Rect Ctrl::GetScreenView() const
{
Rect r = GetScreenRect();
return GetView() + r.TopLeft();
}
Rect Ctrl::GetVisibleScreenRect() const
{
GuiLock __;
Rect r = GetRect();
if(parent) {
Rect pr = inframe ? parent->GetVisibleScreenRect() : parent->GetVisibleScreenView();
Rect pr1 = inframe ? parent->GetScreenRect() : parent->GetScreenView();
r = (r + pr1.TopLeft()) & pr;
}
#ifdef PLATFORM_WIN32
else if(activex)
r = GetWndScreenRect();
#endif
return r & GetVirtualScreenArea();
}
Rect Ctrl::GetVisibleScreenView() const
{
Rect r = GetVisibleScreenRect();
return (GetView() + r.TopLeft()) & r;
}
Size Ctrl::AddFrameSize(int cx, int cy) const
{
GuiLock __;
Size sz = Size(cx, cy);
for(int i = frame.GetCount() - 1; i >= 0; i--)
frame[i].frame->FrameAddSize(sz);
return sz;
}
int EditFieldIsThin();
Size Ctrl::GetMinSize() const
{
int fcy = Draw::GetStdFontCy();
return AddFrameSize(fcy / 2, fcy + 2 + 2 * EditFieldIsThin());
}
Size Ctrl::GetStdSize() const
{
Size sz = GetMinSize();
sz.cx *= 10;
return sz;
}
Size Ctrl::GetMaxSize() const
{
return GetVirtualWorkArea().Size();
}
void Ctrl::SyncLayout(int force)
{
GuiLock __;
LLOG("SyncLayout " << Name() << " size: " << GetSize());
bool refresh = false;
Rect oview = GetView();
Rect view = GetRect().Size();
overpaint = OverPaint();
for(int i = 0; i < frame.GetCount(); i++) {
Frame& f = frame[i];
f.frame->FrameLayout(view);
if(view != f.view) {
f.view = view;
refresh = true;
}
int q = f.frame->OverPaint();
if(q > overpaint) overpaint = q;
}
if(oview.Size() != view.Size() || force > 1) {
for(Ctrl *q = GetFirstChild(); q; q = q->next) {
q->rect = q->CalcRect(rect, view);
LLOG("Layout set rect " << q->Name() << " " << q->rect);
q->SyncLayout(force > 1 ? force : 0);
}
Refresh();
}
if(oview != view || force) {
State(LAYOUTPOS);
Layout();
}
if(refresh)
RefreshFrame();
}
int Ctrl::FindMoveCtrl(const VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x)
{
int q = m.Find(x);
return q >= 0 && m[q].ctrl ? q : -1;
}
Ctrl::MoveCtrl *Ctrl::FindMoveCtrlPtr(VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x)
{
int q = FindMoveCtrl(m, x);
return q >= 0 ? &m[q] : NULL;
}
void Ctrl::SetPos0(LogPos p, bool _inframe)
{
GuiLock __;
if(p == pos && inframe == _inframe) return;
if(parent) {
Rect from = GetRect().Size();
Top *top = GetTopRect(from, true)->top;
if(top) {
LTIMING("SetPos0 MoveCtrl");
pos = p;
inframe = _inframe;
Rect to = GetRect().Size();
UpdateRect0();
GetTopRect(to, true);
MoveCtrl *s = FindMoveCtrlPtr(top->scroll_move, this);
if(s && s->from == from && s->to == to) {
s->ctrl = NULL;
LLOG("SetPos Matched " << from << " -> " << to);
}
else {
MoveCtrl& m = top->move.Add(this);
m.ctrl = this;
m.from = from;
m.to = to;
LLOG("SetPos Add " << UPP::Name(this) << from << " -> " << to);
}
return;
}
RefreshFrame();
}
pos = p;
inframe = _inframe;
UpdateRect();
}
void Ctrl::UpdateRect0()
{
GuiLock __;
LTIMING("UpdateRect0");
if(parent)
rect = CalcRect(parent->GetRect(), parent->GetView());
else {
Rect r = GetWorkArea();
rect = CalcRect(r, r);
}
LTIMING("UpdateRect0 SyncLayout");
SyncLayout();
}
void Ctrl::UpdateRect()
{
GuiLock __;
UpdateRect0();
if(parent) RefreshFrame();
}
Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
{
GuiLock __;
if(p != pos || inframe != _inframe) {
if(parent || !IsOpen())
SetPos0(p, _inframe);
else {
Rect wa = GetWorkArea();
WndSetPos(CalcRect(p, wa, wa));
}
StateH(POSITION);
}
return *this;
}
Ctrl& Ctrl::SetPos(LogPos p)
{
return SetPos(p, false);
}
Ctrl& Ctrl::SetPosX(Logc x)
{
return SetPos(LogPos(x, pos.y));
}
Ctrl& Ctrl::SetPosY(Logc y)
{
return SetPos(LogPos(pos.x, y));
}
Ctrl& Ctrl::SetFramePos(LogPos p)
{
return SetPos(p, true);
}
Ctrl& Ctrl::SetFramePosX(Logc x) {
return SetPos(LogPos(x, pos.y), true);
}
Ctrl& Ctrl::SetFramePosY(Logc y) {
return SetPos(LogPos(pos.x, y), true);
}
void Ctrl::SetRect(int x, int y, int cx, int cy)
{
LLOG("SetRect " << Name() << " rect: " << RectC(x, y, cx, cy));
LTIMING("SetRect");
SetPos(PosLeft(x, cx), PosTop(y, cy));
}
void Ctrl::SetWndRect(const Rect& r)
{
LLOG("SetWndRect " << Name() << " rect: " << r << " (Ctrl::GetRect = " << GetRect() << ")");
SetPos0(LogPos(PosLeft(r.left, r.Width()), PosTop(r.top, r.Height())), false);
StateH(POSITION);
}
void Ctrl::SetRect(const Rect& r)
{
SetRect(r.left, r.top, r.Width(), r.Height());
}
void Ctrl::SetRectX(int x, int cx) {
SetPosX(PosLeft(x, cx));
}
void Ctrl::SetRectY(int y, int cy) {
SetPosY(PosTop(y, cy));
}
void Ctrl::SetFrameRect(int x, int y, int cx, int cy) {
SetFramePos(PosLeft(x, cx), PosTop(y, cy));
}
void Ctrl::SetFrameRect(const Rect& r) {
SetFrameRect(r.left, r.top, r.Width(), r.Height());
}
void Ctrl::SetFrameRectX(int x, int cx) {
SetFramePosX(PosLeft(x, cx));
}
void Ctrl::SetFrameRectY(int y, int cy) {
SetFramePosY(PosTop(y, cy));
}
Ctrl& Ctrl::SetFrame(int i, CtrlFrame& fr) {
GuiLock __;
LLOG("SetFrame " << typeid(fr).name());
while(frame.GetCount() <= i)
frame.Add().frame = &NullFrame();
frame[i].frame->FrameRemove();
frame[i].frame = &fr;
fr.FrameAdd(*this);
SyncLayout();
RefreshFrame();
return *this;
}
Ctrl& Ctrl::AddFrame(CtrlFrame& fr) {
GuiLock __;
LLOG("AddFrame " << typeid(fr).name());
frame.Add().frame = &fr;
fr.FrameAdd(*this);
SyncLayout();
RefreshFrame();
return *this;
}
void Ctrl::ClearFrames() {
GuiLock __;
for(int i = 0; i < frame.GetCount(); i++)
frame[i].frame->FrameRemove();
frame.Clear();
frame.Add().frame = &NullFrame();
RefreshFrame();
SyncLayout();
}
void Ctrl::RemoveFrame(int i) {
GuiLock __;
int n = frame.GetCount();
Mitor<Frame> m;
if(n > 1)
for(int q = 0; q < n; q++)
if(q != i)
m.Add().frame = frame[q].frame;
else
frame[q].frame->FrameRemove();
frame = m;
if(frame.GetCount() == 0)
frame.Add().frame = &NullFrame();
RefreshFrame();
SyncLayout();
}
int Ctrl::FindFrame(CtrlFrame& frm)
{
GuiLock __;
for(int i = 0; i < frame.GetCount(); i++)
if(frame[i].frame == &frm)
return i;
return -1;
}
void Ctrl::RemoveFrame(CtrlFrame& frm)
{
GuiLock __;
int i = FindFrame(frm);
if(i >= 0)
RemoveFrame(i);
}
void Ctrl::InsertFrame(int i, CtrlFrame& fr)
{
GuiLock __;
ASSERT(i >= 0 && i <= frame.GetCount());
int n = frame.GetCount();
Mitor<Frame> m;
if(n >= 1)
for(int q = 0; q < n; q++) {
if(q == i) m.Add().frame = &fr;
m.Add().frame = frame[q].frame;
}
if(i == n)
m.Add().frame = &fr;
frame = m;
fr.FrameAdd(*this);
SyncLayout();
RefreshFrame();
}
Ctrl& Ctrl::LeftPos(int a, int size) {
return SetPosX(PosLeft(a, size));
}
Ctrl& Ctrl::RightPos(int a, int size) {
return SetPosX(PosRight(a, size));
}
Ctrl& Ctrl::TopPos(int a, int size) {
return SetPosY(PosTop(a, size));
}
Ctrl& Ctrl::BottomPos(int a, int size) {
return SetPosY(PosBottom(a, size));
}
Ctrl& Ctrl::HSizePos(int a, int b) {
return SetPosX(PosSize(a, b));
}
Ctrl& Ctrl::VSizePos(int a, int b) {
return SetPosY(PosSize(a, b));
}
Ctrl& Ctrl::SizePos() {
return HSizePos().VSizePos();
}
Ctrl& Ctrl::HCenterPos(int size, int delta) {
return SetPosX(PosCenter(size, delta));
}
Ctrl& Ctrl::VCenterPos(int size, int delta) {
return SetPosY(PosCenter(size, delta));
}
Ctrl& Ctrl::LeftPosZ(int a, int size) {
return LeftPos(HorzLayoutZoom(a), HorzLayoutZoom(size));
}
Ctrl& Ctrl::RightPosZ(int a, int size) {
return RightPos(HorzLayoutZoom(a), HorzLayoutZoom(size));
}
Ctrl& Ctrl::TopPosZ(int a, int size) {
return TopPos(VertLayoutZoom(a), VertLayoutZoom(size));
}
Ctrl& Ctrl::BottomPosZ(int a, int size) {
return BottomPos(VertLayoutZoom(a), VertLayoutZoom(size));
}
Ctrl& Ctrl::HSizePosZ(int a, int b) {
return HSizePos(HorzLayoutZoom(a), HorzLayoutZoom(b));
}
Ctrl& Ctrl::VSizePosZ(int a, int b) {
return VSizePos(VertLayoutZoom(a), VertLayoutZoom(b));
}
Ctrl& Ctrl::HCenterPosZ(int size, int delta) {
return HCenterPos(HorzLayoutZoom(size), HorzLayoutZoom(delta));
}
Ctrl& Ctrl::VCenterPosZ(int size, int delta) {
return VCenterPos(VertLayoutZoom(size), VertLayoutZoom(delta));
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,229 @@
#include "CtrlCore.h"
NAMESPACE_UPP
int MemoryProbeInt;
struct TimeEvent : public Link<TimeEvent> {
dword time;
int delay;
Callback cb;
void *id;
};
static dword sTClick;
static StaticCriticalSection sTimerLock;
struct CtrlTimerOwner__ : public LinkOwner<TimeEvent> {
CtrlTimerOwner__();
~CtrlTimerOwner__();
};
static TimeEvent *tevents() {
static LinkOwner<TimeEvent> t;
return t.GetPtr();
}
static void sTimeCallback(dword time, int delay, Callback cb, void *id) {
TimeEvent *list = tevents();
TimeEvent *e;
for(e = list->GetNext(); e != list && time >= e->time; e = e->GetNext());
TimeEvent *ne = e->InsertPrev();
ne->time = time;
ne->cb = cb;
ne->delay = delay;
ne->id = id;
}
void SetTimeCallback(int delay_ms, Callback cb, void *id) {
Mutex::Lock __(sTimerLock);
ASSERT(abs(delay_ms) < 0x40000000);
sTimeCallback(GetTickCount() + abs(delay_ms), delay_ms, cb, id);
}
void KillTimeCallbacks(void *id, void *idlim) {
Mutex::Lock __(sTimerLock);
TimeEvent *list = tevents();
for(TimeEvent *e = list->GetNext(); e != list;)
if(e->id >= id && e->id < idlim) {
e = e->GetNext();
delete e->GetPrev();
}
else
e = e->GetNext();
}
EXITBLOCK
{
Mutex::Lock __(sTimerLock);
while(tevents()->GetNext() != tevents())
delete tevents()->GetNext();
}
bool ExistsTimeCallback(void *id) {
Mutex::Lock __(sTimerLock);
TimeEvent *list = tevents();
for(TimeEvent *e = list->GetNext(); e != list; e = e->GetNext())
if(e->id == id)
return true;
return false;
}
void KillTimeCallback(void *id) {
KillTimeCallbacks(id, (byte *)id + 1);
}
void Ctrl::TimerProc(dword time)
{
if(IsPanicMode())
return;
sTimerLock.Enter();
TimeEvent *list = tevents();
if(sTClick > time)
for(TimeEvent *e = list->GetNext(); e != list; e = e->GetNext())
if(e->time > 0x80000000)
e->time = 0;
sTClick = time;
sTimerLock.Leave();
Ctrl::CheckMouseCtrl();
Ctrl::SyncCaret();
sTimerLock.Enter();
while(list->GetNext() != list && list->GetNext()->time < time) {
TimeEvent *e = list->GetNext();
e->Unlink();
if(e->delay < 0)
sTimeCallback(time - e->delay, e->delay, e->cb, e->id);
sTimerLock.Leave();
e->cb();
sTimerLock.Enter();
delete e;
}
sTimerLock.Leave();
}
void Ctrl::InitTimer()
{
Mutex::Lock __(sTimerLock);
tevents();
}
void Ctrl::SetTimeCallback(int delay_ms, Callback cb, int id) {
ASSERT(id >= 0 && (size_t)id < (int)sizeof(Ctrl));
UPP::SetTimeCallback(delay_ms, cb, (byte *)this + id);
}
void Ctrl::KillTimeCallback(int id) {
ASSERT(id >= 0 && (size_t)id < sizeof(Ctrl));
UPP::KillTimeCallback((byte *)this + id);
}
void Ctrl::KillSetTimeCallback(int delay_ms, Callback cb, int id)
{
KillTimeCallback(id);
SetTimeCallback(delay_ms, cb, id);
}
void Ctrl::PostCallback(Callback cb, int id)
{
SetTimeCallback(0, cb, id);
}
void Ctrl::KillPostCallback(Callback cb, int id)
{
KillSetTimeCallback(0, cb, id);
}
bool Ctrl::ExistsTimeCallback(int id) const {
ASSERT(id >= 0 && (size_t)id < sizeof(Ctrl));
return UPP::ExistsTimeCallback((byte *)this + id);
}
dword GetTimeClick()
{
return sTClick;
}
void Ctrl::EndLoop()
{
GuiLock __;
inloop = false;
}
void Ctrl::EndLoop(int code)
{
GuiLock __;
ASSERT(!parent);
exitcode = code;
EndLoop();
}
bool Ctrl::InLoop() const
{
GuiLock __;
return inloop;
}
bool Ctrl::InCurrentLoop() const
{
GuiLock __;
return GetLoopCtrl() == this;
}
int Ctrl::GetExitCode() const
{
GuiLock __;
return exitcode;
}
#ifdef _MULTITHREADED
struct Ctrl::CallBox {
Semaphore sem;
Callback cb;
};
void Ctrl::PerformCall(Ctrl::CallBox *cbox)
{
cbox->cb();
cbox->sem.Release();
}
void WakeUpGuiThread();
void Ctrl::Call(Callback cb)
{
if(IsMainThread())
cb();
else {
CallBox cbox;
cbox.cb = cb;
UPP::PostCallback(callback1(Ctrl::PerformCall, &cbox));
WakeUpGuiThread();
int level = LeaveGuiMutexAll();
cbox.sem.Wait();
EnterGuiMutex(level);
}
}
#else
void Ctrl::Call(Callback cb)
{
cb();
}
#endif
void Ctrl::EventLoop(Ctrl *ctrl)
{
Call(callback1(&Ctrl::EventLoop0, ctrl));
}
void Ctrl::WndDestroy()
{
Call(callback(this, &Ctrl::WndDestroy0));
}
void Ctrl::GuiSleep(int ms)
{
Call(callback1(&Ctrl::GuiSleep0, ms));
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,87 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#ifndef PLATFORM_WINCE
void DHCtrl::NcCreate(HWND _hwnd)
{
hwnd = _hwnd;
}
void DHCtrl::NcDestroy()
{
hwnd = NULL;
}
LRESULT DHCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
GuiLock __;
return DefWindowProc(hwnd, message, wParam, lParam);
}
void DHCtrl::CloseHWND()
{
GuiLock __;
if(hwnd) {
DestroyWindow(hwnd);
hwnd = NULL;
}
}
void DHCtrl::OpenHWND()
{
GuiLock __;
CloseHWND();
HWND phwnd = GetTopCtrl()->GetHWND();
if(phwnd) {
CreateWindowEx(0, "UPP-CLASS-A", "",
WS_CHILD|WS_DISABLED|WS_VISIBLE,
0, 0, 20, 20,
phwnd, NULL, hInstance, this);
}
}
void DHCtrl::SyncHWND()
{
GuiLock __;
HWND phwnd = GetTopCtrl()->GetHWND();
if(phwnd) {
Rect r = GetScreenView();
Rect pr = GetScreenClient(phwnd);
SetWindowPos(hwnd, NULL, r.left - pr.left, r.top - pr.top, r.Width(), r.Height(),
SWP_NOACTIVATE|SWP_NOZORDER);
ShowWindow(hwnd, IsVisible() ? SW_SHOW : SW_HIDE);
}
}
void DHCtrl::State(int reason)
{
switch(reason) {
case OPEN:
OpenHWND();
default:
SyncHWND();
break;
case CLOSE:
CloseHWND();
}
}
DHCtrl::DHCtrl()
{
hwnd = NULL;
isdhctrl = true;
}
DHCtrl::~DHCtrl()
{
CloseHWND();
BackPaint(EXCLUDEPAINT);
}
#endif
#endif
END_UPP_NAMESPACE

163
olddraw/CtrlCore/Frame.cpp Normal file
View file

@ -0,0 +1,163 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef flagSO
CtrlFrame::CtrlFrame() {}
CtrlFrame::~CtrlFrame() {}
#endif
void CtrlFrame::FramePaint(Draw& draw, const Rect& r) {}
void CtrlFrame::FrameAdd(Ctrl& ctrl) {}
void CtrlFrame::FrameRemove() {}
int CtrlFrame::OverPaint() const { return 0; }
void NullFrameClass::FrameLayout(Rect& r) {}
void NullFrameClass::FramePaint(Draw& draw, const Rect& r) {}
void NullFrameClass::FrameAddSize(Size& sz) {}
CtrlFrame& GLOBAL_V(NullFrameClass, NullFrame);
#ifdef flagSO
BorderFrame::BorderFrame(const ColorF *border) : border(border) {}
BorderFrame::~BorderFrame() {}
#endif
void BorderFrame::FrameLayout(Rect& r)
{
Size sz = r.GetSize();
int n = (int)(intptr_t)*border;
if(sz.cx >= 2 * n && sz.cy >= 2 * n)
r.Deflate(n);
}
void BorderFrame::FrameAddSize(Size& sz)
{
sz += 2 * (int)(intptr_t)*border;
}
void BorderFrame::FramePaint(Draw& draw, const Rect& r)
{
Size sz = r.GetSize();
int n = (int)(intptr_t)*border;
if(sz.cx >= 2 * n && sz.cy >= 2 * n)
DrawBorder(draw, r.left, r.top, r.Width(), r.Height(), border);
}
CtrlFrame& GLOBAL_VP(BorderFrame, InsetFrame, (InsetBorder()));
CtrlFrame& GLOBAL_VP(BorderFrame, ThinInsetFrame, (ThinInsetBorder()));
CtrlFrame& GLOBAL_VP(BorderFrame, ButtonFrame, (ButtonBorder()));
CtrlFrame& GLOBAL_VP(BorderFrame, BlackFrame, (BlackBorder()));
CtrlFrame& GLOBAL_VP(BorderFrame, OutsetFrame, (OutsetBorder()));
CtrlFrame& GLOBAL_VP(BorderFrame, ThinOutsetFrame, (ThinOutsetBorder()));
CH_COLOR(FieldFrameColor, Blend(SColorHighlight, SColorShadow));
class XPFieldFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.Deflate(2); }
virtual void FramePaint(Draw& w, const Rect& r) {
DrawFrame(w, r, FieldFrameColor());
DrawFrame(w, r.Deflated(1), SColorPaper);
}
virtual void FrameAddSize(Size& sz) { sz += 4; }
};
class XPEditFieldFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.Deflate(1); }
virtual void FramePaint(Draw& w, const Rect& r) {
DrawFrame(w, r, FieldFrameColor());
}
virtual void FrameAddSize(Size& sz) { sz += 2; }
};
CtrlFrame& XPFieldFrame() { return Single<XPFieldFrameCls>(); }
CtrlFrame& XPEditFieldFrame() { return Single<XPEditFieldFrameCls>(); }
CH_INT(EditFieldIsThin, 0);
CtrlFrame& FieldFrame() { return GUI_GlobalStyle() >= GUISTYLE_XP ? XPFieldFrame() : InsetFrame(); }
CH_VALUE(TopSeparator1, SColorShadow());
CH_VALUE(TopSeparator2, SColorLight());
class TopSeparatorFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.top += 2; }
virtual void FramePaint(Draw& w, const Rect& r) {
ChPaint(w, r.left, r.top, r.Width(), 1, TopSeparator1());
ChPaint(w, r.left, r.top + 1, r.Width(), 1, TopSeparator2());
}
virtual void FrameAddSize(Size& sz) { sz.cy += 2; }
};
class BottomSeparatorFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.bottom -= 2; }
virtual void FramePaint(Draw& w, const Rect& r) {
w.DrawRect(r.left, r.bottom - 2, r.Width(), 1, SColorShadow);
w.DrawRect(r.left, r.bottom - 1, r.Width(), 1, SColorLight);
}
virtual void FrameAddSize(Size& sz) { sz.cy += 2; }
};
class LeftSeparatorFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.left += 2; }
virtual void FramePaint(Draw& w, const Rect& r) {
w.DrawRect(r.left, r.top, 1, r.Height(), SColorShadow);
w.DrawRect(r.left + 1, r.top, 1, r.Height(), SColorLight);
}
virtual void FrameAddSize(Size& sz) { sz.cx += 2; }
};
class RightSeparatorFrameCls : public CtrlFrame {
virtual void FrameLayout(Rect& r) { r.right -= 2; }
virtual void FramePaint(Draw& w, const Rect& r) {
w.DrawRect(r.right - 2, r.top, 1, r.Height(), SColorShadow);
w.DrawRect(r.right - 1, r.top, 1, r.Height(), SColorLight);
}
virtual void FrameAddSize(Size& sz) { sz.cx += 2; }
};
CtrlFrame& BottomSeparatorFrame() { return Single<BottomSeparatorFrameCls>(); }
CtrlFrame& TopSeparatorFrame() { return Single<TopSeparatorFrameCls>(); }
CtrlFrame& RightSeparatorFrame() { return Single<RightSeparatorFrameCls>(); }
CtrlFrame& LeftSeparatorFrame() { return Single<LeftSeparatorFrameCls>(); }
CH_INT(FrameButtonWidth, 17);
CH_INT(ScrollBarArrowSize, FrameButtonWidth());
void LayoutFrameLeft(Rect& r, Ctrl *ctrl, int cx)
{
if(ctrl) {
cx *= ctrl->IsShown();
ctrl->SetFrameRect(r.left, r.top, cx, r.Height());
r.left += cx;
}
}
void LayoutFrameRight(Rect& r, Ctrl *ctrl, int cx)
{
if(ctrl) {
cx *= ctrl->IsShown();
ctrl->SetFrameRect(r.right - cx, r.top, cx, r.Height());
r.right -= cx;
}
}
void LayoutFrameTop(Rect& r, Ctrl *ctrl, int cy)
{
if(ctrl) {
cy *= ctrl->IsShown();
ctrl->SetFrameRect(r.left, r.top, r.Width(), cy);
r.top += cy;
}
}
void LayoutFrameBottom(Rect& r, Ctrl *ctrl, int cy)
{
if(ctrl) {
cy *= ctrl->IsShown();
ctrl->SetFrameRect(r.left, r.bottom - cy, r.Width(), cy);
r.bottom -= cy;
}
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,317 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
void LocalLoop::Run()
{
ASSERT(master);
master->AddChild(this);
Ptr<Ctrl> focus = GetFocusCtrl();
SetCapture();
SetFocus();
LLOG("LocalLoop::Run");
EventLoop(this);
LLOG("LocalLoop Finished");
Remove();
if(focus)
focus->SetFocus();
}
void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
Color color, uint64 pattern)
{
ViewDraw w(&q);
DrawDragRect(w, rect1, rect2, clip, n, color, pattern);
}
void RectTracker::LeftUp(Point, dword)
{
EndLoop();
}
void RectTracker::RightUp(Point, dword)
{
EndLoop();
}
Image RectTracker::CursorImage(Point, dword)
{
if(animation)
DrawRect(rect, rect);
return cursorimage;
}
static uint64 RectTracker_normal = I64(0x55aa55aa55aa55aa);
static uint64 RectTracker_dashed = I64(0xf0783c1e0f87c3e1);
static uint64 RectTracker_solid = I64(0);
RectTracker::RectTracker(Ctrl& master)
{
SetMaster(master);
Clip(Rect(0, 0, 100000, 100000));
width = 1;
minsize = Size(0, 0);
maxsize = Size(100000, 100000);
maxrect = Rect(-100000, -100000, 100000, 100000);
keepratio = false;
cursorimage = Image::Arrow();
color = SColorPaper;
pattern = RectTracker_normal;
animation = 0;
rounder = NULL;
}
RectTracker::~RectTracker() {}
RectTracker& RectTracker::Dashed() { pattern = RectTracker_dashed; return *this; }
RectTracker& RectTracker::Solid() { pattern = RectTracker_solid; return *this; }
static uint64 sGetAniPat(uint64 src, int pos)
{
uint64 out = 0;
pos &= 7;
for(int i = 8; --i >= 0;) {
byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7)));
out = (out << 8) | (byte)((sr | (sr << 8)) >> pos);
}
return out;
}
void RectTracker::DrawRect(Rect r1, Rect r2)
{
if(ty < 0) {
r1.left = r1.right - 1;
r2.left = r2.right - 1;
}
if(tx < 0) {
r1.top = r1.bottom - 1;
r2.top = r2.bottom - 1;
}
Rect c = clip & GetMaster().GetSize();
if(animation) {
int nanim = (GetTickCount() / animation) % 8;
DrawDragRect(GetMaster(), Rect(0, 0, 0, 0), r2, c, width, color, sGetAniPat(pattern, nanim));
DrawDragRect(GetMaster(), r1, Rect(0, 0, 0, 0), c, width, color, sGetAniPat(pattern, panim));
panim = nanim;
}
else
DrawDragRect(GetMaster(), r1, r2, c, width, color, pattern);
}
Rect RectTracker::Track(const Rect& r, int _tx, int _ty)
{
rect = r;
tx = _tx;
ty = _ty;
org = rect;
o = rect;
op = GetMousePos();
GetMaster().Sync();
DrawRect(Rect(0, 0, 0, 0), rect);
Run();
DrawRect(o, Rect(0, 0, 0, 0));
return rect;
}
int RectTracker::TrackHorzLine(int x0, int y0, int cx, int line)
{
return Track(RectC(x0, y0, cx, line + 1), -1, ALIGN_BOTTOM).bottom - 1;
}
int RectTracker::TrackVertLine(int x0, int y0, int cy, int line)
{
return Track(RectC(x0, y0, line + 1, cy), ALIGN_RIGHT, -1).right - 1;
}
void RectTracker::MouseMove(Point, dword)
{
Point p = GetMousePos();
rect = org;
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) {
int x = org.left - op.x + p.x;
int y = org.top - op.y + p.y;
if(x + org.Width() > maxrect.right)
x = maxrect.right - org.Width();
if(x < maxrect.left)
x = maxrect.left;
if(y + org.Height() > maxrect.bottom)
y = maxrect.bottom - org.Height();
if(y < maxrect.top)
y = maxrect.top;
rect = RectC(x, y, org.Width(), org.Height());
}
else {
if(tx == ALIGN_LEFT) {
rect.left = max(org.left - op.x + p.x, maxrect.left);
rect.left = minmax(rect.left, rect.right - maxsize.cx, rect.right - minsize.cx);
}
if(tx == ALIGN_RIGHT) {
rect.right = min(org.right - op.x + p.x, maxrect.right);
rect.right = minmax(rect.right, rect.left + minsize.cx, rect.left + maxsize.cx);
}
if(ty == ALIGN_TOP) {
rect.top = max(org.top - op.y + p.y, maxrect.top);
rect.top = minmax(rect.top, rect.bottom - maxsize.cy, rect.bottom - minsize.cy);
}
if(ty == ALIGN_BOTTOM) {
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
rect.bottom = minmax(rect.bottom, rect.top + minsize.cy, rect.top + maxsize.cy);
}
if(tx == ALIGN_NULL) {
rect.right = min(org.right - op.x + p.x, maxrect.right);
if (rect.right < rect.left) {
Swap(rect.right, rect.left);
rect.InflateHorz(1);
}
}
if(ty == ALIGN_NULL) {
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
if (rect.bottom < rect.top) {
Swap(rect.bottom, rect.top);
rect.InflateVert(1);
}
}
if(keepratio) {
int cy = org.Width() ? rect.Width() * org.Height() / org.Width() : 0;
int cx = org.Height() ? rect.Height() * org.Width() / org.Height() : 0;
if(tx == ALIGN_BOTTOM && ty == ALIGN_RIGHT) {
Size sz = rect.Size();
if(cx > sz.cx)
rect.right = rect.left + cx;
else
rect.bottom = rect.top + cy;
}
else
if(tx == ALIGN_RIGHT)
rect.bottom = rect.top + cy;
else
if(ty == ALIGN_BOTTOM)
rect.right = rect.left + cx;
}
}
if(rect != o) {
rect = Round(rect);
if(rect != o) {
DrawRect(o, rect);
sync(rect);
o = rect;
}
}
}
/*
void RectTracker::MouseMove(Point, dword)
{
Point p = GetMousePos();
rect = org;
if(tx == ALIGN_CENTER && ty == ALIGN_CENTER) {
int x = org.left - op.x + p.x;
int y = org.top - op.y + p.y;
if(x + org.Width() > maxrect.right)
x = maxrect.right - org.Width();
if(x < maxrect.left)
x = maxrect.left;
if(y + org.Height() > maxrect.bottom)
y = maxrect.bottom - org.Height();
if(y < maxrect.top)
y = maxrect.top;
rect = RectC(x, y, org.Width(), org.Height());
}
else {
if(tx == ALIGN_LEFT) {
rect.left = max(org.left - op.x + p.x, maxrect.left);
rect.left = minmax(rect.left, rect.right - maxsize.cx, rect.right - minsize.cx);
}
if(tx == ALIGN_RIGHT) {
rect.right = min(org.right - op.x + p.x, maxrect.right);
rect.right = minmax(rect.right, rect.left + minsize.cx, rect.left + maxsize.cx);
}
if(ty == ALIGN_TOP) {
rect.top = max(org.top - op.y + p.y, maxrect.top);
rect.top = minmax(rect.top, rect.bottom - maxsize.cy, rect.bottom - minsize.cy);
}
if(ty == ALIGN_BOTTOM) {
rect.bottom = min(org.bottom - op.y + p.y, maxrect.bottom);
rect.bottom = minmax(rect.bottom, rect.top + minsize.cy, rect.top + maxsize.cy);
}
if(keepratio) {
int cy = org.Width() ? rect.Width() * org.Height() / org.Width() : 0;
int cx = org.Height() ? rect.Height() * org.Width() / org.Height() : 0;
if(tx == ALIGN_BOTTOM && ty == ALIGN_RIGHT) {
Size sz = rect.Size();
if(cx > sz.cx)
rect.right = rect.left + cx;
else
rect.bottom = rect.top + cy;
}
else
if(tx == ALIGN_RIGHT)
rect.bottom = rect.top + cy;
else
if(ty == ALIGN_BOTTOM)
rect.right = rect.left + cx;
}
}
if(rect != o) {
rect = Round(rect);
if(rect != o) {
DrawRect(o, rect);
sync(rect);
o = rect;
}
}
}
*/
class PointLooper : public LocalLoop {
const Vector<Image>& ani;
int ani_ms;
bool result;
public:
virtual void LeftUp(Point, dword);
virtual Image CursorImage(Point p, dword keyflags);
virtual bool Key(dword key, int);
operator bool() const { return result; }
PointLooper(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms)
: ani(ani), ani_ms(ani_ms) { SetMaster(ctrl); }
};
void PointLooper::LeftUp(Point, dword)
{
result = true;
EndLoop();
}
Image PointLooper::CursorImage(Point p, dword keyflags)
{
return ani[int(GetTimeClick() / ani_ms % ani.GetCount())];
}
bool PointLooper::Key(dword key, int)
{
if(key == K_ESCAPE) {
result = false;
EndLoop();
}
return true;
}
bool PointLoop(Ctrl& ctrl, const Vector<Image>& ani, int ani_ms)
{
PointLooper p(ctrl, ani, ani_ms);
p.Run();
return p;
}
bool PointLoop(Ctrl& ctrl, const Image& img)
{
Vector<Image> m;
m.Add(img);
return PointLoop(ctrl, m, 1);
}
END_UPP_NAMESPACE

367
olddraw/CtrlCore/MKeys.h Normal file
View file

@ -0,0 +1,367 @@
#ifdef PLATFORM_X11
#include "X11/keysym.h"
#endif
enum {
#ifdef PLATFORM_X11
#include "X11Keys.i"
#endif
#ifdef PLATFORM_WIN32
#include "Win32Keys.i"
#endif
K_CTRL_BACK = K_CTRL|K_BACKSPACE,
K_CTRL_BACKSPACE = K_CTRL|K_BACKSPACE,
K_CTRL_TAB = K_CTRL|K_TAB,
K_CTRL_RETURN = K_CTRL|K_ENTER,
K_CTRL_ENTER = K_CTRL|K_ENTER,
K_CTRL_ESCAPE = K_CTRL|K_ESCAPE,
K_CTRL_SPACE = K_CTRL|K_SPACE,
K_CTRL_PRIOR = K_CTRL|K_PAGEUP,
K_CTRL_PAGEUP = K_CTRL|K_PAGEUP,
K_CTRL_NEXT = K_CTRL|K_PAGEDOWN,
K_CTRL_PAGEDOWN = K_CTRL|K_PAGEDOWN,
K_CTRL_END = K_CTRL|K_END,
K_CTRL_HOME = K_CTRL|K_HOME,
K_CTRL_LEFT = K_CTRL|K_LEFT,
K_CTRL_UP = K_CTRL|K_UP,
K_CTRL_RIGHT = K_CTRL|K_RIGHT,
K_CTRL_DOWN = K_CTRL|K_DOWN,
K_CTRL_INSERT = K_CTRL|K_INSERT,
K_CTRL_DELETE = K_CTRL|K_DELETE,
K_CTRL_NUMPAD0 = K_CTRL|K_NUMPAD0,
K_CTRL_NUMPAD1 = K_CTRL|K_NUMPAD1,
K_CTRL_NUMPAD2 = K_CTRL|K_NUMPAD2,
K_CTRL_NUMPAD3 = K_CTRL|K_NUMPAD3,
K_CTRL_NUMPAD4 = K_CTRL|K_NUMPAD4,
K_CTRL_NUMPAD5 = K_CTRL|K_NUMPAD5,
K_CTRL_NUMPAD6 = K_CTRL|K_NUMPAD6,
K_CTRL_NUMPAD7 = K_CTRL|K_NUMPAD7,
K_CTRL_NUMPAD8 = K_CTRL|K_NUMPAD8,
K_CTRL_NUMPAD9 = K_CTRL|K_NUMPAD9,
K_CTRL_MULTIPLY = K_CTRL|K_MULTIPLY,
K_CTRL_ADD = K_CTRL|K_ADD,
K_CTRL_SEPARATOR = K_CTRL|K_SEPARATOR,
K_CTRL_SUBTRACT = K_CTRL|K_SUBTRACT,
K_CTRL_DECIMAL = K_CTRL|K_DECIMAL,
K_CTRL_DIVIDE = K_CTRL|K_DIVIDE,
K_CTRL_F1 = K_CTRL|K_F1,
K_CTRL_F2 = K_CTRL|K_F2,
K_CTRL_F3 = K_CTRL|K_F3,
K_CTRL_F4 = K_CTRL|K_F4,
K_CTRL_F5 = K_CTRL|K_F5,
K_CTRL_F6 = K_CTRL|K_F6,
K_CTRL_F7 = K_CTRL|K_F7,
K_CTRL_F8 = K_CTRL|K_F8,
K_CTRL_F9 = K_CTRL|K_F9,
K_CTRL_F10 = K_CTRL|K_F10,
K_CTRL_F11 = K_CTRL|K_F11,
K_CTRL_F12 = K_CTRL|K_F12,
K_CTRL_SCROLL = K_CTRL|K_SCROLL,
K_CTRL_A = K_CTRL|K_A,
K_CTRL_B = K_CTRL|K_B,
K_CTRL_C = K_CTRL|K_C,
K_CTRL_D = K_CTRL|K_D,
K_CTRL_E = K_CTRL|K_E,
K_CTRL_F = K_CTRL|K_F,
K_CTRL_G = K_CTRL|K_G,
K_CTRL_H = K_CTRL|K_H,
K_CTRL_I = K_CTRL|K_I,
K_CTRL_J = K_CTRL|K_J,
K_CTRL_K = K_CTRL|K_K,
K_CTRL_L = K_CTRL|K_L,
K_CTRL_M = K_CTRL|K_M,
K_CTRL_N = K_CTRL|K_N,
K_CTRL_O = K_CTRL|K_O,
K_CTRL_P = K_CTRL|K_P,
K_CTRL_Q = K_CTRL|K_Q,
K_CTRL_R = K_CTRL|K_R,
K_CTRL_S = K_CTRL|K_S,
K_CTRL_T = K_CTRL|K_T,
K_CTRL_U = K_CTRL|K_U,
K_CTRL_V = K_CTRL|K_V,
K_CTRL_W = K_CTRL|K_W,
K_CTRL_X = K_CTRL|K_X,
K_CTRL_Y = K_CTRL|K_Y,
K_CTRL_Z = K_CTRL|K_Z,
K_CTRL_0 = K_CTRL|K_0,
K_CTRL_1 = K_CTRL|K_1,
K_CTRL_2 = K_CTRL|K_2,
K_CTRL_3 = K_CTRL|K_3,
K_CTRL_4 = K_CTRL|K_4,
K_CTRL_5 = K_CTRL|K_5,
K_CTRL_6 = K_CTRL|K_6,
K_CTRL_7 = K_CTRL|K_7,
K_CTRL_8 = K_CTRL|K_8,
K_CTRL_9 = K_CTRL|K_9,
K_SHIFT_BACK = K_SHIFT|K_BACKSPACE,
K_SHIFT_BACKSPACE = K_SHIFT|K_BACKSPACE,
K_SHIFT_TAB = K_SHIFT|K_TAB,
K_SHIFT_RETURN = K_SHIFT|K_ENTER,
K_SHIFT_ENTER = K_SHIFT|K_ENTER,
K_SHIFT_ESCAPE = K_SHIFT|K_ESCAPE,
K_SHIFT_SPACE = K_SHIFT|K_SPACE,
K_SHIFT_PRIOR = K_SHIFT|K_PAGEUP,
K_SHIFT_PAGEUP = K_SHIFT|K_PAGEUP,
K_SHIFT_NEXT = K_SHIFT|K_PAGEDOWN,
K_SHIFT_PAGEDOWN = K_SHIFT|K_PAGEDOWN,
K_SHIFT_END = K_SHIFT|K_END,
K_SHIFT_HOME = K_SHIFT|K_HOME,
K_SHIFT_LEFT = K_SHIFT|K_LEFT,
K_SHIFT_UP = K_SHIFT|K_UP,
K_SHIFT_RIGHT = K_SHIFT|K_RIGHT,
K_SHIFT_DOWN = K_SHIFT|K_DOWN,
K_SHIFT_INSERT = K_SHIFT|K_INSERT,
K_SHIFT_DELETE = K_SHIFT|K_DELETE,
K_SHIFT_NUMPAD0 = K_SHIFT|K_NUMPAD0,
K_SHIFT_NUMPAD1 = K_SHIFT|K_NUMPAD1,
K_SHIFT_NUMPAD2 = K_SHIFT|K_NUMPAD2,
K_SHIFT_NUMPAD3 = K_SHIFT|K_NUMPAD3,
K_SHIFT_NUMPAD4 = K_SHIFT|K_NUMPAD4,
K_SHIFT_NUMPAD5 = K_SHIFT|K_NUMPAD5,
K_SHIFT_NUMPAD6 = K_SHIFT|K_NUMPAD6,
K_SHIFT_NUMPAD7 = K_SHIFT|K_NUMPAD7,
K_SHIFT_NUMPAD8 = K_SHIFT|K_NUMPAD8,
K_SHIFT_NUMPAD9 = K_SHIFT|K_NUMPAD9,
K_SHIFT_MULTIPLY = K_SHIFT|K_MULTIPLY,
K_SHIFT_ADD = K_SHIFT|K_ADD,
K_SHIFT_SEPARATOR = K_SHIFT|K_SEPARATOR,
K_SHIFT_SUBRACT = K_SHIFT|K_SUBTRACT,
K_SHIFT_DECIMAL = K_SHIFT|K_DECIMAL,
K_SHIFT_DIVIDE = K_SHIFT|K_DIVIDE,
K_SHIFT_F1 = K_SHIFT|K_F1,
K_SHIFT_F2 = K_SHIFT|K_F2,
K_SHIFT_F3 = K_SHIFT|K_F3,
K_SHIFT_F4 = K_SHIFT|K_F4,
K_SHIFT_F5 = K_SHIFT|K_F5,
K_SHIFT_F6 = K_SHIFT|K_F6,
K_SHIFT_F7 = K_SHIFT|K_F7,
K_SHIFT_F8 = K_SHIFT|K_F8,
K_SHIFT_F9 = K_SHIFT|K_F9,
K_SHIFT_F10 = K_SHIFT|K_F10,
K_SHIFT_F11 = K_SHIFT|K_F11,
K_SHIFT_F12 = K_SHIFT|K_F12,
K_SHIFT_SCROLL = K_SHIFT|K_SCROLL,
K_SHIFT_A = K_SHIFT|K_A,
K_SHIFT_B = K_SHIFT|K_B,
K_SHIFT_C = K_SHIFT|K_C,
K_SHIFT_D = K_SHIFT|K_D,
K_SHIFT_E = K_SHIFT|K_E,
K_SHIFT_F = K_SHIFT|K_F,
K_SHIFT_G = K_SHIFT|K_G,
K_SHIFT_H = K_SHIFT|K_H,
K_SHIFT_I = K_SHIFT|K_I,
K_SHIFT_J = K_SHIFT|K_J,
K_SHIFT_K = K_SHIFT|K_K,
K_SHIFT_L = K_SHIFT|K_L,
K_SHIFT_M = K_SHIFT|K_M,
K_SHIFT_N = K_SHIFT|K_N,
K_SHIFT_O = K_SHIFT|K_O,
K_SHIFT_P = K_SHIFT|K_P,
K_SHIFT_Q = K_SHIFT|K_Q,
K_SHIFT_R = K_SHIFT|K_R,
K_SHIFT_S = K_SHIFT|K_S,
K_SHIFT_T = K_SHIFT|K_T,
K_SHIFT_U = K_SHIFT|K_U,
K_SHIFT_V = K_SHIFT|K_V,
K_SHIFT_W = K_SHIFT|K_W,
K_SHIFT_X = K_SHIFT|K_X,
K_SHIFT_Y = K_SHIFT|K_Y,
K_SHIFT_Z = K_SHIFT|K_Z,
K_SHIFT_0 = K_SHIFT|K_0,
K_SHIFT_1 = K_SHIFT|K_1,
K_SHIFT_2 = K_SHIFT|K_2,
K_SHIFT_3 = K_SHIFT|K_3,
K_SHIFT_4 = K_SHIFT|K_4,
K_SHIFT_5 = K_SHIFT|K_5,
K_SHIFT_6 = K_SHIFT|K_6,
K_SHIFT_7 = K_SHIFT|K_7,
K_SHIFT_8 = K_SHIFT|K_8,
K_SHIFT_9 = K_SHIFT|K_9,
K_SHIFT_CTRL_BACK = K_SHIFT_CTRL|K_BACKSPACE,
K_SHIFT_CTRL_BACKSPACE = K_SHIFT_CTRL|K_BACKSPACE,
K_SHIFT_CTRL_TAB = K_SHIFT_CTRL|K_TAB,
K_SHIFT_CTRL_RETURN = K_SHIFT_CTRL|K_ENTER,
K_SHIFT_CTRL_ENTER = K_SHIFT_CTRL|K_ENTER,
K_SHIFT_CTRL_ESCAPE = K_SHIFT_CTRL|K_ESCAPE,
K_SHIFT_CTRL_SPACE = K_SHIFT_CTRL|K_SPACE,
K_SHIFT_CTRL_PRIOR = K_SHIFT_CTRL|K_PAGEUP,
K_SHIFT_CTRL_PAGEUP = K_SHIFT_CTRL|K_PAGEUP,
K_SHIFT_CTRL_NEXT = K_SHIFT_CTRL|K_PAGEDOWN,
K_SHIFT_CTRL_PAGEDOWN = K_SHIFT_CTRL|K_PAGEDOWN,
K_SHIFT_CTRL_END = K_SHIFT_CTRL|K_END,
K_SHIFT_CTRL_HOME = K_SHIFT_CTRL|K_HOME,
K_SHIFT_CTRL_LEFT = K_SHIFT_CTRL|K_LEFT,
K_SHIFT_CTRL_UP = K_SHIFT_CTRL|K_UP,
K_SHIFT_CTRL_RIGHT = K_SHIFT_CTRL|K_RIGHT,
K_SHIFT_CTRL_DOWN = K_SHIFT_CTRL|K_DOWN,
K_SHIFT_CTRL_INSERT = K_SHIFT_CTRL|K_INSERT,
K_SHIFT_CTRL_DELETE = K_SHIFT_CTRL|K_DELETE,
K_SHIFT_CTRL_LBRACKET = K_SHIFT_CTRL|219|K_DELTA,
K_SHIFT_CTRL_RBRACKET = K_SHIFT_CTRL|221|K_DELTA,
K_SHIFT_CTRL_NUMPAD0 = K_SHIFT_CTRL|K_NUMPAD0,
K_SHIFT_CTRL_NUMPAD1 = K_SHIFT_CTRL|K_NUMPAD1,
K_SHIFT_CTRL_NUMPAD2 = K_SHIFT_CTRL|K_NUMPAD2,
K_SHIFT_CTRL_NUMPAD3 = K_SHIFT_CTRL|K_NUMPAD3,
K_SHIFT_CTRL_NUMPAD4 = K_SHIFT_CTRL|K_NUMPAD4,
K_SHIFT_CTRL_NUMPAD5 = K_SHIFT_CTRL|K_NUMPAD5,
K_SHIFT_CTRL_NUMPAD6 = K_SHIFT_CTRL|K_NUMPAD6,
K_SHIFT_CTRL_NUMPAD7 = K_SHIFT_CTRL|K_NUMPAD7,
K_SHIFT_CTRL_NUMPAD8 = K_SHIFT_CTRL|K_NUMPAD8,
K_SHIFT_CTRL_NUMPAD9 = K_SHIFT_CTRL|K_NUMPAD9,
K_SHIFT_CTRL_MULTIPLY = K_SHIFT_CTRL|K_MULTIPLY,
K_SHIFT_CTRL_ADD = K_SHIFT_CTRL|K_ADD,
K_SHIFT_CTRL_SEPARATOR = K_SHIFT_CTRL|K_SEPARATOR,
K_SHIFT_CTRL_SUBRACT = K_SHIFT_CTRL|K_SUBTRACT,
K_SHIFT_CTRL_DECIMAL = K_SHIFT_CTRL|K_DECIMAL,
K_SHIFT_CTRL_DIVIDE = K_SHIFT_CTRL|K_DIVIDE,
K_SHIFT_CTRL_F1 = K_SHIFT_CTRL|K_F1,
K_SHIFT_CTRL_F2 = K_SHIFT_CTRL|K_F2,
K_SHIFT_CTRL_F3 = K_SHIFT_CTRL|K_F3,
K_SHIFT_CTRL_F4 = K_SHIFT_CTRL|K_F4,
K_SHIFT_CTRL_F5 = K_SHIFT_CTRL|K_F5,
K_SHIFT_CTRL_F6 = K_SHIFT_CTRL|K_F6,
K_SHIFT_CTRL_F7 = K_SHIFT_CTRL|K_F7,
K_SHIFT_CTRL_F8 = K_SHIFT_CTRL|K_F8,
K_SHIFT_CTRL_F9 = K_SHIFT_CTRL|K_F9,
K_SHIFT_CTRL_F10 = K_SHIFT_CTRL|K_F10,
K_SHIFT_CTRL_F11 = K_SHIFT_CTRL|K_F11,
K_SHIFT_CTRL_F12 = K_SHIFT_CTRL|K_F12,
K_SHIFT_CTRL_SCROLL = K_SHIFT_CTRL|K_SCROLL,
K_SHIFT_CTRL_A = K_SHIFT_CTRL|K_A,
K_SHIFT_CTRL_B = K_SHIFT_CTRL|K_B,
K_SHIFT_CTRL_C = K_SHIFT_CTRL|K_C,
K_SHIFT_CTRL_D = K_SHIFT_CTRL|K_D,
K_SHIFT_CTRL_E = K_SHIFT_CTRL|K_E,
K_SHIFT_CTRL_F = K_SHIFT_CTRL|K_F,
K_SHIFT_CTRL_G = K_SHIFT_CTRL|K_G,
K_SHIFT_CTRL_H = K_SHIFT_CTRL|K_H,
K_SHIFT_CTRL_I = K_SHIFT_CTRL|K_I,
K_SHIFT_CTRL_J = K_SHIFT_CTRL|K_J,
K_SHIFT_CTRL_K = K_SHIFT_CTRL|K_K,
K_SHIFT_CTRL_L = K_SHIFT_CTRL|K_L,
K_SHIFT_CTRL_M = K_SHIFT_CTRL|K_M,
K_SHIFT_CTRL_N = K_SHIFT_CTRL|K_N,
K_SHIFT_CTRL_O = K_SHIFT_CTRL|K_O,
K_SHIFT_CTRL_P = K_SHIFT_CTRL|K_P,
K_SHIFT_CTRL_Q = K_SHIFT_CTRL|K_Q,
K_SHIFT_CTRL_R = K_SHIFT_CTRL|K_R,
K_SHIFT_CTRL_S = K_SHIFT_CTRL|K_S,
K_SHIFT_CTRL_T = K_SHIFT_CTRL|K_T,
K_SHIFT_CTRL_U = K_SHIFT_CTRL|K_U,
K_SHIFT_CTRL_V = K_SHIFT_CTRL|K_V,
K_SHIFT_CTRL_W = K_SHIFT_CTRL|K_W,
K_SHIFT_CTRL_X = K_SHIFT_CTRL|K_X,
K_SHIFT_CTRL_Y = K_SHIFT_CTRL|K_Y,
K_SHIFT_CTRL_Z = K_SHIFT_CTRL|K_Z,
K_SHIFT_CTRL_0 = K_SHIFT_CTRL|K_0,
K_SHIFT_CTRL_1 = K_SHIFT_CTRL|K_1,
K_SHIFT_CTRL_2 = K_SHIFT_CTRL|K_2,
K_SHIFT_CTRL_3 = K_SHIFT_CTRL|K_3,
K_SHIFT_CTRL_4 = K_SHIFT_CTRL|K_4,
K_SHIFT_CTRL_5 = K_SHIFT_CTRL|K_5,
K_SHIFT_CTRL_6 = K_SHIFT_CTRL|K_6,
K_SHIFT_CTRL_7 = K_SHIFT_CTRL|K_7,
K_SHIFT_CTRL_8 = K_SHIFT_CTRL|K_8,
K_SHIFT_CTRL_9 = K_SHIFT_CTRL|K_9,
K_ALT_BACK = K_ALT|K_BACKSPACE,
K_ALT_BACKSPACE = K_ALT|K_BACKSPACE,
K_ALT_TAB = K_ALT|K_TAB,
K_ALT_RETURN = K_ALT|K_ENTER,
K_ALT_ENTER = K_ALT|K_ENTER,
K_ALT_ESCAPE = K_ALT|K_ESCAPE,
K_ALT_SPACE = K_ALT|K_SPACE,
K_ALT_PRIOR = K_ALT|K_PAGEUP,
K_ALT_PAGEUP = K_ALT|K_PAGEUP,
K_ALT_NEXT = K_ALT|K_PAGEDOWN,
K_ALT_PAGEDOWN = K_ALT|K_PAGEDOWN,
K_ALT_END = K_ALT|K_END,
K_ALT_HOME = K_ALT|K_HOME,
K_ALT_LEFT = K_ALT|K_LEFT,
K_ALT_UP = K_ALT|K_UP,
K_ALT_RIGHT = K_ALT|K_RIGHT,
K_ALT_DOWN = K_ALT|K_DOWN,
K_ALT_INSERT = K_ALT|K_INSERT,
K_ALT_DELETE = K_ALT|K_DELETE,
K_ALT_NUMPAD0 = K_ALT|K_NUMPAD0,
K_ALT_NUMPAD1 = K_ALT|K_NUMPAD1,
K_ALT_NUMPAD2 = K_ALT|K_NUMPAD2,
K_ALT_NUMPAD3 = K_ALT|K_NUMPAD3,
K_ALT_NUMPAD4 = K_ALT|K_NUMPAD4,
K_ALT_NUMPAD5 = K_ALT|K_NUMPAD5,
K_ALT_NUMPAD6 = K_ALT|K_NUMPAD6,
K_ALT_NUMPAD7 = K_ALT|K_NUMPAD7,
K_ALT_NUMPAD8 = K_ALT|K_NUMPAD8,
K_ALT_NUMPAD9 = K_ALT|K_NUMPAD9,
K_ALT_MULTIPLY = K_ALT|K_MULTIPLY,
K_ALT_ADD = K_ALT|K_ADD,
K_ALT_SEPARATOR = K_ALT|K_SEPARATOR,
K_ALT_SUBTRACT = K_ALT|K_SUBTRACT,
K_ALT_DECIMAL = K_ALT|K_DECIMAL,
K_ALT_DIVIDE = K_ALT|K_DIVIDE,
K_ALT_F1 = K_ALT|K_F1,
K_ALT_F2 = K_ALT|K_F2,
K_ALT_F3 = K_ALT|K_F3,
K_ALT_F4 = K_ALT|K_F4,
K_ALT_F5 = K_ALT|K_F5,
K_ALT_F6 = K_ALT|K_F6,
K_ALT_F7 = K_ALT|K_F7,
K_ALT_F8 = K_ALT|K_F8,
K_ALT_F9 = K_ALT|K_F9,
K_ALT_F10 = K_ALT|K_F10,
K_ALT_F11 = K_ALT|K_F11,
K_ALT_F12 = K_ALT|K_F12,
K_ALT_SCROLL = K_ALT|K_SCROLL,
K_ALT_A = K_ALT|K_A,
K_ALT_B = K_ALT|K_B,
K_ALT_C = K_ALT|K_C,
K_ALT_D = K_ALT|K_D,
K_ALT_E = K_ALT|K_E,
K_ALT_F = K_ALT|K_F,
K_ALT_G = K_ALT|K_G,
K_ALT_H = K_ALT|K_H,
K_ALT_I = K_ALT|K_I,
K_ALT_J = K_ALT|K_J,
K_ALT_K = K_ALT|K_K,
K_ALT_L = K_ALT|K_L,
K_ALT_M = K_ALT|K_M,
K_ALT_N = K_ALT|K_N,
K_ALT_O = K_ALT|K_O,
K_ALT_P = K_ALT|K_P,
K_ALT_Q = K_ALT|K_Q,
K_ALT_R = K_ALT|K_R,
K_ALT_S = K_ALT|K_S,
K_ALT_T = K_ALT|K_T,
K_ALT_U = K_ALT|K_U,
K_ALT_V = K_ALT|K_V,
K_ALT_W = K_ALT|K_W,
K_ALT_X = K_ALT|K_X,
K_ALT_Y = K_ALT|K_Y,
K_ALT_Z = K_ALT|K_Z,
K_ALT_0 = K_ALT|K_0,
K_ALT_1 = K_ALT|K_1,
K_ALT_2 = K_ALT|K_2,
K_ALT_3 = K_ALT|K_3,
K_ALT_4 = K_ALT|K_4,
K_ALT_5 = K_ALT|K_5,
K_ALT_6 = K_ALT|K_6,
K_ALT_7 = K_ALT|K_7,
K_ALT_8 = K_ALT|K_8,
K_ALT_9 = K_ALT|K_9,
K_CTRL_BREAK = K_CTRL|K_BREAK,
};

View file

@ -0,0 +1,6 @@
FN_C(HMONITOR, WINAPI, MonitorFromWindow, (HWND, DWORD))
FN_C(HMONITOR, WINAPI, MonitorFromRect, (LPCRECT, DWORD))
FN_C(HMONITOR, WINAPI, MonitorFromPoint, (POINT, DWORD))
FN_C(BOOL, WINAPI, GetMonitorInfo, (HMONITOR, LPMONITORINFO))
FN_C(BOOL, WINAPI, EnumDisplayMonitors, (HDC, LPCRECT, MONITORENUMPROC, LPARAM))
FN_C(BOOL, WINAPI, EnumDisplayDevices, (PVOID, DWORD, PDISPLAY_DEVICE,DWORD))

View file

@ -0,0 +1,282 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#ifdef PLATFORM_WIN32
void TopWindow::SyncSizeHints() {}
LRESULT TopWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
GuiLock __;
HWND hwnd = GetHWND();
#ifndef PLATFORM_WINCE
bool inloop;
#endif
switch(message) {
#ifndef PLATFORM_WINCE
case WM_QUERYENDSESSION:
inloop = InLoop();
WhenClose();
return inloop ? !InLoop() : !IsOpen();
case WM_ENDSESSION:
EndSession() = true;
PostQuitMessage(0);
return 0;
#endif
case WM_CLOSE:
if(IsEnabled()) {
IgnoreMouseUp();
WhenClose();
}
return 0;
case WM_WINDOWPOSCHANGED:
#ifndef PLATFORM_WINCE
if(IsIconic(hwnd))
state = MINIMIZED;
else
if(IsZoomed(hwnd))
state = MAXIMIZED;
else
#endif
{
state = OVERLAPPED;
overlapped = GetScreenClient(hwnd);
}
Layout();
break;
}
return Ctrl::WindowProc(message, wParam, lParam);
}
void TopWindow::SyncTitle0()
{
GuiLock __;
HWND hwnd = GetHWND();
#ifndef PLATFORM_WINCE
if(hwnd)
if(IsWindowUnicode(hwnd))
::SetWindowTextW(hwnd, (const WCHAR*)~title);
else
#endif
::SetWindowText(hwnd, ToSystemCharset(title.ToString()));
}
void TopWindow::DeleteIco0()
{
GuiLock __;
if(ico)
DestroyIcon(ico);
if(lico)
DestroyIcon(lico);
ico = lico = NULL;
}
void TopWindow::DeleteIco()
{
Call(THISBACK(DeleteIco0));
}
void TopWindow::SyncCaption0()
{
GuiLock __;
LLOG("SyncCaption");
if(fullscreen)
return;
HWND hwnd = GetHWND();
if(hwnd) {
style = ::GetWindowLong(hwnd, GWL_STYLE);
exstyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
}
style &= ~(WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_POPUP|WS_DLGFRAME);
exstyle &= ~(WS_EX_TOOLWINDOW|WS_EX_DLGMODALFRAME);
style |= WS_CAPTION;
if(hasdhctrl)
style |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
if(minimizebox)
style |= WS_MINIMIZEBOX;
if(maximizebox)
style |= WS_MAXIMIZEBOX;
if(sizeable)
style |= WS_THICKFRAME;
#ifndef PLATFORM_WINCE
if(frameless)
style = (style & ~WS_CAPTION) | WS_POPUP;
else
if(IsNull(icon) && !maximizebox && !minimizebox || noclosebox) {
style |= WS_POPUPWINDOW|WS_DLGFRAME;
exstyle |= WS_EX_DLGMODALFRAME;
if(noclosebox)
style &= ~WS_SYSMENU;
}
else
#endif
style |= WS_SYSMENU;
if(tool)
exstyle |= WS_EX_TOOLWINDOW;
if(hwnd) {
::SetWindowLong(hwnd, GWL_STYLE, style);
::SetWindowLong(hwnd, GWL_EXSTYLE, exstyle);
SyncTitle();
}
DeleteIco();
#ifndef PLATFORM_WINCE //TODO!!!
if(hwnd) {
::SendMessage(hwnd, WM_SETICON, false, (LPARAM)(ico = IconWin32(icon)));
::SendMessage(hwnd, WM_SETICON, true, (LPARAM)(lico = IconWin32(largeicon)));
}
#endif
}
void TopWindow::CenterRect(HWND hwnd, int center)
{
GuiLock __;
SetupRect();
if(hwnd && center == 1 || center == 2) {
Size sz = GetRect().Size();
Rect frmrc(sz);
#ifndef PLATFORM_WINCE
::AdjustWindowRect(frmrc, WS_OVERLAPPEDWINDOW, FALSE);
#endif
Rect r, wr;
wr = Ctrl::GetWorkArea().Deflated(-frmrc.left, -frmrc.top,
frmrc.right - sz.cx, frmrc.bottom - sz.cy);
sz.cx = min(sz.cx, wr.Width());
sz.cy = min(sz.cy, wr.Height());
if(center == 1) {
::GetClientRect(hwnd, r);
if(r.IsEmpty())
r = wr;
else {
Point p = r.TopLeft();
::ClientToScreen(hwnd, p);
r.Offset(p);
}
}
else
r = wr;
Point p = r.CenterPos(sz);
if(p.x + sz.cx > wr.right) p.x = wr.right - sz.cx;
if(p.y + sz.cy > wr.bottom) p.y = wr.bottom - sz.cy;
if(p.x < wr.left) p.x = wr.left;
if(p.y < wr.top) p.y = wr.top;
SetRect(p.x, p.y, sz.cx, sz.cy);
}
}
static HWND trayHWND__;
HWND GetTrayHWND__() { return trayHWND__; }
void SetTrayHWND__(HWND hwnd) { trayHWND__ = hwnd; }
void TopWindow::Open(HWND hwnd)
{
GuiLock __;
if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
DistributeAccessKeys();
UsrLogT(3, "OPEN " + Desc(this));
LLOG("TopWindow::Open, owner HWND = " << FormatIntHex((int)hwnd, 8) << ", Active = " << FormatIntHex((int)::GetActiveWindow(), 8));
IgnoreMouseUp();
SyncCaption();
#ifdef PLATFORM_WINCE
if(!GetRect().IsEmpty())
#endif
if(fullscreen) {
SetRect(GetScreenSize());
Create(hwnd, WS_POPUP, 0, false, SW_SHOWMAXIMIZED, false);
}
else {
CenterRect(hwnd, hwnd && hwnd == GetTrayHWND__() ? center ? 2 : 0 : center);
Create(hwnd, style, exstyle, false, state == OVERLAPPED ? SW_SHOWNORMAL :
state == MINIMIZED ? SW_MINIMIZE :
SW_MAXIMIZE, false);
}
PlaceFocus();
SyncCaption();
FixIcons();
}
void TopWindow::Open(Ctrl *owner)
{
GuiLock __;
LLOG("TopWindow::Open(Ctrl) -> " << UPP::Name(owner));
Open(owner ? owner->GetTopCtrl()->GetHWND() : NULL);
if(IsOpen() && top)
top->owner = owner;
}
void TopWindow::Open()
{
Open(::GetActiveWindow()); // :: needed because of ActiveX controls (to create modal dlgs owned by a HWND)
}
void TopWindow::OpenMain()
{
Open((HWND) NULL);
}
void TopWindow::Minimize(bool effect)
{
state = MINIMIZED;
if(IsOpen())
#ifdef PLATFORM_WINCE
::ShowWindow(GetHWND(), SW_MINIMIZE);
#else
::ShowWindow(GetHWND(), effect ? SW_MINIMIZE : SW_SHOWMINIMIZED);
#endif
}
void TopWindow::Maximize(bool effect)
{
state = MAXIMIZED;
if(IsOpen())
::ShowWindow(GetHWND(), effect ? SW_MAXIMIZE : SW_SHOWMAXIMIZED);
}
void TopWindow::Overlap(bool effect)
{
GuiLock __;
state = OVERLAPPED;
if(IsOpen())
::ShowWindow(GetHWND(), effect ? SW_SHOWNORMAL : SW_RESTORE);
}
TopWindow& TopWindow::Style(dword _style)
{
GuiLock __;
style = _style;
if(GetHWND())
::SetWindowLong(GetHWND(), GWL_STYLE, style);
SyncCaption();
return *this;
}
TopWindow& TopWindow::ExStyle(dword _exstyle)
{
GuiLock __;
exstyle = _exstyle;
if(GetHWND())
::SetWindowLong(GetHWND(), GWL_EXSTYLE, exstyle);
SyncCaption();
return *this;
}
TopWindow& TopWindow::TopMost(bool b, bool stay_top)
{
GuiLock __;
HWND hwnd;
if(hwnd = GetHWND())
SetWindowPos(hwnd, b ? HWND_TOPMOST : (stay_top ? HWND_NOTOPMOST : HWND_BOTTOM),
0,0,0,0,SWP_NOMOVE|SWP_NOSIZE );
return ExStyle(b ? GetExStyle() | WS_EX_TOPMOST : GetExStyle() & ~WS_EX_TOPMOST);
}
bool TopWindow::IsTopMost() const
{
return GetExStyle() & WS_EX_TOPMOST;
}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,312 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) //DLOG(x)
#ifdef PLATFORM_X11
void TopWindow::SyncSizeHints()
{
GuiLock __;
Size min = GetMinSize();
Size max = GetMaxSize();
if(!sizeable)
min = max = GetRect().Size();
Window w = GetWindow();
if(w && (min != xminsize || max != xmaxsize)) {
xminsize = min;
xmaxsize = max;
size_hints->min_width = min.cx;
size_hints->min_height = min.cy;
size_hints->max_width = max.cx;
size_hints->max_height = max.cy;
size_hints->flags = PMinSize|PMaxSize;
XSetWMNormalHints(Xdisplay, w, size_hints);
}
}
void TopWindow::EndIgnoreTakeFocus()
{
GuiLock __;
ignoretakefocus = false;
}
void TopWindow::EventProc(XWindow& w, XEvent *event)
{
GuiLock __;
Ptr<Ctrl> this_ = this;
if(event->type == ClientMessage) {
if(event->xclient.format == 32 && event->xclient.message_type)
if(event->xclient.message_type == XAtom("WM_PROTOCOLS")) {
Atom a = event->xclient.data.l[0];
if(a == XAtom("WM_DELETE_WINDOW") && IsEnabled()) {
LLOG("DELETE_WINDOW " << Name());
WhenClose();
return;
}
if(a == XAtom("WM_TAKE_FOCUS")) {
LLOG("TAKE_FOCUS serial: " << event->xclient.serial);
Xeventtime = event->xclient.data.l[1];
TakeFocus();
return;
}
LLOG("Unknown WM_PROTOCOLS: " << XAtomName(a));
}
}
if(this_) Ctrl::EventProc(w, event);
if(this_) SyncSizeHints();
}
void TopWindow::DefSyncTitle()
{
GuiLock __;
if(title2 == title)
return;
title2 = title;
if(IsOpen() && GetWindow()) {
Window w = GetWindow();
XStoreName(Xdisplay, w, title.ToString());
XSetIconName(Xdisplay, w, title.ToString());
String utf8title = FromUnicode(title, CHARSET_UTF8);
XChangeProperty(Xdisplay, w, XAtom("_NET_WM_NAME"), XAtom("UTF8_STRING"),
8, PropModeReplace,
(const unsigned char *)~utf8title, utf8title.GetLength());
XChangeProperty(Xdisplay, w, XAtom("_NET_WM_ICON_NAME"), XAtom("UTF8_STRING"),
8, PropModeReplace,
(const unsigned char *)~utf8title, utf8title.GetLength());
}
}
void TopWindow::SyncTitle0()
{
GuiLock __;
LLOG("SyncTitle: " << title);
KillTimeCallback(TIMEID_DEFSYNCTITLE);
SetTimeCallback(0, THISBACK(DefSyncTitle), TIMEID_DEFSYNCTITLE);
LLOG("*SyncTitle: " << title);
}
void TopWindow::SyncCaption0()
{
GuiLock __;
LLOG("SyncCaption");
SyncTitle();
if(IsOpen() && GetWindow()) {
unsigned long wina[6];
int n = 0;
Window w = GetWindow();
if(tool)
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_TOOLBAR");
if(GetOwner())
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_DIALOG");
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_NORMAL");
XChangeProperty(Xdisplay, GetWindow(), XAtom("_NET_WM_WINDOW_TYPE"), XAtom("ATOM"), 32,
PropModeReplace, (const unsigned char *)wina, n);
n = 0;
if(topmost)
wina[n++] = XAtom("_NET_WM_STATE_ABOVE");
if(state == MAXIMIZED) {
wina[n++] = XAtom("_NET_WM_STATE_MAXIMIZED_HORZ");
wina[n++] = XAtom("_NET_WM_STATE_MAXIMIZED_VERT");
}
if(fullscreen)
wina[n++] = XAtom("_NET_WM_STATE_FULLSCREEN");
XChangeProperty(Xdisplay, GetWindow(), XAtom("_NET_WM_STATE"), XAtom("ATOM"), 32,
PropModeReplace, (const unsigned char *)wina, n);
wm_hints->flags = InputHint|WindowGroupHint|StateHint;
wm_hints->initial_state = NormalState;
wm_hints->input = XTrue;
Ctrl *owner = GetOwner();
wm_hints->window_group = owner ? owner->GetWindow() : w;
if(!icon.IsEmpty()) {
Size isz = icon.GetSize();
int len = 2 + isz.cx * isz.cy;
Buffer<unsigned long> data(len);
unsigned long *t = data;
*t++ = isz.cx;
*t++ = isz.cy;
for(int y = 0; y < isz.cy; y++) {
const RGBA *q = icon[y];
for(int x = isz.cx; x--;) {
*t++ = ((dword)q->a << 24) |
(dword)q->b | ((dword)q->g << 8) | ((dword)q->r << 16);
q++;
}
}
XChangeProperty(Xdisplay, w, XAtom("_NET_WM_ICON"), XA_CARDINAL, 32, PropModeReplace,
(const unsigned char *)~data, len);
}
XSetWMHints(Xdisplay, w, wm_hints);
}
}
void TopWindow::CenterRect(Ctrl *owner)
{
GuiLock __;
SetupRect();
if(owner && center == 1 || center == 2) {
Size sz = GetRect().Size();
Rect r, wr;
wr = Ctrl::GetWorkArea();
GuiLock __;
Rect fm = windowFrameMargin;
if((fm.left|fm.right|fm.top|fm.bottom) == 0)
fm = Rect(8, 32, 8, 8);
if(center == 1)
r = owner->GetRect();
else
r = wr;
Point p = r.CenterPos(sz);
r = RectC(p.x, p.y, sz.cx, sz.cy);
wr.left += fm.left;
wr.right -= fm.right;
wr.top += fm.top;
wr.bottom -= fm.bottom;
if(r.top < wr.top) {
r.bottom += wr.top - r.top;
r.top = wr.top;
}
if(r.bottom > wr.bottom)
r.bottom = wr.bottom;
minsize.cx = min(minsize.cx, r.GetWidth());
minsize.cy = min(minsize.cy, r.GetHeight());
SetRect(r);
}
}
void TopWindow::Open(Ctrl *owner)
{
GuiLock __;
if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
DistributeAccessKeys();
UsrLogT(3, "OPEN " + Desc(this));
LLOG("OPEN " << Name() << " owner: " << UPP::Name(owner));
IgnoreMouseUp();
if(fullscreen)
SetRect(0, 0, Xwidth, Xheight);
else
CenterRect(owner);
LLOG("Open NextRequest " << NextRequest(Xdisplay));
Create(owner, false, false);
xminsize.cx = xmaxsize.cx = Null;
title2.Clear();
LLOG("SyncCaption");
SyncCaption();
LLOG("SyncSizeHints");
size_hints->flags = 0;
SyncSizeHints();
Rect r = GetRect();
size_hints->x = r.left;
size_hints->y = r.top;
size_hints->width = r.Width();
size_hints->height = r.Height();
size_hints->win_gravity = StaticGravity;
size_hints->flags |= PPosition|PSize|PWinGravity;
if(owner) {
ASSERT(owner->IsOpen());
LLOG("XSetTransientForHint");
XSetTransientForHint(Xdisplay, GetWindow(), owner->GetWindow());
}
LLOG("XSetWMNormalHints");
XSetWMNormalHints(Xdisplay, GetWindow(), size_hints);
Atom protocols[2];
protocols[0] = XAtom("WM_DELETE_WINDOW");
protocols[1] = XAtom("WM_TAKE_FOCUS");
LLOG("XSetWMProtocols");
XSetWMProtocols(Xdisplay, GetWindow(), protocols, 2);
String x = GetExeTitle().ToString();
const char *progname = ~x;
class_hint->res_name = (char *)progname;
class_hint->res_class = (char *)progname;
XSetClassHint(Xdisplay, GetWindow(), class_hint);
LLOG("WndShow(" << visible << ")");
WndShow(visible);
if(visible) {
XEvent e;
LLOG("XWindowEvent");
XWindowEvent(Xdisplay, top->window, VisibilityChangeMask, &e);
ignoretakefocus = true;
SetTimeCallback(500, THISBACK(EndIgnoreTakeFocus));
LLOG("SetWndFocus");
SetWndFocus();
for(int i = 0; i < 50; i++) {
if(XCheckTypedWindowEvent(Xdisplay, top->window, FocusIn, &e)) {
ProcessEvent(&e);
if(e.xfocus.window == top->window)
break;
}
Sleep(10);
}
}
LLOG(">Open NextRequest " << NextRequest(Xdisplay));
LLOG(">OPENED " << Name());
PlaceFocus();
StateH(OPEN);
Vector<int> fe = GetPropertyInts(top->window, XAtom("_NET_FRAME_EXTENTS"));
if(fe.GetCount() >= 4 &&
fe[0] >= 0 && fe[0] <= 16 && fe[1] >= 0 && fe[1] <= 16 && //fluxbox returns wrong numbers - quick&dirty workaround
fe[2] >= 0 && fe[2] <= 64 && fe[3] >= 0 && fe[3] <= 48)
{
GuiLock __;
windowFrameMargin.left = max(windowFrameMargin.left, fe[0]);
windowFrameMargin.right = max(windowFrameMargin.right, fe[1]);
windowFrameMargin.top = max(windowFrameMargin.top, fe[2]);
windowFrameMargin.bottom = max(windowFrameMargin.bottom, fe[3]);
}
if(IsOpen() && top)
top->owner = owner;
int version = 5;
XChangeProperty(Xdisplay, GetWindow(), XAtom("XdndAware"), XA_ATOM, 32,
0, (byte *)&version, 1);
FixIcons();
}
void TopWindow::Open()
{
GuiLock __;
Open(GetActiveWindow());
}
void TopWindow::OpenMain()
{
GuiLock __;
Open(NULL);
}
void TopWindow::Minimize(bool)
{
GuiLock __;
state = MINIMIZED;
XIconifyWindow(Xdisplay, GetWindow(), Xscreenno);
}
void TopWindow::Maximize(bool effect)
{
GuiLock __;
state = MAXIMIZED;
}
void TopWindow::Overlap(bool effect)
{
GuiLock __;
state = OVERLAPPED;
}
TopWindow& TopWindow::TopMost(bool b, bool)
{
GuiLock __;
topmost = b;
return *this;
}
bool TopWindow::IsTopMost() const
{
GuiLock __;
return topmost;
}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,551 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
Rect TopWindow::windowFrameMargin;
String TopWindow::GetDesc() const
{
return title.ToString();
}
Size TopWindow::GetMinSize() const
{
return minsize;
}
Size TopWindow::GetStdSize() const
{
return GetMinSize();
}
void TopWindow::ActiveFocus0(Ctrl& ctrl)
{
if(IsChild()) return;
activefocus = &ctrl;
if(IsForeground()) ctrl.SetWantFocus();
}
void TopWindow::Activate()
{
LLOG("Activate " << Name() << " activefocus = " << UPP::Name(activefocus));
UsrLogT(3, "ACTIVATE " + Desc(this));
if(activefocus && (HasFocus() || !GetFocusChildDeep()) && IsEnabled())
activefocus->SetWantFocus();
LLOG("Activate End");
}
void TopWindow::ChildGotFocus()
{
activefocus = GetFocusCtrl();
}
void TopWindow::Deactivate()
{
LLOG("DeActivate current focus " << UPP::Name(GetFocusCtrl()));
if(HasFocusDeep())
activefocus = GetFocusCtrl();
UsrLogT(3, "DEACTIVATE " + Desc(this));
LLOG("DeActivate " << Name() << " activefocus = " << UPP::Name(activefocus));
}
void TopWindow::PlaceFocus()
{
if(activefocus)
activefocus->SetFocus();
else
IterateFocusForward(this, this, true, true);
}
bool TopWindow::IsShowEnabled() const
{
return true;
}
void TopWindow::SyncCaption()
{
Call(THISBACK(SyncCaption0));
}
void TopWindow::SyncTitle()
{
Call(THISBACK(SyncTitle0));
}
void TopWindow::Close()
{
if(InLoop()) {
if(!InCurrentLoop()) return;
if(FindAction(IDCANCEL))
RejectBreak(IDCANCEL);
else
if(FindAction(IDYES))
AcceptBreak(IDYES);
else
AcceptBreak(IDOK);
return;
}
backup.Clear();
if(IsOpen()) IgnoreMouseUp();
Ctrl::Close();
}
void TopWindow::Backup()
{
StringStream s;
Ctrl::Serialize(s);
backup = s;
}
void TopWindow::Restore()
{
StringStream s(backup);
Ctrl::Serialize(s);
}
bool TopWindow::Accept()
{
Ctrl *q;
for(q = GetFirstChild(); q; q = q->GetNext())
if(!q->Accept())
return false;
return true;
}
void TopWindow::Reject()
{
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
q->Reject();
if(!backup.IsEmpty())
Restore();
}
void TopWindow::Break(int ID)
{
EndLoop(ID);
}
bool TopWindow::AcceptBreak(int ID)
{
if(Accept()) {
Break(ID);
return true;
}
return false;
}
void TopWindow::RejectBreak(int ID)
{
Reject();
Break(ID);
}
void TopWindow::SetupRect()
{
Rect r = GetRect();
if(r.IsEmpty())
SetRect(GetDefaultWindowRect());
else
if(r.left == 0 && r.top == 0 && center == 1) {
Rect area = Ctrl::GetWorkArea();
SetRect(area.CenterRect(min(area.Size(), r.Size())));
}
}
void TopWindow::FixIcons()
{
TopWindow *q = GetMainWindow();
if(q) {
if(IsNull(icon)) {
icon = q->GetIcon();
SyncCaption();
}
if(IsNull(largeicon)) {
largeicon = q->GetIcon();
SyncCaption();
}
}
}
TopWindow::Abreak *TopWindow::FindAction(int ID)
{
for(int i = 0; i < action.GetCount(); i++)
if(action[i].ID == ID) return &action[i];
return NULL;
}
TopWindow::Abreak *TopWindow::FindAddAction(int ID)
{
Abreak *x = FindAction(ID);
if(x) return x;
Abreak& a = action.Add();
a.ID = ID;
a.dlg = this;
return &a;
}
Callback TopWindow::Breaker(int ID)
{
return callback(FindAddAction(ID), &Abreak::Break);
}
Callback TopWindow::Acceptor(int ID)
{
return callback(FindAddAction(ID), &Abreak::Accept);
}
Callback TopWindow::Rejector(int ID)
{
return callback(FindAddAction(ID), &Abreak::Reject);
}
TopWindow& TopWindow::Breaker(Ctrl& m, int ID)
{
m.WhenAction = Breaker(ID);
return *this;
}
TopWindow& TopWindow::Acceptor(Ctrl& m, int ID)
{
m.WhenAction = Acceptor(ID);
return *this;
}
TopWindow& TopWindow::Rejector(Ctrl& m, int ID)
{
m.WhenAction = Rejector(ID);
return *this;
}
void TopWindow::Paint(Draw& w)
{
background.Paint(w, Rect(GetSize()), SColorText, SColorShadow);
}
TopWindow& TopWindow::Background(const PaintRect& prect)
{
background = prect;
Refresh();
return *this;
}
bool TopWindow::Key(dword key, int count)
{
if(Ctrl::Key(key, count))
return true;
if(IsChild()) return false;
if(key == K_DOWN || key == K_RIGHT || key == K_TAB) {
Ctrl *ctrl = GetFocusChildDeep();
if(ctrl && IterateFocusForward(ctrl, this))
return true;
ctrl = GetFirstChild();
if(ctrl) {
if(ctrl->SetWantFocus()) return true;
return IterateFocusForward(ctrl, this);
}
}
if(key == K_UP || key == K_LEFT || key == K_SHIFT_TAB) {
Ctrl *ctrl = GetFocusChildDeep();
if(ctrl && IterateFocusBackward(ctrl, this))
return true;
ctrl = GetLastChild();
if(ctrl) {
if(ctrl->SetWantFocus()) return true;
return IterateFocusBackward(ctrl, this);
}
}
return false;
}
void TopWindow::WorkAreaTrim()
{
Rect a = GetWorkArea();
Rect h = GetRect();
h.left = max(h.left, a.left);
h.right = min(h.right, a.right);
h.top = max(h.top, a.top);
h.bottom = min(h.bottom, a.bottom);
if(h != GetRect() && !IsChild())
SetRect(h);
}
void GatherWindowTree(Ctrl *w, const Vector<Ctrl *>& ws, Vector<Ctrl *>& es)
{
if(!w->InLoop())
es.Add(w);
for(int i = 0; i < ws.GetCount(); i++)
if(ws[i]->GetOwner() == w)
GatherWindowTree(ws[i], ws, es);
}
int TopWindow::Run(bool appmodal)
{
GuiLock __;
LLOG("TopWindow::Run() <- " << typeid(*this).name());
LLOG("Focus = " << UPP::Name(GetFocusCtrl()));
if(!IsOpen())
Open();
if(!IsVisible()) Show();
bool pinloop = inloop;
int pexitcode = exitcode;
exitcode = Null;
Vector<Ctrl *> es;
if(appmodal)
es = GetTopCtrls();
else {
Vector<Ctrl *> ws = GetTopCtrls();
for(int i = 0; i < ws.GetCount(); i++)
if(ws[i]->InLoop())
es.Add(ws[i]);
Ctrl *mw = GetMainWindow();
if(mw) GatherWindowTree(mw, ws, es);
}
Vector< Ptr<Ctrl> > disabled = DisableCtrls(es, this);
#ifdef _DEBUG
for(int d = 0; d < disabled.GetCount(); d++)
LLOG("DisableCtrls[" << d << "] = " << UPP::Name(disabled[d]));
LLOG("Running EventLoop in " << UPP::Name(this));
#endif
EventLoop(this);
#ifdef _DEBUG
LLOG("Finished EventLoop in " << UPP::Name(this));
for(int e = 0; e < disabled.GetCount(); e++)
LLOG("EnableCtrls[" << e << "] = " << UPP::Name(disabled[e]));
#endif
EnableCtrls(disabled);
int q = exitcode;
inloop = pinloop;
exitcode = pexitcode;
LLOG("TopWindow::Run() = " << q << " -> " << typeid(*this).name());
#ifdef PLATFORM_WIN32
LLOG("Focus = " << UPP::Name(GetFocusCtrl()) << ", raw " << (void *)::GetFocus());
#endif
return q;
}
int TopWindow::Execute()
{
int m = Run();
Close();
return m;
}
TopWindow& TopWindow::Title(const WString& _title)
{
if(title != _title) {
title = _title;
SyncTitle();
}
return *this;
}
TopWindow& TopWindow::Title(const char *s)
{
return Title(WString(s));
}
TopWindow& TopWindow::Sizeable(bool b)
{
sizeable = b;
SyncCaption();
SyncSizeHints();
return *this;
}
TopWindow& TopWindow::MinimizeBox(bool b)
{
minimizebox = b;
SyncCaption();
SyncSizeHints();
return *this;
}
TopWindow& TopWindow::MaximizeBox(bool b)
{
maximizebox = b;
SyncCaption();
SyncSizeHints();
return *this;
}
TopWindow& TopWindow::Icon(const Image& m)
{
if(!icon.IsSame(m)) {
icon = m;
SyncCaption();
}
return *this;
}
TopWindow& TopWindow::LargeIcon(const Image& m)
{
if(!largeicon.IsSame(m)) {
largeicon = m;
SyncCaption();
}
return *this;
}
TopWindow& TopWindow::Icon(const Image& smallicon, const Image& _largeicon)
{
if(!icon.IsSame(smallicon) || !largeicon.IsSame(_largeicon)) {
icon = smallicon;
largeicon = _largeicon;
SyncCaption();
}
SyncCaption();
return *this;
}
TopWindow& TopWindow::ToolWindow(bool b)
{
tool = b;
SyncCaption();
return *this;
}
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
{
GuiLock __;
#ifndef PLATFORM_WINCE
int version = 0;
s / version;
Rect rect = GetRect();
s % overlapped % rect;
bool mn = state == MINIMIZED;
bool mx = state == MAXIMIZED;
s.Pack(mn, mx);
LLOG("TopWindow::SerializePlacement / " << (s.IsStoring() ? "write" : "read"));
LLOG("minimized = " << mn << ", maximized = " << mx);
LLOG("rect = " << rect << ", overlapped = " << overlapped);
if(s.IsLoading()) {
if(mn) rect = overlapped;
Rect limit = GetWorkArea();
#ifdef PLATFORM_WIN32
Rect outer = rect;
::AdjustWindowRect(outer, WS_OVERLAPPEDWINDOW, FALSE);
limit.left += rect.left - outer.left;
limit.top += rect.top - outer.top;
limit.right += rect.right - outer.right;
limit.bottom += rect.bottom - outer.bottom;
#endif
#ifdef PLATFORM_X11
Rect fm = windowFrameMargin;
if((fm.left|fm.right|fm.top|fm.bottom) == 0)
fm = Rect(8, 32, 8, 8);
limit.left += fm.left;
limit.right -= fm.right;
limit.top += fm.top;
limit.bottom -= fm.bottom;
#endif
Size sz = min(rect.Size(), limit.Size());
rect = RectC(
minmax(rect.left, limit.left, limit.right - sz.cx),
minmax(rect.top, limit.top, limit.bottom - sz.cy),
sz.cx, sz.cy);
state = OVERLAPPED;
if(mn && reminimize)
state = MINIMIZED;
if(mx)
state = MAXIMIZED;
#ifdef PLATFORM_WIN32
if(state == OVERLAPPED)
#endif
SetRect(rect);
if(IsOpen()) {
#ifdef PLATFORM_WIN32
HWND hwnd = GetHWND();
switch(state) {
case MINIMIZED:
if(!IsIconic(hwnd))
::ShowWindow(hwnd, SW_MINIMIZE);
break;
case MAXIMIZED:
if(!IsZoomed(hwnd))
::ShowWindow(hwnd, SW_MAXIMIZE);
break;
default:
if(IsIconic(hwnd) || IsZoomed(hwnd))
::ShowWindow(hwnd, SW_RESTORE);
break;
}
#endif
}
}
#endif
}
struct DialogBackground : public Display {
void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
{
w.DrawRect(r, SColorFace());
}
};
TopWindow::TopWindow()
{
GuiLock __;
TransparentBackPaint();
background = PaintRect(Single<DialogBackground>(), Null);
center = 1;
minsize = Size(80, 20);
#ifdef PLATFORM_WIN32
style = 0;
exstyle = 0;
ico = lico = NULL;
#endif
#ifdef PLATFORM_X11
size_hints = XAllocSizeHints();
wm_hints = XAllocWMHints();
class_hint = XAllocClassHint();
topmost = false;
#endif
maximizebox = minimizebox = sizeable = tool = noclosebox = false;
state = OVERLAPPED;
WhenClose = THISBACK(Close);
overlapped.Clear();
dokeys = true;
fullscreen = frameless = false;
}
TopWindow::~TopWindow()
{
GuiLock __;
if(InLoop())
EndLoop(IDOK);
if(!IsChild())
Close();
#ifdef PLATFORM_WIN32
DeleteIco();
#endif
#ifdef PLATFORM_X11
XFree(size_hints);
XFree(wm_hints);
XFree(class_hint);
#endif
}
void Maxisize(TopWindow& win, int screencxmax)
{
if(win.GetWorkArea().Width() <= screencxmax)
win.Maximize();
}
CH_INT(SwapOKCancel, 0);
void ArrangeOKCancel(Ctrl& ok, Ctrl& cancel)
{
if(SwapOKCancel() &&
ok.GetPos().x.GetB() == cancel.GetPos().x.GetB() &&
ok.GetPos().y.GetB() == cancel.GetPos().y.GetB()) {
Ctrl::LogPos h = ok.GetPos();
ok.SetPos(cancel.GetPos());
cancel.SetPos(h);
}
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,278 @@
#ifdef PLATFORM_X11
enum {
IDOK = 1,
IDCANCEL = 2,
IDABORT = 3,
IDRETRY = 4,
IDIGNORE = 5,
IDYES = 6,
IDNO = 7,
IDCLOSE = 8,
IDHELP = 9,
};
#endif
enum {
IDEXIT = IDYES
};
class TopWindow : public Ctrl {
public:
virtual Size GetMinSize() const;
virtual Size GetStdSize() const;
virtual void Activate();
virtual void Deactivate();
virtual bool Accept();
virtual void Reject();
virtual void Paint(Draw& w);
virtual bool IsShowEnabled() const;
virtual bool Key(dword key, int count);
virtual void Close();
virtual String GetDesc() const;
virtual void ChildGotFocus();
#ifdef PLATFORM_WIN32
public:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
private:
dword style;
dword exstyle;
HICON ico, lico;
void DeleteIco0();
void DeleteIco();
#endif
protected:
enum {
TIMEID_DEFSYNCTITLE = Ctrl::TIMEID_COUNT,
TIMEID_COUNT,
};
#ifdef PLATFORM_X11
virtual void EventProc(XWindow& w, XEvent *event);
private:
XSizeHints *size_hints;
XWMHints *wm_hints;
XClassHint *class_hint;
Size xminsize, xmaxsize;
bool topmost;
#endif
static Rect windowFrameMargin;
private:
struct Abreak : Pte<Abreak> {
int ID;
TopWindow *dlg;
void Accept() { dlg->AcceptBreak(ID); }
void Reject() { dlg->RejectBreak(ID); }
void Break() { dlg->Break(ID); }
};
Array<Abreak> action;
Ptr<Ctrl> activefocus;
String backup;
PaintRect background;
Size minsize;
bool dokeys;
bool fullscreen;
byte center:2;
void PlaceFocus();
void ActiveFocus0(Ctrl& ctrl);
Abreak *FindAddAction(int ID);
Abreak *FindAction(int ID);
#ifdef PLATFORM_WIN32
void CenterRect(HWND owner, int center);
#endif
#ifdef PLATFORM_X11
void CenterRect(Ctrl *owner);
void DefSyncTitle();
void EndIgnoreTakeFocus();
#endif
Rect overlapped;
void SyncTitle0();
void SyncSizeHints();
void SyncTitle();
void SyncCaption0();
void SyncCaption();
void SetupRect();
void FixIcons();
enum { MINIMIZED, MAXIMIZED, OVERLAPPED };
WString title;
bool minimizebox:1;
bool maximizebox:1;
bool noclosebox:1;
bool sizeable:1;
bool tool:1;
bool frameless:1;
byte state;
Image icon, largeicon;
#ifdef PLATFORM_X11
Image invert;
WString title2;
#endif
public:
Callback WhenClose;
void Backup();
void Restore();
void Break(int ID = IDEXIT);
bool AcceptBreak(int ID);
void RejectBreak(int ID);
void WorkAreaTrim();
Callback Breaker(int ID = IDEXIT);
Callback Acceptor(int ID);
Callback Rejector(int ID);
TopWindow& Breaker(Ctrl& m, int ID = -1);
TopWindow& Acceptor(Ctrl& m, int ID);
TopWindow& Rejector(Ctrl& m, int ID);
TopWindow& NoCenter() { center = 0; return *this; }
TopWindow& CenterOwner() { center = 1; return *this; }
TopWindow& CenterScreen() { center = 2; return *this; }
void SetMinSize(Size sz) { minsize = sz; }
#ifdef PLATFORM_WIN32
void Open(HWND ownerhwnd);
TopWindow& Style(dword _style);
dword GetStyle() const { return style; }
TopWindow& ExStyle(dword _exstyle);
dword GetExStyle() const { return exstyle; }
#endif
void Open(Ctrl *owner);
void Open();
void OpenMain();
int Run(bool appmodal = false);
int RunAppModal() { return Run(true); }
int Execute();
bool ExecuteOK() { return Execute() == IDOK; }
bool ExecuteCancel() { return Execute() == IDCANCEL; }
void Minimize(bool effect = false);
void Maximize(bool effect = false);
void Overlap(bool effect = false);
bool IsMaximized() const { return state == MAXIMIZED; }
bool IsMinimized() const { return state == MINIMIZED; }
bool IsOverlapped() const { return state == OVERLAPPED; }
TopWindow& ActiveFocus(Ctrl& ctrl) { ActiveFocus0(ctrl); return *this; }
TopWindow& Title(const WString& _title);
TopWindow& Title(const char *s);
const WString& GetTitle() const { return title; }
TopWindow& Sizeable(bool b = true);
TopWindow& NoSizeable() { return Sizeable(false); }
bool IsSizeable() const { return sizeable; }
TopWindow& MinimizeBox(bool b = true);
TopWindow& MaximizeBox(bool b = true);
TopWindow& Zoomable(bool b = true) { MinimizeBox(b); return MaximizeBox(b); }
TopWindow& NoZoomable() { return Zoomable(false); }
bool IsZoomable() const { return maximizebox; }
TopWindow& Background(const PaintRect& prect);
const PaintRect& GetBackground() const { return background; }
TopWindow& ToolWindow(bool b = true);
TopWindow& NoToolWindow() { return ToolWindow(false); }
bool IsToolWindow() const { return tool; }
TopWindow& TopMost(bool b = true, bool stay_top = true);
TopWindow& NoTopMost() { return TopMost(false); }
bool IsTopMost() const;
TopWindow& FullScreen(bool b = true) { fullscreen = b; return *this; }
bool IsFullScreen() const { return fullscreen; }
TopWindow& FrameLess(bool b = true) { frameless = b; return *this; }
bool IsFrameLess() const { return frameless; }
TopWindow& NoAccessKeysDistribution() { dokeys = false; return *this; }
TopWindow& NoCloseBox(bool b = true) { noclosebox = b; return *this; }
TopWindow& Icon(const Image& m);
TopWindow& LargeIcon(const Image& m);
TopWindow& Icon(const Image& smallicon, const Image& largeicon);
Image GetIcon() const { return icon; }
Image GetLargeIcon() const { return largeicon; }
void SerializePlacement(Stream& s, bool reminimize = false);
typedef TopWindow CLASSNAME;
TopWindow();
~TopWindow();
};
void Maxisize(TopWindow& win, int screencxmax);
void ArrangeOKCancel(Ctrl& ok, Ctrl& cancel);
int SwapOKCancel();
void SwapOKCancel_Write(int b);
template <class L>
void InitLayout(Ctrl& ctrl, L& layout)
{
InitLayout(ctrl, layout, layout, layout);
}
template <class T>
void CtrlLayout(T& ctrl) {
InitLayout(ctrl, ctrl, ctrl, ctrl);
Size sz = ctrl.AddFrameSize(T::GetLayoutSize());
ctrl.SetMinSize(sz);
ctrl.SetRect(sz);
}
template <class T>
void CtrlLayout(T& ctrl, const char *title) {
CtrlLayout(ctrl);
ctrl.Title(title);
}
template <class T>
void CtrlLayoutOK(T& ctrl, const char *title) {
CtrlLayout(ctrl, title);
ctrl.Acceptor(ctrl.ok, IDOK);
ctrl.ok.Ok();
}
template <class T>
void CtrlLayoutCancel(T& ctrl, const char *title) {
CtrlLayout(ctrl, title);
ctrl.Rejector(ctrl.cancel, IDCANCEL);
ctrl.cancel.Cancel();
}
template <class T>
void CtrlLayoutOKCancel(T& ctrl, const char *title) {
CtrlLayoutOK(ctrl, title);
ctrl.Rejector(ctrl.cancel, IDCANCEL);
ctrl.cancel.Cancel();
ArrangeOKCancel(ctrl.ok, ctrl.cancel);
}
template <class T>
void CtrlLayoutExit(T& ctrl, const char *title) {
CtrlLayout(ctrl, title);
ctrl.Acceptor(ctrl.exit, IDEXIT);
ctrl.exit.Exit();
}

View file

@ -0,0 +1,435 @@
#include "CtrlCore.h"
#include <plugin/bmp/bmp.h>
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#define LLOG(x) // LOG(x)
VectorMap<int, ClipData>& sClipMap()
{
static VectorMap<int, ClipData> x;
return x;
}
extern HWND utilityHWND;
int GetClipboardFormatCode(const char *format_id)
{
GuiLock ___;
int x = (int)(intptr_t)format_id;
if(x >= 0 && x < 65535)
return x;
String fmt = format_id;
if(fmt == "text")
return CF_TEXT;
if(fmt == "wtext")
return CF_UNICODETEXT;
if(fmt == "dib")
return CF_DIB;
if(fmt == "files")
return CF_HDROP;
static StaticMutex m;
Mutex::Lock __(m);
static VectorMap<String, int> format_map;
int f = format_map.Find(format_id);
if(f < 0) {
f = format_map.GetCount();
format_map.Add(format_id,
#ifdef PLATFORM_WINCE
::RegisterClipboardFormat(ToSystemCharset(format_id))
#else
::RegisterClipboardFormat(format_id)
#endif
);
}
return format_map[f];
}
void ClearClipboard()
{
GuiLock __;
sClipMap().Clear();
if(OpenClipboard(utilityHWND)) {
EmptyClipboard();
CloseClipboard();
}
}
void SetClipboardRaw(int format, const byte *data, int length)
{
GuiLock __;
HANDLE handle = NULL;
if(data) {
handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, length + 2);
byte *ptr;
if(!handle)
return;
if(!(ptr = (byte *)GlobalLock(handle))) {
GlobalFree(handle);
return;
}
memcpy(ptr, data, length);
ptr[length] = 0;
ptr[length + 1] = 0;
GlobalUnlock(handle);
}
if(!SetClipboardData(format, handle)) {
LLOG("SetClipboardData error: " << GetLastErrorMessage());
GlobalFree(handle);
}
}
void AppendClipboard(int format, const byte *data, int length)
{
GuiLock __;
if(OpenClipboard(utilityHWND)) {
SetClipboardRaw(format, data, length);
CloseClipboard();
}
}
void AppendClipboard(const char *format, const byte *data, int length)
{
GuiLock __;
Vector<String> f = Split(format, ';');
for(int i = 0; i < f.GetCount(); i++)
AppendClipboard(GetClipboardFormatCode(f[i]), data, length);
}
void AppendClipboard(const char *format, const String& data)
{
GuiLock __;
AppendClipboard(format, data, data.GetLength());
}
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&))
{
GuiLock __;
Vector<String> f = Split(format, ';');
for(int i = 0; i < f.GetCount(); i++) {
int c = GetClipboardFormatCode(f[i]);
sClipMap().GetAdd(c) = ClipData(data, render);
AppendClipboard(c, NULL, 0);
}
}
void Ctrl::RenderFormat(int format)
{
GuiLock __;
int q = sClipMap().Find(format);
if(q >= 0) {
String s = sClipMap()[q].Render();
SetClipboardRaw(format, s, s.GetLength());
}
}
void Ctrl::RenderAllFormats()
{
GuiLock __;
if(sClipMap().GetCount() && OpenClipboard(utilityHWND)) {
for(int i = 0; i < sClipMap().GetCount(); i++)
RenderFormat(sClipMap().GetKey(i));
CloseClipboard();
}
}
void Ctrl::DestroyClipboard()
{
GuiLock __;
sClipMap().Clear();
}
String ReadClipboard(const char *format)
{
GuiLock __;
if(!OpenClipboard(NULL))
return Null;
HGLOBAL hmem = GetClipboardData(GetClipboardFormatCode(format));
if(hmem == 0) {
CloseClipboard();
return Null;
}
const byte *src = (const byte *)GlobalLock(hmem);
ASSERT(src);
int length = (int)GlobalSize(hmem);
if(length < 0) {
CloseClipboard();
return Null;
}
String out(src, length);
GlobalUnlock(hmem);
CloseClipboard();
return out;
}
void AppendClipboardText(const String& s)
{
#ifdef PLATFORM_WINCE
AppendClipboardUnicodeText(s.ToWString());
#else
AppendClipboard("text", ToSystemCharset(s));
#endif
}
void AppendClipboardUnicodeText(const WString& s)
{
#ifndef PLATFORM_WINCE
AppendClipboardText(s.ToString());
#endif
AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength());
}
const char *ClipFmtsText()
{
return "wtext;text";
}
String GetString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString();
}
if(clip.IsAvailable("text"))
return ~clip;
return Null;
}
WString GetWString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
}
if(clip.IsAvailable("text"))
return (~clip).ToWString();
return Null;
}
bool AcceptText(PasteClip& clip)
{
return clip.Accept(ClipFmtsText());
}
static String sText(const Value& data)
{
return data;
}
static String sWText(const Value& data)
{
return Unicode__(WString(data));
}
void Append(VectorMap<String, ClipData>& data, const String& text)
{
data.GetAdd("text", ClipData(text, sText));
data.GetAdd("wtext", ClipData(text, sWText));
}
void Append(VectorMap<String, ClipData>& data, const WString& text)
{
data.GetAdd("text", ClipData(text, sText));
data.GetAdd("wtext", ClipData(text, sWText));
}
String GetTextClip(const WString& text, const String& fmt)
{
if(fmt == "text")
return text.ToString();
if(fmt == "wtext")
return Unicode__(text);
return Null;
}
String GetTextClip(const String& text, const String& fmt)
{
if(fmt == "text")
return text;
if(fmt == "wtext")
return Unicode__(text.ToWString());
return Null;
}
String ReadClipboardText()
{
#ifdef PLATFORM_WINCE
return ReadClipboardUnicodeText().ToString();
#else
String s = ReadClipboard((const char *)CF_TEXT);
return String(s, (int)strlen(~s));
#endif
}
WString ReadClipboardUnicodeText()
{
String s = ReadClipboard((const char *)CF_UNICODETEXT);
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
}
bool IsClipboardAvailable(const char *id)
{
return ::IsClipboardFormatAvailable(GetClipboardFormatCode(id));
}
bool IsClipboardAvailableText()
{
return IsClipboardAvailable((const char *)CF_TEXT);
}
const char *ClipFmtsImage()
{
static const char *q;
ONCELOCK {
static String s = "dib;" + ClipFmt<Image>();
q = s;
}
return q;
}
bool AcceptImage(PasteClip& clip)
{
GuiLock __;
return clip.Accept(ClipFmtsImage());
}
Image GetImage(PasteClip& clip)
{
GuiLock __;
Image m;
if(Accept<Image>(clip)) {
LoadFromString(m, ~clip);
if(!m.IsEmpty())
return m;
}
if(clip.Accept("dib")) {
String data = ~clip;
if(data.GetCount() < sizeof(BITMAPINFO)) return Null;
BITMAPINFO *lpBI = (BITMAPINFO *)~data;
BITMAPINFOHEADER& hdr = lpBI->bmiHeader;
byte *bits = (byte *)lpBI + hdr.biSize;
if(hdr.biBitCount <= 8)
bits += (hdr.biClrUsed ? hdr.biClrUsed : 1 << hdr.biBitCount) * sizeof(RGBQUAD);
if(hdr.biBitCount >= 16 || hdr.biBitCount == 32) {
if(hdr.biCompression == 3)
bits += 12;
if(hdr.biClrUsed != 0)
bits += hdr.biClrUsed * sizeof(RGBQUAD);
}
int h = abs((int)hdr.biHeight);
ImageDraw iw(hdr.biWidth, h);
::StretchDIBits(iw.GetHandle(),
0, 0, hdr.biWidth, h,
0, 0, hdr.biWidth, h,
bits, lpBI, DIB_RGB_COLORS, SRCCOPY);
return iw;
}
return Null;
}
Image ReadClipboardImage()
{
GuiLock __;
PasteClip d = Ctrl::Clipboard();
return GetImage(d);
}
String sDib(const Value& image)
{
Image img = image;
BITMAPINFOHEADER header;
Zero(header);
header.biSize = sizeof(header);
header.biWidth = img.GetWidth();
header.biHeight = -img.GetHeight();
header.biBitCount = 32;
header.biPlanes = 1;
header.biCompression = BI_RGB;
StringBuffer b(sizeof(header) + 4 * img.GetLength());
byte *p = (byte *)~b;
memcpy(p, &header, sizeof(header));
memcpy(p + sizeof(header), ~img, 4 * img.GetLength());
return b;
}
String sImage(const Value& image)
{
Image img = image;
return StoreAsString(const_cast<Image&>(img));
}
String GetImageClip(const Image& img, const String& fmt)
{
GuiLock __;
if(img.IsEmpty()) return Null;
if(fmt == "dib")
return sDib(img);
if(fmt == ClipFmt<Image>())
return sImage(img);
return Null;
}
void AppendClipboardImage(const Image& img)
{
GuiLock __;
if(img.IsEmpty()) return;
AppendClipboard(ClipFmt<Image>(), img, sImage);
AppendClipboard("dib", img, sDib);
}
bool AcceptFiles(PasteClip& clip)
{
if(clip.Accept("files")) {
clip.SetAction(DND_COPY);
return true;
}
return false;
}
struct sDROPFILES {
DWORD offset;
POINT dummy;
BOOL dummy2;
BOOL unicode;
};
Vector<String> GetFiles(PasteClip& clip)
{
GuiLock __;
Vector<String> f;
String data = clip;
if(data.GetCount() < sizeof(sDROPFILES) + 2)
return f;
const sDROPFILES *df = (const sDROPFILES *)~data;
const char *s = ((const char *)df + df->offset);
if(df->unicode) {
const wchar *ws = (wchar *)s;
while(*ws) {
WString fn;
while(*ws)
fn.Cat(*ws++);
f.Add(fn.ToString());
ws++;
}
}
else
while(*s) {
String fn;
while(*s)
fn.Cat(*s++);
f.Add(fn.ToString());
s++;
}
return f;
}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,542 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
#define LLOG(x) // LOG(x)
int GetClipboardFormatCode(const char *format_id);
int ToWin32CF(const char *s)
{
return GetClipboardFormatCode(s);
}
String FromWin32CF(int cf)
{
GuiLock __;
if(cf == CF_TEXT)
return "text";
if(cf == CF_UNICODETEXT)
return "wtext";
if(cf == CF_DIB)
return "dib";
#ifndef PLATFORM_WINCE
if(cf == CF_HDROP)
return "files";
#endif
char h[256];
GetClipboardFormatNameA(cf, h, 255);
return h;
}
FORMATETC ToFORMATETC(const char *s)
{
FORMATETC fmtetc;
fmtetc.cfFormat = ToWin32CF(s);
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.ptd = NULL;
fmtetc.tymed = TYMED_HGLOBAL;
return fmtetc;
}
String AsString(POINTL p)
{
return String().Cat() << "[" << p.x << ", " << p.y << "]";
}
struct UDropTarget : public IDropTarget {
ULONG rc;
LPDATAOBJECT data;
Ptr<Ctrl> ctrl;
Index<String> fmt;
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragLeave)();
STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
void DnD(POINTL p, bool drop, DWORD *effect, DWORD keys);
void FreeData();
void Repeat();
void EndDrag();
String Get(const char *fmt) const;
UDropTarget() { rc = 1; data = NULL; }
~UDropTarget();
};
bool Has(UDropTarget *dt, const char *fmt)
{
return dt->fmt.Find(fmt) >= 0;
}
String Get(UDropTarget *dt, const char *fmt)
{
return dt->Get(fmt);
}
STDMETHODIMP UDropTarget::QueryInterface(REFIID iid, void ** ppv)
{
if(iid == IID_IUnknown || iid == IID_IDropTarget) {
*ppv = this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
String UDropTarget::Get(const char *fmt) const
{
FORMATETC fmtetc = ToFORMATETC(fmt);
STGMEDIUM s;
if(data->GetData(&fmtetc, &s) == S_OK && s.tymed == TYMED_HGLOBAL) {
char *val = (char *)GlobalLock(s.hGlobal);
String data(val, (int)GlobalSize(s.hGlobal));
GlobalUnlock(s.hGlobal);
ReleaseStgMedium(&s);
return data;
}
return Null;
}
void UDropTarget::DnD(POINTL pl, bool drop, DWORD *effect, DWORD keys)
{
GuiLock __;
LLOG("DnD effect: " << *effect);
dword e = *effect;
*effect = DROPEFFECT_NONE;
if(!ctrl)
return;
PasteClip d;
d.dt = this;
d.paste = drop;
d.accepted = false;
d.allowed = 0;
d.action = 0;
if(e & DROPEFFECT_COPY) {
LLOG("DnD DROPEFFECT_COPY");
d.allowed = DND_COPY;
d.action = DND_COPY;
}
if(e & DROPEFFECT_MOVE) {
LLOG("DnD DROPEFFECT_MOVE");
d.allowed |= DND_MOVE;
if(Ctrl::GetDragAndDropSource())
d.action = DND_MOVE;
}
LLOG("DnD keys & MK_CONTROL:" << (keys & MK_CONTROL));
if((keys & MK_CONTROL) && (d.allowed & DND_COPY))
d.action = DND_COPY;
if((keys & (MK_ALT|MK_SHIFT)) && (d.allowed & DND_MOVE))
d.action = DND_MOVE;
ctrl->DnD(Point(pl.x, pl.y), d);
if(d.IsAccepted()) {
LLOG("DnD accepted, action: " << (int)d.action);
if(d.action == DND_MOVE)
*effect = DROPEFFECT_MOVE;
if(d.action == DND_COPY)
*effect = DROPEFFECT_COPY;
}
}
void UDropTarget::Repeat()
{
Ctrl::DnDRepeat();
}
STDMETHODIMP UDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
GuiLock __;
LLOG("DragEnter " << pt);
data = pDataObj;
data->AddRef();
fmt.Clear();
IEnumFORMATETC *fe;
if(!ctrl || pDataObj->EnumFormatEtc(DATADIR_GET, &fe) != NOERROR) {
*pdwEffect = DROPEFFECT_NONE;
return NOERROR;
}
FORMATETC fmtetc;
while(fe->Next(1, &fmtetc, 0) == S_OK) {
fmt.FindAdd(FromWin32CF(fmtetc.cfFormat));
if(fmtetc.ptd)
CoTaskMemFree(fmtetc.ptd);
}
fe->Release();
DnD(pt, false, pdwEffect, grfKeyState);
return NOERROR;
}
STDMETHODIMP UDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
LLOG("DragOver " << pt << " keys: " << grfKeyState);
DnD(pt, false, pdwEffect, grfKeyState);
return NOERROR;
}
void UDropTarget::FreeData()
{
if(data) {
data->Release();
data = NULL;
}
}
void UDropTarget::EndDrag()
{
Ctrl::DnDLeave();
}
STDMETHODIMP UDropTarget::DragLeave()
{
LLOG("DragLeave");
EndDrag();
FreeData();
return NOERROR;
}
STDMETHODIMP UDropTarget::Drop(LPDATAOBJECT, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
LLOG("Drop");
if(Ctrl::GetDragAndDropSource())
Ctrl::OverrideCursor(Null);
DnD(pt, true, pdwEffect, grfKeyState);
EndDrag();
FreeData();
return NOERROR;
}
UDropTarget::~UDropTarget()
{
if(data) data->Release();
EndDrag();
}
// --------------------------------------------------------------------------------------------
Ptr<Ctrl> sDnDSource;
Ctrl * Ctrl::GetDragAndDropSource()
{
return sDnDSource;
}
struct UDataObject : public IDataObject {
ULONG rc;
dword effect;
VectorMap<String, ClipData> data;
STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(GetData)(FORMATETC *fmtetc, STGMEDIUM *medium);
STDMETHOD(GetDataHere)(FORMATETC *, STGMEDIUM *);
STDMETHOD(QueryGetData)(FORMATETC *fmtetc);
STDMETHOD(GetCanonicalFormatEtc)(FORMATETC *, FORMATETC *pformatetcOut);
STDMETHOD(SetData)(FORMATETC *fmtetc, STGMEDIUM *medium, BOOL release);
STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ief);
STDMETHOD(DAdvise)(FORMATETC *, DWORD, IAdviseSink *, DWORD *);
STDMETHOD(DUnadvise)(DWORD);
STDMETHOD(EnumDAdvise)(LPENUMSTATDATA *);
UDataObject() { rc = 1; effect = 0; }
};
struct UEnumFORMATETC : public IEnumFORMATETC {
ULONG rc;
int ii;
UDataObject *data;
STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(Next)(ULONG n, FORMATETC *fmtetc, ULONG *fetched);
STDMETHOD(Skip)(ULONG n);
STDMETHOD(Reset)(void);
STDMETHOD(Clone)(IEnumFORMATETC **newEnum);
UEnumFORMATETC() { ii = 0; rc = 1; }
~UEnumFORMATETC() { data->Release(); }
};
struct UDropSource : public IDropSource {
ULONG rc;
Image no, move, copy;
STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
STDMETHOD_(ULONG, AddRef)(void) { return ++rc; }
STDMETHOD_(ULONG, Release)(void) { if(--rc == 0) { delete this; return 0; } return rc; }
STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
STDMETHOD(GiveFeedback)(DWORD dwEffect);
UDropSource() { rc = 1; }
};
STDMETHODIMP UDataObject::QueryInterface(REFIID iid, void ** ppv)
{
if(iid == IID_IUnknown || iid == IID_IDataObject) {
*ppv = this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
void SetMedium(STGMEDIUM *medium, const String& data)
{
int sz = data.GetCount();
HGLOBAL hData = GlobalAlloc(0, sz + 4);
if (hData) {
char *ptr = (char *) GlobalLock(hData);
memcpy(ptr, ~data, sz);
memset(ptr + sz, 0, 4);
GlobalUnlock(hData);
medium->tymed = TYMED_HGLOBAL;
medium->hGlobal = hData;
medium->pUnkForRelease = 0;
}
}
STDMETHODIMP UDataObject::GetData(FORMATETC *fmtetc, STGMEDIUM *medium)
{
String fmt = FromWin32CF(fmtetc->cfFormat);
ClipData *s = data.FindPtr(fmt);
if(s) {
String q = s->Render();
SetMedium(medium, q.GetCount() ? q : sDnDSource ? sDnDSource->GetDropData(fmt) : String());
return S_OK;
}
return DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::GetDataHere(FORMATETC *, STGMEDIUM *)
{
return DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::QueryGetData(FORMATETC *fmtetc)
{
return data.Find(FromWin32CF(fmtetc->cfFormat)) >= 0 ? S_OK : DV_E_FORMATETC;
}
STDMETHODIMP UDataObject::GetCanonicalFormatEtc(FORMATETC *, FORMATETC *pformatetcOut)
{
pformatetcOut->ptd = NULL;
return E_NOTIMPL;
}
#ifdef PLATFORM_WINCE
static int CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat(_T("Performed DropEffect"));
#else
static int CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat("Performed DropEffect");
#endif
STDMETHODIMP UDataObject::SetData(FORMATETC *fmtetc, STGMEDIUM *medium, BOOL release)
{
if(fmtetc->cfFormat == CF_PERFORMEDDROPEFFECT && medium->tymed == TYMED_HGLOBAL) {
DWORD *val = (DWORD*)GlobalLock(medium->hGlobal);
effect = *val;
GlobalUnlock(medium->hGlobal);
if(release)
ReleaseStgMedium(medium);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP UDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ief)
{
UEnumFORMATETC *ef = new UEnumFORMATETC;
ef->data = this;
AddRef();
*ief = ef;
return S_OK;
}
STDMETHODIMP UDataObject::DAdvise(FORMATETC *, DWORD, IAdviseSink *, DWORD *)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UDataObject::DUnadvise(DWORD)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP UEnumFORMATETC::QueryInterface(REFIID riid, void FAR* FAR* ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) {
*ppvObj = this;
AddRef();
return NOERROR;
}
*ppvObj = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP UEnumFORMATETC::Next(ULONG n, FORMATETC *t, ULONG *fetched) {
if(t == NULL)
return E_INVALIDARG;
if(fetched) *fetched = 0;
while(ii < data->data.GetCount() && n > 0) {
if(fetched) (*fetched)++;
n--;
*t++ = ToFORMATETC(data->data.GetKey(ii++));
}
return n ? S_FALSE : NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Skip(ULONG n) {
ii += n;
if(ii >= data->data.GetCount())
return S_FALSE;
return NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Reset()
{
ii = 0;
return NOERROR;
}
STDMETHODIMP UEnumFORMATETC::Clone(IEnumFORMATETC **newEnum)
{
if(newEnum == NULL)
return E_INVALIDARG;
UEnumFORMATETC *ef = new UEnumFORMATETC;
ef->data = data;
data->AddRef();
ef->ii = ii;
*newEnum = ef;
return NOERROR;
}
STDMETHODIMP UDropSource::QueryInterface(REFIID riid, void **ppvObj)
{
if (riid == IID_IUnknown || riid == IID_IDropSource) {
*ppvObj = this;
AddRef();
return NOERROR;
}
*ppvObj = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP UDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
if(fEscapePressed)
return DRAGDROP_S_CANCEL;
else
if(!(grfKeyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)))
return DRAGDROP_S_DROP;
Ctrl::ProcessEvents();
return NOERROR;
}
STDMETHODIMP UDropSource::GiveFeedback(DWORD dwEffect)
{
LLOG("GiveFeedback");
Image m = IsNull(move) ? copy : move;
if((dwEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY) {
LLOG("GiveFeedback COPY");
if(!IsNull(copy)) m = copy;
}
else
if((dwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE) {
LLOG("GiveFeedback MOVE");
if(!IsNull(move)) m = move;
}
else
m = no;
Ctrl::OverrideCursor(m);
Ctrl::SetMouseCursor(m);
return S_OK;
}
Image MakeDragImage(const Image& arrow, Image sample);
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
{
if(IsWin2K())
return MakeDragImage(arrow, sample);
else
return arrow98;
}
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
const VectorMap<String, ClipData>& data)
{
UDataObject *obj = new UDataObject;
obj->data <<= data;
if(fmts) {
Vector<String> f = Split(fmts, ';');
for(int i = 0; i < f.GetCount(); i++)
obj->data.GetAdd(f[i]);
}
UDropSource *dsrc = new UDropSource;
DWORD result = 0;
Image m = Ctrl::OverrideCursor(CtrlCoreImg::DndMove());
dsrc->no = MakeDragImage(CtrlCoreImg::DndNone(), CtrlCoreImg::DndNone98(), sample);
if(actions & DND_COPY)
dsrc->copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), CtrlCoreImg::DndCopy98(), sample);
if(actions & DND_MOVE)
dsrc->move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMove(), CtrlCoreImg::DndMove98(), sample);
sDnDSource = this;
int level = LeaveGuiMutexAll();
HRESULT r = DoDragDrop(obj, dsrc,
(actions & DND_COPY ? DROPEFFECT_COPY : 0) |
(actions & DND_MOVE ? DROPEFFECT_MOVE : 0), &result);
EnterGuiMutex(level);
DWORD re = obj->effect;
obj->Release();
dsrc->Release();
OverrideCursor(m);
SyncCaret();
CheckMouseCtrl();
KillRepeat();
sDnDSource = NULL;
if(r == DRAGDROP_S_DROP) {
if(((result | re) & DROPEFFECT_MOVE) == DROPEFFECT_MOVE && (actions & DND_MOVE))
return DND_MOVE;
if(((result | re) & DROPEFFECT_COPY) == DROPEFFECT_COPY && (actions & DND_COPY))
return DND_COPY;
}
return DND_NONE;
}
void ReleaseUDropTarget(UDropTarget *dt)
{
dt->Release();
}
UDropTarget *NewUDropTarget(Ctrl *ctrl)
{
UDropTarget *dt = new UDropTarget;
dt->ctrl = ctrl;
return dt;
}
void Ctrl::SetSelectionSource(const char *fmts) {}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,109 @@
K_BACK = VK_BACK + K_DELTA,
K_BACKSPACE = VK_BACK + K_DELTA,
K_TAB = 9,
K_SPACE = 32,
K_RETURN = 13,
K_ENTER = K_RETURN,
K_SHIFT_KEY = VK_SHIFT + K_DELTA,
K_CTRL_KEY = VK_CONTROL + K_DELTA,
K_ALT_KEY = VK_MENU + K_DELTA,
K_CAPSLOCK = VK_CAPITAL + K_DELTA,
K_ESCAPE = VK_ESCAPE + K_DELTA,
K_PRIOR = VK_PRIOR + K_DELTA,
K_PAGEUP = VK_PRIOR + K_DELTA,
K_NEXT = VK_NEXT + K_DELTA,
K_PAGEDOWN = VK_NEXT + K_DELTA,
K_END = VK_END + K_DELTA,
K_HOME = VK_HOME + K_DELTA,
K_LEFT = VK_LEFT + K_DELTA,
K_UP = VK_UP + K_DELTA,
K_RIGHT = VK_RIGHT + K_DELTA,
K_DOWN = VK_DOWN + K_DELTA,
K_INSERT = VK_INSERT + K_DELTA,
K_DELETE = VK_DELETE + K_DELTA,
K_NUMPAD0 = VK_NUMPAD0 + K_DELTA,
K_NUMPAD1 = VK_NUMPAD1 + K_DELTA,
K_NUMPAD2 = VK_NUMPAD2 + K_DELTA,
K_NUMPAD3 = VK_NUMPAD3 + K_DELTA,
K_NUMPAD4 = VK_NUMPAD4 + K_DELTA,
K_NUMPAD5 = VK_NUMPAD5 + K_DELTA,
K_NUMPAD6 = VK_NUMPAD6 + K_DELTA,
K_NUMPAD7 = VK_NUMPAD7 + K_DELTA,
K_NUMPAD8 = VK_NUMPAD8 + K_DELTA,
K_NUMPAD9 = VK_NUMPAD9 + K_DELTA,
K_MULTIPLY = VK_MULTIPLY + K_DELTA,
K_ADD = VK_ADD + K_DELTA,
K_SEPARATOR = VK_SEPARATOR + K_DELTA,
K_SUBTRACT = VK_SUBTRACT + K_DELTA,
K_DECIMAL = VK_DECIMAL + K_DELTA,
K_DIVIDE = VK_DIVIDE + K_DELTA,
K_SCROLL = VK_SCROLL + K_DELTA,
K_F1 = VK_F1 + K_DELTA,
K_F2 = VK_F2 + K_DELTA,
K_F3 = VK_F3 + K_DELTA,
K_F4 = VK_F4 + K_DELTA,
K_F5 = VK_F5 + K_DELTA,
K_F6 = VK_F6 + K_DELTA,
K_F7 = VK_F7 + K_DELTA,
K_F8 = VK_F8 + K_DELTA,
K_F9 = VK_F9 + K_DELTA,
K_F10 = VK_F10 + K_DELTA,
K_F11 = VK_F11 + K_DELTA,
K_F12 = VK_F12 + K_DELTA,
K_A = 'A' + K_DELTA,
K_B = 'B' + K_DELTA,
K_C = 'C' + K_DELTA,
K_D = 'D' + K_DELTA,
K_E = 'E' + K_DELTA,
K_F = 'F' + K_DELTA,
K_G = 'G' + K_DELTA,
K_H = 'H' + K_DELTA,
K_I = 'I' + K_DELTA,
K_J = 'J' + K_DELTA,
K_K = 'K' + K_DELTA,
K_L = 'L' + K_DELTA,
K_M = 'M' + K_DELTA,
K_N = 'N' + K_DELTA,
K_O = 'O' + K_DELTA,
K_P = 'P' + K_DELTA,
K_Q = 'Q' + K_DELTA,
K_R = 'R' + K_DELTA,
K_S = 'S' + K_DELTA,
K_T = 'T' + K_DELTA,
K_U = 'U' + K_DELTA,
K_V = 'V' + K_DELTA,
K_W = 'W' + K_DELTA,
K_X = 'X' + K_DELTA,
K_Y = 'Y' + K_DELTA,
K_Z = 'Z' + K_DELTA,
K_0 = '0' + K_DELTA,
K_1 = '1' + K_DELTA,
K_2 = '2' + K_DELTA,
K_3 = '3' + K_DELTA,
K_4 = '4' + K_DELTA,
K_5 = '5' + K_DELTA,
K_6 = '6' + K_DELTA,
K_7 = '7' + K_DELTA,
K_8 = '8' + K_DELTA,
K_9 = '9' + K_DELTA,
K_CTRL_LBRACKET = K_CTRL|219|K_DELTA,
K_CTRL_RBRACKET = K_CTRL|221|K_DELTA,
K_CTRL_MINUS = K_CTRL|0xbd|K_DELTA,
K_CTRL_GRAVE = K_CTRL|0xc0|K_DELTA,
K_CTRL_SLASH = K_CTRL|0xbf|K_DELTA,
K_CTRL_BACKSLASH = K_CTRL|0xdc|K_DELTA,
K_CTRL_COMMA = K_CTRL|0xbc|K_DELTA,
K_CTRL_PERIOD = K_CTRL|0xbe|K_DELTA,
K_CTRL_SEMICOLON = K_CTRL|0xbe|K_DELTA,
K_CTRL_EQUAL = K_CTRL|0xbb|K_DELTA,
K_CTRL_APOSTROPHE= K_CTRL|0xde|K_DELTA,
K_BREAK = VK_CANCEL + K_DELTA,

126
olddraw/CtrlCore/Win32Msg.i Normal file
View file

@ -0,0 +1,126 @@
#pragma BLITZ_APPROVE
x_MSG(WM_CREATE)
x_MSG(WM_DESTROY)
x_MSG(WM_MOVE)
x_MSG(WM_SIZE)
x_MSG(WM_ACTIVATE)
x_MSG(WM_SETFOCUS)
x_MSG(WM_KILLFOCUS)
x_MSG(WM_ENABLE)
x_MSG(WM_SETREDRAW)
x_MSG(WM_SETTEXT)
x_MSG(WM_GETTEXT)
x_MSG(WM_GETTEXTLENGTH)
x_MSG(WM_PAINT)
x_MSG(WM_CLOSE)
x_MSG(WM_QUIT)
x_MSG(WM_ERASEBKGND)
x_MSG(WM_SYSCOLORCHANGE)
x_MSG(WM_SHOWWINDOW)
x_MSG(WM_WININICHANGE)
x_MSG(WM_FONTCHANGE)
x_MSG(WM_NEXTDLGCTL)
x_MSG(WM_DRAWITEM)
x_MSG(WM_MEASUREITEM)
x_MSG(WM_DELETEITEM)
x_MSG(WM_VKEYTOITEM)
x_MSG(WM_CHARTOITEM)
x_MSG(WM_SETFONT)
x_MSG(WM_GETFONT)
x_MSG(WM_QUERYDRAGICON)
x_MSG(WM_COMPAREITEM)
x_MSG(WM_GETDLGCODE)
x_MSG(WM_KEYDOWN)
x_MSG(WM_KEYUP)
x_MSG(WM_CHAR)
x_MSG(WM_DEADCHAR)
x_MSG(WM_SYSKEYDOWN)
x_MSG(WM_SYSKEYUP)
x_MSG(WM_SYSCHAR)
x_MSG(WM_SYSDEADCHAR)
x_MSG(WM_KEYLAST)
x_MSG(WM_INITDIALOG)
x_MSG(WM_COMMAND)
x_MSG(WM_SYSCOMMAND)
x_MSG(WM_TIMER)
x_MSG(WM_HSCROLL)
x_MSG(WM_VSCROLL)
x_MSG(WM_INITMENUPOPUP)
x_MSG(WM_MENUCHAR)
x_MSG(WM_LBUTTONDOWN)
x_MSG(WM_LBUTTONUP)
x_MSG(WM_LBUTTONDBLCLK)
x_MSG(WM_RBUTTONDOWN)
x_MSG(WM_RBUTTONUP)
x_MSG(WM_RBUTTONDBLCLK)
x_MSG(WM_MBUTTONDOWN)
x_MSG(WM_MBUTTONUP)
x_MSG(WM_MBUTTONDBLCLK)
x_MSG(WM_MOUSEMOVE)
x_MSG(WM_CUT)
x_MSG(WM_COPY)
x_MSG(WM_PASTE)
x_MSG(WM_CLEAR)
x_MSG(WM_UNDO)
x_MSG(WM_RENDERFORMAT)
x_MSG(WM_RENDERALLFORMATS)
x_MSG(WM_DESTROYCLIPBOARD)
x_MSG(WM_QUERYNEWPALETTE)
x_MSG(WM_PALETTECHANGED)
x_MSG(WM_WINDOWPOSCHANGED)
#ifndef PLATFORM_WINCE
x_MSG(WM_QUERYENDSESSION)
x_MSG(WM_ENDSESSION)
x_MSG(WM_QUERYOPEN)
x_MSG(WM_DEVMODECHANGE)
x_MSG(WM_ACTIVATEAPP)
x_MSG(WM_TIMECHANGE)
x_MSG(WM_MOUSEACTIVATE)
x_MSG(WM_CHILDACTIVATE)
x_MSG(WM_QUEUESYNC)
x_MSG(WM_GETMINMAXINFO)
x_MSG(WM_ICONERASEBKGND)
x_MSG(WM_SPOOLERSTATUS)
x_MSG(WM_COMPACTING)
x_MSG(WM_NCLBUTTONDOWN)
x_MSG(WM_NCLBUTTONUP)
x_MSG(WM_NCLBUTTONDBLCLK)
x_MSG(WM_NCRBUTTONDOWN)
x_MSG(WM_NCRBUTTONUP)
x_MSG(WM_NCRBUTTONDBLCLK)
x_MSG(WM_NCMBUTTONDOWN)
x_MSG(WM_NCMBUTTONUP)
x_MSG(WM_NCMBUTTONDBLCLK)
x_MSG(WM_NCCREATE)
x_MSG(WM_NCDESTROY)
x_MSG(WM_NCCALCSIZE)
x_MSG(WM_NCPAINT)
x_MSG(WM_NCACTIVATE)
x_MSG(WM_INITMENU)
x_MSG(WM_MENUSELECT)
x_MSG(WM_PARENTNOTIFY)
x_MSG(WM_MDICREATE)
x_MSG(WM_MDIDESTROY)
x_MSG(WM_MDIACTIVATE)
x_MSG(WM_MDIRESTORE)
x_MSG(WM_MDINEXT)
x_MSG(WM_MDIMAXIMIZE)
x_MSG(WM_MDITILE)
x_MSG(WM_MDICASCADE)
x_MSG(WM_MDIICONARRANGE)
x_MSG(WM_MDIGETACTIVE)
x_MSG(WM_MDISETMENU)
x_MSG(WM_DRAWCLIPBOARD)
x_MSG(WM_PAINTCLIPBOARD)
x_MSG(WM_VSCROLLCLIPBOARD)
x_MSG(WM_SIZECLIPBOARD)
x_MSG(WM_ASKCBFORMATNAME)
x_MSG(WM_CHANGECBCHAIN)
x_MSG(WM_HSCROLLCLIPBOARD)
x_MSG(WM_PALETTEISCHANGING)
x_MSG(WM_DROPFILES)
x_MSG(WM_POWER)
x_MSG(WM_WINDOWPOSCHANGING)
#endif

View file

@ -0,0 +1,488 @@
#include "CtrlCore.h"
#ifdef PLATFORM_WIN32
#include <winnls.h>
#endif
//#include "imm.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#ifdef PLATFORM_WIN32
dword Ctrl::KEYtoK(dword chr) {
if(chr == VK_TAB)
chr = K_TAB;
else
if(chr == VK_SPACE)
chr = K_SPACE;
else
if(chr == VK_RETURN)
chr = K_RETURN;
else
chr = chr + K_DELTA;
if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)
return chr;
if(GetCtrl()) chr |= K_CTRL;
if(GetAlt()) chr |= K_ALT;
if(GetShift()) chr |= K_SHIFT;
return chr;
}
class NilDrawFull : public NilDraw {
virtual bool IsPaintingOp(const Rect& r) const { return true; }
};
#ifdef PLATFORM_WINCE
bool GetShift() { return false; }
bool GetCtrl() { return false; }
bool GetAlt() { return false; }
bool GetCapsLock() { return false; }
bool wince_mouseleft;
bool wince_mouseright;
bool GetMouseLeft() { return wince_mouseleft; }
bool GetMouseRight() { return wince_mouseright; }
bool GetMouseMiddle() { return false; }
Point wince_mousepos = Null;
Point GetMousePos() {
return wince_mousepos;
}
void SetWinceMouse(HWND hwnd, LPARAM lparam)
{
Point p(lparam);
ClientToScreen(hwnd, p);
wince_mousepos = p;
}
#else
void SetWinceMouse(HWND hwnd, LPARAM lparam) {}
#endif
#ifdef _DEBUG
static String sPainting;
#endif
bool PassWindowsKey(int wParam);
LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
GuiLock __;
ASSERT_(IsNull(sPainting), "WindowProc invoked while in Paint routine");
// LLOG("Ctrl::WindowProc(" << message << ") in " << ::Name(this) << ", focus " << (void *)::GetFocus());
Ptr<Ctrl> _this = this;
HWND hwnd = GetHWND();
switch(message) {
case WM_PALETTECHANGED:
if((HWND)wParam == hwnd)
break;
#ifndef PLATFORM_WINCE
case WM_QUERYNEWPALETTE:
if(!SystemDraw::AutoPalette()) break;
{
HDC hDC = GetDC(hwnd);
HPALETTE hOldPal = SelectPalette(hDC, GetQlibPalette(), FALSE);
int i = RealizePalette(hDC);
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(hwnd, hDC);
LLOG("Realized " << i << " colors");
if(i) InvalidateRect(hwnd, NULL, TRUE);
return i;
}
#endif
case WM_PAINT:
ASSERT(hwnd);
if(IsVisible() && hwnd) {
PAINTSTRUCT ps;
SyncScroll();
HDC dc = BeginPaint(hwnd, &ps);
fullrefresh = false;
SystemDraw draw(dc);
#ifndef PLATFORM_WINCE
HPALETTE hOldPal;
if(draw.PaletteMode() && SystemDraw::AutoPalette()) {
hOldPal = SelectPalette(dc, GetQlibPalette(), TRUE);
int n = RealizePalette(dc);
LLOG("In paint realized " << n << " colors");
}
#endif
#ifdef _DEBUG
sPainting = Name();
#endif
UpdateArea(draw, Rect(ps.rcPaint));
#ifdef _DEBUG
sPainting = Null;
#endif
#ifndef PLATFORM_WINCE
if(draw.PaletteMode() && SystemDraw::AutoPalette())
SelectPalette(dc, hOldPal, TRUE);
#endif
EndPaint(hwnd, &ps);
}
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCHITTEST:
CheckMouseCtrl();
if(ignoremouse) return HTTRANSPARENT;
break;
#endif
case WM_LBUTTONDOWN:
#ifdef PLARFORM_WINCE
wince_mouseleft = true;
#endif
SetWinceMouse(hwnd, lParam);
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOWN, Point((dword)lParam), 0);
if(_this) PostInput();
return 0L;
case WM_LBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(LEFTUP, Point((dword)lParam), 0);
#ifdef PLATFORM_WINCE
wince_mouseleft = false;
#endif
#ifdef PLATFORM_WINCE
wince_mousepos = Point(-99999, -99999);
if(!ignoreclick)
if(_this) DoMouse(MOUSEMOVE, Point(-99999, -99999));
#endif
if(_this) PostInput();
return 0L;
case WM_LBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOUBLE, Point((dword)lParam), 0);
if(_this) PostInput();
return 0L;
case WM_RBUTTONDOWN:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(RIGHTDOWN, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_RBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(RIGHTUP, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_RBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(RIGHTDOUBLE, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONDOWN:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(MIDDLEDOWN, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONUP:
if(ignoreclick)
EndIgnore();
else
DoMouse(MIDDLEUP, Point((dword)lParam));
if(_this) PostInput();
return 0L;
case WM_MBUTTONDBLCLK:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(MIDDLEDOUBLE, Point((dword)lParam));
if(_this) PostInput();
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
ClickActivateWnd();
IgnoreMouseUp();
break;
#endif
case WM_MOUSEMOVE:
SetWinceMouse(hwnd, lParam);
LLOG("WM_MOUSEMOVE: ignoreclick = " << ignoreclick);
if(ignoreclick) {
EndIgnore();
return 0L;
}
if(_this)
DoMouse(MOUSEMOVE, Point((dword)lParam));
DoCursorShape();
return 0L;
case 0x20a: // WM_MOUSEWHEEL:
if(ignoreclick) {
EndIgnore();
return 0L;
}
if(_this)
DoMouse(MOUSEWHEEL, Point((dword)lParam), (short)HIWORD(wParam));
if(_this) PostInput();
return 0L;
case WM_SETCURSOR:
if((HWND)wParam == hwnd && LOWORD((dword)lParam) == HTCLIENT) {
if(hCursor) SetCursor(hCursor);
return TRUE;
}
break;
// case WM_MENUCHAR:
// return MAKELONG(0, MNC_SELECT);
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_CHAR:
ignorekeyup = false;
case WM_KEYUP:
case WM_SYSKEYUP:
{
#if 0
String msgdump;
switch(message)
{
case WM_KEYDOWN: msgdump << "WM_KEYDOWN"; break;
case WM_KEYUP: msgdump << "WM_KEYUP"; break;
case WM_SYSKEYDOWN: msgdump << "WM_SYSKEYDOWN"; break;
case WM_SYSKEYUP: msgdump << "WM_SYSKEYUP"; break;
case WM_CHAR: msgdump << "WM_CHAR"; break;
}
msgdump << " wParam = 0x" << FormatIntHex(wParam, 8)
<< ", lParam = 0x" << FormatIntHex(lParam, 8)
<< ", ignorekeyup = " << (ignorekeyup ? "true" : "false");
LLOG(msgdump);
#endif
dword keycode = 0;
if(message == WM_KEYDOWN)
keycode = KEYtoK((dword)wParam);
else
if(message == WM_KEYUP)
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_SYSKEYDOWN /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/)
keycode = KEYtoK((dword)wParam);
else
if(message == WM_SYSKEYUP /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/)
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_CHAR && wParam != 127 && wParam > 32) {
#ifdef PLATFORM_WINCE
keycode = wParam;
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch
keycode = (dword)wParam;
else {
char b[20];
::GetLocaleInfo(MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE, b, 20);
int codepage = atoi(b);
if(codepage >= 1250 && codepage <= 1258)
keycode = ToUnicode((dword)wParam, codepage - 1250 + CHARSET_WIN1250);
else
keycode = (dword)wParam;
}
#endif
}
bool b = false;
if(keycode) {
b = DispatchKey(keycode, LOWORD(lParam));
SyncCaret();
if(_this) PostInput();
}
// LOG("key processed = " << b);
if(b || (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
&& wParam != VK_F4 && !PassWindowsKey((dword)wParam)) // 17.11.2003 Mirek -> invoke system menu
return 0L;
break;
}
break;
// case WM_GETDLGCODE:
// return wantfocus ? 0 : DLGC_STATIC;
case WM_ERASEBKGND:
return 1L;
case WM_DESTROY:
PreDestroy();
#ifndef PLATFORM_WINCE
break;
case WM_NCDESTROY:
#endif
if(!hwnd) break;
if(HasChildDeep(mouseCtrl) || this == ~mouseCtrl) mouseCtrl = NULL;
if(HasChildDeep(focusCtrl) || this == ~focusCtrl) focusCtrl = NULL;
if(HasChildDeep(focusCtrlWnd) || this == ~focusCtrlWnd) {
LLOG("WM_NCDESTROY: clearing focusCtrlWnd = " << ::Name(focusCtrlWnd));
focusCtrlWnd = NULL;
focusCtrl = NULL;
}
if(::GetFocus() == NULL) {
Ctrl *owner = GetOwner();
if(owner && (owner->IsForeground() || IsForeground()) && !owner->SetWantFocus())
IterateFocusForward(owner, owner);
}
#ifdef PLATFORM_WINCE
DefWindowProc(hwnd, message, wParam, lParam);
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch
DefWindowProcW(hwnd, message, wParam, lParam);
else
DefWindowProc(hwnd, message, wParam, lParam);
#endif
hwnd = NULL;
return 0L;
case WM_CANCELMODE:
if(this == ~captureCtrl || HasChildDeep(captureCtrl))
ReleaseCtrlCapture();
break;
case WM_SHOWWINDOW:
visible = (BOOL) wParam;
StateH(SHOW);
break;
#ifndef PLATFORM_WINCE
case WM_MOUSEACTIVATE:
LLOG("WM_MOUSEACTIVATE " << Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
if(!IsEnabled()) {
if(lastActiveWnd && lastActiveWnd->IsEnabled()) {
LLOG("WM_MOUSEACTIVATE -> ::SetFocus for " << UPP::Name(lastActiveWnd));
::SetFocus(lastActiveWnd->GetHWND());
}
else
MessageBeep(MB_OK);
return MA_NOACTIVATEANDEAT;
}
if(IsPopUp()) return MA_NOACTIVATE;
break;
#endif
case WM_SIZE:
case WM_MOVE:
if(hwnd) {
Rect rect;
#ifndef PLATFORM_WINCE
if(activex) {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWINFO);
::GetWindowPlacement(hwnd, &wp);
rect = wp.rcNormalPosition;
}
else
#endif
rect = GetScreenClient(hwnd);
LLOG("WM_MOVE / WM_SIZE: screen client = " << rect);
if(GetRect() != rect)
SetWndRect(rect);
WndDestroyCaret();
caretCtrl = NULL;
SyncCaret();
}
return 0L;
case WM_HELP:
return TRUE;
case WM_ACTIVATE:
LLOG("WM_ACTIVATE " << Name() << ", wParam = " << (int)wParam << ", focusCtrlWnd = " << ::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
ignorekeyup = true;
break;
case WM_SETFOCUS:
LLOG("WM_SETFOCUS " << Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
if(this != focusCtrlWnd)
if(IsEnabled()) {
LLOG("WM_SETFOCUS -> ActivateWnd: this != focusCtrlWnd, this = "
<< Name() << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd));
ActivateWnd();
}
else {
if(focusCtrlWnd && focusCtrlWnd->IsEnabled()) {
if(!IsEnabled())
MessageBeep(MB_OK);
LLOG("WM_SETFOCUS -> ::SetFocus for " << UPP::Name(focusCtrlWnd));
::SetFocus(focusCtrlWnd->GetHWND());
}
else
if(lastActiveWnd && lastActiveWnd->IsEnabled()) {
LLOG("WM_SETFOCUS -> ::SetFocus for " << UPP::Name(lastActiveWnd));
::SetFocus(lastActiveWnd->GetHWND());
}
else {
LLOG("WM_SETFOCUS - ::SetFocus(NULL)");
::SetFocus(NULL);
}
}
LLOG("//WM_SETFOCUS " << (void *)hwnd << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
return 0L;
case WM_KILLFOCUS:
LLOG("WM_KILLFOCUS " << (void *)(HWND)wParam << ", this = " << UPP::Name(this) << ", focusCtrlWnd = " << UPP::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
LLOG("Kill " << ::Name(CtrlFromHWND((HWND)wParam)));
if(!CtrlFromHWND((HWND)wParam)) {
LLOG("WM_KILLFOCUS -> KillFocusWnd: " << UPP::Name(this));
KillFocusWnd();
}
LLOG("//WM_KILLFOCUS " << (void *)(HWND)wParam << ", focusCtrlWnd = " << ::Name(focusCtrlWnd) << ", raw = " << (void *)::GetFocus());
return 0L;
case WM_ENABLE:
if(!!wParam != enabled) {
enabled = !!wParam;
RefreshFrame();
StateH(ENABLE);
}
return 0L;
#ifndef PLATFORM_WINCE
case WM_GETMINMAXINFO:
{
MINMAXINFO *mmi = (MINMAXINFO *)lParam;
Rect minr(Point(50, 50), GetMinSize());
Rect maxr(Point(50, 50), GetMaxSize());
dword style = ::GetWindowLong(hwnd, GWL_STYLE);
dword exstyle = ::GetWindowLong(hwnd, GWL_EXSTYLE);
AdjustWindowRectEx(minr, style, FALSE, exstyle);
AdjustWindowRectEx(maxr, style, FALSE, exstyle);
mmi->ptMinTrackSize = Point(minr.Size());
mmi->ptMaxTrackSize = Point(maxr.Size());
LLOG("WM_GETMINMAXINFO: MinTrackSize = " << Point(mmi->ptMinTrackSize) << ", MaxTrackSize = " << Point(mmi->ptMaxTrackSize));
LLOG("ptMaxSize = " << Point(mmi->ptMaxSize) << ", ptMaxPosition = " << Point(mmi->ptMaxPosition));
}
return 0L;
#endif
case WM_SETTINGCHANGE:
case 0x031A: // WM_THEMECHANGED
ChSync();
RefreshLayoutDeep();
RefreshFrame();
break;
/*
case WM_IME_COMPOSITION:
HIMC himc = ImmGetContext(hwnd);
if(!himc) break;
CANDIDATEFORM cf;
Rect r = GetScreenRect();
cf.dwIndex = 0;
cf.dwStyle = CFS_CANDIDATEPOS;
cf.ptCurrentPos.x = r.left + caretx;
cf.ptCurrentPos.y = r.top + carety + caretcy;
ImmSetCandidateWindow (himc, &cf);
break;
*/
}
if(hwnd)
#ifdef PLATFORM_WINCE
return DefWindowProc(hwnd, message, wParam, lParam);
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch
return DefWindowProcW(hwnd, message, wParam, lParam);
else
return DefWindowProc(hwnd, message, wParam, lParam);
#endif
return 0L;
}
void Ctrl::PreDestroy() {}
#endif
END_UPP_NAMESPACE

File diff suppressed because it is too large Load diff

505
olddraw/CtrlCore/X11App.cpp Normal file
View file

@ -0,0 +1,505 @@
#include "CtrlCore.h"
#ifdef PLATFORM_X11
#include <locale.h>
#endif
NAMESPACE_UPP
#ifdef PLATFORM_X11
#define LLOG(x) // LOG(x)
XIM Ctrl::xim;
Atom XAtom(const char *name)
{
GuiLock __;
Atom x;
INTERLOCKED {
static VectorMap<String, int> atoms;
int q = atoms.Get(name, Null);
if(IsNull(q)) {
q = XInternAtom(Xdisplay, name, XFalse);
atoms.Add(name, q);
}
x = q;
}
return x;
}
String XAtomName(Atom atom)
{
GuiLock __;
LLOG("GetAtomName");
return XGetAtomName(Xdisplay, atom);
}
String GetProperty(Window w, Atom property, Atom rtype)
{
GuiLock __;
LLOG("GetProperty");
String result;
int format;
unsigned long nitems, after = 1;
long offset = 0;
Atom type = None;
unsigned char *data;
long rsize = minmax((long)(XMaxRequestSize(Xdisplay) - 100), (long)256, (long)65536);
while(after > 0) {
if(XGetWindowProperty(Xdisplay, w, property, offset, rsize, XFalse,
rtype, &type, &format, &nitems, &after, &data) != Success)
break;
if(type == None)
break;
if(data) {
int len = format == 32 ? sizeof(unsigned long) * nitems : nitems * (format >> 3);
result.Cat(data, len);
XFree((char *)data);
offset += nitems / (32 / format);
}
else
break;
}
result.Shrink();
XFlush(Xdisplay);
return result;
}
bool WaitForEvent(Window w, int type, XEvent& event){
GuiLock __;
for(int i = 0; i < 80; i++) {
if(XCheckTypedWindowEvent(Xdisplay, w, type, &event))
return true;
XFlush(Xdisplay);
Sleep(50);
}
LOG("WaitForEvent failed");
return false;
}
String ReadPropertyData(Window w, Atom property, Atom rtype)
{
GuiLock __;
static Atom XA_INCR = XAtom("INCR");
Atom type;
int format;
unsigned long nitems, after;
unsigned char *ptr;
String r;
if(XGetWindowProperty(Xdisplay, w, property, 0, 0, XFalse, AnyPropertyType,
&type, &format, &nitems, &after, &ptr) == Success && type != None) {
XFree(ptr);
if(type == XA_INCR) {
XDeleteProperty(Xdisplay, w, property);
XEvent event;
for(;;) {
XFlush(Xdisplay);
if(!WaitForEvent(w, PropertyNotify, event))
break;
if(event.xproperty.atom == property && event.xproperty.state == PropertyNewValue) {
String x = GetProperty(w, property);
if(!x.GetLength())
break;
r.Cat(x);
XDeleteProperty(Xdisplay, w, property);
}
}
}
else {
r = GetProperty(w, property);
XDeleteProperty(Xdisplay, w, property);
}
}
return r;
}
Vector<int> GetPropertyInts(Window w, Atom property, Atom rtype)
{
GuiLock __;
Vector<int> result;
String p = GetProperty(w, property, rtype);
const long int *ptr = (const long int *)~p;
const long int *lim = ptr + p.GetLength() / 4;
result.Reserve(p.GetLength() / 4);
while(ptr < lim)
result.Add(*ptr++);
return result;
}
Index<Atom>& _NET_Supported()
{
static Index<Atom> q;
return q;
}
bool X11ErrorTrap;
bool Ctrl::TrapX11Errors()
{
GuiLock __;
bool b = X11ErrorTrap;
X11ErrorTrap = true;
return b;
}
void Ctrl::UntrapX11Errors(bool b)
{
GuiLock __;
X11ErrorTrap = b;
}
static void sPanicMessageBox(const char *title, const char *text)
{
GuiLock __;
Ctrl::ReleaseCtrlCapture();
XDisplay *display = XOpenDisplay(NULL);
if(!display)
return;
int screen = DefaultScreen(display);
int x = (DisplayWidth(display, screen) - 600) / 2;
int y = (DisplayHeight(display, screen) - 120) / 2;
Window win = XCreateSimpleWindow(display, RootWindow(display, screen),
x, y, 600, 120, 4,
BlackPixel(display, screen),
WhitePixel(display, screen));
XSizeHints size_hints;
size_hints.flags = PPosition|PSize|PMinSize;
size_hints.x = x;
size_hints.y = x;
size_hints.width = 600;
size_hints.height = 120;
size_hints.min_width = 600;
size_hints.min_height = 120;
char *h[1];
char hh[1];
*hh = 0;
h[0] = hh;
XSetStandardProperties(display, win, title, title, None, h, 0, &size_hints);
XSelectInput(display, win, ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask);
XGCValues values;
GC gc = XCreateGC(display, win, 0, &values);
// New section
unsigned long wina[1];
wina[0] = XAtom("_NET_WM_STATE_ABOVE");
XChangeProperty(display, win, XAtom("_NET_WM_STATE"), XAtom("ATOM"), 32,
PropModeReplace, (const unsigned char *)&wina, 1);
XMapWindow(display, win);
XSetInputFocus(display, win, RevertToParent, CurrentTime);
// End section
XRaiseWindow(display, win);
XFontStruct *font_info = XQueryFont(display, XGContextFromGC(gc));
for(;;) {
XEvent e;
XNextEvent(display, &e);
switch(e.type) {
case ButtonPress:
XFreeFont(display, font_info);
XFreeGC(display, gc);
XCloseDisplay(display);
#ifdef _DEBUG
__BREAK__;
#endif
return;
case Expose:
int y = 20;
const char *b = text;
for(;;) {
const char *e = strchr(b, '\n');
if(!e) break;
XDrawString(display, win, gc, 20, y, b, e - b);
y += font_info->max_bounds.ascent + font_info->max_bounds.descent;
b = e + 1;
}
XDrawString(display, win, gc, 20, y, b, strlen(b));
break;
}
}
}
#ifdef _DEBUG
#define INI_PREFIX "DEBUG_"
#else
#define INI_PREFIX
#endif
int X11ErrorHandler(XDisplay *, XErrorEvent *error)
{
if(GetIniKey(INI_PREFIX "X11_ERRORS") != "1")
return 0;
if(X11ErrorTrap || IsPanicMode()) return 0;
static const char *request[] = {
"",
"X_CreateWindow",
"X_ChangeWindowAttributes",
"X_GetWindowAttributes",
"X_DestroyWindow",
"X_DestroySubwindows",
"X_ChangeSaveSet",
"X_ReparentWindow",
"X_MapWindow",
"X_MapSubwindows",
"X_UnmapWindow",
"X_UnmapSubwindows",
"X_ConfigureWindow",
"X_CirculateWindow",
"X_GetGeometry",
"X_QueryTree",
"X_InternAtom",
"X_GetAtomName",
"X_ChangeProperty",
"X_DeleteProperty",
"X_GetProperty",
"X_ListProperties",
"X_SetSelectionOwner",
"X_GetSelectionOwner",
"X_ConvertSelection",
"X_SendEvent",
"X_GrabPointer",
"X_UngrabPointer",
"X_GrabButton",
"X_UngrabButton",
"X_ChangeActivePointerGrab",
"X_GrabKeyboard",
"X_UngrabKeyboard",
"X_GrabKey",
"X_UngrabKey",
"X_AllowEvents",
"X_GrabServer",
"X_UngrabServer",
"X_QueryPointer",
"X_GetMotionEvents",
"X_TranslateCoords",
"X_WarpPointer",
"X_SetInputFocus",
"X_GetInputFocus",
"X_QueryKeymap",
"X_OpenFont",
"X_CloseFont",
"X_QueryFont",
"X_QueryTextExtents",
"X_ListFonts",
"X_ListFontsWithInfo",
"X_SetFontPath",
"X_GetFontPath",
"X_CreatePixmap",
"X_FreePixmap",
"X_CreateGC",
"X_ChangeGC",
"X_CopyGC",
"X_SetDashes",
"X_SetClipRectangles",
"X_FreeGC",
"X_ClearArea",
"X_CopyArea",
"X_CopyPlane",
"X_PolyPoint",
"X_PolyLine",
"X_PolySegment",
"X_PolyRectangle",
"X_PolyArc",
"X_FillPoly",
"X_PolyFillRectangle",
"X_PolyFillArc",
"X_PutImage",
"X_GetImage",
"X_PolyText8",
"X_PolyText16",
"X_ImageText8",
"X_ImageText16",
"X_CreateColormap",
"X_FreeColormap",
"X_CopyColormapAndFree",
"X_InstallColormap",
"X_UninstallColormap",
"X_ListInstalledColormaps",
"X_AllocColor",
"X_AllocNamedColor",
"X_AllocColorCells",
"X_AllocColorPlanes",
"X_FreeColors",
"X_StoreColors",
"X_StoreNamedColor",
"X_QueryColors",
"X_LookupColor",
"X_CreateCursor",
"X_CreateGlyphCursor",
"X_FreeCursor",
"X_RecolorCursor",
"X_QueryBestSize",
"X_QueryExtension",
"X_ListExtensions",
"X_ChangeKeyboardMapping",
"X_GetKeyboardMapping",
"X_ChangeKeyboardControl",
"X_GetKeyboardControl",
"X_Bell",
"X_ChangePointerControl",
"X_GetPointerControl",
"X_SetScreenSaver",
"X_GetScreenSaver",
"X_ChangeHosts",
"X_ListHosts",
"X_SetAccessControl",
"X_SetCloseDownMode",
"X_KillClient",
"X_RotateProperties",
"X_ForceScreenSaver",
"X_SetPointerMapping",
"X_GetPointerMapping",
"X_SetModifierMapping",
"X_GetModifierMapping",
"X_NoOperation",
};
char h[512];
XGetErrorText(Xdisplay, error->error_code, h, 512);
String e;
e << "X Error: " << h;
if(error->request_code < __countof(request))
e << "\nrequest: " << request[error->request_code];
e << "\nresource id: " << (int)error->resourceid << " = " << Format("%0X", (int)error->resourceid);
RLOG(e);
puts(e);
BugLog() << e << "\r\n";
UsrLogT(e);
Panic(e);
return 0;
}
void SetX11ErrorHandler()
{
XSetErrorHandler(X11ErrorHandler);
}
void WakeUpGuiThread()
{
}
void Ctrl::InitX11(const char *display)
{
GuiLock __;
InstallPanicMessageBox(sPanicMessageBox);
InitX11Draw(display);
InitTimer();
byte dummy[5];
Xbuttons = XGetPointerMapping(Xdisplay, dummy, 5);
Xeventtime = CurrentTime;
SetX11ErrorHandler();
if(GetIniKey(INI_PREFIX "X11_SYNCHRONIZE") == "1")
XSynchronize(Xdisplay, 1);
Vector<int> nets = GetPropertyInts(Xroot, XAtom("_NET_SUPPORTED"));
for(int i = 0; i < nets.GetCount(); i++)
_NET_Supported().Add(nets[i]);
ChSync();
GUI_GlobalStyle_Write(GUISTYLE_XP);
GUI_DragFullWindow_Write(1);
GUI_PopUpEffect_Write(IsCompositedGui() ? GUIEFFECT_NONE : GUIEFFECT_SLIDE);
GUI_DropShadows_Write(1);
GUI_AltAccessKeys_Write(1);
GUI_AKD_Conservative_Write(0);
setlocale(LC_ALL, "en_US.utf8");
if(XSupportsLocale()) {
XSetLocaleModifiers("");
xim = XOpenIM(Xdisplay, NULL, NULL, NULL);
}
else {
xim = NULL;
LOG("IM unsupported!");
}
}
void Ctrl::ExitX11()
{
GuiLock __;
// if(xic)
// XDestroyIC(xic);
if(xim)
XCloseIM(xim);
}
Rect Ctrl::GetDefaultWindowRect()
{
GuiLock __;
static int pos = 0;
pos += 10;
int cx = Xwidth * 2 / 3;
int cy = Xheight * 2 / 3;
if(pos + cx + 50 > Xwidth || pos + cy + 50 > Xheight)
pos = 0;
return RectC(pos + 20, pos + 20, cx, cy);
}
void Ctrl::GetWorkArea(Array<Rect>& out)
{
out.Add(GetPrimaryWorkArea());
}
Rect Ctrl::GetWorkArea() const
{
return GetPrimaryWorkArea();
}
Rect Ctrl::GetWorkArea(Point pt)
{
Array<Rect> rc;
GetWorkArea(rc);
for(int i = 0; i < rc.GetCount(); i++)
if(rc[i].Contains(pt))
return rc[i];
return GetPrimaryWorkArea();
}
Rect Ctrl::GetVirtualWorkArea()
{
return GetPrimaryWorkArea();
}
Rect Ctrl::GetVirtualScreenArea()
{
return GetPrimaryScreenArea();
}
Rect Ctrl::GetPrimaryWorkArea()
{
GuiLock __;
static Rect r;
if(r.right == 0) {
Vector<int> x = GetPropertyInts(Xroot, XAtom("_NET_WORKAREA"));
if(x.GetCount())
r = RectC(x[0], x[1], x[2], x[3]);
else
r = RectC(0, 0, Xwidth, Xheight);
}
return r;
}
Rect Ctrl::GetPrimaryScreenArea()
{
return RectC(0, 0, Xwidth, Xheight);
}
int Ctrl::GetKbdDelay()
{
return 250;
}
int Ctrl::GetKbdSpeed()
{
return 25;
}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,365 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#ifdef PLATFORM_X11
Index<String> Ctrl::sel_formats;
Ptr<Ctrl> Ctrl::sel_ctrl;
void Ctrl::SetSelectionSource(const char *fmts)
{
GuiLock __;
LLOG("SetSelectionSource " << UPP::Name(this) << ": " << fmts);
sel_formats = Split(fmts, ';');
sel_ctrl = this;
XSetSelectionOwner(Xdisplay, XAtom("PRIMARY"), xclipboard().win, CurrentTime);
}
Ctrl::Xclipboard::Xclipboard()
{
GuiLock __;
XSetWindowAttributes swa;
win = XCreateWindow(Xdisplay, RootWindow(Xdisplay, Xscreenno),
0, 0, 10, 10, 0, CopyFromParent, InputOnly, CopyFromParent,
0, &swa);
XSelectInput(Xdisplay, win, PropertyChangeMask);
}
Ctrl::Xclipboard::~Xclipboard()
{
GuiLock __;
XDestroyWindow(Xdisplay, win);
}
void Ctrl::Xclipboard::Write(int fmt, const ClipData& _data)
{
GuiLock __;
LLOG("SetSelectionOwner " << XAtomName(fmt));
data.GetAdd(fmt) = _data;
XSetSelectionOwner(Xdisplay, XAtom("CLIPBOARD"), win, CurrentTime);
}
void Ctrl::Xclipboard::Request(XSelectionRequestEvent *se)
{
GuiLock __;
LLOG("Request " << XAtomName(se->target));
XEvent e;
e.xselection.type = SelectionNotify;
e.xselection.display = Xdisplay;
e.xselection.requestor = se->requestor;
e.xselection.selection = se->selection;
e.xselection.target = se->target;
e.xselection.time = se->time;
e.xselection.property = se->property;
if(se->target == XAtom("TARGETS")) {
LLOG("Request targets:");
if(se->selection == XAtom("PRIMARY")) {
Buffer<Atom> x(sel_formats.GetCount());
for(int i = 0; i < sel_formats.GetCount(); i++) {
x[i] = XAtom(sel_formats[i]);
LLOG('\t' << sel_formats[i]);
}
XChangeProperty(Xdisplay, se->requestor, se->property, XAtom("ATOM"),
32, 0, (unsigned char*)~x,
sel_formats.GetCount());
}
else {
Buffer<Atom> x(data.GetCount());
for(int i = 0; i < data.GetCount(); i++) {
x[i] = data.GetKey(i);
LLOG('\t' << XAtomName(x[i]));
}
XChangeProperty(Xdisplay, se->requestor, se->property, XAtom("ATOM"),
32, 0, (unsigned char*)~x,
data.GetCount());
}
}
else {
if(se->selection == XAtom("PRIMARY")) {
LLOG("Request PRIMARY data " << XAtomName(se->target));
String fmt = XAtomName(se->target);
int i = sel_formats.Find(fmt);
if(i >= 0 && sel_ctrl) {
String d = sel_ctrl->GetSelectionData(fmt);
XChangeProperty(Xdisplay, se->requestor, se->property, se->target, 8, PropModeReplace,
d, d.GetLength());
}
else
e.xselection.property = None;
}
else {
LLOG("Request CLIPBOARD data " << XAtomName(se->target));
int i = data.Find(se->target);
if(i >= 0) {
String d = data[i].Render();
XChangeProperty(Xdisplay, se->requestor, se->property, se->target, 8, PropModeReplace,
d, d.GetLength());
}
else
e.xselection.property = None;
}
}
XSendEvent(Xdisplay, se->requestor, XFalse, 0, &e);
}
String Ctrl::Xclipboard::Read(int fmt, int selection, int property)
{
GuiLock __;
if(data.GetCount() && (dword)selection == XAtom("CLIPBOARD")) {
int q = data.Find(fmt);
return q >= 0 ? data[q].Render() : String();
}
if(sel_ctrl && (dword)selection == XAtom("PRIMARY"))
return sel_ctrl->GetSelectionData(XAtomName(fmt));
XConvertSelection(Xdisplay, selection, fmt, property, win, CurrentTime);
XFlush(Xdisplay);
XEvent event;
for(int i = 0; i < 20; i++) {
if(XCheckTypedWindowEvent(Xdisplay, win, SelectionNotify, &event)) {
if(event.xselection.property != None) {
XSync(Xdisplay, false);
return ReadPropertyData(win, event.xselection.property);
}
return Null;
}
if(XCheckTypedWindowEvent(Xdisplay, win, SelectionRequest, &event) &&
event.xselectionrequest.owner == win)
Request(&event.xselectionrequest);
if(XCheckTypedWindowEvent(Xdisplay, win, SelectionClear, &event) &&
event.xselectionclear.window == win) {
if(event.xselectionclear.selection == XAtom("CLIPBOARD"))
Clear();
if(event.xselectionclear.selection == XAtom("PRIMARY")) {
sel_ctrl = NULL;
sel_formats.Clear();
}
}
Sleep(10);
}
return Null;
}
Ctrl::Xclipboard& Ctrl::xclipboard()
{
static Xclipboard xc;
return xc;
}
void ClearClipboard()
{
GuiLock __;
Ctrl::xclipboard().Clear();
}
void AppendClipboard(const char *format, const Value& data, String (*render)(const Value& data))
{
GuiLock __;
Vector<String> s = Split(format, ';');
for(int i = 0; i < s.GetCount(); i++)
Ctrl::xclipboard().Write(XAtom(s[i]), ClipData(data, render));
}
String sRawClipData(const Value& data);
void AppendClipboard(const char *fmt, const String& data)
{
GuiLock __;
AppendClipboard(fmt, data, sRawClipData);
}
String ReadClipboard(const char *fmt)
{
GuiLock __;
return Ctrl::xclipboard().Read(XAtom(fmt), XAtom("CLIPBOARD"), XAtom("CLIPDATA"));
}
void AppendClipboardText(const String& s)
{
GuiLock __;
AppendClipboard("STRING", s);
}
String ReadClipboardText()
{
GuiLock __;
return ReadClipboard("STRING");
}
void AppendClipboardUnicodeText(const WString& s)
{
GuiLock __;
AppendClipboard("UTF8_STRING", ToUtf8(s));
}
WString ReadClipboardUnicodeText()
{
GuiLock __;
return FromUtf8(ReadClipboard("UTF8_STRING"));
}
bool Ctrl::Xclipboard::IsAvailable(int fmt, const char *type)
{
GuiLock __;
if(data.GetCount())
return data.Find(fmt) >= 0;
String formats = Read(XAtom("TARGETS"), XAtom(type), XAtom("CLIPDATA"));
int c = formats.GetCount() / sizeof(Atom);
const Atom *m = (Atom *) ~formats;
for(int i = 0; i < c; i++) {
if(m[i] == (dword)fmt)
return true;
}
return false;
}
bool Ctrl::ClipHas(int type, const char *fmt)
{
GuiLock __;
LLOG("ClipHas " << type << ": " << fmt);
if(type == 0)
return Ctrl::xclipboard().IsAvailable(XAtom(fmt), "CLIPBOARD");
if(type == 2) {
if(sel_ctrl)
return sel_formats.Find(fmt) >= 0;
return Ctrl::xclipboard().IsAvailable(XAtom(fmt), "PRIMARY");
}
return drop_formats.Find(fmt) >= 0;
}
String DnDGetData(const String& f);
String Ctrl::ClipGet(int type, const char *fmt)
{
GuiLock __;
LLOG("ClipGet " << type << ": " << fmt);
if(type && GetDragAndDropSource())
return DnDGetData(fmt);
return Ctrl::xclipboard().Read(
XAtom(fmt),
XAtom(type == 2 ? "PRIMARY" : type == 1 ? "XdndSelection" : "CLIPBOARD"),
type == 1 ? XA_SECONDARY : XAtom("CLIPDATA")
);
}
const char *ClipFmtsText()
{
return "STRING;UTF8_STRING;text/plain;text/unicode";
}
String GetString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("STRING") || clip.Accept("text/plain"))
return ~clip;
if(clip.Accept("UTF8_STRING"))
return FromUtf8(~clip).ToString();
if(clip.Accept("text/unicode"))
return Unicode__(~clip).ToString();
return Null;
}
WString GetWString(PasteClip& clip)
{
GuiLock __;
if(clip.Accept("STRING") || clip.Accept("text/plain"))
return (~clip).ToWString();
if(clip.Accept("UTF8_STRING"))
return FromUtf8(~clip);
if(clip.Accept("text/unicode"))
return Unicode__(~clip);
return Null;
}
String GetTextClip(const WString& text, const String& fmt)
{
GuiLock __;
if(fmt == "STRING" || fmt == "text/plain")
return text.ToString();
if(fmt == "UTF8_STRING")
return ToUtf8(text);
if(fmt == "text/unicode")
return Unicode__(text);
return Null;
}
String GetTextClip(const String& text, const String& fmt)
{
GuiLock __;
if(fmt == "STRING" || fmt == "text/plain")
return text;
if(fmt == "UTF8_STRING")
return ToUtf8(text.ToWString());
if(fmt == "text/unicode")
return Unicode__(text.ToWString());
return Null;
}
bool AcceptText(PasteClip& clip)
{
GuiLock __;
return clip.Accept(ClipFmtsText());
}
void Append(VectorMap<String, ClipData>& data, const String& text) // optimize
{
GuiLock __;
data.GetAdd("STRING", text);
data.GetAdd("text/plain", text);
data.GetAdd("UTF8_STRING", ToUtf8(text.ToWString()));
data.GetAdd("text/unicode", Unicode__(text.ToWString()));
}
void Append(VectorMap<String, ClipData>& data, const WString& text) // optimize
{
GuiLock __;
data.GetAdd("STRING", text.ToString());
data.GetAdd("text/plain", text.ToString());
data.GetAdd("UTF8_STRING", ToUtf8(text));
data.GetAdd("text/unicode", Unicode__(text));
}
bool IsClipboardAvailable(const char *fmt)
{
GuiLock __;
return Ctrl::xclipboard().IsAvailable(XAtom(fmt), "CLIPBOARD");
}
bool IsClipboardAvailableText()
{
GuiLock __;
return IsClipboardAvailable("STRING") ||
IsClipboardAvailable("UTF8_STRING") ||
IsClipboardAvailable("text/plain") ||
IsClipboardAvailable("text/unicode");
}
bool AcceptFiles(PasteClip& clip)
{
GuiLock __;
return clip.Accept("text/uri-list");
}
int JustLf(int c)
{
return (byte)c >= 32 || c == '\n' ? c : 0;
}
Vector<String> GetFiles(PasteClip& clip) {
GuiLock __;
Vector<String> r;
if(clip.Accept("text/uri-list")) {
String txt = clip;
Vector<String> f = Split(Filter(txt, JustLf), '\n');
for(int i = 0; i < f.GetCount(); i++)
if(f[i].StartsWith("file://"))
r.Add(f[i].Mid(7));
}
return r;
}
#endif
END_UPP_NAMESPACE

View file

@ -0,0 +1,417 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_X11
/////////////////////////////////////////////////////////////////////////////////////////
// Constructor
DHCtrl::DHCtrl()
{
// Sets control NOT initialized
isInitialized = false;
// Sets control NOT mapped
isMapped = false;
// Resets error contition
isError = false;
// Sets the user visual to null
UserVisualInfo = 0;
// No background painting
backpaint = NOBACKPAINT;
// transparent = true;
} // END Constructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Destructor
DHCtrl::~DHCtrl()
{
// Destroys the associated window and clean up stuffs
Terminate();
} // END Destructor class DHCtrl
/////////////////////////////////////////////////////////////////////////////////////////
// Maps/unmaps the window
void DHCtrl::MapWindow(bool map)
{
GuiLock __;
// no action if not initialized
if(!isInitialized)
return;
if(map && !isMapped)
XMapWindow(Xdisplay, top->window);
else if(!map && isMapped)
XUnmapWindow(Xdisplay, top->window);
isMapped = map;
} // END DHCtrl::MapWndow()
/////////////////////////////////////////////////////////////////////////////////////////
// Initializes the view
bool DHCtrl::Init()
{
GuiLock __;
static bool isInitializing = false;
// Just for security sakes...
if(isInitialized)
return true;
// Prevents reentrant call....
if(isInitializing)
return false;
isInitializing = true;
// Call BeforeInit user func...
BeforeInit();
// if display is null, error
if(!Xdisplay)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Bad display");
isError = true;
isInitializing = false;
return false;
}
// Calls the user visual function
UserVisualInfo = CreateVisual();
// If error, returns
if(isError)
{
isInitializing = false;
return false;
}
// Gets the default visual, if none is given
Visual *visual;
int Depth;
if(UserVisualInfo)
{
visual = UserVisualInfo->visual;
Depth = UserVisualInfo->depth;
}
else
{
visual = DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
Depth = DefaultDepth(Xdisplay, DefaultScreen(Xdisplay));
}
// Initializes attribute setting flags
unsigned long ValueMask =
CWBorderPixel
| CWColormap
| CWSaveUnder
// | CWBackPixel
// | CWBorderPixel
| CWColormap
// | CWEventMask
// | CWWinGravity
// | CWBitGravity
; // END ValueMask
// Initializes attribute structure
XSetWindowAttributes winAttributes;
// creates a ColorMap, in case we're not using default visual
winAttributes.colormap = XCreateColormap(Xdisplay, GetTopWindow()->GetWindow(), visual, AllocNone);
winAttributes.border_pixel = 0;
winAttributes.save_under = XFalse;
// winAttributes.win_gravity = StaticGravity;
// winAttributes.bit_gravity = ForgetGravity;
// Calls the attributes user setting routine
SetAttributes(ValueMask, winAttributes);
// Creates the X11 window
Rect r = GetRectInParentWindow();
Window WindowHandle = XCreateWindow
(
Xdisplay, // display
// GetTopWindow()->GetWindow(), // parent
GetParentWindow(),
r.left, r.top, r.Width(), r.Height(), // x, y, width, height
0, // border width
Depth, // depth
InputOutput, // class
visual, // visual
ValueMask, // value mask
&winAttributes // attributes
);
// Frees VisualInfo
if (UserVisualInfo)
{
XFree( (char *)UserVisualInfo);
UserVisualInfo = 0;
}
// If problem creating window, error
if(!WindowHandle)
{
// Call AfterInit user func...
AfterInit(true);
// Sets the appropriate error message
SetErrorMessage("DHCtrl : Can't create window");
isError = true;
isInitializing = false;
return false;
}
// Adds window to UPP managed windows
XWindow *cw = AddXWindow(WindowHandle);
cw->xic = xim ? XCreateIC
(
xim,
XNInputStyle,
XIMPreeditNothing | XIMStatusNothing,
XNClientWindow,
WindowHandle,
XNFocusWindow,
WindowHandle,
NULL
)
: NULL;
top = new Top;
top->window = WindowHandle;
long im_event_mask = 0;
if(cw->xic)
XGetICValues(cw->xic, XNFilterEvents, &im_event_mask, NULL);
XSelectInput
(
Xdisplay,
WindowHandle,
ExposureMask
// | StructureNotifyMask // *very* important, flag MUST NOT be set
| KeyPressMask
| FocusChangeMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PropertyChangeMask
| VisibilityChangeMask
| im_event_mask
);
int version = 5;
XChangeProperty
(
Xdisplay,
WindowHandle,
XAtom("XdndAware"),
XA_ATOM,
32,
0,
(byte *)&version,
1
);
// Maps the window if needed
if(IsShown())
MapWindow(true);
// Flushes the display
XFlush(Xdisplay);
// Stores the initial control size
CurrentSize = GetSize();
// Exits from initializing lock
isInitializing = false;
// mark control as initialized
isInitialized = true;
// Resets the message
isError = false;
SetErrorMessage("");
// Call AfterInit user func...
AfterInit(false);
return true;
} // END DHCtrl::Init()
/////////////////////////////////////////////////////////////////////////////////////////
// Terminates the view
void DHCtrl::Terminate(void)
{
GuiLock __;
BeforeTerminate();
if(!isInitialized)
return;
// Unmaps the window
MapWindow(false);
// gathers data from XWindow (needs Input Context...)
XWindow *cw = XWindowFromWindow(top->window);
// Frees input context as needed
if(cw->xic)
{
XDestroyIC(cw->xic);
cw->xic = NULL;
}
// Removes XWindow from Upp list
RemoveXWindow(top->window);
// Destroys the window
// Not to do, it's done destroying the parent window by X11 system
// XDestroyWindow(Xdisplay, top->window);
// Destroys created Top struct
delete top;
top = NULL;
// Resets initialization and error flags
isInitialized = false;
isError = false;
} // END DHCtrl::Terminate()
/////////////////////////////////////////////////////////////////////////////////////////
// State handler
void DHCtrl::State(int reason)
{
GuiLock __;
// Window dummy;
// int x, y;
// unsigned int width, height, border, depth;
Rect r;
// No handling if in error state
if( isError)
return;
// Initializes the control if needed (and possible...)
if(!isInitialized && GetTopWindow() && GetTopWindow()->GetWindow())
Init();
if(isInitialized)
{
switch( reason )
{
case FOCUS : // = 10,
break;
case ACTIVATE : // = 11,
break;
case DEACTIVATE : // = 12,
break;
case SHOW : // = 13,
MapWindow(IsVisible());
break;
case ENABLE : // = 14,
break;
case EDITABLE : // = 15,
break;
case OPEN : // = 16,
MapWindow(IsShown());
break;
case CLOSE : // = 17,
Terminate();
break;
case POSITION : // = 100,
case LAYOUTPOS : // = 101,
SyncNativeWindows();
break;
default:
break;
} // switch(reason)
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Property Visual
Visual *DHCtrl::GetVisual(void)
{
GuiLock __;
if(UserVisualInfo)
return UserVisualInfo->visual;
else
return DefaultVisual(Xdisplay, DefaultScreen(Xdisplay));
} // END DHCtrl::getVisual()
/////////////////////////////////////////////////////////////////////////////////////////
// Property VisualInfo
XVisualInfo DHCtrl::GetVisualInfo(void)
{
GuiLock __;
// if present an user visual info, just return it
if(UserVisualInfo)
return *UserVisualInfo;
XVisualInfo visualInfo;
// get the active visual
Visual *visual = GetVisual();
// gets a list of all available XVsualinfo
XVisualInfo *v = 0;
XVisualInfo vtemplate;
int nVis;
XVisualInfo *vlist = XGetVisualInfo(Xdisplay, VisualNoMask, &vtemplate, &nVis);
// search for current visual inside the list
if(vlist)
{
for (v = vlist; v < vlist + nVis; v++)
{
if (v->visual == visual)
{
visualInfo = *v;
break;
}
}
XFree(vlist);
}
else
{
isError = true;
ErrorMessage = "DHCtrl: no XVisualInfo for current Visual";
}
// returns the found XVisualInfo struct
return visualInfo;
}
#endif
END_UPP_NAMESPACE

428
olddraw/CtrlCore/X11DnD.cpp Normal file
View file

@ -0,0 +1,428 @@
#include "CtrlCore.h"
#define LLOG(x) // LOG(x)
#ifdef PLATFORM_X11
NAMESPACE_UPP
bool Xdnd_waiting_status;
bool Xdnd_waiting_finished;
int Xdnd_status;
int Xdnd_version;
static Atom XdndEnter;
static Atom XdndPosition;
static Atom XdndLeave;
static Atom XdndDrop;
static Atom XdndStatus;
static Atom XdndFinished;
static Atom XdndActionCopy;
static Atom XdndActionMove;
void InitDndAtoms()
{
ONCELOCK {
XdndEnter = XAtom("XdndEnter");
XdndPosition = XAtom("XdndPosition");
XdndLeave = XAtom("XdndLeave");
XdndDrop = XAtom("XdndDrop");
XdndStatus = XAtom("XdndStatus");
XdndFinished = XAtom("XdndFinished");
XdndActionCopy = XAtom("XdndActionCopy");
XdndActionMove = XAtom("XdndActionMove");
}
}
XEvent ClientMsg(Window src, Atom type, int format = 32)
{
XEvent e;
Zero(e);
e.xclient.type = ClientMessage;
e.xclient.display = Xdisplay;
e.xclient.window = src;
e.xclient.message_type = type;
e.xclient.format = format;
return e;
}
struct DnDLoop : LocalLoop {
Image move, copy, reject;
Vector<Atom> fmt;
const VectorMap<String, ClipData> *data;
Ptr<Ctrl> source;
void SetFmts(Window w, Atom property);
Window src, target;
int action;
void Request(XSelectionRequestEvent *se);
void Sync();
String GetData(const String& f);
void Leave();
virtual void LeftUp(Point, dword);
virtual bool Key(dword, int);
virtual void MouseMove(Point p, dword);
virtual Image CursorImage(Point, dword);
};
Ptr<DnDLoop> dndloop;
void DnDLoop::Leave()
{
GuiLock __;
if(target) {
LLOG("Sending XdndLeave to " << target);
XEvent e = ClientMsg(target, XdndLeave);
e.xclient.data.l[0] = src;
XSendEvent(Xdisplay, target, XFalse, 0, &e);
}
}
void DnDLoop::Sync()
{
GuiLock __;
if(Xdnd_waiting_status || Xdnd_waiting_finished)
return;
bool tx = Ctrl::TrapX11Errors();
Window root;
unsigned int d1;
int x, y, d2;
Window tgt = Xroot;
int version;
for(;;) {
if(XQueryPointer(Xdisplay, tgt, &root, &tgt, &x, &y, &d2, &d2, &d1)) {
if(!tgt)
break;
Vector<int> x = GetPropertyInts(tgt, XAtom("XdndAware"));
LLOG("XdndAware " << tgt << ": " << x.GetCount());
if(x.GetCount()) {
Xdnd_version = x[0];
break;
}
}
else {
tgt = None;
break;
}
}
if(Xdnd_version < 3)
tgt = None;
if(tgt != target) {
Leave();
target = tgt;
if(target) {
LLOG("Sending XdndEnter to " << target << ", src = " << src);
XEvent e = ClientMsg(target, XdndEnter);
e.xclient.data.l[0] = src;
e.xclient.data.l[1] = (fmt.GetCount() > 3) | (version << 24);
for(int i = 0; i < min(3, fmt.GetCount()); i++)
e.xclient.data.l[i + 2] = fmt[i];
XSendEvent(Xdisplay, target, XFalse, 0, &e);
}
}
if(target) {
LLOG("Sending XdndPosition to " << target << " " << x << ", " << y);
XEvent e = ClientMsg(target, XdndPosition);
e.xclient.data.l[0] = src;
e.xclient.data.l[1] = 0;
e.xclient.data.l[2] = MAKELONG(y, x);
e.xclient.data.l[3] = Xeventtime;
int action = XdndActionCopy;
if(source && source->GetTopCtrl()->GetWindow() == target)
action = XdndActionMove;
if(GetShift())
action = XdndActionMove;
if(GetCtrl())
action = XdndActionCopy;
e.xclient.data.l[4] = action;
XSendEvent(Xdisplay, target, XFalse, 0, &e);
XFlush(Xdisplay);
Xdnd_waiting_status = true;
dword timeout = GetTickCount();
LLOG("Waiting for XdndStatus");
while(Xdnd_waiting_status && GetTickCount() - timeout < 200) {
GuiSleep(0);
ProcessEvents();
}
LLOG("Waiting status " << GetTickCount() - timeout << "ms");
if(Xdnd_waiting_status) {
LLOG("XdndStatus timeout");
Xdnd_status = DND_NONE;
Xdnd_waiting_status = false;
}
else
LLOG("XdndStatus recieved " << Xdnd_status);
}
Ctrl::UntrapX11Errors(tx);
}
void Ctrl::DropStatusEvent(XEvent *event)
{
GuiLock __;
InitDndAtoms();
if(event->type != ClientMessage)
return;
LLOG("DropStatus Client Message " << XAtomName(event->xclient.message_type));
if(event->type == ClientMessage && dndloop && event->xclient.data.l[0] == (int)dndloop->target) {
if(event->xclient.message_type == XdndStatus && Xdnd_waiting_status) {
LLOG("XdndStatus, xdnd action: " << XAtomName(event->xclient.data.l[4]));
if(Xdnd_status == DND_NONE)
Xdnd_status = (event->xclient.data.l[1] & 1) ?
event->xclient.data.l[4] == (int)XdndActionMove ? DND_MOVE : DND_COPY
: DND_NONE;
Xdnd_waiting_status = false;
}
if(event->xclient.message_type == XdndFinished && Xdnd_waiting_finished) {
LLOG("XdndFinished, xdnd action: " << XAtomName(event->xclient.data.l[2]));
if(Xdnd_version == 5)
Xdnd_status = (event->xclient.data.l[1] & 1) ?
event->xclient.data.l[2] == (int)XdndActionMove ? DND_MOVE : DND_COPY
: DND_NONE;
Xdnd_waiting_finished = false;
}
}
}
void DnDLoop::LeftUp(Point, dword)
{
GuiLock __;
LLOG("DnDLoop::LeftUp");
bool tx = TrapX11Errors();
if(target) {
LLOG("Sending XdndDrop to " << target);
XEvent e = ClientMsg(target, XdndDrop);
e.xclient.data.l[0] = src;
e.xclient.data.l[1] = 0;
e.xclient.data.l[2] = Xeventtime;
Xdnd_waiting_finished = true;
XSendEvent(Xdisplay, target, XFalse, 0, &e);
XFlush(Xdisplay);
int timeout = GetTickCount();
LLOG("Waiting for XdndFinished");
while(Xdnd_waiting_finished && GetTickCount() - timeout < 200) {
GuiSleep(0);
ProcessEvents();
}
LLOG("Waiting finished " << GetTickCount() - timeout << "ms");
if(Xdnd_waiting_status) {
LLOG("XdndFinished timeout");
Xdnd_status = DND_NONE;
Xdnd_waiting_finished = false;
}
else
LLOG("XdndFinished recieved");
}
EndLoop();
UntrapX11Errors(tx);
}
void DnDLoop::MouseMove(Point p, dword)
{
GuiLock __;
LLOG("DnDLoop::MouseMove");
Sync();
}
bool DnDLoop::Key(dword, int)
{
GuiLock __;
LLOG("DnDLoop::Key");
Sync();
return false;
}
Image DnDLoop::CursorImage(Point, dword)
{
GuiLock __;
return Xdnd_status == DND_MOVE ? move : Xdnd_status == DND_COPY ? copy : reject;
}
void DnDLoop::SetFmts(Window w, Atom property)
{
GuiLock __;
Buffer<Atom> x(fmt.GetCount());
for(int i = 0; i < fmt.GetCount(); i++) {
x[i] = fmt[i];
LLOG('\t' << XAtomName(x[i]));
}
XChangeProperty(Xdisplay, w, property, XAtom("ATOM"),
32, 0, (unsigned char*)~x,
fmt.GetCount());
}
String DnDLoop::GetData(const String& f)
{
GuiLock __;
int i = data->Find(f);
String d;
if(i >= 0)
d = (*data)[i].Render();
else
if(source)
d = source->GetDropData(f);
return d;
}
String DnDGetData(const String& f)
{
GuiLock __;
String d;
if(dndloop)
d = dndloop->GetData(f);
return d;
}
void DnDLoop::Request(XSelectionRequestEvent *se)
{
GuiLock __;
LLOG("DnDRequest " << XAtomName(se->target));
XEvent e;
e.xselection.type = SelectionNotify;
e.xselection.display = Xdisplay;
e.xselection.requestor = se->requestor;
e.xselection.selection = XAtom("XdndSelection");
e.xselection.target = se->target;
e.xselection.time = se->time;
e.xselection.property = se->property;
if(se->target == XAtom("TARGETS")) {
LLOG("DnDRequest targets:");
SetFmts(se->requestor, se->property);
}
else {
String d = GetData(XAtomName(se->target));
if(d.GetCount())
XChangeProperty(Xdisplay, se->requestor, se->property, se->target, 8, PropModeReplace,
d, d.GetCount());
else
e.xselection.property = None;
}
XSendEvent(Xdisplay, se->requestor, XFalse, 0, &e);
}
void DnDRequest(XSelectionRequestEvent *se)
{
GuiLock __;
if(dndloop) dndloop->Request(se);
}
void DnDClear() {}
Image MakeDragImage(const Image& arrow, Image sample);
Ptr<Ctrl> sDnDSource;
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
const VectorMap<String, ClipData>& data)
{
GuiLock __;
InitDndAtoms();
DnDLoop d;
Xdnd_waiting_status = Xdnd_waiting_finished = false;
d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample);
if(actions & DND_COPY)
d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample);
if(actions & DND_MOVE)
d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample);
d.SetMaster(*this);
d.data = &data;
d.source = this;
dndloop = &d;
Vector<String> f = Split(fmts, ';');
for(int i = 0; i < f.GetCount(); i++)
d.fmt.Add(XAtom(f[i]));
for(int i = 0; i < data.GetCount(); i++)
d.fmt.Add(XAtom(data.GetKey(i)));
d.SetFmts(xclipboard().win, XAtom("XdndTypeList"));
XSetSelectionOwner(Xdisplay, XAtom("XdndSelection"), xclipboard().win, CurrentTime);
d.src = xclipboard().win;
d.target = None;
sDnDSource = this;
d.Run();
sDnDSource = NULL;
SyncCaret();
LLOG("DoDragAndDrop finished");
return Xdnd_status;
}
Ctrl *Ctrl::GetDragAndDropSource()
{
GuiLock __;
return sDnDSource;
}
Index<String> Ctrl::drop_formats;
int XdndAction;
Point XdndPos;
PasteClip sMakeDropClip(bool paste)
{
PasteClip d;
d.type = 1;
d.paste = paste;
d.accepted = false;
d.allowed = DND_MOVE|DND_COPY;
d.action = XdndAction;
return d;
}
void Ctrl::DnD(Window src, bool paste)
{
GuiLock __;
PasteClip d = sMakeDropClip(paste);
LLOG("Source action " << XdndAction);
DnD(XdndPos, d);
XdndAction = d.GetAction();
LLOG("Target action " << XdndAction);
XEvent e = ClientMsg(src, paste ? XdndFinished : XdndStatus);
e.xclient.data.l[0] = GetWindow();
(paste ? e.xclient.data.l[2] : e.xclient.data.l[4])
= XdndAction == DND_MOVE ? XdndActionMove : XdndActionCopy;
if(d.IsAccepted())
e.xclient.data.l[1] = 1;
LLOG("Sending status/finished to " << src << " accepted: " << d.IsAccepted());
XSendEvent(Xdisplay, src, XFalse, 0, &e);
}
void Ctrl::DropEvent(XWindow& w, XEvent *event)
{
GuiLock __;
InitDndAtoms();
if(event->type != ClientMessage)
return;
Window src = event->xclient.data.l[0];
LLOG("Client Message " << GetWindow() << " " << XAtomName(event->xclient.message_type)
<< ", src: " << src);
if(event->xclient.message_type == XdndEnter) {
LLOG("DnDEnter");
drop_formats.Clear();
if(event->xclient.data.l[1] & 1) {
Vector<int> v = GetPropertyInts(src, XAtom("XdndTypeList"), XA_ATOM);
for(int i = 0; i < v.GetCount(); i++)
drop_formats.Add(XAtomName(v[i]));
}
else
for(int i = 2; i <= 4; i++)
drop_formats.Add(XAtomName(event->xclient.data.l[i]));
}
static Point xdndpos;
if(event->xclient.message_type == XdndPosition) {
dword x = event->xclient.data.l[2];
XdndPos = Point(HIWORD(x), LOWORD(x));
LLOG("XdndPosition " << XdndPos << ", action " << XAtomName(event->xclient.data.l[4]));
XdndAction = event->xclient.data.l[4] == (int)XdndActionMove ? DND_MOVE : DND_COPY;
DnD(src, false);
}
if(event->xclient.message_type == XdndLeave)
DnDLeave();
if(event->xclient.message_type == XdndDrop && dndctrl) {
LLOG("XdndDrop to " << UPP::Name(dndctrl));
DnD(src, true);
DnDLeave();
}
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,35 @@
//#BLITZ_APPROVE
x_Event(KeyPress)
x_Event(KeyRelease)
x_Event(ButtonPress)
x_Event(ButtonRelease)
x_Event(MotionNotify)
x_Event(EnterNotify)
x_Event(LeaveNotify)
x_Event(FocusIn)
x_Event(FocusOut)
x_Event(KeymapNotify)
x_Event(Expose)
x_Event(GraphicsExpose)
x_Event(NoExpose)
x_Event(VisibilityNotify)
x_Event(CreateNotify)
x_Event(DestroyNotify)
x_Event(UnmapNotify)
x_Event(MapNotify)
x_Event(MapRequest)
x_Event(ReparentNotify)
x_Event(ConfigureNotify)
x_Event(ConfigureRequest)
x_Event(GravityNotify)
x_Event(ResizeRequest)
x_Event(CirculateNotify)
x_Event(CirculateRequest)
x_Event(PropertyNotify)
x_Event(SelectionClear)
x_Event(SelectionRequest)
x_Event(SelectionNotify)
x_Event(ColormapNotify)
x_Event(ClientMessage)
x_Event(MappingNotify)

View file

@ -0,0 +1,75 @@
#include "CtrlCore.h"
#include <plugin/bmp/bmp.h>
NAMESPACE_UPP
#ifdef PLATFORM_X11
const char *ClipFmtsImage()
{
static const char *q;
ONCELOCK {
static String s(ClipFmt<Image>() + ";image/png");
q = s;
}
return q;
}
bool AcceptImage(PasteClip& clip)
{
return clip.Accept(ClipFmt<Image>()) || clip.Accept("image/png");
}
Image GetImage(PasteClip& clip)
{
Image m;
if(Accept<Image>(clip)) {
LoadFromString(m, ~clip);
if(!m.IsEmpty())
return m;
}
if(clip.Accept("image/png"))
return StreamRaster::LoadStringAny(~clip);
return Null;
}
Image ReadClipboardImage()
{
return GetImage(Ctrl::Clipboard());
}
static String sBmp(const Value& data)
{
Image img = data;
return BMPEncoder().SaveString(img);
}
static String sImg(const Value& data)
{
Image img = data;
return StoreAsString(const_cast<Image&>(img));
}
String GetImageClip(const Image& img, const String& fmt)
{
if(img.IsEmpty())
return Null;
if(fmt == "image/bmp")
return BMPEncoder().SaveString(img);
if(fmt == ClipFmt<Image>())
return StoreAsString(const_cast<Image&>(img));
return Null;
}
void AppendClipboardImage(const Image& img)
{
if(img.IsEmpty()) return;
AppendClipboard(ClipFmt<Image>(), img, sImg);
AppendClipboard("image/bmp", img, sBmp);
}
#endif
END_UPP_NAMESPACE

111
olddraw/CtrlCore/X11Keys.i Normal file
View file

@ -0,0 +1,111 @@
K_BACK = 8,
K_BACKSPACE = 8,
K_TAB = 9,
K_RETURN = 13,
K_ENTER = 13,
K_ESCAPE = 27,
K_SPACE = 32,
K_DELETE = XK_Delete + K_DELTA,
K_SHIFT_KEY = XK_Shift_L + K_DELTA,
K_CTRL_KEY = XK_Control_L + K_DELTA,
K_ALT_KEY = XK_Meta_L + K_DELTA,
K_CAPSLOCK = XK_Caps_Lock + K_DELTA,
K_PRIOR = XK_Page_Up + K_DELTA,
K_PAGEUP = XK_Page_Up + K_DELTA,
K_NEXT = XK_Page_Down + K_DELTA,
K_PAGEDOWN = XK_Page_Down + K_DELTA,
K_END = XK_End + K_DELTA,
K_HOME = XK_Home + K_DELTA,
K_LEFT = XK_Left + K_DELTA,
K_UP = XK_Up + K_DELTA,
K_RIGHT = XK_Right + K_DELTA,
K_DOWN = XK_Down + K_DELTA,
K_INSERT = XK_Insert + K_DELTA,
K_NUMPAD0 = XK_KP_0 + K_DELTA,
K_NUMPAD1 = XK_KP_1 + K_DELTA,
K_NUMPAD2 = XK_KP_2 + K_DELTA,
K_NUMPAD3 = XK_KP_3 + K_DELTA,
K_NUMPAD4 = XK_KP_4 + K_DELTA,
K_NUMPAD5 = XK_KP_5 + K_DELTA,
K_NUMPAD6 = XK_KP_6 + K_DELTA,
K_NUMPAD7 = XK_KP_7 + K_DELTA,
K_NUMPAD8 = XK_KP_8 + K_DELTA,
K_NUMPAD9 = XK_KP_9 + K_DELTA,
K_MULTIPLY = XK_KP_Multiply + K_DELTA,
K_ADD = XK_KP_Add + K_DELTA,
K_SEPARATOR = XK_KP_Separator + K_DELTA,
K_SUBTRACT = XK_KP_Subtract + K_DELTA,
K_DECIMAL = XK_KP_Decimal + K_DELTA,
K_DIVIDE = XK_KP_Divide + K_DELTA,
K_SCROLL = XK_Scroll_Lock + K_DELTA,
K_F1 = XK_F1 + K_DELTA,
K_F2 = XK_F2 + K_DELTA,
K_F3 = XK_F3 + K_DELTA,
K_F4 = XK_F4 + K_DELTA,
K_F5 = XK_F5 + K_DELTA,
K_F6 = XK_F6 + K_DELTA,
K_F7 = XK_F7 + K_DELTA,
K_F8 = XK_F8 + K_DELTA,
K_F9 = XK_F9 + K_DELTA,
K_F10 = XK_F10 + K_DELTA,
K_F11 = XK_F11 + K_DELTA,
K_F12 = XK_F12 + K_DELTA,
K_A = 'A' + K_DELTA,
K_B = 'B' + K_DELTA,
K_C = 'C' + K_DELTA,
K_D = 'D' + K_DELTA,
K_E = 'E' + K_DELTA,
K_F = 'F' + K_DELTA,
K_G = 'G' + K_DELTA,
K_H = 'H' + K_DELTA,
K_I = 'I' + K_DELTA,
K_J = 'J' + K_DELTA,
K_K = 'K' + K_DELTA,
K_L = 'L' + K_DELTA,
K_M = 'M' + K_DELTA,
K_N = 'N' + K_DELTA,
K_O = 'O' + K_DELTA,
K_P = 'P' + K_DELTA,
K_Q = 'Q' + K_DELTA,
K_R = 'R' + K_DELTA,
K_S = 'S' + K_DELTA,
K_T = 'T' + K_DELTA,
K_U = 'U' + K_DELTA,
K_V = 'V' + K_DELTA,
K_W = 'W' + K_DELTA,
K_X = 'X' + K_DELTA,
K_Y = 'Y' + K_DELTA,
K_Z = 'Z' + K_DELTA,
K_0 = '0' + 128 + K_DELTA,
K_1 = '1' + 128 + K_DELTA,
K_2 = '2' + 128 + K_DELTA,
K_3 = '3' + 128 + K_DELTA,
K_4 = '4' + 128 + K_DELTA,
K_5 = '5' + 128 + K_DELTA,
K_6 = '6' + 128 + K_DELTA,
K_7 = '7' + 128 + K_DELTA,
K_8 = '8' + 128 + K_DELTA,
K_9 = '9' + 128 + K_DELTA,
K_CTRL_LBRACKET = K_CTRL|XK_bracketleft|K_DELTA,
K_CTRL_RBRACKET = K_CTRL|XK_bracketright|K_DELTA,
K_CTRL_MINUS = K_CTRL|0x2d|K_DELTA,
K_CTRL_GRAVE = K_CTRL|XK_grave|K_DELTA,
K_CTRL_SLASH = K_CTRL|0x5f|K_DELTA,
K_CTRL_BACKSLASH = K_CTRL|0x5c|K_DELTA,
K_CTRL_COMMA = K_CTRL|0x2c|K_DELTA,
K_CTRL_PERIOD = K_CTRL|XK_period|K_DELTA,
K_CTRL_SEMICOLON = K_CTRL|XK_semicolon|K_DELTA,
K_CTRL_EQUAL = K_CTRL|0x3d|K_DELTA,
K_CTRL_APOSTROPHE= K_CTRL|0x27|K_DELTA,
K_BREAK = XK_Pause|K_DELTA,

View file

@ -0,0 +1,384 @@
#include "CtrlCore.h"
NAMESPACE_UPP
#ifdef PLATFORM_X11
#define LLOG(x) // DLOG(x)
#define LTIMING(x) //TIMING(x)
static dword sKbdState;
static dword sModState;
void ClearKbdState_()
{
GuiLock __;
sKbdState = 0;
}
Point GetMousePos()
{
GuiLock __;
LTIMING("GetMousePos");
return Ctrl::mousePos;
}
void Ctrl::SyncMousePos()
{
GuiLock __;
LTIMING("XQueryPointer");
int x, y, xx, yy;
Window dm1, dm2;
Ctrl::mousePos = Null;
if(XQueryPointer(Xdisplay, Xroot, &dm1, &dm2, &x, &y, &xx, &yy, &sKbdState))
Ctrl::mousePos = Point(x, y);
}
bool GetShift() { GuiLock __; return sKbdState & ShiftMask; }
bool GetCtrl() { GuiLock __; return sKbdState & ControlMask; }
bool GetAlt() { GuiLock __; return sKbdState & Mod1Mask; }
bool GetCapsLock() { GuiLock __; return sKbdState & LockMask; }
bool GetMouseLeft() { GuiLock __; return sModState & Button1Mask; }
bool GetMouseRight() { GuiLock __; return sModState & (Ctrl::Xbuttons >= 3 ? Button3Mask : Button2Mask); }
bool GetMouseMiddle() { GuiLock __; return sModState & (Ctrl::Xbuttons >= 3 ? Button2Mask : 0); }
int Ctrl::Xbuttontime;
dword Ctrl::KEYtoK(dword key)
{
if(key != K_CTRL_KEY && key != K_SHIFT_KEY) {
if(GetCtrl()) key |= K_CTRL;
if(GetAlt()) key |= K_ALT;
if(GetShift()) key |= K_SHIFT;
}
return key;
}
void Ctrl::SetLastActive(XWindow *w, Ctrl *la)
{
GuiLock __;
while(w) {
LLOG(" to " << UPP::Name(w->ctrl));
w->last_active = la;
w = w->owner ? w->owner->GetXWindow() : NULL;
}
}
void Ctrl::EventProc(XWindow& w, XEvent *event)
{
GuiLock __;
Ptr<Ctrl> _this = this;
bool pressed = false;
int count = 1;
switch(event->type) {
case NoExpose:
LLOG("NoExpose serial " << event->xnoexpose.serial);
break;
case GraphicsExpose:
LLOG("GraphicsExpose serial " << event->xgraphicsexpose.serial);
case Expose: {
XExposeEvent& e = event->xexpose;
w.exposed = true;
LLOG("Expose " << RectC(e.x, e.y, e.width, e.height));
Invalidate(w, RectC(e.x, e.y, e.width, e.height));
}
return;
case ConfigureNotify: {
XConfigureEvent& e = event->xconfigure;
int x, y;
Window dummy;
// 01/12/2007 - mdelfede
// added support for windowed controls
// if(top)
// XTranslateCoordinates(Xdisplay, top->window, Xroot, 0, 0, &x, &y, &dummy);
if(top) {
Window DestW = (parent ? GetParentWindow() : Xroot);
XTranslateCoordinates(Xdisplay, top->window, DestW, 0, 0, &x, &y, &dummy);
}
Rect rect = RectC(x, y, e.width, e.height);
LLOG("CongigureNotify " << rect);
if(GetRect() != rect)
SetWndRect(rect);
// Synchronizes native windows (NOT the main one)
SyncNativeWindows();
// 01/12/2007 - END
}
return;
default:
if(!IsEnabled()) return;
}
LTIMING("XUserInput");
switch(event->type) {
case FocusIn:
if(w.xic)
XSetICFocus(w.xic);
break;
case FocusOut:
if(w.xic)
XUnsetICFocus(w.xic);
break;
case KeyPress:
pressed = true;
LLOG("event type:" << event->type << " state:" << event->xkey.state <<
"keycode:" << event->xkey.keycode);
for(;;) {
XEvent ev1[1], ev2[1];
bool hasev2 = false;
if(!IsWaitingEvent()) break;
do
XNextEvent(Xdisplay, ev1);
while(ev1->type == NoExpose && IsWaitingEvent());
LLOG("ev1 type:" << ev1->type << " state:" << ev1->xkey.state <<
"keycode:" << ev1->xkey.keycode);
if(ev1->type == KeyPress)
*ev2 = *ev1;
else {
if(ev1->type != KeyRelease ||
ev1->xkey.state != event->xkey.state ||
ev1->xkey.keycode != event->xkey.keycode ||
!IsWaitingEvent()) {
XPutBackEvent(Xdisplay, ev1);
break;
}
do
XNextEvent(Xdisplay, ev2);
while(ev2->type == NoExpose && IsWaitingEvent());
LLOG("ev2 type:" << ev2->type << " state:" << ev2->xkey.state <<
"keycode:" << ev2->xkey.keycode);
hasev2 = true;
}
if(ev2->type != KeyPress ||
ev2->xkey.state != event->xkey.state ||
ev2->xkey.keycode != event->xkey.keycode) {
if(hasev2)
XPutBackEvent(Xdisplay, ev2);
XPutBackEvent(Xdisplay, ev1);
break;
}
else {
XFilterEvent(ev1, None);
if(hasev2)
XFilterEvent(ev2, None);
}
count++;
}
case KeyRelease: {
mousePos = Point(event->xkey.x_root, event->xkey.y_root);
char buff[128];
Xeventtime = event->xkey.time;
LLOG("Key Xeventtime: " << Xeventtime << " count:" << count);
KeySym keysym;
int chr = 0;
WString wtext;
if(pressed && w.xic) {
Status status;
int len = Xutf8LookupString(w.xic, &event->xkey, buff, sizeof(buff), &keysym, &status);
buff[len] = 0;
if(status == XLookupChars || status == XLookupBoth) {
chr = FromUtf8(buff, len)[0];
if(status == XLookupChars)
wtext = FromUtf8(buff, len);
}
else
if(status != XLookupKeySym && status != XLookupBoth)
keysym = 0;
}
else {
int len = XLookupString(&event->xkey, buff, sizeof(buff), &keysym, NULL);
buff[len] = 0;
chr = FromUtf8(buff, len)[0];
if(len > 1)
wtext = FromUtf8(buff, len);
}
if(keysym == XK_Control_L || keysym == XK_Control_R) {
keysym = XK_Control_L;
if(pressed)
sKbdState |= ControlMask;
else
sKbdState &= ~ControlMask;
}
if(keysym == XK_Shift_L || keysym == XK_Shift_R) {
keysym = XK_Shift_L;
if(pressed)
sKbdState |= ShiftMask;
else
sKbdState &= ~ShiftMask;
}
if(keysym == XK_Meta_L || keysym == XK_Meta_R || keysym == XK_Alt_L ||
keysym == XK_Alt_R || keysym == XK_Super_L || keysym == XK_Super_R ||
keysym == XK_Hyper_L || keysym == XK_Hyper_R || keysym == XK_ISO_Prev_Group) {
keysym = XK_Meta_L;
if(pressed)
sKbdState |= Mod1Mask;
else
sKbdState &= ~Mod1Mask;
}
LLOG("KeySym:" << FormatIntHex(keysym) << " " << (char)keysym << " " << count);
dword up = pressed ? 0 : K_KEYUP;
static struct { KeySym keysym; dword key; } tab[] = {
{ XK_ISO_Left_Tab, K_TAB|K_SHIFT },
{ XK_BackSpace, K_BACKSPACE },
{ XK_Tab, K_TAB },
{ XK_Return, K_ENTER },
{ XK_KP_Enter, K_ENTER },
{ XK_Escape, K_ESCAPE },
{ XK_space, K_SPACE },
{ XK_KP_Space, K_SPACE },
{ XK_KP_Tab, K_TAB },
{ XK_KP_Enter, K_ENTER },
{ XK_KP_F1, K_F1 },
{ XK_KP_F2, K_F2 },
{ XK_KP_F3, K_F3 },
{ XK_KP_F4, K_F4 },
{ XK_KP_Home, K_HOME },
{ XK_KP_Left, K_LEFT },
{ XK_KP_Up, K_UP },
{ XK_KP_Right, K_RIGHT },
{ XK_KP_Down, K_DOWN },
{ XK_KP_Page_Up, K_PAGEUP },
{ XK_KP_Page_Down, K_PAGEDOWN },
{ XK_KP_End, K_END },
{ XK_KP_Begin, K_HOME },
{ XK_KP_Insert, K_INSERT },
{ XK_KP_Delete, K_DELETE },
};
for(int i = 0; i < __countof(tab); i++)
if(tab[i].keysym == keysym) {
DispatchKey(KEYtoK(tab[i].key)|up, count);
return;
}
if(GetShift() && chr == 0) {
static dword k[] = { 41, 33, 64, 35, 36, 37, 94, 38, 42, 40 };
for(int i = 0; i < 10; i++)
if(keysym == k[i]) {
DispatchKey(KEYtoK(i + K_0)|up, count);
return;
}
}
if(keysym >= 48 && keysym <= 57 && chr == 0) {
DispatchKey(KEYtoK(keysym - 48 + K_0)|up, count);
return;
}
if(chr >= 1 && chr < 32) {
DispatchKey(KEYtoK(chr - 1 + K_CTRL_A)|up, count);
return;
}
if(keysym >= 0xff80 && keysym <= 0xffb9 && chr) {
DispatchKey(KEYtoK(chr)|up, count);
return;
}
if(keysym >= 0xff00 && chr < 128 ||
(GetCtrl() || GetAlt()) && keysym >= 0x20 && keysym < 0x7f) {
if(keysym >= 'a' && keysym <= 'z')
keysym = keysym - 'a' + 'A';
DispatchKey(KEYtoK(keysym|K_DELTA)|up, count);
return;
}
if((chr == 32 || chr == 9 || chr == 13) && !pressed)
DispatchKey(chr|K_KEYUP, count);
if(chr && pressed) {
DispatchKey(chr, count);
for(int ii = 1; ii < wtext.GetLength(); ii++)
DispatchKey(wtext[ii], count);
}
}
break;
case ButtonPress: {
if(!HasWndFocus() && !popup)
SetWndFocus();
ClickActivateWnd();
mousePos = Point(event->xbutton.x_root, event->xbutton.y_root);
ReleaseGrab();
XButtonEvent& e = event->xbutton;
sModState = e.state;
Xeventtime = e.time;
if(ignoreclick) break;
Point p = Point(e.x, e.y);
dword action = DOWN;
if((dword)e.time - (dword)Xbuttontime < 800)
action = DOUBLE;
Xbuttontime = e.time;
switch(e.button) {
case Button1:
sModState |= Button1Mask;
DispatchMouse(LEFT|action, p, 0);
break;
case Button2:
sModState |= Button2Mask;
if(Xbuttons < 3)
DispatchMouse(RIGHT|action, p, 0);
else
DispatchMouse(MIDDLE|action, p, 0);
break;
case Button3:
sModState |= Button3Mask;
DispatchMouse(RIGHT|action, p, 0);
break;
}
if(_this) PostInput();
}
break;
case ButtonRelease: {
mousePos = Point(event->xbutton.x_root, event->xbutton.y_root);
XButtonEvent& e = event->xbutton;
sModState = e.state;
Xeventtime = e.time;
Point p = Point(e.x, e.y);
switch(e.button) {
case Button1:
sModState &= ~Button1Mask;
break;
case Button2:
sModState &= ~Button2Mask;
break;
case Button3:
sModState &= ~Button3Mask;
break;
}
if(ignoreclick)
EndIgnore();
else
switch(e.button) {
case Button1:
DispatchMouse(LEFTUP, p, 0);
break;
case Button2:
if(Xbuttons < 3)
DispatchMouse(RIGHTUP, p, 0);
else
DispatchMouse(MIDDLEUP, p, 0);
break;
case Button3:
DispatchMouse(RIGHTUP, p, 0);
break;
case Button4:
DispatchMouse(MOUSEWHEEL, p, 120);
break;
case Button5:
DispatchMouse(MOUSEWHEEL, p, -120);
break;
}
if(_this) PostInput();
}
break;
case MotionNotify:
while(XCheckWindowEvent(Xdisplay, top->window, PointerMotionMask, event));
EndIgnore();
mousePos = Point(event->xmotion.x_root, event->xmotion.y_root);
Xeventtime = event->xmotion.time;
Xbuttontime = Xeventtime - 0x80000000;
sModState = event->xmotion.state;
DispatchMouse(MOUSEMOVE, Point(event->xmotion.x, event->xmotion.y));
DoCursorShape();
break;
}
DropEvent(w, event);
}
#endif
END_UPP_NAMESPACE

1070
olddraw/CtrlCore/X11Wnd.cpp Normal file

File diff suppressed because it is too large Load diff

8
olddraw/CtrlCore/init Normal file
View file

@ -0,0 +1,8 @@
#ifndef _CtrlCore_icpp_init_stub
#define _CtrlCore_icpp_init_stub
#include "Draw/init"
#include "plugin\bmp/init"
#define BLITZ_INDEX__ F3E00C8C1D354C9B98AA929A9E9F39109
#include "CtrlCore.icpp"
#undef BLITZ_INDEX__
#endif

43
olddraw/CtrlCore/lay.h Normal file
View file

@ -0,0 +1,43 @@
//#BLITZ_APPROVE
#define LAYOUT(name, x, y) struct name##__layid {};
#define UNTYPED(variable, param)
#define ITEM(classname, var, param)
#define END_LAYOUT
#include LAYOUTFILE
#undef LAYOUT
#undef UNTYPED
#undef ITEM
#undef END_LAYOUT
#define LAYOUT(name, x, y) template<class T> \
struct With##name : public T, public name##__layid { \
static UPP::Size GetLayoutSize() { return UPP::Ctrl::LayoutZoom(x, y); }
#define UNTYPED(variable, param)
#define ITEM(classname, var, param) classname var;
#define END_LAYOUT };
#include LAYOUTFILE
#undef LAYOUT
#undef UNTYPED
#undef ITEM
#undef END_LAYOUT
#define LAYOUT(nm, x, y) template <class L, class D> \
void InitLayout(UPP::Ctrl& parent, L& layout, D& uts, nm##__layid&) { \
parent.LayoutId(#nm);
#define UNTYPED(var, param) uts.var.param; uts.var.LayoutId(#var); parent.Add(uts.var);
#define ITEM(clss, var, param) layout.var.param; layout.var.LayoutId(#var); parent.Add(layout.var);
#define END_LAYOUT };
#include LAYOUTFILE
#undef LAYOUT
#undef UNTYPED
#undef ITEM
#undef END_LAYOUT
#undef LAYOUTFILE

3
olddraw/CtrlCore/llay.h Normal file
View file

@ -0,0 +1,3 @@
#include <Core/lt_.h>
#include <CtrlCore/lay.h>
#include <Core/t_.h>

10
olddraw/CtrlCore/prj.aux Normal file
View file

@ -0,0 +1,10 @@
file
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Thrdcore.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Afxtls.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Winmain.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Cmdtarg.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Appui.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Appcore.cpp",
"D:\\Program Files\\Microsoft Visual Studio\\Vc98\\Mfc\\Src\\Wincore.cpp",
F:\Source\repository,
F:\Source\Qlib.txt;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,324 @@
topic "Frame";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,0#27521748481378242620020725143825:desc]
[a83;*R6 $$3,0#31310162474203024125188417583966:caption]
[l288;i1121;b17;O9;~~~.1408;2 $$4,0#10431211400427159095818037425705:param]
[i448;a25;kKO9;*@(64)2 $$5,0#37138531426314131252341829483370:item]
[*+117 $$6,6#14700283458701402223321329925657:header]
[{_}%EN-US
[s3; Frame&]
[s0; [^topic`:`/`/CtrlCore`/srcdoc`/AboutFrames`$en`-us^ Frames] are
objects derived from CtrlFrame class that form appearance and
functionality of area between outer Ctrl border and its view.&]
[s0; &]
[s0; &]
[s5;K%- [@(0.0.255) class]_[@0 CtrlFrame]&]
[s2; Interface definition of frame classes.&]
[s0;3 &]
[s0;:`:`:CtrlFrame`:`:CtrlFrame`(`):%- `~[* CtrlFrame]()&]
[s2; Empty virtual destructor.&]
[s0;3 &]
[s5;K%- virtual [@(0.0.255) void]_[@0 FrameLayout]([^`:`:Rect^ Rect]`&_[@3 r])_`=_[@3 0]&]
[s2; Frame reacts to this method by defining its own layout (if needed)
and reducing the size of Ctrl view rectangle.&]
[s4; [%-*C@3 r]-|Reference to current Ctrl rectangle. When Ctrl recomputes
its layout, it starts with Rect equivalent to its external size
(GetRect().Size()). Then it calls FrameLayout of all its frames
(starting with frame 0) and resulting Rect is the size of Ctrl`'s
view.&]
[s0;3 &]
[s5;K%- virtual [@(0.0.255) void]_[@0 FrameAddSize]([^`:`:Size^ Size]`&_[@3 sz])_`=_[@3 0]&]
[s2; Adds size of the frame to the current external size of Ctrl.
This is used to compute the external size of Ctrl for given size
of view.&]
[s4; [%-*C@3 sz]-|Reference to actual size of Ctrl.&]
[s0;3 &]
[s5;K%- virtual [@(0.0.255) void]_[@0 FramePaint]([^`:`:Draw^ Draw]`&_[@3 w],
[@(0.0.255) const]_[^`:`:Rect^ Rect]`&_[@3 r])&]
[s2; Paint the frame. Default implementation is empty.&]
[s4; [%-*C@3 w]-|Draw.&]
[s4; [%-*C@3 r]-|Outer rectangle of the frame (this is the same rectangle
as was given in last FrameLayout).&]
[s0;3 &]
[s5;K%- virtual [@(0.0.255) void]_[@0 FrameAdd]([^`:`:Ctrl^ Ctrl]`&_[@3 parent])&]
[s2; Called when frame is added to the Ctrl. Frame can use it to
add its subctrls to the parent. Default implementation is empty.&]
[s4; [%-*C@3 parent]-|Parent Ctrl.&]
[s0;3 &]
[s5;K%- virtual [@(0.0.255) void]_[@0 FrameRemove]()&]
[s2; Called when frame is removed from the Ctrl. Frame can use it
to remove subctrls from its parent. Default implementation is
empty. &]
[s0; &]
[s5;K:`:`:CtrlFrame`:`:OverPaint`(`)const:%- virtual [@(0.0.255) int]_[@0 OverPaint]()_[@(0.0.255) c
onst]&]
[s2; This method can returns non`-zero number that represents paint
extension margin of Ctrl rectangle `- frame can paint over this
margin despite that fact that it does not belong to the Ctrl
rectangle. This is useful to represent some specific skinning
effect (like glare around the EditField). Default implementation
returns zero. &]
[s0; &]
[s0; &]
[s0; &]
[s0; Standard static frames&]
[s0; U`+`+ defines several standard static frames. Those frames are
mostly used to define (or alter) appearance of border of Ctrls.
All of them are obtained as a reference to single global instance
by single global function and can be assigned to unlimited number
of Ctrls.&]
[s0; Appearance of some of them can be altered by current OS look`&feel.&]
[s0; &]
[ {{3967:1202:1908:2923h1;@(204) [s0; Function]
:: [s0; altered by look`&feel]
:: [s0; Appearance]
:: [s0; Comment]
::@2 [s0; CtrlFrame`&_[* NullFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; [1 Default Frame for Ctrl.]]
:: [s0; CtrlFrame`&_[* InsetFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ēσ<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* OutsetFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* ButtonFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* ThinInsetFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* ThinOutsetFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Λ<EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* BlackFrame]()]
:: [s0; No.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* FieldFrame]()]
:: [s0; Yes.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ι<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; [1 Good for borders of all Ctrls that display somthing, like EditField
or ArrayCtrl.]]
:: [s0; CtrlFrame`&_[* TopSeparatorFrame]()]
:: [s0; Yes.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD>§窿<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* BottomSeparatorFrame]()]
:: [s0; Yes.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD>§窿<EFBFBD>
<EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* LeftSeparatorFrame]()]
:: [s0; Yes.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>
]
:: [s0; ]
:: [s0; CtrlFrame`&_[* RightSeparatorFrame]()]
:: [s0; Yes.]
:: [s0;
@@image:612&237
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><EFBFBD>
<EFBFBD>
]
:: [s0; ]}}&]
[s0;3 &]
[s0;3 &]
[s0; Simple Ctrl frame templates&]
[s0;3 &]
[s0;3 &]
[s5;K%- template_<[@(0.0.255) class]_[@3 T]>__[@(0.0.255) class]_[@0 FrameCtrl]_:_[@(0.0.255) pu
blic]_[@3 T], [@(0.0.255) public]_[^`:`:CtrlFrame^ CtrlFrame]&]
[s0;%- class_[* FrameCtrl]&]
[s2; &]
[s2; This is the base class of simple Ctrl frames `- frames that
place single Ctrl at some edge of parent Ctrl.&]
[s2; &]
[s2; This class basically overloads FrameAdd and FrameRemove virtual
methods of [^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:CtrlFrame`:`:class CtrlFrame^ C
trlFrame] so that they add/remove `'this`' from parent`'s children`-list.&]
[s2; &]
[s4; [%-*C@4 T]-|Ctrl type.&]
[s0; &]
[s0;%- [%%/ Derived from][%% ]T, [^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:CtrlFrame`:`:class CtrlFrame^@(0.0.255) C
trlFrame]&]
[s0;3 &]
[s0; &]
[s0; &]
[s0;%- template_<class_[*@4 T]>&]
[s5;K%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameLR]_:_[@(0.0.255) publ
ic]_[^`:`:FrameCtrl^ FrameCtrl]<[@4 T]>_&]
[s2; &]
[s2; This class extends CtrlFrame class with width attribute and
serves as base class to classes placing Ctrl at the left or right
size of parent Ctrl frame. Width is initialized to 0. 0 as width
indicates that width is equal to the height.&]
[s2; &]
[s4; [%-*C@4 T]-|Ctrl type.&]
[s0; &]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameCtrl`:`:template `<class T`> class FrameCtrl^ F
rameCtrl<T>] &]
[s0;3 &]
[s0;:`:`:FrameLR`:`:FrameLR`(`):%- FrameLR`&_[* Width](int_[*@3 `_cx])&]
[s2; Sets the new width.&]
[s4; [%-*C@3 `_cx]-|Width.&]
[s4; [*/ Return value]-|`*this.&]
[s0;3 &]
[s5;K%- [@(0.0.255) int]_[@0 GetWidth]()_[@(0.0.255) const]&]
[s4; [*/ Return value]-|Current width.&]
[s0; &]
[s0;3 &]
[s0;3 &]
[s0;3 &]
[s5;K%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameLeft]_:_[@(0.0.255) pu
blic]_[^`:`:FrameLR^ FrameLR]<[@4 T]>_&]
[s0;%- class_[* FrameLeft]&]
[s2; &]
[s2; This class places Ctrl to the parent`'s left side as frame.&]
[s0; &]
[s4; [%-*C@4 T]-|Ctrl type.&]
[s0; &]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameLR`:`:template `<class T`> class FrameLR^ F
rameLR<T>] &]
[s0;3 &]
[s0;3 &]
[s0;3 &]
[s5;K%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameRight]_:_[@(0.0.255) p
ublic]_[^`:`:FrameLR^ FrameLR]<[@4 T]>_&]
[s0;%- class_[* FrameRight]&]
[s2; &]
[s2; This class places Ctrl to the parent`'s right side as frame.&]
[s0; [%-*C@4 T]-|Ctrl type.&]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameLR`:`:template `<class T`> class FrameLR^ F
rameLR<T>] &]
[s0; &]
[s0; &]
[s0;3 &]
[s5;K%- [@(0.0.255) template]_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameTB]_:_[@(0.0.255) p
ublic]_[^`:`:FrameCtrl^ FrameCtrl]<[@4 T]>_&]
[s0;%- class_[* FrameTB]&]
[s2; &]
[s2; This class extends CtrlFrame class with height attribute and
serves as base class to classes placing Ctrl as the top or bottom
side of parent Ctrl frame. Height is initialized to 0. 0 as height
indicates that height is equal to the width.&]
[s2; &]
[s0; [%-*C@4 T]-|Ctrl type.&]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameCtrl`:`:template `<class T`> class FrameCtrl^ F
rameCtrl<T>] &]
[s0;3 &]
[s5;K%- [^`:`:FrameTB^ FrameTB]`&_[@0 Height]([@(0.0.255) int]_[@3 `_cy])&]
[s2; Sets the new height.&]
[s4; [%-*C@3 `_cy]-|Height.&]
[s4; [*/ Return value]-|`*this.&]
[s0; &]
[s5;K%- [@(0.0.255) int]_[@0 GetHeight]()_[@(0.0.255) const]&]
[s4; [*/ Return value]-|Current height.&]
[s0; &]
[s0; &]
[s0; &]
[s0;3 &]
[s5;K%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameTop]_:_[@(0.0.255) pub
lic]_[^`:`:FrameTB^ FrameTB]<[@4 T]>_&]
[s0;%- class_[* FrameTop]&]
[s2; &]
[s2; This class places Ctrl to the parent`'s top side as frame.&]
[s0; [%-*C@4 T]-|Ctrl type.&]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameTB`:`:template `<class T`> class FrameTB^ F
rameTB<T>] &]
[s0; &]
[s0; &]
[s0;3 &]
[s5;K%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) class]_[@0 FrameBottom]_:_[@(0.0.255) p
ublic]_[^`:`:FrameTB^ FrameTB]<[@4 T]>_&]
[s0;%- class_[* FrameBottom]&]
[s2; &]
[s2; This class places Ctrl to the parent`'s bottom side as frame.&]
[s0; [%-*C@4 T]-|Ctrl type.&]
[s0;%- [%%/ Derived from][%% ][^topic`:`/`/CtrlCore`/src`/Frame`$en`-us`#`:`:FrameTB`:`:template `<class T`> class FrameTB^ F
rameTB<T>] &]
[s0; &]
[s0; &]
[s0; Frame utility functions&]
[s0; Following functions are intended as helpers to for implementation
of FrameLayout method of CtrlFrame, placing some Ctrl to the
side of parent Ctrl. They adjust given Rect (parameter of FrameLayout)
and also alter position of given Ctrl.&]
[s0;3 &]
[s5;K%- [@(0.0.255) void]_[@0 LayoutFrameLeft]([^`:`:Rect^ Rect]`&_[@3 r],
[^`:`:Ctrl^ Ctrl]_`*[@3 ctrl], [@(0.0.255) int]_[@3 cx])&]
[s2; Places ctrl at the left side of parent Ctrl.&]
[s4; [%-*C@3 r]-|Current parent Ctrl rect.&]
[s4; [%-*C@3 ctrl]-|Ctrl to be placed.&]
[s4; [%-*C@3 cx]-|Required width.&]
[s0;3 &]
[s5;K%- [@(0.0.255) void]_[@0 LayoutFrameRight]([^`:`:Rect^ Rect]`&_[@3 r],
[^`:`:Ctrl^ Ctrl]_`*[@3 ctrl], [@(0.0.255) int]_[@3 cx])&]
[s2; Places ctrl at the right side of parent Ctrl.&]
[s4; [%-*C@3 r]-|Current parent Ctrl rect.&]
[s4; [%-*C@3 ctrl]-|Ctrl to be placed.&]
[s4; [%-*C@3 cx]-|Required width.&]
[s0;3 &]
[s5;K%- [@(0.0.255) void]_[@0 LayoutFrameTop]([^`:`:Rect^ Rect]`&_[@3 r],
[^`:`:Ctrl^ Ctrl]_`*[@3 ctrl], [@(0.0.255) int]_[@3 cy])&]
[s2; Places ctrl at the top side of parent Ctrl.&]
[s4; [%-*C@3 r]-|Current parent Ctrl rect.&]
[s4; [%-*C@3 ctrl]-|Ctrl to be placed.&]
[s4; [%-*C@3 cy]-|Required height.&]
[s0;3 &]
[s5;K%- [@(0.0.255) void]_[@0 LayoutFrameBottom]([^`:`:Rect^ Rect]`&_[@3 r],
[^`:`:Ctrl^ Ctrl]_`*[@3 ctrl], [@(0.0.255) int]_[@3 cy])&]
[s2; Places ctrl at the bottom side of parent Ctrl.&]
[s4; [%-*C@3 r]-|Current parent Ctrl rect.&]
[s4; [%-*C@3 ctrl]-|Ctrl to be placed.&]
[s4; [%-*C@3 cy]-|Required height.&]
[s0; ]

View file

@ -0,0 +1,75 @@
topic "Layout functions";[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,0#27521748481378242620020725143825:desc]
[a83;*R6 $$3,0#31310162474203024125188417583966:caption]
[l288;i1121;b17;O9;~~~.1408;2 $$4,0#10431211400427159095818037425705:param]
[i448;a25;kKO9;*@(64)2 $$5,0#37138531426314131252341829483370:item]
[*+117 $$6,6#14700283458701402223321329925657:header]
[{_}%EN-US
[s3;%- Layout functions&]
[s0; &]
[s0; &]
[s5;K:`:`:InitLayout`(`:`:Ctrl`&`,L`&`):%- template_<[@(0.0.255) class]_[@4 L]>__[@(0.0.255) v
oid]_[@0 InitLayout]([^`:`:Ctrl^ Ctrl]`&_[@3 ctrl], [^L^ L]`&_[@3 layout])&]
[s2; Assigns layout parameters to member Ctrl variables of [@3 layout],
and adds them to the specified [*@3 ctrl].&]
[s4; [*C@4 L]-|Class (or structure) with Ctrl variables. Ctrl variables
must have public access.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 layout]-|[*C@4 L] instance.&]
[s0; &]
[s5;K:`:`:CtrlLayout`(T`&`):%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) void]_[@0 Ct
rlLayout]([^T^ T]`&_[@3 ctrl])&]
[s2; Assigns layout parameters to member variables. Required layout
must be one of base classes of T.&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s0; &]
[s5;K:`:`:CtrlLayout`(T`&`,const char`*`):%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) v
oid]_[@0 CtrlLayout]([^T^ T]`&_[@3 ctrl], [@(0.0.255) const]_[@(0.0.255) char]_`*[@3 title])&]
[s2; Calls CtrlLayout and then calls Title method of [*@3 ctrl ](assigning
a caption text to the TopWindow).&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 title]-|Window title.&]
[s0; &]
[s5;K:`:`:CtrlLayoutOK`(T`&`,const char`*`):%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) v
oid]_[@0 CtrlLayoutOK]([^T^ T]`&_[@3 ctrl], [@(0.0.255) const]_[@(0.0.255) char]_`*[@3 title])
&]
[s2; Calls CtrlLayout and then assigns Acceptor(IDOK) to the [/ ok]
member Ctrl variable and makes it the default button (activated
by Enter).&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 title]-|Window title.&]
[s0; &]
[s5;K:`:`:CtrlLayoutCancel`(T`&`,const char`*`):%- template_<[@(0.0.255) class]_[@4 T]>__
[@(0.0.255) void]_[@0 CtrlLayoutCancel]([^T^ T]`&_[@3 ctrl], [@(0.0.255) const]_[@(0.0.255) c
har]_`*[@3 title])&]
[s2; Calls CtrlLayout and then assigns Rejector(IDCANCEL) to the
[/ cancel] member Ctrl variable and makes it the default cancel
button (activated by Esc).&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 title]-|Window title.&]
[s0; &]
[s5;K:`:`:CtrlLayoutOKCancel`(T`&`,const char`*`):%- template_<[@(0.0.255) class]_[@4 T]>
__[@(0.0.255) void]_[@0 CtrlLayoutOKCancel]([^T^ T]`&_[@3 ctrl], [@(0.0.255) const]_[@(0.0.255) c
har]_`*[@3 title])&]
[s2; Calls CtrlLayoutOK and then assigns Rejector(IDCANCEL) to the
[/ cancel] member Ctrl variable and makes it the default cancel
button (activated by Esc).&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 title]-|Window title.&]
[s0; &]
[s5;K:`:`:CtrlLayoutExit`(T`&`,const char`*`):%- template_<[@(0.0.255) class]_[@4 T]>__[@(0.0.255) v
oid]_[@0 CtrlLayoutExit]([^T^ T]`&_[@3 ctrl], [@(0.0.255) const]_[@(0.0.255) char]_`*[@3 titl
e])&]
[s2; Calls CtrlLayoutOK and then assigns Acceptor(IDEXIT) to the
[/ exit] member Ctrl variable and makes it the default button (activated
by Enter).&]
[s4; [*C@4 T]-|Parent Ctrl type.&]
[s4; [%-*C@3 ctrl]-|Parent Ctrl.&]
[s4; [%-*C@3 title]-|Window title.&]
[s0; ]

View file

@ -0,0 +1,9 @@
TITLE("RectTracker")
COMPRESSED
120,156,213,89,107,115,218,56,20,253,43,154,233,99,72,150,178,178,108,99,99,186,157,116,211,180,205,52,109,58,148,221,253,192,64,16,70,9,222,24,203,35,139,36,164,211,254,246,189,242,11,155,24,226,134,180,51,219,204,128,172,199,185,247,28,93,93,95,209,1,65,79,159,226,38,126,130,239,249,231,188,97,231,116,225,203,225,192,51,12,187,75,137,217,189,252,112,218,233,238,31,52,218,198,158,66,209,0,69,183,52,221,54,117,205,32,109,248,208,116,141,152,68,55,52,155,116,12,91,215,109,236,184,62,141,162,225,192,39,182,221,85,139,72,147,60,33,150,73,52,203,176,13,91,211,45,155,192,90,130,49,193,22,49,53,67,183,137,233,76,89,228,14,7,212,214,187,251,189,54,44,210,149,37,0,199,90,155,24,150,65,176,142,137,1,166,52,219,54,52,203,180,245,78,187,237,184,52,148,30,15,82,91,158,166,17,173,59,209,172,46,248,252,253,251,247,150,102,224,196,3,3,192,52,108,128,171,26,244,97,131,88,154,217,193,29,211,214,108,172,3,184,105,97,211,9,
169,160,243,205,212,205,123,169,91,216,241,36,3,136,253,223,52,205,130,37,237,102,251,137,102,88,64,212,214,13,211,182,48,24,39,132,232,58,209,116,210,233,16,179,109,90,206,140,209,41,19,195,193,215,179,111,207,142,62,189,248,235,11,26,68,90,247,131,51,134,191,30,115,101,95,80,247,146,9,245,24,11,235,140,84,243,132,187,212,63,225,60,28,161,193,51,140,95,96,60,26,29,52,112,11,183,136,105,238,161,116,11,178,17,116,182,106,31,96,84,128,45,206,113,138,179,86,88,225,98,226,123,110,21,24,202,189,24,62,31,14,34,210,45,34,35,47,66,52,113,4,201,25,149,72,176,80,176,136,5,113,139,71,158,218,57,47,184,64,115,62,165,62,242,1,165,133,142,37,114,105,80,152,128,104,48,253,157,11,232,137,188,91,6,95,174,164,193,133,207,16,244,249,94,192,16,141,80,228,197,61,9,14,15,153,160,106,101,75,185,132,187,72,125,153,213,122,70,203,192,117,64,143,140,154,234,59,164,190,63,129,25,218,40,222,121,148,63,103,164,147,238,151,195,226,34,
133,155,206,87,205,242,212,87,43,189,148,193,76,170,254,12,4,114,83,116,148,182,217,20,49,234,206,144,244,230,12,84,99,104,10,141,32,2,58,48,62,3,230,172,6,173,47,76,30,46,68,196,197,241,156,94,176,113,195,133,213,82,13,36,207,207,199,123,14,90,247,62,93,62,170,138,13,52,126,158,83,0,181,202,240,249,164,198,138,245,42,12,149,229,124,198,89,73,179,120,245,8,149,65,138,150,116,52,207,251,247,50,213,192,120,20,11,51,231,139,136,33,55,118,4,209,48,100,112,122,3,23,4,91,8,21,84,106,74,28,82,247,203,245,209,11,190,64,108,141,27,177,118,170,181,155,62,41,222,93,97,70,153,129,17,42,77,40,82,142,110,183,113,246,2,111,14,49,30,31,5,126,190,58,13,117,88,210,155,199,101,153,224,253,12,150,244,102,23,150,170,167,16,243,241,227,174,33,159,194,62,56,214,227,252,80,74,13,235,145,46,182,8,50,225,139,96,170,130,122,149,253,174,103,158,202,18,51,149,17,35,120,99,151,71,33,133,6,92,34,118,227,50,54,173,161,
218,161,239,133,143,45,153,194,252,121,122,185,91,228,114,193,114,88,18,164,134,4,255,120,83,57,27,55,188,64,238,200,59,6,218,74,28,108,84,30,138,96,11,167,107,133,170,14,131,84,198,203,187,29,205,104,200,226,151,97,84,243,229,192,125,46,146,68,144,52,119,127,31,40,152,13,169,32,30,27,161,242,148,218,123,169,86,109,224,221,240,206,17,20,8,112,20,36,156,17,24,190,16,234,160,236,213,16,225,51,149,146,137,32,141,121,116,205,197,116,188,191,163,12,41,230,131,98,94,57,48,138,221,88,13,142,247,11,26,133,91,52,10,19,195,74,165,186,65,240,134,70,51,54,133,16,216,141,114,2,179,98,92,246,109,26,143,102,238,213,9,77,238,123,187,59,21,163,108,242,41,82,131,63,224,210,107,245,194,85,213,228,99,164,134,28,236,65,233,33,146,44,28,159,205,163,66,132,252,81,28,55,240,221,24,121,237,74,239,138,74,22,229,65,66,51,31,106,144,255,192,88,216,83,147,199,141,9,231,254,142,236,115,180,173,236,149,161,74,250,147,187,236,222,114,225,
2,181,85,70,144,28,93,130,149,248,84,112,225,93,120,1,148,17,241,109,160,6,219,158,74,30,73,86,172,26,129,230,174,175,196,24,103,67,150,172,54,57,66,105,99,195,107,112,91,213,32,178,170,129,79,254,5,240,26,10,188,99,178,250,244,173,189,138,139,156,96,77,197,89,235,49,185,16,65,154,194,23,66,168,75,223,221,12,94,195,165,184,121,183,52,105,170,195,216,220,112,34,183,120,27,195,253,188,170,100,181,29,77,244,3,39,91,222,148,206,244,235,147,227,119,159,198,103,189,227,119,239,251,63,134,179,172,194,249,243,180,223,63,253,152,111,205,103,38,206,185,152,103,151,40,117,101,46,28,160,108,143,146,219,120,138,182,159,248,168,174,226,165,174,229,16,69,33,115,189,243,101,90,143,178,233,69,124,49,119,185,8,152,40,213,238,234,130,59,97,10,58,185,198,78,157,212,31,248,66,95,191,18,27,91,14,177,77,236,24,186,161,191,84,191,230,188,210,48,124,206,180,238,65,131,96,184,70,171,80,81,102,51,138,224,209,208,113,238,118,47,243,110,116,152,152,
130,231,3,146,244,164,154,156,28,189,237,231,179,210,190,254,233,231,188,171,207,195,241,11,159,157,203,148,74,107,125,114,21,192,225,209,167,254,81,47,239,61,81,203,149,34,181,22,39,187,148,247,254,201,165,228,243,237,62,172,217,171,166,145,123,0,42,154,166,138,159,150,214,33,123,53,128,214,122,123,197,157,156,243,43,184,88,220,213,181,26,169,146,91,181,52,113,208,223,187,51,144,218,103,27,101,169,132,88,39,19,3,212,247,96,195,238,148,253,248,246,109,21,210,197,36,72,81,192,174,127,60,235,189,231,226,246,4,234,185,164,242,104,150,63,86,105,239,222,188,144,102,189,12,238,65,181,199,13,126,88,102,91,62,112,157,123,243,176,117,126,145,96,69,202,43,164,183,75,149,158,102,80,37,220,242,64,170,223,31,97,105,41,227,1,231,102,241,25,184,196,73,140,70,80,114,115,240,160,52,10,30,151,47,106,10,175,52,35,246,173,244,70,204,126,227,108,149,222,151,42,88,242,145,154,177,242,55,19,242,17,99,37,131,251,127,196,202,242,215,196,202,21,136,226,185,
143,16,41,203,36,10,102,44,206,30,191,48,84,214,187,146,95,0,164,240,75,149,109,245,255,15,172,95,234,97,21,220,233,225,115,211,15,90,20,238,43,21,229,233,161,170,175,196,194,133,34,181,96,165,25,211,185,242,128,15,21,140,42,81,10,114,164,88,74,211,69,4,55,74,216,32,52,21,244,90,237,142,170,73,92,14,23,103,168,245,37,67,209,18,166,206,139,90,192,215,240,63,201,155,238,64,

View file

@ -0,0 +1,19 @@
TITLE("TopWindow")
COMPRESSED
120,156,229,28,107,83,219,72,242,175,76,177,143,179,89,27,252,4,7,246,170,146,5,54,71,37,132,173,144,92,238,142,194,145,44,143,177,22,89,227,211,72,60,114,92,126,251,117,247,60,36,89,50,24,108,216,92,109,62,196,88,154,233,233,119,247,116,207,248,180,197,190,255,190,81,107,124,215,184,231,223,206,62,31,185,73,16,159,157,250,157,78,111,215,109,117,119,47,222,28,191,216,93,127,89,217,234,84,17,74,19,160,180,183,155,237,94,183,221,236,180,182,224,191,102,187,217,234,182,218,157,102,175,245,162,211,107,183,123,141,29,47,112,165,60,59,13,90,189,222,46,78,106,193,164,214,118,183,213,220,238,244,58,189,102,123,187,215,130,185,173,70,163,213,216,110,117,155,157,118,175,213,221,25,114,233,157,157,186,189,246,238,250,251,45,152,212,198,149,0,120,163,185,213,234,108,119,90,141,118,163,213,129,165,154,189,94,167,185,221,237,181,95,108,109,237,120,238,52,246,69,168,215,242,155,205,86,115,119,208,220,222,5,156,191,126,253,186,209,236,52,20,6,29,0,214,
108,116,0,213,38,60,107,116,90,219,205,238,139,198,139,110,175,217,107,180,1,120,119,187,209,221,153,186,145,59,153,79,122,247,94,210,183,27,59,126,204,1,196,250,79,205,230,54,76,217,170,109,125,215,236,108,3,161,189,118,167,219,219,110,192,226,173,86,171,221,110,53,219,173,23,47,90,221,173,238,246,206,152,187,67,30,157,157,254,231,243,127,127,56,120,87,255,120,194,78,101,123,151,125,16,211,79,126,56,20,87,63,158,157,202,198,46,195,143,238,238,155,190,179,227,236,236,197,81,208,103,167,63,52,26,245,70,163,223,127,89,105,108,52,54,90,221,110,149,105,214,155,55,236,115,250,247,203,70,10,51,59,98,39,59,38,133,52,77,6,129,239,149,129,98,184,252,25,226,211,82,104,53,118,251,177,152,250,30,160,182,233,108,226,219,61,17,113,103,83,70,158,250,234,124,207,67,167,158,72,231,59,131,61,126,18,174,64,198,38,0,223,231,145,127,201,135,108,20,9,224,31,60,96,197,213,26,102,181,148,14,22,241,105,196,37,15,99,201,0,5,167,30,240,75,30,
48,120,199,167,28,254,11,99,118,165,6,138,17,27,11,25,179,227,147,26,75,100,226,6,193,13,27,114,79,68,110,12,203,94,249,241,152,105,101,170,1,19,133,228,155,95,132,152,108,2,240,24,104,97,131,36,142,69,40,25,143,189,141,60,46,135,147,169,136,98,23,86,26,185,94,12,88,176,80,196,156,249,128,208,216,53,203,59,245,136,123,48,232,60,224,172,226,74,88,121,228,135,176,238,224,134,41,110,236,156,240,248,61,12,97,110,56,52,143,94,235,71,19,30,143,197,80,86,217,80,112,137,208,129,62,47,72,134,28,6,223,40,170,94,127,60,100,114,202,61,127,228,123,134,44,31,241,173,88,162,226,177,239,93,176,129,136,64,217,216,72,68,192,58,233,127,241,195,243,106,141,253,158,0,140,120,12,0,35,238,42,188,1,127,103,205,19,97,28,137,32,224,67,103,13,113,253,232,252,228,252,52,67,255,167,49,15,51,2,129,121,2,88,207,135,53,230,19,148,1,242,153,188,10,243,64,30,60,66,118,111,68,27,241,6,242,202,7,193,137,171,16,80,170,248,35,
68,33,34,214,1,97,213,13,246,97,140,243,249,216,189,244,69,18,129,124,66,248,198,220,64,1,1,192,239,196,30,129,100,64,142,250,235,196,139,56,224,163,89,182,145,183,157,29,212,58,139,42,126,121,207,127,7,14,59,21,167,186,99,204,137,93,250,81,12,250,97,21,48,99,19,151,194,31,90,189,180,246,0,134,165,224,216,87,149,170,49,15,34,193,64,84,88,17,139,46,121,20,8,176,251,33,50,97,202,35,16,200,4,160,40,101,3,6,42,249,49,203,147,43,151,152,194,64,219,145,25,18,152,17,4,56,247,23,215,187,72,166,26,244,12,189,75,145,180,135,70,176,56,69,254,100,26,240,9,202,0,190,102,21,66,10,173,80,49,27,128,118,93,72,54,17,67,152,26,8,49,69,250,50,182,156,128,194,250,160,23,135,25,77,248,5,231,128,132,201,66,15,247,247,94,189,219,59,120,107,236,167,102,88,39,181,4,104,116,197,12,3,21,58,70,64,87,190,228,53,230,207,135,250,207,131,19,50,75,240,71,254,121,168,132,194,175,1,99,180,68,99,164,111,221,27,
145,196,7,240,184,154,89,247,149,231,241,169,93,23,0,85,9,255,80,132,92,173,168,108,41,142,18,64,33,63,248,248,77,21,95,105,80,92,73,15,56,124,136,76,209,60,177,38,15,204,201,48,206,24,23,121,170,33,115,234,200,243,24,37,227,185,72,43,170,138,140,193,181,177,129,210,15,48,11,114,116,64,75,78,99,16,136,244,64,219,188,49,159,85,31,80,2,227,253,201,109,131,198,33,180,62,69,68,102,190,166,58,133,79,211,32,129,126,65,233,80,86,113,60,61,107,198,51,248,225,165,184,64,199,128,206,132,102,105,143,107,253,54,122,184,43,235,98,166,137,68,124,153,206,87,82,193,129,11,38,187,145,89,187,82,0,243,58,59,199,84,22,177,12,197,192,18,211,56,129,32,230,6,254,23,46,201,153,162,247,196,8,4,36,160,177,226,87,151,188,62,106,19,184,230,68,130,247,101,167,143,138,157,118,41,240,93,248,53,6,249,78,156,31,157,106,63,197,226,108,134,100,208,182,16,93,46,250,201,16,158,162,179,113,207,57,226,103,141,112,131,125,148,124,148,4,
74,18,214,168,17,209,61,55,244,32,182,234,72,184,4,255,180,155,43,97,160,126,35,239,99,29,102,9,5,58,200,238,10,196,129,38,240,201,52,190,169,89,83,26,3,49,203,72,31,173,55,197,189,196,165,2,14,37,51,219,224,103,210,199,206,95,63,31,238,31,252,227,240,131,165,253,112,148,143,162,96,240,33,178,29,35,36,249,202,138,228,252,78,109,73,35,91,78,101,242,1,47,9,157,202,64,136,0,53,5,190,156,97,232,92,1,208,87,211,233,17,122,39,12,165,4,216,60,56,179,233,75,205,248,127,180,13,162,136,188,175,78,91,64,182,228,113,61,49,228,36,157,206,174,145,202,250,158,98,94,253,246,32,55,226,78,249,33,141,165,242,203,248,224,101,165,152,198,196,200,231,228,113,92,2,94,170,179,224,237,208,249,161,72,21,10,148,132,209,200,177,31,232,81,144,155,130,177,129,246,138,9,135,4,45,78,34,8,137,35,55,0,247,165,124,188,76,188,49,249,120,229,237,181,19,207,141,36,59,152,129,171,71,232,48,132,120,232,24,56,43,131,195,125,202,64,
13,64,28,191,160,52,112,196,250,38,152,48,45,116,233,6,9,135,49,31,0,0,198,193,89,124,174,48,16,43,110,161,215,134,37,77,84,172,82,174,163,3,194,82,94,198,38,4,43,147,179,130,41,103,228,123,229,15,207,121,156,147,176,26,88,46,225,24,61,235,157,34,88,133,254,207,229,203,39,17,93,188,130,117,65,103,39,37,46,248,213,16,55,3,210,196,218,169,144,62,69,212,76,26,103,115,18,126,237,113,62,196,221,140,188,136,209,158,1,180,156,186,30,168,224,1,189,66,86,192,174,26,57,6,226,142,97,69,72,115,88,5,54,40,128,0,69,63,189,12,236,68,120,117,14,81,249,228,163,144,119,20,157,51,110,166,87,238,158,223,107,139,48,203,19,55,106,58,76,42,101,173,233,63,36,24,130,14,19,74,182,232,240,30,226,230,142,184,148,24,187,200,73,22,135,23,173,204,32,181,2,14,42,223,36,150,102,225,163,25,151,245,207,255,127,236,83,134,255,7,178,47,235,246,190,33,246,217,124,161,95,44,66,49,231,199,133,108,56,83,250,162,154,80,217,244,
54,75,157,90,173,108,191,123,63,239,95,86,154,173,94,53,83,128,114,254,10,193,183,153,102,249,46,196,102,8,81,19,246,243,207,240,202,216,58,96,76,209,11,226,180,218,141,200,236,171,116,227,3,89,2,110,141,94,169,141,138,14,224,144,231,166,34,66,226,202,164,51,65,94,207,121,247,56,201,57,235,152,69,172,72,110,243,61,199,51,9,142,221,33,34,139,92,137,140,236,187,63,129,144,230,251,167,111,64,72,22,185,18,33,217,119,127,2,33,153,178,102,105,137,1,146,169,116,159,136,89,24,176,97,192,51,181,85,140,12,88,130,53,219,220,103,64,88,161,123,140,117,220,251,113,158,197,87,213,130,109,33,88,151,125,125,105,138,67,207,75,132,42,32,47,74,133,201,124,13,53,143,197,117,145,196,29,16,56,242,195,19,44,236,148,27,47,190,234,179,220,128,172,13,202,47,37,54,136,68,97,130,48,241,67,127,130,101,19,152,77,219,150,43,93,14,34,97,208,83,234,104,128,110,169,189,161,170,37,190,182,56,205,150,215,112,19,154,214,235,168,215,224,14,2,78,
133,75,207,13,81,113,129,127,19,119,8,201,9,44,28,240,8,51,27,93,196,196,245,202,108,19,72,0,219,204,162,42,204,42,75,48,246,120,154,21,184,101,233,223,62,189,219,239,51,252,191,148,157,164,172,227,171,112,88,228,42,2,180,59,40,202,193,84,139,35,117,76,224,246,64,143,218,45,6,36,15,3,187,157,83,207,76,35,167,140,3,233,170,245,91,178,55,179,76,30,208,146,166,112,18,223,4,243,180,108,8,187,188,97,159,209,71,41,99,156,207,50,55,61,175,108,138,68,179,237,195,129,139,19,111,32,215,111,79,236,196,7,24,91,70,23,138,4,169,242,117,142,170,153,138,54,240,5,212,61,199,26,53,162,82,77,171,222,158,8,101,60,159,96,126,29,99,91,114,184,16,229,79,236,239,14,174,151,20,51,191,158,35,232,7,8,212,192,168,223,206,167,250,9,164,56,67,251,61,114,92,20,181,21,56,157,57,73,216,103,103,125,214,245,204,115,59,105,136,114,173,15,242,195,108,19,37,87,109,82,49,119,158,167,177,94,38,245,179,232,216,223,125,124,251,182,
150,122,30,172,6,101,0,173,130,33,115,137,202,184,83,254,111,140,55,16,136,189,36,138,176,91,128,205,159,75,110,137,30,233,38,25,142,166,104,133,129,110,26,9,15,146,187,37,17,61,114,253,249,200,102,28,191,72,226,69,25,83,158,58,55,168,72,127,87,49,97,78,161,187,205,220,233,148,26,134,185,170,22,85,136,45,190,7,215,220,75,98,158,237,200,98,236,207,116,131,102,187,18,24,183,49,185,212,113,28,139,152,72,52,196,242,17,118,174,101,236,70,212,44,82,77,202,65,146,47,24,82,187,18,91,188,37,250,102,209,173,223,98,255,151,10,213,88,59,133,231,129,239,169,118,184,230,44,22,19,135,190,196,124,2,243,93,63,224,166,213,103,150,38,196,137,214,26,19,97,112,147,18,225,252,5,179,145,192,205,104,138,100,149,180,80,130,155,18,103,77,38,0,208,89,115,234,36,188,106,110,197,59,252,243,123,46,233,156,3,236,21,208,98,82,182,46,37,126,219,74,41,73,74,245,30,10,70,85,144,101,213,231,69,78,235,79,25,98,254,196,15,220,8,173,19,
112,83,154,64,210,207,217,50,166,147,118,139,37,31,141,123,62,42,232,39,197,195,30,26,219,227,55,185,243,30,139,244,140,236,204,59,68,96,108,9,41,205,116,91,208,13,233,86,246,241,27,106,109,224,129,37,185,136,26,153,233,48,79,152,99,12,186,197,147,151,216,92,82,85,203,246,177,228,170,217,75,145,172,123,198,143,34,91,207,157,67,58,123,140,235,166,173,67,233,6,106,17,135,202,71,163,236,33,159,162,59,53,224,179,91,146,25,47,167,97,212,111,247,5,155,130,23,162,243,9,246,228,22,198,103,53,98,153,0,117,228,94,63,41,149,26,252,31,76,229,49,30,161,114,167,79,68,228,111,137,61,57,72,39,250,34,220,113,10,181,228,148,242,119,55,46,221,162,62,150,244,98,90,155,195,190,152,197,30,74,35,136,153,84,183,60,141,189,187,61,155,139,241,19,3,119,5,40,106,139,88,57,138,6,238,242,40,30,91,161,174,24,71,72,186,181,222,84,82,197,169,102,52,103,21,37,119,76,99,126,21,94,34,139,118,176,88,65,215,203,190,42,214,133,50,43,
168,106,170,42,8,209,185,56,106,122,143,232,213,85,225,16,40,229,226,120,228,44,127,156,15,54,10,52,151,18,46,157,175,19,136,26,27,249,145,212,39,238,242,243,139,39,76,135,220,190,174,169,25,212,155,198,157,136,194,7,107,72,120,146,136,42,45,33,191,42,208,65,71,14,50,4,8,136,53,115,8,96,238,57,100,251,172,146,132,1,68,176,220,185,11,111,236,134,231,92,230,160,79,184,27,82,78,90,213,152,227,132,90,230,184,29,102,205,54,111,45,46,201,205,217,62,216,222,0,2,1,110,108,112,143,131,204,7,177,208,34,149,106,153,235,33,81,170,194,54,206,24,187,192,219,103,170,37,124,240,227,178,74,66,246,96,58,153,80,193,23,211,66,159,78,226,8,50,247,62,211,127,204,81,85,231,115,156,91,166,168,173,244,30,19,68,252,50,63,60,25,64,96,184,248,249,92,5,151,71,51,41,59,98,236,166,59,255,124,85,64,46,207,24,249,88,150,148,248,221,28,45,51,142,55,39,117,245,110,70,244,234,97,158,127,175,121,156,99,225,195,253,244,158,46,20,
88,118,220,89,59,126,112,213,20,2,18,238,16,31,151,146,12,114,217,8,109,230,236,209,192,112,136,59,96,78,126,22,93,105,246,120,245,88,36,193,16,107,233,84,99,39,4,176,214,145,200,242,178,206,192,132,43,240,16,146,63,91,115,229,157,40,114,167,176,159,48,67,42,42,23,91,129,18,222,23,252,103,145,122,184,74,253,29,63,87,195,35,147,44,253,34,174,87,174,66,197,238,21,133,7,215,102,82,0,245,122,158,190,196,207,175,47,38,183,125,94,94,152,157,205,183,197,139,127,9,49,121,18,191,82,218,210,52,171,97,255,221,176,198,48,102,211,106,203,40,112,207,37,221,169,144,201,20,47,64,169,10,43,85,153,205,182,103,195,26,118,70,179,43,131,234,70,70,184,248,245,91,242,82,69,94,23,188,148,25,242,124,94,106,22,169,71,122,41,12,120,86,186,40,192,85,29,216,114,189,139,243,72,36,153,86,232,67,51,192,223,32,195,166,203,110,125,102,255,156,147,5,78,163,236,187,188,46,219,185,230,238,93,16,160,74,39,82,223,179,194,215,25,133,31,88,
196,211,155,36,41,8,26,45,51,131,212,166,229,100,79,4,34,250,21,79,185,150,40,174,194,174,126,107,193,60,71,38,149,114,79,189,45,176,112,78,54,85,20,220,61,141,48,115,24,81,111,220,82,94,45,192,225,249,124,200,243,106,5,121,54,152,211,204,128,85,121,204,35,247,34,87,193,198,61,189,27,153,115,150,126,152,222,33,21,119,123,198,35,188,113,9,170,9,206,205,244,78,102,207,236,204,119,135,148,197,91,3,126,22,191,88,198,211,130,103,76,7,61,159,111,44,34,182,132,119,76,129,149,249,199,98,153,29,190,28,129,92,205,141,154,157,199,107,44,193,121,34,117,181,135,45,220,27,42,97,210,237,64,42,171,219,158,174,49,236,82,169,20,233,70,125,208,148,47,65,181,133,114,167,74,209,136,172,62,221,133,24,234,131,69,140,196,190,243,40,157,202,161,117,143,83,204,104,15,77,91,101,104,125,39,240,112,170,148,111,248,141,220,247,37,108,145,7,137,250,193,131,2,199,246,85,123,82,98,159,210,142,163,11,116,4,129,93,0,136,13,0,136,21,201,224,
166,150,205,251,236,237,37,58,110,169,39,56,117,156,193,42,192,120,193,46,66,113,21,162,60,156,181,177,136,213,43,103,173,74,147,32,198,138,17,157,223,83,215,92,76,83,117,198,173,169,194,161,46,131,13,13,178,113,238,138,247,131,252,69,99,183,68,254,32,25,167,66,226,161,175,19,247,156,227,173,200,244,118,119,58,60,101,244,58,195,121,41,79,105,254,103,61,57,29,149,59,254,154,242,157,174,34,75,230,195,172,124,247,220,94,254,181,191,55,224,75,136,0,55,234,134,180,182,74,29,48,88,101,166,89,80,154,22,227,185,85,68,245,185,252,254,91,55,58,231,121,222,60,48,177,35,38,246,25,125,204,73,232,238,224,169,179,22,32,6,206,90,9,119,55,216,97,108,126,18,32,101,44,223,0,77,195,187,208,174,188,96,18,226,178,55,38,135,55,212,14,15,134,129,114,23,184,237,123,171,227,247,3,244,178,246,116,154,74,135,42,253,236,224,26,155,63,154,216,156,27,93,144,197,0,24,136,39,35,16,46,8,4,89,154,23,143,156,145,79,89,125,209,34,85,191,
61,193,191,105,98,217,200,20,161,250,45,105,97,126,228,147,28,175,213,215,166,127,67,21,193,75,207,69,165,239,167,119,173,251,76,125,206,81,106,153,97,251,67,130,121,196,39,179,61,234,98,115,50,115,207,220,28,125,154,26,164,103,110,115,31,146,3,42,104,123,13,242,209,43,142,185,128,31,226,11,117,188,6,173,201,252,180,136,84,63,164,97,239,255,129,77,57,107,170,159,5,242,86,191,45,128,58,96,16,192,39,9,24,150,109,30,214,210,38,93,77,55,194,74,109,76,210,113,78,100,101,217,219,12,63,232,92,144,186,11,139,11,227,207,103,224,113,31,204,133,179,68,208,221,112,58,202,67,64,51,104,104,172,245,41,38,253,203,46,195,251,76,55,253,146,205,117,214,75,124,103,26,139,247,208,208,162,4,239,43,220,7,222,249,90,190,0,115,190,158,45,180,214,62,47,95,138,157,253,15,42,215,166,43,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
TITLE("Logical positions")
COMPRESSED
120,156,149,85,219,110,219,70,16,253,149,69,228,22,182,43,
11,59,123,33,119,197,151,20,78,158,26,36,65,210,246,193,
130,96,211,212,74,90,132,34,85,146,138,47,69,243,237,61,
67,202,142,29,181,72,107,193,162,77,242,204,185,204,12,57,
83,226,232,72,142,229,72,126,231,103,250,42,44,243,93,217,
205,103,165,114,46,139,169,52,89,78,105,246,206,103,95,190,
124,153,120,175,50,46,69,40,69,210,104,82,68,70,74,163,
82,178,94,122,235,200,73,157,26,101,83,105,167,219,188,201,
55,243,89,238,116,118,250,33,1,74,141,237,72,147,38,73,
137,50,184,75,106,169,12,41,75,206,25,74,173,211,62,73,
166,69,190,237,98,93,205,103,215,140,3,74,3,37,83,151,
24,2,198,88,165,83,107,128,53,134,8,127,147,77,147,52,
157,118,177,43,3,48,148,164,89,110,84,118,206,42,205,56,
25,65,157,74,1,53,202,36,70,59,165,201,41,149,120,109,
188,129,108,82,211,216,5,136,188,6,134,113,12,179,32,52,
214,144,70,30,38,181,26,183,165,56,26,233,73,129,213,73,
107,65,24,110,31,66,226,124,24,151,128,78,165,150,239,118,
198,145,78,157,50,42,81,16,32,83,152,100,118,59,93,132,
182,0,78,43,202,58,72,202,206,95,218,140,0,78,199,233,
72,73,47,85,146,122,16,66,44,12,107,239,73,59,16,26,
178,146,244,180,168,23,108,82,89,169,51,96,28,186,144,160,
112,31,137,77,8,122,149,118,96,76,73,107,124,91,227,210,
105,27,184,15,93,221,204,103,167,47,143,229,68,78,148,181,
39,172,215,3,238,180,209,218,36,222,144,212,96,65,13,195,
113,37,18,157,36,171,220,244,58,111,65,217,25,14,246,156,
59,207,83,132,216,181,179,26,204,9,190,208,81,216,211,72,
70,121,227,180,118,114,90,148,121,219,62,137,231,148,45,18,
141,137,70,41,167,106,181,50,158,163,209,10,241,170,196,122,
66,190,54,49,82,77,155,240,199,46,54,97,19,42,4,28,
49,24,217,67,115,246,67,8,45,195,16,170,49,41,140,161,
77,18,201,105,89,204,130,210,22,113,75,114,6,138,240,65,
131,187,253,28,246,179,209,207,5,233,49,233,145,87,70,67,
137,55,6,1,160,0,121,34,146,14,31,56,67,44,253,100,
16,36,244,38,6,250,1,110,198,100,70,41,6,24,125,242,
134,233,189,230,248,20,210,87,137,180,104,131,26,224,138,67,
87,71,136,157,148,227,223,19,198,219,49,97,17,160,144,172,
133,109,141,160,149,131,117,139,228,117,63,220,148,186,233,219,
112,211,190,202,187,176,159,150,211,243,163,97,204,40,25,83,
50,146,140,183,206,163,125,100,56,62,109,140,87,94,107,171,
188,213,137,68,140,237,176,199,12,230,93,234,247,240,177,72,
58,166,20,107,5,171,214,194,124,15,131,241,148,88,138,114,
62,225,16,246,69,174,206,202,88,177,14,204,69,54,140,194,
233,249,79,68,41,23,114,216,22,231,18,169,61,178,64,4,
210,98,204,241,36,112,232,51,218,172,176,3,252,40,40,62,
229,171,112,117,182,223,211,63,47,255,250,225,245,219,179,223,
62,138,89,171,50,241,166,94,197,34,47,197,182,110,35,47,
127,251,227,124,214,218,76,188,47,243,162,31,4,81,47,197,
121,215,148,173,184,137,221,58,86,34,118,173,64,95,249,82,
108,197,34,116,161,217,64,227,66,92,223,137,242,219,106,147,
3,2,145,151,245,141,216,212,77,16,69,189,217,150,225,86,
108,31,185,154,80,230,93,252,28,68,87,63,112,48,55,206,
23,93,94,173,202,48,17,191,174,3,160,184,38,150,245,174,
17,221,221,54,180,172,113,93,55,241,190,174,58,80,29,168,
152,14,166,34,86,57,123,39,51,49,59,21,101,88,118,115,
113,117,38,224,8,182,90,81,96,219,198,7,208,175,254,96,
53,182,16,81,128,184,169,55,125,1,17,22,171,192,228,123,
173,143,50,69,94,45,158,42,106,227,125,152,28,138,224,211,
189,136,255,78,123,93,119,235,129,155,41,154,184,90,15,42,
218,39,50,62,64,198,33,217,112,239,252,59,108,223,136,238,
89,158,43,248,202,201,148,204,245,15,206,10,232,8,205,255,
244,54,128,254,37,55,241,123,104,186,190,208,65,123,251,105,
224,71,215,231,188,68,137,7,192,235,188,88,139,46,110,194,
179,81,42,214,232,16,168,121,140,203,252,174,222,117,226,120,
215,238,242,178,188,19,121,43,134,181,99,103,69,19,242,94,
111,221,240,217,120,31,171,213,201,88,108,227,109,120,202,141,
59,129,221,175,8,11,193,16,96,174,119,29,111,4,102,106,
33,80,226,112,47,246,26,127,174,208,79,120,142,109,187,195,
212,175,243,126,169,250,53,0,146,183,224,145,40,62,234,189,
175,107,196,183,234,119,65,108,155,250,186,12,27,209,175,5,
238,233,107,228,219,109,9,194,94,126,145,87,98,215,242,186,
12,203,188,136,203,101,232,243,232,27,92,15,59,196,184,74,
112,55,22,121,195,154,3,131,22,188,30,123,86,188,62,227,
170,130,214,155,117,168,246,255,65,197,254,50,139,25,196,223,
172,239,30,32,7,173,175,194,224,234,58,244,38,194,98,34,
46,112,20,203,188,192,107,242,240,121,210,176,5,22,205,239,
124,49,123,169,197,213,139,119,191,92,158,243,204,148,151,175,
111,99,119,249,33,116,205,221,213,139,57,43,109,118,85,223,
239,71,27,189,231,222,38,72,63,226,120,236,253,88,144,62,
225,193,28,236,47,135,245,239,9,118,45,27,122,134,126,104,
212,197,144,249,131,179,103,109,89,12,105,241,229,175,143,178,
77,232,214,245,98,120,106,138,11,209,238,150,203,120,43,142,
203,248,41,136,55,216,223,247,117,123,33,66,87,76,38,147,
147,158,68,102,90,204,255,6,214,199,18,85,

View file

@ -0,0 +1,190 @@
TITLE("About modal loops and periodic timer events")
COMPRESSED
120,156,197,88,107,115,227,182,21,253,43,104,189,237,218,27,
217,37,248,16,73,169,211,137,227,36,141,39,217,199,196,155,
233,7,143,39,130,72,200,66,76,18,44,9,90,171,73,147,
223,222,115,1,80,15,123,147,166,51,233,116,119,118,37,81,
184,175,115,207,125,64,183,33,123,241,34,152,4,39,193,127,
248,51,251,92,174,196,80,153,187,219,42,204,178,185,74,131,
120,46,120,58,127,155,207,127,254,249,231,139,60,15,231,164,
138,67,21,15,226,136,135,156,199,65,16,135,41,79,242,32,
79,50,158,5,81,26,135,73,26,36,179,86,116,162,190,187,
21,89,52,127,245,237,20,82,225,36,57,137,120,196,3,62,
13,99,156,10,162,32,140,121,152,240,44,139,121,154,100,81,
62,157,206,10,209,26,165,155,187,219,37,201,65,42,130,84,
144,102,211,152,67,38,78,194,40,77,98,200,198,49,231,120,
207,147,116,154,166,51,163,76,37,239,110,21,57,189,228,211,
116,46,226,144,156,190,34,111,227,201,244,4,94,134,41,84,
196,97,60,141,163,44,140,120,22,134,211,60,138,243,24,238,
243,112,166,140,132,179,75,136,145,40,137,37,48,28,39,49,
143,128,75,156,38,17,142,165,120,141,131,156,135,176,158,5,
73,2,195,242,195,8,22,225,68,114,83,152,11,211,132,78,
103,113,198,163,52,11,227,112,26,194,129,32,69,176,100,61,
153,149,178,47,32,23,133,124,110,224,210,252,234,211,100,206,
33,156,78,210,147,48,200,131,112,154,230,48,8,103,17,120,
148,231,60,202,96,48,230,73,192,163,89,161,75,4,187,12,
147,32,154,67,38,67,54,166,80,108,161,73,166,28,254,134,
81,6,139,41,143,34,252,159,196,89,58,235,37,229,195,232,
238,238,246,213,167,167,193,69,112,17,38,201,25,249,155,67,
60,139,226,40,138,167,121,204,131,8,86,160,35,38,184,166,
1,50,202,147,48,155,45,69,15,147,38,38,108,175,136,1,
196,38,192,31,101,73,4,203,83,252,135,204,34,188,8,200,
132,121,156,69,81,22,204,138,74,244,253,1,60,175,40,68,
206,39,156,159,164,132,106,18,133,113,78,208,68,33,224,13,
167,73,206,129,111,50,141,131,112,214,201,127,14,170,147,181,
108,0,176,2,65,230,99,114,60,25,225,139,35,99,56,225,
33,232,152,76,167,1,161,149,128,19,97,148,0,238,128,103,
49,60,194,95,36,216,120,62,90,122,88,94,240,104,194,163,
147,60,140,35,120,146,199,49,0,128,2,158,115,206,131,12,
127,17,25,96,177,204,224,158,91,135,180,226,241,132,199,39,
41,136,140,60,229,49,153,207,35,130,47,4,250,225,52,72,
144,134,208,137,135,4,122,248,2,176,243,48,163,127,103,36,
159,76,56,10,2,30,242,36,65,216,17,128,14,51,132,158,
0,249,200,146,156,167,217,236,141,220,244,159,11,35,61,91,
94,93,189,112,52,227,211,9,159,158,4,36,159,100,57,210,
199,99,130,47,138,227,60,204,163,40,9,243,36,154,6,128,
177,119,245,76,194,84,83,182,30,119,74,210,9,79,81,94,
8,53,73,16,188,21,67,224,41,39,87,194,44,159,18,8,
94,201,226,188,82,13,249,1,94,204,29,21,94,93,125,194,
121,74,138,50,84,75,150,77,131,40,7,22,128,32,72,64,
115,116,132,12,121,70,154,67,212,0,181,132,226,65,220,203,
197,185,175,215,31,191,255,233,79,95,188,57,255,238,134,221,
246,225,156,93,46,245,96,88,173,75,81,177,74,235,182,103,
162,41,89,43,59,165,75,85,48,163,106,217,49,249,8,70,
244,127,190,187,237,131,57,243,47,215,13,51,107,133,227,157,
81,69,37,217,70,50,211,109,153,209,76,126,104,43,161,26,
182,89,11,195,112,98,211,233,230,158,109,148,89,59,137,86,
201,66,50,189,98,84,83,179,3,173,233,156,157,168,166,168,
134,82,178,191,94,153,174,250,70,45,255,226,95,47,214,127,
243,71,252,139,229,57,251,230,237,219,119,108,198,218,97,89,
193,219,247,186,253,135,106,74,189,97,139,31,253,49,247,205,
204,127,58,255,151,217,182,178,148,43,39,120,245,205,229,205,
205,155,203,215,95,204,119,223,211,243,211,179,253,231,71,173,
74,182,226,251,71,139,159,230,199,142,248,23,18,92,204,102,
78,126,60,251,227,78,207,141,52,239,129,229,149,168,170,37,
50,114,186,56,167,158,49,97,239,191,186,190,249,236,242,234,
235,211,21,63,59,176,225,223,88,235,94,51,57,241,92,239,
187,78,215,173,121,251,245,233,226,143,173,125,251,135,197,31,
159,235,241,47,127,255,238,122,241,253,229,187,119,139,239,95,
95,94,191,121,174,204,57,127,241,237,208,156,62,209,177,207,
251,251,53,37,90,3,86,73,201,53,148,100,131,103,163,35,
108,169,63,176,123,105,122,166,91,217,200,146,233,71,48,136,
72,229,222,220,131,26,19,214,107,134,79,91,188,234,134,109,
245,192,122,3,34,177,110,104,26,5,178,16,39,65,16,151,
204,158,161,22,244,208,21,178,103,167,27,151,223,53,20,86,
178,63,187,128,63,240,162,175,232,24,190,104,172,47,29,26,
175,106,204,5,123,75,36,27,186,30,174,174,172,153,2,100,
120,96,186,177,252,163,163,240,86,246,19,86,139,102,203,52,
30,116,196,104,201,68,213,73,81,110,201,173,226,1,65,44,
37,44,48,101,200,113,27,50,148,45,94,226,96,35,109,84,
132,6,168,95,84,26,182,160,166,134,134,234,226,24,185,239,
122,10,77,60,45,46,170,33,32,10,191,182,84,31,205,253,
156,81,11,174,151,248,206,154,130,213,7,41,81,153,35,58,
80,109,125,39,249,137,45,78,38,122,27,222,74,202,138,173,
144,9,251,61,210,205,30,149,220,180,26,96,140,186,22,47,
123,68,3,145,101,165,93,104,148,133,90,90,211,23,236,178,
48,3,244,111,39,174,86,23,47,215,18,137,89,74,1,65,
86,41,164,192,231,219,166,175,208,221,14,73,42,84,214,111,
123,244,94,155,95,184,253,195,208,219,156,162,7,172,165,67,
138,78,218,118,194,64,87,100,212,98,66,16,84,0,24,222,
0,68,35,30,36,67,11,41,36,220,169,160,233,24,14,210,
112,88,74,172,84,125,43,76,129,220,49,240,210,160,95,146,
194,213,128,40,32,10,83,157,128,57,229,168,209,203,198,102,
200,225,90,136,6,49,52,144,25,236,87,165,37,31,209,192,
39,167,134,135,232,158,189,67,121,192,201,202,2,221,73,51,
116,205,30,234,213,208,20,180,67,65,99,85,57,80,149,121,
146,255,27,237,142,34,208,98,77,108,215,150,147,96,79,219,
130,150,194,202,99,232,43,210,177,101,75,48,240,97,36,181,
23,213,132,146,205,211,151,186,163,22,216,41,131,84,9,214,
15,117,45,144,16,159,11,66,19,10,225,136,37,48,252,20,
136,196,53,99,101,12,101,223,18,90,138,98,205,218,181,232,
45,123,215,178,106,109,116,40,95,232,92,74,156,236,16,116,
137,170,48,194,131,227,12,168,190,31,228,113,124,10,139,210,
252,45,62,126,209,208,32,0,229,52,21,240,107,84,162,59,
96,103,216,21,187,189,244,78,221,45,110,253,247,139,187,39,
42,84,131,35,196,114,155,4,12,152,7,178,109,189,229,200,
19,82,86,126,84,231,236,72,41,91,220,30,116,229,103,70,
64,76,79,69,26,124,35,65,236,96,112,93,230,191,50,129,
166,249,204,130,88,17,128,163,199,51,204,17,215,25,29,73,
126,155,250,221,76,27,109,224,153,133,229,208,248,138,63,179,
189,235,199,214,34,213,72,37,182,32,4,117,98,133,39,251,
145,79,64,252,206,190,224,211,104,255,87,161,17,141,43,182,
143,3,52,14,139,37,77,3,244,56,182,86,247,246,244,158,
211,255,123,191,127,35,220,99,36,191,2,123,255,127,193,253,
247,74,209,47,177,152,134,215,90,117,165,159,70,190,155,186,
73,7,65,12,8,227,27,154,106,86,170,193,106,142,230,89,
96,38,163,219,29,247,199,55,122,51,25,231,244,90,144,226,
94,213,45,173,25,207,4,169,88,5,108,213,237,96,108,223,
4,164,237,47,180,212,9,53,122,116,62,92,109,160,162,82,
15,178,218,238,102,56,219,232,161,42,109,43,240,59,135,35,
215,110,57,177,163,12,75,163,143,193,99,130,65,187,241,120,
244,174,225,30,180,240,162,19,253,26,221,22,111,157,50,90,
124,168,235,179,211,163,73,54,161,40,252,138,227,199,173,221,
5,42,116,104,90,39,236,74,0,246,203,66,12,187,13,198,
45,29,122,191,42,61,181,238,219,88,41,151,195,253,189,236,
38,110,234,29,251,49,244,118,198,51,171,248,121,0,104,220,
170,174,101,169,48,65,232,148,93,106,0,159,52,248,68,123,
60,65,69,66,141,238,106,32,47,154,70,111,201,151,197,203,
47,133,161,7,7,202,100,215,233,14,187,3,22,173,11,118,
77,115,71,161,233,238,194,5,186,99,128,186,41,228,129,183,
142,99,154,24,96,221,144,31,214,56,134,153,54,217,237,133,
165,110,22,47,13,43,105,99,163,20,238,150,184,113,110,187,
58,179,33,181,148,92,101,206,158,12,229,175,176,117,60,18,
76,150,54,189,194,246,227,96,60,200,68,169,86,43,217,73,
90,40,47,11,172,60,118,16,238,70,114,87,15,149,147,249,
40,249,14,2,234,220,46,75,167,31,41,34,218,90,241,178,
56,119,139,146,176,87,49,199,173,53,166,110,103,247,8,67,
43,151,231,218,4,0,222,15,8,109,130,133,74,97,24,34,
217,180,224,141,83,185,116,191,36,161,86,95,127,118,148,4,
231,64,165,106,101,215,30,226,143,173,128,122,40,214,150,225,
207,246,16,218,140,78,119,235,141,147,119,123,36,108,145,205,
51,135,56,134,167,20,228,60,8,130,2,4,244,248,30,178,
224,72,71,107,245,118,41,209,242,58,172,114,59,164,203,161,
115,196,133,240,40,68,199,159,241,208,213,230,184,203,120,124,
232,218,228,187,236,184,188,59,44,106,12,7,23,218,146,28,
70,245,16,93,151,114,11,224,118,140,41,68,43,150,10,121,
85,36,72,131,101,23,129,235,18,253,208,217,93,136,114,227,
214,113,191,130,129,13,26,4,248,108,107,221,220,8,170,204,
45,150,88,191,194,210,246,187,248,228,203,216,206,215,181,174,
44,71,160,18,252,96,98,48,64,160,149,190,229,244,107,27,
215,82,62,185,54,140,107,125,123,16,156,85,247,20,23,44,
251,27,89,85,251,214,96,15,236,141,236,13,172,16,216,225,
222,236,85,23,88,45,125,179,192,215,143,182,132,237,206,122,
224,184,13,218,122,79,248,194,207,3,215,15,56,140,182,80,
60,80,117,122,11,98,9,230,210,190,125,180,120,158,186,205,
25,109,220,246,29,119,19,243,87,37,86,17,250,71,215,71,
31,244,179,133,140,6,168,172,86,19,223,134,93,222,159,81,
87,126,160,57,59,138,186,225,118,56,118,73,187,59,227,103,
236,211,158,112,13,28,90,73,47,2,235,33,117,152,13,46,
22,196,46,98,50,61,213,5,149,158,181,124,88,127,96,40,
90,91,45,140,7,189,193,245,144,238,56,216,204,47,216,215,
184,195,145,84,173,108,116,192,203,14,25,123,243,244,68,179,
83,205,81,149,178,224,46,83,246,62,186,191,199,184,253,141,
168,74,84,135,22,162,13,230,164,6,15,65,167,137,61,96,
119,118,86,168,174,24,106,90,221,233,234,236,132,96,98,37,
10,115,52,13,39,123,130,244,72,215,254,50,163,169,145,162,
221,151,71,3,223,118,133,71,92,61,244,208,31,165,121,226,
46,146,170,30,239,75,232,140,70,209,4,119,207,132,113,61,
254,148,60,247,115,202,30,49,107,186,109,203,114,113,110,175,
103,174,48,253,176,183,44,179,38,233,150,179,252,200,69,139,
212,160,51,208,239,84,31,32,51,182,98,171,221,122,79,191,
18,208,152,241,65,175,113,253,239,13,25,1,228,149,106,30,
220,181,179,71,47,220,111,24,238,103,128,125,60,27,141,59,
144,173,85,186,106,226,214,221,183,178,80,150,205,27,207,212,
173,21,65,159,70,210,233,234,101,127,241,42,97,170,27,138,
209,41,80,66,47,127,192,247,23,236,244,186,22,247,116,89,
21,251,177,99,87,2,71,107,215,207,157,176,118,93,213,53,
153,115,250,93,184,244,106,232,199,4,26,65,189,117,21,69,
37,69,51,56,138,251,54,75,60,63,184,106,147,218,98,188,
57,215,18,23,209,70,245,245,33,14,118,73,117,91,138,179,
129,188,18,79,48,6,69,165,239,237,134,215,233,138,86,22,
16,178,95,17,209,220,35,102,149,218,193,8,166,173,69,181,
90,156,143,33,236,60,62,110,161,227,26,128,48,214,162,117,
85,91,211,143,135,32,68,175,93,3,162,103,55,235,193,216,
142,180,115,153,144,178,120,188,236,47,206,216,107,221,83,91,
83,118,215,100,125,171,77,63,50,140,14,93,81,221,86,106,
217,209,29,89,173,168,137,216,100,1,24,227,146,5,30,141,
148,174,129,97,239,238,30,80,106,105,177,75,144,31,26,214,
237,82,203,222,118,7,18,112,37,100,15,139,131,61,181,160,
221,200,184,149,240,89,167,242,109,39,98,119,255,6,15,61,
167,109,

21
olddraw/Draw/Copying Normal file
View file

@ -0,0 +1,21 @@
Copyright 1998-2008 The U++ Project. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE U++ PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

Some files were not shown because too many files have changed in this diff Show more