From c50daeece493e4bdf91c823876c81f5d5f9be782 Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 1 Dec 2013 16:12:14 +0000 Subject: [PATCH] rainbow: Developing tel++ git-svn-id: svn://ultimatepp.org/upp/trunk@6624 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/Telpp/After.h | 47 ++++ rainbow/Telpp/ChSysInit.cpp | 21 ++ rainbow/Telpp/Clip.cpp | 238 +++++++++++++++++ rainbow/Telpp/Ctrl.cpp | 81 ++++++ rainbow/Telpp/Ctrl.h | 78 ++++++ rainbow/Telpp/Cursor.cpp | 22 ++ rainbow/Telpp/DnD.cpp | 150 +++++++++++ rainbow/Telpp/DrawDragRect.cpp | 94 +++++++ rainbow/Telpp/Event.cpp | 369 ++++++++++++++++++++++++++ rainbow/Telpp/FB.iml | 63 +++++ rainbow/Telpp/Gui.h | 358 +++++++++++++++++++++++++ rainbow/Telpp/Image.cpp | 47 ++++ rainbow/Telpp/Keys.h | 112 ++++++++ rainbow/Telpp/Local.h | 63 +++++ rainbow/Telpp/Paint.cpp | 5 + rainbow/Telpp/TelDraw.cpp | 69 +++++ rainbow/Telpp/Telpp.brc | 1 + rainbow/Telpp/Telpp.h | 124 +++++++++ rainbow/Telpp/Telpp.html | 170 ++++++++++++ rainbow/Telpp/Telpp.upp | 33 +++ rainbow/Telpp/Top.cpp | 152 +++++++++++ rainbow/Telpp/Top.h | 16 ++ rainbow/Telpp/TopFrame.cpp | 236 +++++++++++++++++ rainbow/Telpp/Wnd.cpp | 459 +++++++++++++++++++++++++++++++++ rainbow/Telpp/init | 6 + rainbow/UWord/UWord.cpp | 2 + rainbow/UWord/UWord.upp | 6 +- rainbow/UWord/init | 1 + rainbow/guiplatform.h | 6 + 29 files changed, 3027 insertions(+), 2 deletions(-) create mode 100644 rainbow/Telpp/After.h create mode 100644 rainbow/Telpp/ChSysInit.cpp create mode 100644 rainbow/Telpp/Clip.cpp create mode 100644 rainbow/Telpp/Ctrl.cpp create mode 100644 rainbow/Telpp/Ctrl.h create mode 100644 rainbow/Telpp/Cursor.cpp create mode 100644 rainbow/Telpp/DnD.cpp create mode 100644 rainbow/Telpp/DrawDragRect.cpp create mode 100644 rainbow/Telpp/Event.cpp create mode 100644 rainbow/Telpp/FB.iml create mode 100644 rainbow/Telpp/Gui.h create mode 100644 rainbow/Telpp/Image.cpp create mode 100644 rainbow/Telpp/Keys.h create mode 100644 rainbow/Telpp/Local.h create mode 100644 rainbow/Telpp/Paint.cpp create mode 100644 rainbow/Telpp/TelDraw.cpp create mode 100644 rainbow/Telpp/Telpp.brc create mode 100644 rainbow/Telpp/Telpp.h create mode 100644 rainbow/Telpp/Telpp.html create mode 100644 rainbow/Telpp/Telpp.upp create mode 100644 rainbow/Telpp/Top.cpp create mode 100644 rainbow/Telpp/Top.h create mode 100644 rainbow/Telpp/TopFrame.cpp create mode 100644 rainbow/Telpp/Wnd.cpp create mode 100644 rainbow/Telpp/init diff --git a/rainbow/Telpp/After.h b/rainbow/Telpp/After.h new file mode 100644 index 000000000..322f22e60 --- /dev/null +++ b/rainbow/Telpp/After.h @@ -0,0 +1,47 @@ +class ViewDraw : public SystemDraw { +public: + ViewDraw(Ctrl *ctrl); + ~ViewDraw(); +}; + + +/* +class ViewDraw : public SystemDraw { + Vector dummy; +public: + ViewDraw(Ctrl *) : SystemDraw(Ctrl::framebuffer, dummy) { dummy.Add(Rect(10, 10, 100, 100)); } +}; +*/ +class DHCtrl : Ctrl {}; + +#ifdef PLATFORM_WIN32 +#define GUI_APP_MAIN \ +void GuiMainFn_(); \ +\ +extern "C" int main(int argc, char *argv[]) { \ + UPP::AppInit__(argc, (const char **)argv); \ + FBInit(); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + FBDeInit(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() + +#endif + +#ifdef PLATFORM_POSIX +#define GUI_APP_MAIN \ +void GuiMainFn_(); \ +\ +extern "C" int main(int argc, const char **argv, const char **envptr) { \ + UPP::AppInit__(argc, argv, envptr); \ + UPP::Ctrl::InitTelpp(); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() +#endif diff --git a/rainbow/Telpp/ChSysInit.cpp b/rainbow/Telpp/ChSysInit.cpp new file mode 100644 index 000000000..4a4eca9a0 --- /dev/null +++ b/rainbow/Telpp/ChSysInit.cpp @@ -0,0 +1,21 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +void ChSysInit() +{ + CtrlImg::Reset(); + CtrlsImg::Reset(); + ChReset(); +} + +void ChHostSkin() +{ + ChSysInit(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Clip.cpp b/rainbow/Telpp/Clip.cpp new file mode 100644 index 000000000..2958ed548 --- /dev/null +++ b/rainbow/Telpp/Clip.cpp @@ -0,0 +1,238 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +static VectorMap fbClipboard; + +void ClearClipboard() +{ + GuiLock __; + fbClipboard.Clear(); +} + +void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&)) +{ + GuiLock __; + ClipData& cd = fbClipboard.GetAdd(format); + cd.data = data; + cd.render = render; +} + +static String sRawRender(const Value& v) +{ + return v; +} + +void AppendClipboard(const char *format, const String& data) +{ + GuiLock __; + AppendClipboard(format, data, sRawRender); +} + +void AppendClipboard(const char *format, const byte *data, int length) +{ + GuiLock __; + AppendClipboard(format, String(data, length)); +} + +String ReadClipboard(const char *format) +{ + GuiLock __; + int q = fbClipboard.Find(format); + return q >= 0 ? (*fbClipboard[q].render)(fbClipboard[q].data) : String(); +} + +void AppendClipboardText(const String& s) +{ + AppendClipboard("text", ToSystemCharset(s)); +} + +void AppendClipboardUnicodeText(const WString& s) +{ + 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& data, const String& text) +{ + data.GetAdd("text", ClipData(text, sText)); + data.GetAdd("wtext", ClipData(text, sWText)); +} + +void Append(VectorMap& 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() +{ + String w = ReadClipboard("text"); + return w.GetCount() ? w : ReadClipboardUnicodeText().ToString(); +} + +WString ReadClipboardUnicodeText() +{ + String w = ReadClipboard("wtext"); + if(w.GetCount()) + return WString((const wchar *)~w, w.GetLength() / 2); + return ReadClipboard("text").ToWString(); +} + +bool IsClipboardAvailable(const char *id) +{ + return fbClipboard.Find(id) >= 0; +} + +bool IsClipboardAvailableText() +{ + return IsClipboardAvailable("text") || IsClipboardAvailable("wtext"); +} + +const char *ClipFmtsImage() +{ + static const char *q; + ONCELOCK { + static String s = "dib;" + ClipFmt(); + q = s; + } + return q; +} + +bool AcceptImage(PasteClip& clip) +{ + GuiLock __; + return clip.Accept(ClipFmtsImage()); +} + +Image GetImage(PasteClip& clip) +{ + GuiLock __; + Image m; + if(Accept(clip)) { + LoadFromString(m, ~clip); + if(!m.IsEmpty()) + return m; + } + return Null; +} + +Image ReadClipboardImage() +{ + GuiLock __; + PasteClip d = Ctrl::Clipboard(); + return GetImage(d); +} + +String sImage(const Value& image) +{ + Image img = image; + return StoreAsString(const_cast(img)); +} + +String GetImageClip(const Image& img, const String& fmt) +{ + GuiLock __; + if(img.IsEmpty()) return Null; + if(fmt == ClipFmt()) + return sImage(img); + return Null; +} + +void AppendClipboardImage(const Image& img) +{ + GuiLock __; + if(img.IsEmpty()) return; + AppendClipboard(ClipFmt(), img, sImage); +} + +bool AcceptFiles(PasteClip& clip) +{ + if(clip.Accept("files")) { + clip.SetAction(DND_COPY); + return true; + } + return false; +} + +bool IsAvailableFiles(PasteClip& clip) +{ + return clip.IsAvailable("files"); +} + +Vector GetFiles(PasteClip& clip) +{ + GuiLock __; + Vector f; + return f; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Ctrl.cpp b/rainbow/Telpp/Ctrl.cpp new file mode 100644 index 000000000..7c561357e --- /dev/null +++ b/rainbow/Telpp/Ctrl.cpp @@ -0,0 +1,81 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +#define LLOG(x) // DLOG(x) + +NAMESPACE_UPP + +void Ctrl::GuiPlatformConstruct() +{ +} + +void Ctrl::GuiPlatformRemove() +{ +} + +void Ctrl::GuiPlatformGetTopRect(Rect& r) const +{ +} + +bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r) +{ + return false; +} + +bool Ctrl::GuiPlatformSetFullRefreshSpecial() +{ + return false; +} + +void Ctrl::PaintCaret(SystemDraw& w) +{ +} + +String GuiPlatformGetKeyDesc(dword key) +{ + return Null; +} + +void Ctrl::GuiPlatformSelection(PasteClip&) +{ +} + +void GuiPlatformAdjustDragImage(ImageBuffer&) +{ +} + +bool GuiPlatformHasSizeGrip() +{ + return true; +} + +void GuiPlatformGripResize(TopWindow *q) +{ + q->GripResize(); +} + +Color GuiPlatformGetScreenPixel(int x, int y) +{ + return Null; +} + +void GuiPlatformAfterMenuPopUp() +{ +} + +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()) << ")"; + return s; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Ctrl.h b/rainbow/Telpp/Ctrl.h new file mode 100644 index 000000000..86607ccfd --- /dev/null +++ b/rainbow/Telpp/Ctrl.h @@ -0,0 +1,78 @@ +//$ class Ctrl { +private: + static Ptr desktop; + static Vector topctrl; + static bool invalid; + + static Point fbCursorPos; + static Image fbCursorImage; + static bool sdlMouseIsIn; + + static Rect fbCaretRect; + static int fbCaretTm; + + static bool fbEndSession; + static int64 fbEventLoop; + static int64 fbEndSessionLoop; + + static void CursorSync(); + + int FindTopCtrl() const; + static Rect GetClipBound(const Vector& inv, const Rect& r); + static void DoPaint(); + static void SyncTopWindows(); + +// static void AddInvalid(const Rect& rect); + + void DestroyWnd(); + + void NewTop() { top = new Top; top->owner_window = NULL; } + void PutForeground(); + static void MouseEventFB(Ptr t, int event, Point p, int zdelta); + + static void DrawLine(const Vector& clip, int x, int y, int cx, int cy, bool horz, + const byte *pattern, int animation); + static void DragRectDraw0(const Vector& clip, const Rect& rect, int n, + const byte *pattern, int animation); + + friend struct PaintProxy__; + friend class TopWindowFrame; + friend class SystemDraw; + friend struct DnDLoop; + + void SetOpen(bool b) { isopen = b; } + +protected: + static int PaintLock; + +public: + static void DoMouseFB(int event, Point p, int zdelta = 0); + static bool DoKeyFB(dword key, int cnt); + + static void InitTelpp(); + static void Exit(); + + static void EndSession(); + + static void SetDesktop(Ctrl& q); + static Ctrl *GetDesktop() { return desktop; } + static void SetDesktopSize(Size sz); + + static void Invalidate() { invalid = true; } + + void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation); + + static Ctrl *FindMouseTopCtrl(); + + static void PaintScene(SystemDraw& draw); + static void PaintCaretCursor(SystemDraw& draw); + + static bool SystemCursor; + + enum { DRAWDRAGRECT_SCREEN = 0x8000 }; + + _TODO_ + static bool ProcessEventQueue(const String& event_queue); + +//$ }; diff --git a/rainbow/Telpp/Cursor.cpp b/rainbow/Telpp/Cursor.cpp new file mode 100644 index 000000000..543207908 --- /dev/null +++ b/rainbow/Telpp/Cursor.cpp @@ -0,0 +1,22 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) + +void Ctrl::SetMouseCursor(const Image& image) +{ + GuiLock __; + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + _TODO_ + } +} + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/Telpp/DnD.cpp b/rainbow/Telpp/DnD.cpp new file mode 100644 index 000000000..63e67035b --- /dev/null +++ b/rainbow/Telpp/DnD.cpp @@ -0,0 +1,150 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) // DLOG(x) + +// -------------------------------------------------------------------------------------------- + +Ptr sDnDSource; + +Ctrl * Ctrl::GetDragAndDropSource() +{ + return sDnDSource; +} + +struct DnDLoop : LocalLoop { + const VectorMap *data; + Vector fmts; + + Image move, copy, reject; + Ptr target; + int action; + byte actions; + + void Sync(); + String GetData(const String& f); + void DnD(bool paste); + + virtual void LeftUp(Point, dword); + virtual bool Key(dword, int); + virtual void MouseMove(Point p, dword); + virtual Image CursorImage(Point, dword); +}; + +Ptr dndloop; + +bool PasteClip::IsAvailable(const char *fmt) const +{ + GuiLock __; + return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0 + : IsClipboardAvailable(fmt); +} + +String DnDLoop::GetData(const String& f) +{ + GuiLock __; + int i = data->Find(f); + String d; + if(i >= 0) + d = (*data)[i].Render(); + else + if(sDnDSource) + d = sDnDSource->GetDropData(f); + return d; +} + +String PasteClip::Get(const char *fmt) const +{ + return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt); +} + +void PasteClip::GuiPlatformConstruct() +{ + dnd = false; +} + +void DnDLoop::DnD(bool paste) +{ + PasteClip d; + d.paste = paste; + d.accepted = false; + d.allowed = (byte)actions; + d.action = GetCtrl() ? DND_COPY : DND_MOVE; + d.dnd = true; + if(target) + target->DnD(GetMousePos(), d); + action = d.IsAccepted() ? d.GetAction() : DND_NONE; +} + +void DnDLoop::Sync() +{ + GuiLock __; + Ptr t = FindMouseTopCtrl(); + if(t != target) + if(target) + target->DnDLeave(); + target = t; + DnD(false); +} + +void DnDLoop::LeftUp(Point, dword) +{ + GuiLock __; + LLOG("DnDLoop::LeftUp"); + DnD(true); + EndLoop(); +} + +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 action == DND_MOVE ? move : action == DND_COPY ? copy : reject; +} + +int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, + const VectorMap& data) +{ + GuiLock __; + DnDLoop d; + d.actions = (byte)actions; + 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.action = DND_NONE; + d.fmts = Split(fmts, ';'); + dndloop = &d; + sDnDSource = this; + d.Run(); + sDnDSource = NULL; + SyncCaret(); + LLOG("DoDragAndDrop finished"); + return d.action; +} + +void Ctrl::SetSelectionSource(const char *fmts) {} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/DrawDragRect.cpp b/rainbow/Telpp/DrawDragRect.cpp new file mode 100644 index 000000000..6bd413089 --- /dev/null +++ b/rainbow/Telpp/DrawDragRect.cpp @@ -0,0 +1,94 @@ +#include "Local.h" + +NAMESPACE_UPP + +struct DrawDragRectInfo { + Rect rect1, rect2, clip; + int n; + int type; + int animation; +}; + +void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, const int *pattern, int animation) +{ + if(len <= 0) + return; + if(horz) + w.Clip(x, y, len, n); + else + w.Clip(x, y, n, len); + + (horz ? x : y) -= animation; + len += animation; + bool ch = false; + while(len > 0) { + int segment = pattern[ch]; + int d = segment + pattern[2]; + if(horz) { + w.DrawRect(x, y, segment, n, InvertColor()); + x += d; + } + else { + w.DrawRect(x, y, n, segment, InvertColor()); + y += d; + } + len -= d; + ch = !ch; + } + w.End(); +} + +void DrawDragFrame(SystemDraw& w, const Rect& r, int n, const int *pattern, int animation) +{ + DrawDragLine(w, true, r.left, r.top, r.GetWidth(), n, pattern, animation); + DrawDragLine(w, false, r.left, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); + DrawDragLine(w, false, r.right - n, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); + DrawDragLine(w, true, r.left, r.bottom - n, r.GetWidth(), n, pattern, animation); +} + +void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) +{ + _TODO_ + SystemDraw w; + Ctrl::PaintScene(w); + w.Clip(f.clip); + static int dashes[3][3] = { + { 32, 32, 0 }, + { 1, 1, 1 }, + { 5, 1, 2 }, + }; + const int *dash = dashes[minmax(f.type, 0, 2)]; + DrawDragFrame(w, f.rect1, f.n, dash, f.animation); + DrawDragFrame(w, f.rect2, f.n, dash, f.animation); +// w.End(); + Ctrl::PaintCaretCursor(w); +// SDL_GL_SwapWindow(screen.win); +} + +void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation) +{ + Ctrl *top = q.GetTopCtrl(); + if(top) { + Point off = q.GetScreenView().TopLeft(); + DrawDragRectInfo f; + f.rect1 = rect1.Offseted(off); + f.rect2 = rect2.Offseted(off); + f.clip = (clip & q.GetSize()).Offseted(off); + f.n = n; + f.type = type; + f.animation = animation; + DrawDragRect(*top, f); + } +} + +void FinishDragRect(Ctrl& q) +{ + SystemDraw w; + Ctrl::PaintScene(w); + Ctrl::PaintCaretCursor(w); + _TODO_ + //SDL_GL_SwapWindow(screen.win); +} + +END_UPP_NAMESPACE diff --git a/rainbow/Telpp/Event.cpp b/rainbow/Telpp/Event.cpp new file mode 100644 index 000000000..ed70c9d82 --- /dev/null +++ b/rainbow/Telpp/Event.cpp @@ -0,0 +1,369 @@ +#include "Local.h" + +#include "Telpp.brc" + + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) DDUMP(x) +#define LTIMING(x) + +static Point MousePos; + +int Width = 1000; +int Height = 1000; + +TcpSocket server; +TcpSocket socket; + +One desktop_ctrl; + +void Ctrl::InitTelpp() +{ + if(!server.Listen(8000, 10)) { + LOG("Cannot open server port for listening\r\n"); + return; + } + + Ctrl::GlobalBackBuffer(); + Ctrl::InitTimer(); + +#ifdef PLATFORM_POSIX + SetStdFont(ScreenSans(12)); //FIXME general handling +#endif + ChStdSkin(); + + static StaticRect x; + x.Color(Cyan()); + x.SetRect(0, 0, Width, Height); + SetDesktop(x); +} + +Point GetMousePos() { + return MousePos; +} + +dword mouseb = 0; +dword modkeys = 0; + +enum KM { + KM_NONE = 0x00, + + KM_LSHIFT= 0x01, + KM_RSHIFT= 0x02, + KM_LCTRL = 0x04, + KM_RCTRL = 0x08, + KM_LALT = 0x10, + KM_RALT = 0x20, + + KM_CAPS = 0x40, + KM_NUM = 0x80, + + KM_CTRL = KM_LCTRL | KM_RCTRL, + KM_SHIFT = KM_LSHIFT | KM_RSHIFT, + KM_ALT = KM_LALT | KM_RALT, +}; + +bool GetMouseLeft() { return mouseb & (1<<0); } +bool GetMouseRight() { return mouseb & (1<<1); } +bool GetMouseMiddle() { return mouseb & (1<<2); } +bool GetShift() { return modkeys & KM_SHIFT; } +bool GetCtrl() { return modkeys & KM_CTRL; } +bool GetAlt() { return modkeys & KM_ALT; } +bool GetCapsLock() { return modkeys & KM_CAPS; } + +dword fbKEYtoK(dword chr) { +_TODO_ +/* + if(chr == SDLK_TAB) + chr = K_TAB; + else + if(chr == SDLK_SPACE) + chr = K_SPACE; + else + if(chr == SDLK_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; +*/ +} + +dword lastbdowntime[8] = {0}; +dword isdblclick[8] = {0}; + +void Ctrl::MouseEventFB(Ptr t, int event, Point p, int zdelta) +{ + if(!t->IsEnabled()) + return; + Rect rr = t->GetRect(); + if((event & Ctrl::ACTION) == DOWN) { + Ptr q = t; + TopWindowFrame *wf = dynamic_cast(~t); + if(wf) + q = wf->window; + if(q) q->ClickActivateWnd(); + if(q) q->SetForeground(); + if(ignoreclick) + return; + } + if(t) + t->DispatchMouse(event, p - rr.TopLeft(), zdelta); + if(t) + t->PostInput(); +} + +Ctrl *Ctrl::FindMouseTopCtrl() +{ + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ctrl *t = topctrl[i]; + if(t->GetRect().Contains(MousePos)) + return t->IsEnabled() ? t : NULL; + } + return desktop->IsEnabled() ? desktop : NULL; +} + +void Ctrl::DoMouseFB(int event, Point p, int zdelta) +{ + MousePos = p; + int a = event & Ctrl::ACTION; + if(a == Ctrl::UP && Ctrl::ignoreclick) { + EndIgnore(); + return; + } + else + if(a == Ctrl::DOWN && ignoreclick) + return; + LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl)); + if(captureCtrl) + MouseEventFB(captureCtrl->GetTopCtrl(), event, p, zdelta); + else + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ptr t = topctrl[i]; + Rect rr = t->GetRect(); + if(rr.Contains(p)) { + MouseEventFB(t, event, p, zdelta); + return; + } + } + Ctrl *desktop = GetDesktop(); + if(desktop) { + desktop->DispatchMouse(event, p, zdelta); + desktop->PostInput(); + } +} + +bool Ctrl::DoKeyFB(dword key, int cnt) +{ + LLOG("DoKeyFB " << GetKeyDesc(key) << ", " << cnt); + + bool b = DispatchKey(key, cnt); + SyncCaret(); + Ctrl *desktop = GetDesktop(); + if(desktop) + desktop->PostInput(); + return b; +} + +void Ctrl::SetCaret(int x, int y, int cx, int cy) +{ + GuiLock __; + caretx = x; + carety = y; + caretcx = cx; + caretcy = cy; + fbCaretTm = GetTickCount(); + SyncCaret(); +} + +void Ctrl::SyncCaret() +{ + CursorSync(); +} + +void Ctrl::CursorSync() +{ +// LLOG("@ CursorSync"); + Point p = GetMousePos() - fbCursorImage.GetHotSpot(); + Rect cr = Null; + if(focusCtrl && (((GetTickCount() - fbCaretTm) / 500) & 1) == 0) + cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy) + + focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView(); + if(fbCursorPos != p && !SystemCursor || cr != fbCaretRect) { + fbCaretRect = cr; + fbCursorPos = p; + Invalidate(); + } +} + +String content; + +void Ctrl::PaintScene(SystemDraw& draw) +{ + if(!desktop) + return; + LLOG("@ DoPaint"); + LTIMING("DoPaint paint"); + draw.Init(Size(Width, Height)); + draw.Begin(); + Vector invalid; + invalid.Add(Size(Width, Height)); + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Rect r = topctrl[i]->GetRect(); + Rect ri = GetClipBound(invalid, r); + if(!IsNull(ri)) { + draw.Clipoff(r); + topctrl[i]->UpdateArea(draw, ri - r.TopLeft()); + draw.End(); + Subtract(invalid, r); + draw.ExcludeClip(r); + } + } + Rect ri = GetClipBound(invalid, desktop->GetRect().GetSize()); + if(!IsNull(ri)) + desktop->UpdateArea(draw, ri); + draw.End(); +} + +void Ctrl::PaintCaretCursor(SystemDraw& draw) +{ + if(!IsNull(fbCaretRect)) + draw.DrawRect(fbCaretRect, InvertColor); + if(sdlMouseIsIn && !SystemCursor) + draw.DrawImage(fbCursorPos.x, fbCursorPos.y, fbCursorImage); +} + +void Ctrl::DoPaint() +{ + if(!PaintLock) { + if(invalid && desktop) { + invalid = false; + SystemDraw draw; + PaintScene(draw); + PaintCaretCursor(draw); + content << String(draw.result); + } + } +} + +bool Ctrl::ProcessEventQueue(const String& event_queue) +{ + StringStream ss(event_queue); + while(!ss.IsEof()) { + String s = ss.GetLine(); + CParser p(s); + try { + if(p.Id("RI")) + SystemDraw::ResetI(); + else + if(p.Id("MM")) { + int x = p.ReadInt(); + int y = p.ReadInt(); + DoMouseFB(MOUSEMOVE, Point(x, y), 0); + } + } + catch(CParser::Error) {} + } +} + +bool Ctrl::IsWaitingEvent() +{ +// LLOG("IsWaitingEvent"); + if(socket.IsOpen()) + return true; + return socket.Timeout(0).Accept(server); +} + +bool Ctrl::ProcessEvents(bool *quit) +{ + LLOG("ProcessEvents"); + if(!socket.IsOpen()) { + if(!IsWaitingEvent()) + return false; + } + + HttpHeader http; + TimeStop tm; + LLOG("Trying to read socket"); + socket.Timeout(20000); + if(!http.Read(socket)) { + LLOG("Header failed to read"); + socket.Close(); + return false; + } + String event_queue = socket.Get((int)http.GetContentLength()); + LDUMP(event_queue); + content.Clear(); + bool r = ProcessEventQueue(event_queue); + _TODO_ // Resolve eventloop exit issue + TimerProc(GetTickCount()); + DefferedFocusSync(); + SyncCaret(); + SyncTopWindows(); + SweepMkImageCache(); + DoPaint(); + + if(http.GetURI().GetCount() < 2) + HttpResponse(socket, http.scgi, 200, "OK", "text/html", String(telpp_html, telpp_html_length)); + else + HttpResponse(socket, http.scgi, 200, "OK", "text/plain; charset=x-user-defined", content); + + socket.Close(); + return r; +} + +void Ctrl::EventLoop(Ctrl *ctrl) +{ + GuiLock __; + ASSERT(IsMainThread()); + ASSERT(LoopLevel == 0 || ctrl); + LoopLevel++; + LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN); + Ptr ploop; + if(ctrl) { + ploop = LoopCtrl; + LoopCtrl = ctrl; + ctrl->inloop = true; + } + + bool quit = false; + int64 loopno = ++EventLoopNo; + ProcessEvents(&quit); + while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) + { +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); + SyncCaret(); + GuiSleep(20); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); + ProcessEvents(&quit); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); +// LDUMP(loopno); + } + + if(ctrl) + LoopCtrl = ploop; + LoopLevel--; + LLOG(LOG_END << "Leaving event loop "); +} + +void Ctrl::GuiSleep(int ms) +{ + GuiLock __; + ASSERT(IsMainThread()); +// LLOG("GuiSleep"); + int level = LeaveGuiMutexAll(); + Sleep(ms); _TODO_ + EnterGuiMutex(level); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/FB.iml b/rainbow/Telpp/FB.iml new file mode 100644 index 000000000..c36090ae7 --- /dev/null +++ b/rainbow/Telpp/FB.iml @@ -0,0 +1,63 @@ +PREMULTIPLIED +IMAGE_ID(Arrow) +IMAGE_ID(IBeam) +IMAGE_ID(Wait) +IMAGE_ID(No) +IMAGE_ID(SizeAll) +IMAGE_ID(SizeHorz) +IMAGE_ID(SizeRight) +IMAGE_ID(SizeLeft) +IMAGE_ID(SizeVert) +IMAGE_ID(SizeTopLeft) +IMAGE_ID(SizeTop) +IMAGE_ID(SizeTopRight) +IMAGE_ID(SizeBottomLeft) +IMAGE_ID(SizeBottom) +IMAGE_ID(SizeBottomRight) +IMAGE_ID(overlap) +IMAGE_ID(maximize) +IMAGE_ID(close) +IMAGE_ID(bgtitle) +IMAGE_ID(title) +IMAGE_ID(border) +IMAGE_ID(Hand) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,90,61,104,20,65,20,30,77,162,9,92,144,248,135,160,133,117,42,177,18,21,4,171,84,65,76,22,4,149) +IMAGE_DATA(136,17,37,49,66,4,13,40,72,34,4,145,128,120,133,196,20,49,30,24,11,207,104,33,105,196,4,114,133,34,66,68) +IMAGE_DATA(52,129,67,20,65,4,145,52,218,217,61,103,214,157,117,118,110,126,222,91,247,240,135,157,229,177,55,51,223,247,230,205) +IMAGE_DATA(247,222,206,94,244,88,129,109,98,162,173,97,171,196,13,184,5,12,223,128,200,129,114,153,196,129,239,223,183,195,244,244) +IMAGE_DATA(22,44,7,190,125,219,13,95,191,238,131,169,169,29,24,14,172,172,28,128,47,95,186,225,243,231,195,48,62,190,223,199) +IMAGE_DATA(129,79,159,122,225,227,199,83,240,225,195,25,120,255,254,28,20,139,7,93,28,120,247,238,60,188,125,123,1,170,213,97) +IMAGE_DATA(88,90,186,2,175,95,95,131,177,177,99,54,14,44,47,143,194,155,55,87,225,213,171,235,240,242,229,4,188,120,113,7) +IMAGE_DATA(158,63,159,134,209,209,126,19,135,99,138,176,184,120,131,227,38,225,217,179,123,176,176,176,16,217,3,24,30,30,208,57) +IMAGE_DATA(220,215,4,199,77,194,211,167,119,160,82,121,24,98,75,165,146,196,169,22,226,43,149,91,220,74,48,63,127,23,230,230) +IMAGE_DATA(238,195,227,199,143,156,251,125,242,228,54,92,188,120,58,246,51,52,52,232,196,15,13,245,169,243,194,96,112,112,64,141) +IMAGE_DATA(33,129,55,105,208,223,127,210,170,167,97,44,92,163,183,247,152,109,13,83,131,158,158,35,148,186,13,215,8,130,110,210) +IMAGE_DATA(26,93,93,7,41,248,128,16,143,185,53,177,117,108,53,91,27,26,211,18,47,76,54,237,115,28,176,214,255,231,199,44) +IMAGE_DATA(251,173,209,133,21,184,112,77,92,180,166,164,112,88,11,51,183,245,222,184,211,20,44,147,248,109,101,179,41,248,120,83) +IMAGE_DATA(155,175,93,50,114,196,152,152,211,240,65,203,174,157,176,254,236,137,4,71,124,22,99,98,142,25,158,36,149,227,193,38) +IMAGE_DATA(56,98,125,97,30,108,204,209,180,115,98,9,254,41,241,83,245,161,234,79,201,47,181,126,104,245,217,198,175,230,232,178) +IMAGE_DATA(9,103,33,163,143,70,132,89,147,230,193,81,230,93,241,186,252,164,225,215,36,80,233,99,215,183,125,166,196,111,138,139) +IMAGE_DATA(194,151,205,231,195,199,247,249,192,240,77,62,108,251,196,232,100,251,236,203,117,205,97,237,136,203,23,131,105,140,194,255) +IMAGE_DATA(157,231,129,82,79,212,231,22,227,203,204,69,28,72,63,189,242,38,94,217,226,142,8,194,200,47,151,203,130,15,209,157) +IMAGE_DATA(228,71,229,243,110,42,63,81,252,9,97,162,109,185,14,139,68,12,160,180,200,101,220,92,177,168,92,137,83,125,216,48) +IMAGE_DATA(166,253,171,241,234,62,212,125,170,250,232,250,233,205,54,166,250,49,233,135,53,25,119,22,113,100,161,71,86,121,201,170) +IMAGE_DATA(62,212,102,210,153,82,167,186,62,204,160,95,26,63,105,248,170,31,148,6,109,252,107,127,51,107,8,77,39,251,4,176) +IMAGE_DATA(9,109,43,22,155,15,234,195,99,106,236,15,60,60,152,56,178,208,35,147,188,228,137,206,19,157,39,250,127,74,244,90) +IMAGE_DATA(158,234,134,40,213,186,67,87,2,93,137,241,9,174,196,155,16,72,235,199,65,203,57,211,134,254,230,57,215,254,92,186) +IMAGE_DATA(184,244,116,229,65,205,83,77,254,90,249,181,38,186,106,235,19,87,61,166,96,41,28,204,151,17,149,211,222,222,142,230) +IMAGE_DATA(72,49,132,117,118,118,122,121,74,18,2,41,40,134,167,182,44,121,152,167,88,231,97,79,15,201,19,122,178,72,91,44) +IMAGE_DATA(135,41,249,195,228,91,47,106,12,199,88,139,249,201,84,191,57,215,254,92,186,212,253,100,114,53,107,165,120,56,212,138) +IMAGE_DATA(76,83,249,212,39,140,250,36,83,79,12,204,201,164,36,27,125,2,74,61,169,39,173,212,132,114,162,51,150,254,205,193) +IMAGE_DATA(8,111,40,106,77,229,5,155,23,172,147,195,254,182,130,205,95,165,245,155,115,237,207,165,75,221,95,165,105,42,69,110) +IMAGE_DATA(66,15,150,194,201,191,228,219,121,174,19,208,198,251,175,191,228,23,248,149,81,3,143,153,240,46,95,105,241,152,56,116) +IMAGE_DATA(188,111,205,172,240,24,125,234,165,139,58,70,201,19,190,101,80,76,190,224,40,98,153,48,57,62,123,60,37,95,248,246) +IMAGE_DATA(187,197,180,177,177,49,216,219,218,10,226,142,153,19,253,61,220,244,113,137,149,115,182,113,209,55,141,153,214,13,231,11) +IMAGE_DATA(133,208,108,216,4,71,96,35,156,248,108,195,82,241,148,120,168,251,77,171,39,54,95,164,214,200,47,217,186,186,38,224) +IMAGE_DATA(80,223,12,28,189,60,3,199,111,206,0,181,31,59,107,8,255,111,102,4,90,218,203,176,33,88,134,109,195,226,37,76) +IMAGE_DATA(236,139,50,111,226,87,244,183,44,246,121,74,188,249,125,77,252,166,90,197,255,250,77,182,217,70,70,70,114,124,157,240) +IMAGE_DATA(178,239,179,52,181,16,22,147,227,31,70,228,175,156,212,187,11,7,197,98,49,113,183,112,226,249,106,181,154,184,91,56) +IMAGE_DATA(53,56,121,87,214,97,234,198,108,120,101,157,56,142,142,142,14,52,94,244,165,97,240,179,179,179,9,142,201,20,124,32) +IMAGE_DATA(98,17,49,33,241,94,142,88,95,195,199,28,19,94,140,219,114,230,139,229,7,18,241,124,50,0,0,0,0,0,0,0) +IMAGE_END_DATA(1184, 22) diff --git a/rainbow/Telpp/Gui.h b/rainbow/Telpp/Gui.h new file mode 100644 index 000000000..ef00bff2b --- /dev/null +++ b/rainbow/Telpp/Gui.h @@ -0,0 +1,358 @@ +#define GUI_TELPP + +NAMESPACE_UPP + +class SystemDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + + virtual void BeginOp(); + virtual void EndOp(); + virtual void OffsetOp(Point p); + virtual bool ClipOp(const Rect& r); + virtual bool ClipoffOp(const Rect& r); + virtual bool ExcludeClipOp(const Rect& r); + virtual bool IntersectClipOp(const Rect& r); + virtual bool IsPaintingOp(const Rect& r) const; + virtual Rect GetPaintRect() const; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); + + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor); + virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, + const int *subpolygon_counts, int scc, + const int *disjunct_polygon_counts, int dpcc, + Color color, int width, Color outline, + uint64 pattern, Color doxor); + virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color); + + virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor); + virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx); + + virtual Size GetNativeDpi() const; + virtual void BeginNative(); + virtual void EndNative(); + + virtual int GetCloffLevel() const; + +private: + Size pageSize; + Size nativeSize; + Size nativeDpi; + bool palette:1; + bool color16:1; + bool is_mono:1; + int native; + + friend class ImageDraw; + friend class FontInfo; + friend class Font; + + friend void StaticExitDraw_(); + + Point actual_offset_bak; + + struct Cloff : Moveable { + Point org; + HRGN hrgn; + Rect drawingclip; + }; + + Array cloff; + Rect drawingclip; + + COLORREF lastTextColor; + Color lastColor; + HBRUSH orgBrush; + HBRUSH actBrush; + HPEN orgPen; + HPEN actPen; + int lastPen; + Color lastPenColor; + + void Unselect0(); + void Cinit(); + + void LoadCaps(); + void SetPrinterMode(); + void Reset(); + void SetOrg(); + friend HPALETTE GetQlibPalette(); + void DotsMode(); + + static void InitColors(); + + friend class BackDraw; + friend class ScreenDraw; + friend class PrintDraw; + +protected: + dword style; + HDC handle; + Point actual_offset; + + SystemDraw(); + void Init(); + void InitClip(const Rect& clip); + +public: + static Rect GetVirtualScreenArea(); + + static void SetAutoPalette(bool ap); + static bool AutoPalette(); + bool PaletteMode() { return palette; } + + static void Flush() { GdiFlush(); } + + COLORREF GetColor(Color color) const; + + Point GetOffset() const { return actual_offset; } + +#ifndef PLATFORM_WINCE + Point LPtoDP(Point p) const; + Point DPtoLP(Point p) const; + Rect LPtoDP(const Rect& r) const; + Rect DPtoLP(const Rect& r) const; +#endif + + void SetColor(Color color); + void SetDrawPen(int width, Color color); + + Size GetSizeCaps(int i, int j) const; + HDC BeginGdi(); + void EndGdi(); + HDC GetHandle() { return handle; } + operator HDC() const { return handle; } + void Unselect(); + void Attach(HDC ahandle) { handle = ahandle; Init(); } + HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; } + + SystemDraw(HDC hdc); + virtual ~SystemDraw(); + + bool CanSetSurface() { return IsGui() && IsWinNT(); } +}; + +#ifndef PLATFORM_WINCE +class WinMetaFile { + Size size; + HENHMETAFILE hemf; + + void Init(); + +public: + void Attach(HENHMETAFILE emf); + HENHMETAFILE Detach(); + + void Set(const void *data, dword len); + void Set(const String& data) { Set(~data, data.GetCount()); } + + String Get() const; + + operator bool() const { return hemf; } + void SetSize(const Size& sz) { size = sz; } + Size GetSize() const { return hemf ? size : Size(0, 0); } + + void Clear(); + + void Paint(Draw& w, const Rect& r) const; + void Paint(Draw& w, int x, int y, int cx, int cy) const; + + void Serialize(Stream& s); + + void ReadClipboard(); + void WriteClipboard() const; + void Load(const char *file) { Set(LoadFile(file)); } + + WinMetaFile() { Init(); } + WinMetaFile(HENHMETAFILE hemf); + WinMetaFile(HENHMETAFILE hemf, Size sz); + WinMetaFile(const char *file); + WinMetaFile(void *data, int len); + WinMetaFile(const String& data); + + ~WinMetaFile() { Clear(); } + + HENHMETAFILE GetHEMF() const { return hemf; } +}; + +class WinMetaFileDraw : public SystemDraw { + Size size; + +public: + bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFile Close(); + + WinMetaFileDraw() {} + WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + ~WinMetaFileDraw(); +}; + +void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf); +void DrawWMF(Draw& w, int x, int y, const String& wmf); +Drawing LoadWMF(const char *path, int cx, int cy); +Drawing LoadWMF(const char *path); + +String AsWMF(const Drawing& iw); + +#endif + +class ScreenDraw : public SystemDraw { +public: + ScreenDraw(bool ic = false); + ~ScreenDraw(); +}; + +#ifndef PLATFORM_WINCE +class PrintDraw : public SystemDraw { +public: + virtual void StartPage(); + virtual void EndPage(); + +private: + bool aborted; + + void InitPrinter(); +public: + PrintDraw(HDC hdc, const char *jobname); + ~PrintDraw(); +}; +#endif + +inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); } + +inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); } + +inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY) +{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); } + +inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); } +inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); } + +inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); } +inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); } + +#ifndef PLATFORM_WINCE +inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); } +#endif +inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); } +inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); } +inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +HDC ScreenHDC(); +HPALETTE GetQlibPalette(); + +Image Win32Icon(LPCSTR id, int iconsize = 0); +Image Win32Icon(int id, int iconsize = 0); +Image Win32Cursor(LPCSTR id); +Image Win32Cursor(int id); +HICON IconWin32(const Image& img, bool cursor = false); +Image Win32DllIcon(const char *dll, int ii, bool large); + +class BackDraw : public SystemDraw { +public: + virtual bool IsPaintingOp(const Rect& r) const; + +protected: + HBITMAP hbmpold; + HBITMAP hbmp; + + Size size; + Draw *painting; + Point painting_offset; + +public: + void Put(SystemDraw& w, int x, int y); + void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); } + + void Create(SystemDraw& w, int cx, int cy); + void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); } + void Destroy(); + + void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; } + + BackDraw(); + ~BackDraw(); +}; + +class ImageDraw : public SystemDraw { + Size size; + + struct Section { + HDC dc; + HBITMAP hbmp, hbmpOld; + RGBA *pixels; + + void Init(int cx, int cy); + ~Section(); + }; + + Section rgb; + Section a; + SystemDraw alpha; + + + bool has_alpha; + + void Init(); + Image Get(bool pm) const; + +public: + Draw& Alpha(); + + operator Image() const; + + Image GetStraight() const; + + ImageDraw(Size sz); + ImageDraw(int cx, int cy); + ~ImageDraw(); +}; + +END_UPP_NAMESPACE + +#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h" + + +#define GUIPLATFORM_CTRL_TOP_DECLS \ + HWND hwnd; \ + UDropTarget *dndtgt; \ + + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h" + + +#define GUIPLATFORM_PASTECLIP_DECLS \ + UDropTarget *dt; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h" + +NAMESPACE_UPP + +inline unsigned GetHashValue(const HWND& hwnd) +{ + return (unsigned)(intptr_t)hwnd; +} +END_UPP_NAMESPACE + +#ifdef PLATFORM_WIN32 +#ifndef PLATFORM_WINCE + +#include + +#endif +#endif + +#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h" diff --git a/rainbow/Telpp/Image.cpp b/rainbow/Telpp/Image.cpp new file mode 100644 index 000000000..f7b274f1a --- /dev/null +++ b/rainbow/Telpp/Image.cpp @@ -0,0 +1,47 @@ +#include + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LTIMING(x) // RTIMING(x) + +void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) +{ + GuiLock __; + // Empty as CanSetSurface is false +} + +void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff) +{ + GuiLock __; + // Empty as CanSetSurface is false +} + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +#define STD_CURSOR(name, sdl) \ +Image Image::name() { static Image img; ONCELOCK { img = FBImg::name(); img.SetAuxData(sdl + 1); } return img; } + +STD_CURSOR(Arrow, 1) +STD_CURSOR(Wait, 2) +STD_CURSOR(IBeam, 3) +STD_CURSOR(No, 4) +STD_CURSOR(SizeAll, 5) +STD_CURSOR(SizeHorz, 6) +STD_CURSOR(SizeVert, 7) +STD_CURSOR(SizeTopLeft, 8) +STD_CURSOR(SizeTop, 9) +STD_CURSOR(SizeTopRight, 10) +STD_CURSOR(SizeLeft, 11) +STD_CURSOR(SizeRight, 12) +STD_CURSOR(SizeBottomLeft, 13) +STD_CURSOR(SizeBottom, 14) +STD_CURSOR(SizeBottomRight, 15) +STD_CURSOR(Hand, 16) + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Keys.h b/rainbow/Telpp/Keys.h new file mode 100644 index 000000000..52b323fe3 --- /dev/null +++ b/rainbow/Telpp/Keys.h @@ -0,0 +1,112 @@ +#define WEBKEY(x) x + +K_BACK = WEBKEY(100) + K_DELTA, +K_BACKSPACE = WEBKEY(101) + K_DELTA, + +//handled extra in fbKEYtoK +K_TAB = 9, //SDLK_TAB, + +K_SPACE = 32, //SDLK_SPACE, + +K_RETURN = 13, //SDLK_RETURN, +K_ENTER = K_RETURN, + +K_SHIFT_KEY = WEBKEY(0) + K_DELTA, +K_CTRL_KEY = WEBKEY(1) + K_DELTA, +K_ALT_KEY = WEBKEY(2) + K_DELTA, +K_CAPSLOCK = WEBKEY(3) + K_DELTA, +K_ESCAPE = WEBKEY(4) + K_DELTA, +K_PRIOR = WEBKEY(5) + K_DELTA, +K_PAGEUP = WEBKEY(6) + K_DELTA, +K_NEXT = WEBKEY(7) + K_DELTA, +K_PAGEDOWN = WEBKEY(8) + K_DELTA, +K_END = WEBKEY(9) + K_DELTA, +K_HOME = WEBKEY(10) + K_DELTA, +K_LEFT = WEBKEY(11) + K_DELTA, +K_UP = WEBKEY(12) + K_DELTA, +K_RIGHT = WEBKEY(13) + K_DELTA, +K_DOWN = WEBKEY(14) + K_DELTA, +K_INSERT = WEBKEY(15) + K_DELTA, +K_DELETE = WEBKEY(16) + K_DELTA, + +K_NUMPAD0 = WEBKEY(17) + K_DELTA, +K_NUMPAD1 = WEBKEY(18) + K_DELTA, +K_NUMPAD2 = WEBKEY(19) + K_DELTA, +K_NUMPAD3 = WEBKEY(20) + K_DELTA, +K_NUMPAD4 = WEBKEY(21) + K_DELTA, +K_NUMPAD5 = WEBKEY(22) + K_DELTA, +K_NUMPAD6 = WEBKEY(23) + K_DELTA, +K_NUMPAD7 = WEBKEY(24) + K_DELTA, +K_NUMPAD8 = WEBKEY(25) + K_DELTA, +K_NUMPAD9 = WEBKEY(26) + K_DELTA, +K_MULTIPLY = WEBKEY(27) + K_DELTA, +K_ADD = WEBKEY(28) + K_DELTA, +K_SEPARATOR = WEBKEY(29) + K_DELTA, +K_SUBTRACT = WEBKEY(30) + K_DELTA, +K_DECIMAL = WEBKEY(31) + K_DELTA, +K_DIVIDE = WEBKEY(32) + K_DELTA, +K_SCROLL = WEBKEY(33) + K_DELTA, + +K_F1 = WEBKEY(34) + K_DELTA, +K_F2 = WEBKEY(35) + K_DELTA, +K_F3 = WEBKEY(36) + K_DELTA, +K_F4 = WEBKEY(37) + K_DELTA, +K_F5 = WEBKEY(38) + K_DELTA, +K_F6 = WEBKEY(39) + K_DELTA, +K_F7 = WEBKEY(40) + K_DELTA, +K_F8 = WEBKEY(41) + K_DELTA, +K_F9 = WEBKEY(42) + K_DELTA, +K_F10 = WEBKEY(43) + K_DELTA, +K_F11 = WEBKEY(44) + K_DELTA, +K_F12 = WEBKEY(45) + K_DELTA, + +K_A = WEBKEY(46) + K_DELTA, +K_B = WEBKEY(47) + K_DELTA, +K_C = WEBKEY(48) + K_DELTA, +K_D = WEBKEY(49) + K_DELTA, +K_E = WEBKEY(50) + K_DELTA, +K_F = WEBKEY(51) + K_DELTA, +K_G = WEBKEY(52) + K_DELTA, +K_H = WEBKEY(53) + K_DELTA, +K_I = WEBKEY(54) + K_DELTA, +K_J = WEBKEY(55) + K_DELTA, +K_K = WEBKEY(56) + K_DELTA, +K_L = WEBKEY(57) + K_DELTA, +K_M = WEBKEY(58) + K_DELTA, +K_N = WEBKEY(59) + K_DELTA, +K_O = WEBKEY(60) + K_DELTA, +K_P = WEBKEY(61) + K_DELTA, +K_Q = WEBKEY(62) + K_DELTA, +K_R = WEBKEY(63) + K_DELTA, +K_S = WEBKEY(64) + K_DELTA, +K_T = WEBKEY(65) + K_DELTA, +K_U = WEBKEY(66) + K_DELTA, +K_V = WEBKEY(67) + K_DELTA, +K_W = WEBKEY(68) + K_DELTA, +K_X = WEBKEY(69) + K_DELTA, +K_Y = WEBKEY(70) + K_DELTA, +K_Z = WEBKEY(71) + K_DELTA, +K_0 = WEBKEY(72) + K_DELTA, +K_1 = WEBKEY(73) + K_DELTA, +K_2 = WEBKEY(74) + K_DELTA, +K_3 = WEBKEY(75) + K_DELTA, +K_4 = WEBKEY(76) + K_DELTA, +K_5 = WEBKEY(77) + K_DELTA, +K_6 = WEBKEY(78) + K_DELTA, +K_7 = WEBKEY(79) + K_DELTA, +K_8 = WEBKEY(80) + K_DELTA, +K_9 = WEBKEY(81) + 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 = WEBKEY(82) + K_DELTA, // Is it really? diff --git a/rainbow/Telpp/Local.h b/rainbow/Telpp/Local.h new file mode 100644 index 000000000..2fbfbb88a --- /dev/null +++ b/rainbow/Telpp/Local.h @@ -0,0 +1,63 @@ +#include + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +class TopWindowFrame : public Ctrl { +public: + virtual void Layout(); + virtual void Paint(Draw& w); + virtual Image CursorImage(Point p, dword keyflags); + virtual void LeftDown(Point p, dword keyflags); + virtual void LeftHold(Point p, dword keyflags); + virtual void LeftDouble(Point p, dword keyflags); + virtual void MouseMove(Point p, dword keyflags); + virtual void CancelMode(); + virtual void LeftUp(Point p, dword keyflags); + +private: + Point dir; + Point startpos; + Rect startrect; + + bool maximized; + Rect overlapped; + + bool holding; + TimeCallback hold; + + Point GetDragMode(Point p); + Image GetDragImage(Point dragmode); + void StartDrag(); + Rect Margins() const; + Rect ComputeClient(Rect r); + void Hold(); + + typedef TopWindowFrame CLASSNAME; + +public: + String title; + Button close, maximize; + Image icon; + Size minsize; + bool sizeable; + TopWindow *window; + + void SetTitle(const String& s) { title = s; Refresh(); } + Rect GetClient() const; + void SetClient(Rect r); + void GripResize(); + + void Maximize(); + void Overlap(); + void ToggleMaximize(); + bool IsMaximized() const { return maximized; } + void SyncRect(); + + TopWindowFrame(); +}; + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/Telpp/Paint.cpp b/rainbow/Telpp/Paint.cpp new file mode 100644 index 000000000..51548ac6e --- /dev/null +++ b/rainbow/Telpp/Paint.cpp @@ -0,0 +1,5 @@ +#include "Telpp.h" + +NAMESPACE_UPP + +END_UPP_NAMESPACE diff --git a/rainbow/Telpp/TelDraw.cpp b/rainbow/Telpp/TelDraw.cpp new file mode 100644 index 000000000..adea9dbcf --- /dev/null +++ b/rainbow/Telpp/TelDraw.cpp @@ -0,0 +1,69 @@ +#include "Telpp.h" + +NAMESPACE_UPP + +void SystemDraw::Put16(int x) +{ + result.Cat(LOBYTE(x)); + result.Cat(HIBYTE(x)); +} + +void SystemDraw::Put(Point p) +{// TODO: Clamp? + Put16(p.x); + Put16(p.y); +} + +void SystemDraw::Put(Size sz) +{ + Put((Point)sz); +} + +void SystemDraw::Put(const Rect& r) +{ + Put(r.TopLeft()); + Put(r.GetSize()); +} + +Index SystemDraw::img_index; + +int SystemDraw::GetImageI(SystemDraw& w, const Image& img) +{ + int id = img.GetSerialId(); + int q = img_index.Find(id); + if(q < 0) { // TODO: Implement some sort of victim elimination + q = img_index.GetCount(); + img_index.Add(id); + w.Put8(SETIMAGE); + w.Put16(q); + w.Put(img.GetSize()); + const RGBA *end = ~img + img.GetLength(); + for(const RGBA *s = ~img; s < end; s++) { + w.Put8(s->r); + w.Put8(s->g); + w.Put8(s->b); + w.Put8(s->a); + } + } + return q; +} + +void SystemDraw::PutImage(Point p, const Image& img, const Rect& src) +{ + int i = GetImageI(*this, img); + Put8(IMAGE); + Put16(i); + Put(p); + Put(src); +} + +void SystemDraw::PutRect(const Rect& r, Color color) +{ // TODO: Support InvertColor + Put8(RECT); + Put(r); + Put8(color.GetR()); + Put8(color.GetG()); + Put8(color.GetB()); +} + +END_UPP_NAMESPACE diff --git a/rainbow/Telpp/Telpp.brc b/rainbow/Telpp/Telpp.brc new file mode 100644 index 000000000..933eae921 --- /dev/null +++ b/rainbow/Telpp/Telpp.brc @@ -0,0 +1 @@ +BINARY(telpp_html, "Telpp.html") diff --git a/rainbow/Telpp/Telpp.h b/rainbow/Telpp/Telpp.h new file mode 100644 index 000000000..82faf2851 --- /dev/null +++ b/rainbow/Telpp/Telpp.h @@ -0,0 +1,124 @@ +#define GUI_TELPP + +#define _TODO_ _DBG_ + +#include + +#ifdef PLATFORM_POSIX +#include +#endif + +NAMESPACE_UPP + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +struct SystemDraw : public SDraw { +public: + virtual void PutImage(Point p, const Image& img, const Rect& src); + virtual void PutRect(const Rect& r, Color color); + +public: + enum Code { + RECT = 0, + IMAGE = 1, + SETIMAGE = 2, + }; + + static Index img_index; + + static int GetImageI(SystemDraw& w, const Image& img); + static void ResetI() { img_index.Clear(); } + + StringBuffer result; + + void Put8(int x) { result.Cat(x); } + void Put16(int x); + void Put(Point p); + void Put(Size sz); + void Put(const Rect& r); + + bool CanSetSurface() { return false; } + static void Flush() {} +}; + +struct BackDraw__ : public SystemDraw { + BackDraw__() : SystemDraw() {} +}; + +class BackDraw : public BackDraw__ { // Dummy only, as we are running in GlobalBackBuffer mode + Size size; + Draw *painting; + Point painting_offset; + ImageBuffer ib; + +public: + virtual bool IsPaintingOp(const Rect& r) const; + +public: + void Put(SystemDraw& w, int x, int y) {} + void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); } + + void Create(SystemDraw& w, int cx, int cy) {} + void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); } + void Destroy() {} + + void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; } + + BackDraw(); + ~BackDraw(); +}; + +class ImageDraw : public SImageDraw { +public: + ImageDraw(Size sz) : SImageDraw(sz) {} + ImageDraw(int cx, int cy) : SImageDraw(cx, cy) {} +}; + +void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, uint64 pattern); + +class TopWindowFrame; + +#define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window; + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE + +#define GUIPLATFORM_PASTECLIP_DECLS \ + bool dnd; \ + friend struct DnDLoop; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE + +class PrinterJob { // Dummy only... + NilDraw nil; + Vector pages; + +public: + Draw& GetDraw() { return nil; } + operator Draw&() { return GetDraw(); } + const Vector& GetPages() const { return pages; } + int operator[](int i) const { return 0; } + int GetPageCount() const { return 0; } + + bool Execute() { return false; } + + PrinterJob& Landscape(bool b = true) { return *this; } + PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; } + PrinterJob& PageCount(int n) { return *this; } + PrinterJob& CurrentPage(int currentpage) { return *this; } + PrinterJob& Name(const char *_name) { return *this; } + + PrinterJob(const char *name = NULL) {} + ~PrinterJob() {} +}; + +void USDLSetup(dword flags); + + +void InitTelpp(); + +END_UPP_NAMESPACE + +#define GUIPLATFORM_INCLUDE_AFTER diff --git a/rainbow/Telpp/Telpp.html b/rainbow/Telpp/Telpp.html new file mode 100644 index 000000000..c31056d57 --- /dev/null +++ b/rainbow/Telpp/Telpp.html @@ -0,0 +1,170 @@ + + + + + + + + + + +Your browser does not support the HTML5 canvas tag. + + + + + diff --git a/rainbow/Telpp/Telpp.upp b/rainbow/Telpp/Telpp.upp new file mode 100644 index 000000000..3f32d158a --- /dev/null +++ b/rainbow/Telpp/Telpp.upp @@ -0,0 +1,33 @@ +description "SDL20 U++ backend\377"; + +uses + Painter, + CtrlLib, + GLDraw; + +library(POSIX) "SDL2 SDL2main GL"; + +file + Telpp.h, + Keys.h, + After.h, + Local.h, + TelDraw.cpp, + Image.cpp, + FB.iml, + Ctrl.h, + DrawDragRect.cpp, + Ctrl.cpp, + Wnd.cpp, + Cursor.cpp, + Paint.cpp, + Event.cpp, + Top.h, + TopFrame.cpp, + Top.cpp, + Clip.cpp, + DnD.cpp, + ChSysInit.cpp, + Telpp.brc, + Telpp.html; + diff --git a/rainbow/Telpp/Top.cpp b/rainbow/Telpp/Top.cpp new file mode 100644 index 000000000..37f79f7e5 --- /dev/null +++ b/rainbow/Telpp/Top.cpp @@ -0,0 +1,152 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +void TopWindow::SyncFrameRect(const Rect& r) +{ + frame->SetClient(r); +} + +void TopWindow::DestroyFrame() +{ + if(frame->IsOpen()) + frame->DestroyWnd(); +} + +void TopWindow::GripResize() +{ + frame->GripResize(); +} + +void TopWindow::SyncSizeHints() +{ + SyncCaption(); +} + +void TopWindow::SyncTitle() +{ + SyncCaption(); +} + +void TopWindow::SyncCaption() +{ + GuiLock __; + frame->title = title.ToString(); +#ifdef _DEBUG + frame->title = "TELPP"; +#endif + frame->minsize = minsize; + frame->close.Show(!noclosebox); + frame->maximize.Show(maximizebox); + frame->sizeable = sizeable; + frame->RefreshLayout(); + frame->Refresh(); + frame->close <<= Proxy(WhenClose); + frame->icon = icon; + frame->Enable(IsEnabled()); +} + +void TopWindow::State(int reason) +{ + SyncCaption(); +} + +void TopWindow::SyncRect() +{ + frame->SyncRect(); + Rect r = frame->GetClient(); + if(r != GetRect()) + SetRect(r); +} + +void TopWindow::Open(Ctrl *owner) +{ + GuiLock __; + LLOG("Open " << Upp::Name(owner)); + Rect r = GetRect(); + if(r.IsEmpty()) + SetRect(GetDefaultWindowRect()); + else + if(r.left == 0 && r.top == 0) + if(owner && center == 1) + SetRect(owner->GetRect().CenterRect(r.GetSize())); + else + if(center) + SetRect(GetWorkArea().CenterRect(r.GetSize())); + frame->SetClient(GetRect()); + frame->window = this; + frame->PopUp(owner, false, true); + PopUp(frame, false, true); + popup = false; + SetRect(frame->GetClient()); + SyncCaption(); + if(state == MAXIMIZED) + frame->Maximize(); +} + +void TopWindow::Open() +{ + Open(GetActiveCtrl()); +} + +void TopWindow::OpenMain() +{ + Open(NULL); +} + +void TopWindow::Minimize(bool effect) +{ +// state = MINIMIZED; +} + +TopWindow& TopWindow::FullScreen(bool b) +{ + return *this; +} + +void TopWindow::Maximize(bool effect) +{ + state = MAXIMIZED; + frame->Maximize(); +} + +void TopWindow::Overlap(bool effect) +{ + GuiLock __; + state = OVERLAPPED; + frame->Overlap(); +} + +TopWindow& TopWindow::TopMost(bool b, bool stay_top) +{ + GuiLock __; + return *this; +} + +bool TopWindow::IsTopMost() const +{ + return true; +} + +void TopWindow::GuiPlatformConstruct() +{ + frame = new TopWindowFrame; +} + +void TopWindow::GuiPlatformDestruct() +{ + delete frame; +} + +void TopWindow::SerializePlacement(Stream& s, bool reminimize) +{ + GuiLock __; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Top.h b/rainbow/Telpp/Top.h new file mode 100644 index 000000000..2e9b12c16 --- /dev/null +++ b/rainbow/Telpp/Top.h @@ -0,0 +1,16 @@ +//$ class TopWindow { +public: + virtual void State(int reason); + +private: + TopWindowFrame *frame; + + void SyncRect(); + void SyncFrameRect(const Rect& r); + void DestroyFrame(); + + friend class Ctrl; + +public: + void GripResize(); +//$ }; diff --git a/rainbow/Telpp/TopFrame.cpp b/rainbow/Telpp/TopFrame.cpp new file mode 100644 index 000000000..258fb51e0 --- /dev/null +++ b/rainbow/Telpp/TopFrame.cpp @@ -0,0 +1,236 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) +#define LDUMP(x) //DDUMP(x) + +TopWindowFrame::TopWindowFrame() +{ + close.SetImage(FBImg::close()); + close.EdgeStyle(); + Add(close); + maximize.SetImage(FBImg::maximize()); + maximize.EdgeStyle(); + Add(maximize); + maximize <<= THISBACK(ToggleMaximize); + maximized = false; + sizeable = false; + holding = false; +} + +void TopWindowFrame::SyncRect() +{ + if(maximized) { + Size sz = GetWorkArea().GetSize(); + if(GetRect().GetSize() != sz) + SetRect(sz); + } +} + +void TopWindowFrame::Maximize() +{ + if(!maximized && maximize.IsShown()) { + maximized = true; + overlapped = GetRect(); + SetRect(GetWorkArea().GetSize()); + maximize.SetImage(FBImg::overlap()); + } +} + +void TopWindowFrame::Overlap() +{ + if(maximized && maximize.IsShown()) { + maximized = false; + SetRect(overlapped); + maximize.SetImage(FBImg::maximize()); + } +} + +void TopWindowFrame::ToggleMaximize() +{ + if(maximized) + Overlap(); + else + Maximize(); +} + +Rect TopWindowFrame::Margins() const +{ + return maximized ? Rect(0, 0, 0, 0) : ChMargins(FBImg::border()); +} + +void TopWindowFrame::Paint(Draw& w) +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + ChPaintEdge(w, sz, FBImg::border()); + ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4, + window->IsForeground() ? FBImg::title() : FBImg::bgtitle()); + int tx = m.left + 2; + int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown()); + if(!IsNull(icon)) { + Image h = icon; + if(h.GetWidth() > c || h.GetHeight() > c) + h = Rescale(h, GetFitSize(h.GetSize(), Size(c))); + w.DrawImage(tx, m.top + 2, h); + tx += c; + tcx -= c; + } + DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText()); +} + +void TopWindowFrame::Layout() +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + int x = sz.cx - m.right; + if(close.IsShown()) + close.SetRect(x -= c, m.top, c, c); + if(maximize.IsShown()) + maximize.SetRect(x -= c, m.top, c, c); +} + +Rect TopWindowFrame::GetClient() const +{ + Rect r = GetRect(); + Rect m = Margins(); + r.left += m.left; + r.right -= m.right; + r.top += m.top; + r.bottom -= m.bottom; + r.top += GetStdFontCy() + 4; + return r; +} + +Rect TopWindowFrame::ComputeClient(Rect r) +{ + Rect m = Margins(); + r.left -= m.left; + r.right += m.right; + r.top -= m.top; + r.bottom += m.bottom; + r.top -= GetStdFontCy() + 4; + return r; +} + +void TopWindowFrame::SetClient(Rect r) +{ + SetRect(ComputeClient(r)); +} + +Point TopWindowFrame::GetDragMode(Point p) +{ + Size sz = GetSize(); + Rect m = ChMargins(FBImg::border()); + Point dir; + dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0; + dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0; + return dir; +} + +void TopWindowFrame::StartDrag() +{ + if(maximized) + return; + if(!sizeable && (dir.x || dir.y)) + return; + SetCapture(); + startrect = GetRect(); + startpos = GetMousePos(); + LLOG("START DRAG ---------------"); +} + +void TopWindowFrame::GripResize() +{ + dir = Point(1, 1); + StartDrag(); +} + +void TopWindowFrame::LeftDown(Point p, dword keyflags) +{ + dir = GetDragMode(p); + StartDrag(); +} + +void TopWindowFrame::CancelMode() +{ + holding = false; +} + +void TopWindowFrame::LeftUp(Point p, dword keyflags) +{ + holding = false; +} + +void TopWindowFrame::Hold() +{ + if(HasCapture()) { + if(HasMouse() && GetMouseLeft() && holding) + StartDrag(); + ReleaseCapture(); + holding = false; + } +} + +void TopWindowFrame::LeftHold(Point p, dword keyflags) +{ +/* if(HasCapture() || FullWindowDrag) + return; + dir = GetDragMode(p); + if(!dir.x && !dir.y) + StartDrag();*/ +} + +void TopWindowFrame::LeftDouble(Point p, dword keyflags) +{ + ToggleMaximize(); + IgnoreMouseUp(); +} + +void TopWindowFrame::MouseMove(Point, dword) +{ + LDUMP(HasWndCapture()); + LDUMP(HasCapture()); + if(!HasCapture() || holding) + return; + Size msz = ComputeClient(minsize).GetSize(); + Point p = GetMousePos() - startpos; + Rect r = startrect; + if(dir.x == -1) + r.left = min(r.left + p.x, startrect.right - msz.cx); + if(dir.x == 1) + r.right = max(r.right + p.x, startrect.left + msz.cx); + if(dir.y == -1) + r.top = min(r.top + p.y, startrect.bottom - msz.cy); + if(dir.y == 1) + r.bottom = max(r.bottom + p.y, startrect.top + msz.cy); + if(dir.y == 0 && dir.x == 0) + r.Offset(p); + SetRect(r); +} + +Image TopWindowFrame::GetDragImage(Point dir) +{ + static Image (*im[9])() = { + Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft, + Image::SizeTop, Image::Arrow, Image::SizeBottom, + Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight, + }; + return (*im[(dir.x + 1) * 3 + (dir.y + 1)])(); +} + +Image TopWindowFrame::CursorImage(Point p, dword) +{ + if(!sizeable) + return Image::Arrow(); + return GetDragImage(HasCapture() ? dir : GetDragMode(p)); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/Wnd.cpp b/rainbow/Telpp/Wnd.cpp new file mode 100644 index 000000000..f70c0c72a --- /dev/null +++ b/rainbow/Telpp/Wnd.cpp @@ -0,0 +1,459 @@ +#include "Local.h" + +#ifdef GUI_TELPP + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) +#define LDUMPC(x) //DDUMPC(x) +#define LTIMING(x) RTIMING(x) + +Ptr Ctrl::desktop; +Vector Ctrl::topctrl; + +bool Ctrl::invalid; + +bool Ctrl::sdlMouseIsIn; + +Point Ctrl::fbCursorPos = Null; +Image Ctrl::fbCursorImage; +Rect Ctrl::fbCaretRect; +int Ctrl::fbCaretTm; +bool Ctrl::fbEndSession; +int Ctrl::PaintLock; + +bool Ctrl::SystemCursor; + +void Ctrl::SetDesktop(Ctrl& q) +{ + desktop = &q; + desktop->SetOpen(true); + desktop->NewTop(); + invalid = true; +} + +void Ctrl::EndSession() +{ + GuiLock __; + LLOG("Ctrl::EndSession"); + fbEndSession = true; + EndSessionLoopNo = EventLoopNo; +} + +void Ctrl::Exit() +{ + TopWindow::ShutdownWindows(); + Ctrl::CloseTopCtrls(); + _TODO_ +} + +void Ctrl::SetDesktopSize(Size sz) +{ + if(desktop) + desktop->SetRect(sz); + invalid = true; + SyncTopWindows(); +} + +int Ctrl::FindTopCtrl() const +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(this == topctrl[i]) + return i; + return -1; +} + +bool Ctrl::IsAlphaSupported() +{ + return false; +} + +bool Ctrl::IsCompositedGui() +{ + return false; +} + +Vector Ctrl::GetTopCtrls() +{ + Vector ctrl; + if(desktop) + ctrl.Add(desktop); + for(int i = 0; i < topctrl.GetCount(); i++) + if(!dynamic_cast(topctrl[i])) + ctrl.Add(topctrl[i]); + return ctrl; +} + +Ctrl *Ctrl::GetOwner() +{ + GuiLock __; + int q = FindTopCtrl(); + if(q > 0 && topctrl[q]->top) { + Ctrl *x = topctrl[q]->top->owner_window; + LDUMP(Upp::Name(x)); + return dynamic_cast(x) ? x->GetOwner() : x; + } + return NULL; +} + +Ctrl *Ctrl::GetActiveCtrl() +{ + GuiLock __; + return focusCtrl ? focusCtrl->GetTopCtrl() : NULL; +} + +// Vector Ctrl::hotkey; + +int Ctrl::RegisterSystemHotKey(dword key, Callback cb) +{ +/* ASSERT(key >= K_DELTA); + int q = hotkey.GetCount(); + for(int i = 0; i < hotkey.GetCount(); i++) + if(!hotkey[i]) { + q = i; + break; + } + hotkey.At(q) = cb; + dword mod = 0; + if(key & K_ALT) + mod |= MOD_ALT; + if(key & K_SHIFT) + mod |= MOD_SHIFT; + if(key & K_CTRL) + mod |= MOD_CONTROL; + + return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/ + return -1; +} + +void Ctrl::UnregisterSystemHotKey(int id) +{ +/* if(id >= 0 && id < hotkey.GetCount()) { + UnregisterHotKey(NULL, id); + hotkey[id].Clear(); + }*/ +} + +void Ctrl::SyncTopWindows() +{ + for(int i = 0; i < topctrl.GetCount(); i++) { + TopWindow *w = dynamic_cast(topctrl[i]); + if(w) + w->SyncRect(); + } +} + +/* +ViewDraw::ViewDraw(Ctrl *ctrl) +{ + if(Ctrl::invalid) + Ctrl::DoPaint(); + Ctrl::invalid = false; + Ctrl::RemoveCursor(); + Ctrl::RemoveCaret(); + Rect r = ctrl->GetScreenView(); + Ctrl::invalid.Add(r); + Ctrl::AddUpdate(r); + for(int i = max(ctrl->GetTopCtrl()->FindTopCtrl() + 1, 0); i < Ctrl::topctrl.GetCount(); i++) { + Rect rr = Ctrl::topctrl[i]->GetScreenRect(); + ExcludeClip(rr); + Subtract(Ctrl::invalid, rr); + } + Offset(r.TopLeft()); +} + +ViewDraw::~ViewDraw() +{ + Ctrl::DoUpdate(); +} +*/ + +Rect Ctrl::GetClipBound(const Vector& inv, const Rect& r) +{ + Rect ri = Null; + for(int j = 0; j < inv.GetCount(); j++) { + Rect rr = inv[j] & r; + if(!rr.IsEmpty()) + ri = IsNull(ri) ? rr : rr | ri; + } + return ri; +} + +void Ctrl::WndUpdate(const Rect&) +{ + GuiLock __; + Invalidate(); + DoPaint(); +} + +Rect Ctrl::GetWndScreenRect() const +{ + GuiLock __; + return GetRect(); +} + +void Ctrl::WndShow(bool b) +{ + GuiLock __; +} + +void Ctrl::WndUpdate() +{ + GuiLock __; +} + +bool Ctrl::IsWndOpen() const { + GuiLock __; + return FindTopCtrl() >= 0 || this == desktop; +} + +void Ctrl::SetAlpha(byte alpha) +{ + GuiLock __; +} + +Rect Ctrl::GetWorkArea() const +{ + GuiLock __; + return GetVirtualScreenArea(); +} + +void Ctrl::GetWorkArea(Array& rc) +{ + GuiLock __; + Array r; + r.Add(GetVirtualScreenArea()); +} + +Rect Ctrl::GetVirtualWorkArea() +{ + return GetVirtualScreenArea(); +} + +Rect Ctrl::GetWorkArea(Point pt) +{ + return GetVirtualScreenArea(); +} + +Rect Ctrl::GetVirtualScreenArea() +{ + GuiLock __; + return desktop ? desktop->GetRect() : Rect(0, 0, 0, 0); +} + +Rect Ctrl::GetPrimaryWorkArea() +{ + return GetVirtualScreenArea(); +} + +Rect Ctrl::GetPrimaryScreenArea() +{ + return GetVirtualScreenArea(); +} + +int Ctrl::GetKbdDelay() +{ + GuiLock __; + return 500; +} + +int Ctrl::GetKbdSpeed() +{ + GuiLock __; + return 1000 / 32; +} + +void Ctrl::DestroyWnd() +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(topctrl[i]->top && topctrl[i]->top->owner_window == this) + topctrl[i]->WndDestroy(); + int q = FindTopCtrl(); + if(q >= 0) { + Invalidate(); + topctrl.Remove(q); + } + if(top) { + delete top; + top = NULL; + } + isopen = false; + TopWindow *win = dynamic_cast(this); + if(win) + win->DestroyFrame(); +} + +void Ctrl::WndDestroy() +{ + DestroyWnd(); + if(topctrl.GetCount()) + topctrl.Top()->ActivateWnd(); +} + +void Ctrl::PutForeground() +{ + int q = FindTopCtrl(); + if(q >= 0) { + Invalidate(); + topctrl.Remove(q); + topctrl.Add(this); + } + Vector< Ptr > fw; + for(int i = 0; i < topctrl.GetCount(); i++) + if(topctrl[i] && topctrl[i]->top && topctrl[i]->top->owner_window == this && topctrl[i] != this) + fw.Add(topctrl[i]); + for(int i = 0; i < fw.GetCount(); i++) + if(fw[i]) + fw[i]->PutForeground(); +} + +void Ctrl::SetWndForeground() +{ + GuiLock __; + ASSERT(IsOpen()); + if(IsWndForeground()) + return; + Ctrl *to = this; + while(to->top && to->top->owner_window) + to = to->top->owner_window; + to->PutForeground(); + if(this != focusCtrl) + ActivateWnd(); +} + +bool Ctrl::IsWndForeground() const +{ + GuiLock __; + bool b = false; + for(int i = 0; i < topctrl.GetCount(); i++) { + const TopWindow *tw = dynamic_cast(topctrl[i]); + if(tw) + b = tw == this; + } + return b; +} + +void Ctrl::WndEnable(bool) +{ + GuiLock __; +} + +bool Ctrl::SetWndFocus() +{ + GuiLock __; + return true; +} + +bool Ctrl::HasWndFocus() const +{ + GuiLock __; + return focusCtrl && focusCtrl->GetTopCtrl() == this; +} + +bool Ctrl::SetWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::ReleaseWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::HasWndCapture() const +{ + GuiLock __; + return captureCtrl && captureCtrl->GetTopCtrl() == this; +} + +void Ctrl::WndInvalidateRect(const Rect&) +{ + GuiLock __; + Invalidate(); +} + +void Ctrl::WndSetPos(const Rect& rect) +{ + GuiLock __; + TopWindow *w = dynamic_cast(this); + if(w) + w->SyncFrameRect(rect); + Invalidate(); + SetWndRect(rect); +} + +void Ctrl::WndScrollView(const Rect& r, int dx, int dy) +{ + GuiLock __; + LLOG("ScrollView " << rect); + WndInvalidateRect(r); +} + +void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) +{ + ASSERT(!IsChild() && !IsOpen() && FindTopCtrl() < 0); + NewTop(); + if(owner) { + Ctrl *owner_window = owner->GetTopWindow(); + if(!owner_window) + owner_window = owner->GetTopCtrl(); + ASSERT(owner_window->IsOpen()); + if(owner_window != desktop) { + owner_window->SetForeground(); + top->owner_window = owner_window; + } + } + topctrl.Add(this); + popup = isopen = true; + RefreshLayoutDeep(); + if(activate) SetFocusWnd(); + Invalidate(); +} + +Rect Ctrl::GetDefaultWindowRect() { + GuiLock __; + static int ii = 0; + Rect rect = GetVirtualScreenArea(); + Size sz = rect.GetSize(); + rect.Deflate(sz / 10); + rect.Offset(Size(GetStdFontCy(), 2 * GetStdFontCy()) * (++ii % 8)); + return rect; +} + +Vector SplitCmdLine__(const char *cmd) +{ + Vector out; + while(*cmd) + if((byte)*cmd <= ' ') + cmd++; + else if(*cmd == '\"') { + WString quoted; + while(*++cmd && (*cmd != '\"' || *++cmd == '\"')) + quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString()); + out.Add(quoted); + } + else { + const char *begin = cmd; + while((byte)*cmd > ' ') + cmd++; + out.Add(String(begin, cmd).ToWString()); + } + return out; +} + +void Ctrl::InstallPanicBox() +{ +} + +void Ctrl::SysEndLoop() +{ +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/Telpp/init b/rainbow/Telpp/init new file mode 100644 index 000000000..a8de2d520 --- /dev/null +++ b/rainbow/Telpp/init @@ -0,0 +1,6 @@ +#ifndef _Telpp_icpp_init_stub +#define _Telpp_icpp_init_stub +#include "Painter/init" +#include "CtrlLib/init" +#include "GLDraw/init" +#endif diff --git a/rainbow/UWord/UWord.cpp b/rainbow/UWord/UWord.cpp index d32882e5c..2214a2135 100644 --- a/rainbow/UWord/UWord.cpp +++ b/rainbow/UWord/UWord.cpp @@ -261,6 +261,8 @@ void UWord::SerializeApp(Stream& s) GUI_APP_MAIN { + StdLogSetup(LOG_COUT|LOG_FILE); + SetLanguage(LNG_ENGLISH); SetDefaultCharset(CHARSET_UTF8); diff --git a/rainbow/UWord/UWord.upp b/rainbow/UWord/UWord.upp index a82e4094f..5fc33fcda 100644 --- a/rainbow/UWord/UWord.upp +++ b/rainbow/UWord/UWord.upp @@ -5,7 +5,8 @@ uses RichEdit, PdfDraw, plugin\jpg, - SDL20; + SDL20, + Telpp; uses(SKELETON) Skeleton; @@ -31,5 +32,6 @@ mainconfig "" = "GUI SDLFB", "" = "GUI WINGL", "" = "GUI", - "" = "GUI SDL20"; + "" = "GUI SDL20", + "" = "GUI TELPP"; diff --git a/rainbow/UWord/init b/rainbow/UWord/init index e752b0039..32ac46d1d 100644 --- a/rainbow/UWord/init +++ b/rainbow/UWord/init @@ -5,6 +5,7 @@ #include "PdfDraw/init" #include "plugin\jpg/init" #include "SDL20/init" +#include "Telpp/init" #include "Skeleton/init" #include "WinAlt/init" #include "WinFb/init" diff --git a/rainbow/guiplatform.h b/rainbow/guiplatform.h index a097ee2d7..b34419d64 100644 --- a/rainbow/guiplatform.h +++ b/rainbow/guiplatform.h @@ -46,3 +46,9 @@ //need to make SDL_keysym.h known before K_ enum #define GUIPLATFORM_INCLUDE #endif + +#ifdef flagTELPP +#define GUIPLATFORM_KEYCODES_INCLUDE +//need to make SDL_keysym.h known before K_ enum +#define GUIPLATFORM_INCLUDE +#endif