.Developing TURTLE

git-svn-id: svn://ultimatepp.org/upp/trunk@6713 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-01-01 18:38:55 +00:00
parent 097ab8ec58
commit c3da96adbd
31 changed files with 3328 additions and 3 deletions

View file

@ -1,5 +1,7 @@
#include "Local.h"
#ifdef GUI_TELPP
NAMESPACE_UPP
struct DrawDragRectInfo {
@ -92,3 +94,5 @@ void FinishDragRect(Ctrl& q)
}
END_UPP_NAMESPACE
#endif

View file

@ -1,4 +1,6 @@
#include "Telpp.h"
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_TELPP
NAMESPACE_UPP
@ -99,3 +101,5 @@ void SystemDraw::PutRect(const Rect& r, Color color)
}
END_UPP_NAMESPACE
#endif

View file

@ -223,6 +223,7 @@ document.onkeydown = function(event)
{
event_queue += "K " + event.keyCode + " " + event.which + key_flags(event);
Ping();
Ping();
}
document.onkeypress = function(event)

46
rainbow/Turtle/After.h Normal file
View file

@ -0,0 +1,46 @@
class ViewDraw : public SystemDraw {
public:
ViewDraw(Ctrl *ctrl);
~ViewDraw();
};
/*
class ViewDraw : public SystemDraw {
Vector<Rect> 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, const char **argv, const char **envptr) { \
UPP::AppInitEnvironment__(); \
UPP::Ctrl::InitTelpp(); \
GuiMainFn_(); \
UPP::Ctrl::CloseTopCtrls(); \
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

View file

@ -0,0 +1,21 @@
#include "Local.h"
#ifdef GUI_TURTLE
NAMESPACE_UPP
void ChSysInit()
{
CtrlImg::Reset();
CtrlsImg::Reset();
ChReset();
}
void ChHostSkin()
{
ChSysInit();
}
END_UPP_NAMESPACE
#endif

238
rainbow/Turtle/Clip.cpp Normal file
View file

@ -0,0 +1,238 @@
#include "Local.h"
#ifdef GUI_TURTLE
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
static VectorMap<String, ClipData> 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<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()
{
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<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;
}
return Null;
}
Image ReadClipboardImage()
{
GuiLock __;
PasteClip d = Ctrl::Clipboard();
return GetImage(d);
}
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 == ClipFmt<Image>())
return sImage(img);
return Null;
}
void AppendClipboardImage(const Image& img)
{
GuiLock __;
if(img.IsEmpty()) return;
AppendClipboard(ClipFmt<Image>(), 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<String> GetFiles(PasteClip& clip)
{
GuiLock __;
Vector<String> f;
return f;
}
END_UPP_NAMESPACE
#endif

81
rainbow/Turtle/Ctrl.cpp Normal file
View file

@ -0,0 +1,81 @@
#include "Local.h"
#ifdef GUI_TURTLE
#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

84
rainbow/Turtle/Ctrl.h Normal file
View file

@ -0,0 +1,84 @@
//$ class Ctrl {
private:
static Ptr<Ctrl> desktop;
static Vector<Ctrl *> 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<Rect>& 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<Ctrl> t, int event, Point p, int zdelta);
static void DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz,
const byte *pattern, int animation);
static void DragRectDraw0(const Vector<Rect>& clip, const Rect& rect, int n,
const byte *pattern, int animation);
static void ReadKeyMods(CParser& p);
static void DoMouseButton(int event, CParser& p);
static void DoMouseFB(int event, Point p, int zdelta, CParser& cp);
static void Reply();
friend struct PaintProxy__;
friend class TopWindowFrame;
friend class SystemDraw;
friend struct DnDLoop;
void SetOpen(bool b) { isopen = b; }
protected:
static int PaintLock;
public:
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);
//$ };

22
rainbow/Turtle/Cursor.cpp Normal file
View file

@ -0,0 +1,22 @@
#include "Local.h"
#ifdef GUI_TURTLE
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

150
rainbow/Turtle/DnD.cpp Normal file
View file

@ -0,0 +1,150 @@
#include "Local.h"
#ifdef GUI_TURTLE
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
// --------------------------------------------------------------------------------------------
Ptr<Ctrl> sDnDSource;
Ctrl * Ctrl::GetDragAndDropSource()
{
return sDnDSource;
}
struct DnDLoop : LocalLoop {
const VectorMap<String, ClipData> *data;
Vector<String> fmts;
Image move, copy, reject;
Ptr<Ctrl> 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> 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<Ctrl> 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<String, ClipData>& 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

105
rainbow/Turtle/Draw.cpp Normal file
View file

@ -0,0 +1,105 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_TURTLE
NAMESPACE_UPP
void SystemDraw::Put16(int x)
{
result.Cat(LOBYTE(x));
result.Cat(HIBYTE(x));
}
void SystemDraw::Put32(int x)
{
Put16(LOWORD(x));
Put16(HIWORD(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());
}
void SystemDraw::Put(const String& s)
{
Put32(s.GetLength());
result.Cat(s);
}
Index<int64> SystemDraw::img_index[3];
int SystemDraw::GetImageI(int from, Index<int64>& img_index, int maxcount, SystemDraw& w, const Image& img)
{
int64 id = img.GetSerialId();
int q = img_index.Find(id);
if(q < 0) {
if(img_index.GetCount() < maxcount) {
q = img_index.GetCount();
img_index.Add(id);
}
else {
q = Random(maxcount);
img_index.Set(q, id);
}
w.Put8(SETIMAGE);
w.Put16(q + from);
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 + from;
}
int SystemDraw::GetImageI(SystemDraw& w, const Image& img)
{
int area = img.GetWidth() * img.GetHeight();
return area <= 64*64 ? GetImageI(0, img_index[0], 2048, w, img) :
area <= 512 * 512 ? GetImageI(2048, img_index[1], 64, w, img) :
GetImageI(2048 + 64, img_index[2], 8, w, img);
}
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
if(color == InvertColor()) {
Put8(INVERTRECT);
Put(r);
}
else {
Put8(RECT);
Put(r);
Put8(color.GetR());
Put8(color.GetG());
Put8(color.GetB());
}
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,98 @@
#include "Local.h"
#ifdef GUI_TURTLE
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
#endif

482
rainbow/Turtle/Event.cpp Normal file
View file

@ -0,0 +1,482 @@
#include "Local.h"
#include "Turtle.brc"
#ifdef GUI_TURTLE
NAMESPACE_UPP
#define LLOG(x) DLOG(x)
#define LDUMP(x) DDUMP(x)
#define LTIMING(x)
static Point MousePos;
Size DesktopSize = Size(1000, 1000);
StaticRect& Desktop()
{
static StaticRect x;
return x;
}
HttpHeader http;
TcpSocket server;
TcpSocket socket;
WebSocket websocket;
String content;
void Ctrl::InitTelpp()
{
if(!server.Listen(8088, 10)) {
LOG("Cannot open server port for listening\r\n");
return;
}
LLOG("Starting to listen");
socket.Timeout(20000);
for(;;) {
if(socket.Accept(server)) {
if(http.Read(socket)) {
LLOG("Accepted, header read");
if(websocket.WebAccept(socket, http))
break;
LLOG("Sending HTML");
HttpResponse(socket, http.scgi, 200, "OK", "text/html", String(turtle_html, turtle_html_length));
}
socket.Close();
}
}
LLOG("WebSocket connected");
Ctrl::GlobalBackBuffer();
Ctrl::InitTimer();
#ifdef PLATFORM_POSIX
SetStdFont(ScreenSans(12)); //FIXME general handling
#endif
ChStdSkin();
Desktop().Color(Cyan());
Desktop().SetRect(0, 0, DesktopSize.cx, DesktopSize.cy);
SetDesktop(Desktop());
}
void Ctrl::Reply()
{
GuiLock __;
if(websocket.IsOpen()) {
TimerProc(GetTickCount());
DefferedFocusSync();
SyncCaret();
SyncTopWindows();
SweepMkImageCache();
DoPaint();
// String s = GZCompress(content);
String s = content;
websocket.SendBinary(s);
}
}
bool Ctrl::IsWaitingEvent()
{
GuiLock __;
Reply();
return socket.Timeout(0).Peek() >= 0;
}
bool Ctrl::ProcessEvents(bool *quit)
{
GuiLock __;
LLOG("ProcessEvents");
if(!IsWaitingEvent())
return false;
TimeStop tm;
LLOG("Trying to read socket");
String event_queue = websocket.Recieve();
LLOG("---- Process events");
if(event_queue.GetCount())
LOG(event_queue);
content.Clear();
bool r = ProcessEventQueue(event_queue);
_TODO_ // Resolve eventloop exit issue
Reply();
return r;
}
void Ctrl::GuiSleep(int ms)
{
GuiLock __;
Reply();
ASSERT(IsMainThread());
// LLOG("GuiSleep");
int level = LeaveGuiMutexAll();
Sleep(ms); _TODO_
EnterGuiMutex(level);
}
dword lastbdowntime[8] = {0};
dword isdblclick[8] = {0};
void Ctrl::MouseEventFB(Ptr<Ctrl> t, int event, Point p, int zdelta)
{
if(!t->IsEnabled())
return;
Rect rr = t->GetRect();
if((event & Ctrl::ACTION) == DOWN) {
Ptr<Ctrl> q = t;
TopWindowFrame *wf = dynamic_cast<TopWindowFrame *>(~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::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();
}
}
void Ctrl::PaintScene(SystemDraw& draw)
{
if(!desktop)
return;
LLOG("@ DoPaint");
LTIMING("DoPaint paint");
draw.Init(DesktopSize);
draw.Begin();
Vector<Rect> invalid;
invalid.Add(DesktopSize); _TODO_
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);
int64 q = fbCursorImage.GetAuxData();
if(q) {
draw.Put8(SystemDraw::STD_CURSORIMAGE);
draw.Put8(clamp((int)q, 1, 16));
}
else {
String h;
Point p = fbCursorImage.GetHotSpot();
h << "url('data:image/png;base64,"
<< Base64Encode(PNGEncoder().SaveString(fbCursorImage))
<< "') " << p.x << ' ' << p.y << ", default";
draw.Put8(SystemDraw::SETCURSORIMAGE);
draw.Put16(0); // _TODO_ Cursor cache
draw.Put(h);
draw.Put8(SystemDraw::CURSORIMAGE);
draw.Put16(0); // _TODO_ Cursor cache
}
}
void Ctrl::DoPaint()
{
if(!PaintLock) {
if(invalid && desktop) {
invalid = false;
SystemDraw draw;
PaintScene(draw);
PaintCaretCursor(draw);
content << String(draw.result);
}
}
}
bool keyShift;
bool keyCtrl;
bool keyAlt;
bool GetShift() { return keyShift; }
bool GetCtrl() { return keyCtrl; }
bool GetAlt() { return keyAlt; }
bool GetCapsLock() { return false; } // Impossible to implement
dword fbKEYtoK(dword chr) {
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;
/*
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;
*/
}
void Ctrl::ReadKeyMods(CParser& p)
{
const char *s = p.GetPtr();
if(*s)
keyShift = *s++ == '1';
if(*s)
keyCtrl = *s++ == '1';
if(*s)
keyAlt = *s++ == '1';
}
bool Ctrl::DoKeyFB(dword key, int cnt)
{
LLOG("DoKeyFB [" << GetKeyDesc(key) << "] " << key << ", " << cnt);
bool b = DispatchKey(key, cnt);
SyncCaret();
Ctrl *desktop = GetDesktop();
if(desktop)
desktop->PostInput();
return b;
}
bool mouseLeft, mouseMiddle, mouseRight;
Point mouseDownPos;
int64 mouseDownTime;
bool GetMouseLeft() { return mouseLeft; }
bool GetMouseRight() { return mouseRight; }
bool GetMouseMiddle() { return mouseMiddle; }
void Ctrl::DoMouseFB(int event, Point p, int zdelta, CParser& cp)
{
ReadKeyMods(cp);
MousePos = p;
int a = event & ACTION;
if(a == UP && Ctrl::ignoreclick) {
EndIgnore();
return;
}
else
if(a == 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<Ctrl> 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();
}
}
static int sDistMax(Point a, Point b)
{
return IsNull(a) ? INT_MAX : max(abs(a.x - b.x), abs(a.y - b.y));
}
Point ReadPoint(CParser& p)
{
Point pt;
pt.x = p.ReadInt();
pt.y = p.ReadInt();
return pt;
}
void Ctrl::DoMouseButton(int event, CParser& p)
{
int button = p.ReadInt();
Point pt = ReadPoint(p);
int64 tm = p.ReadInt64();
(button == 0 ? mouseLeft : button == 2 ? mouseRight : mouseMiddle) = event == DOWN;
if(event == DOWN)
if(sDistMax(mouseDownPos, pt) < GUI_DragDistance() && tm - mouseDownTime < 800) {
event = DOUBLE;
mouseDownTime = 0;
}
else {
mouseDownPos = pt;
mouseDownTime = tm;
}
DoMouseFB(decode(button, 0, LEFT, 2, RIGHT, MIDDLE)|event, pt, 0, p);
}
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("I"))
SystemDraw::ResetI();
else
if(p.Id("R")) {
DesktopSize = ReadPoint(p);
Desktop().SetRect(0, 0, DesktopSize.cx, DesktopSize.cy);
}
if(p.Id("M")) {
Point pt = ReadPoint(p);
int64 tm = p.ReadInt64();
DoMouseFB(MOUSEMOVE, pt, 0, p);
}
else
if(p.Id("W")) {
double w = p.ReadDouble();
Point pt = ReadPoint(p);
int64 tm = p.ReadInt64();
DoMouseFB(MOUSEWHEEL, pt, w < 0 ? 120 : -120, p);
}
else
if(p.Id("O")) {
mouseLeft = mouseMiddle = mouseRight = false;
mouseDownTime = 0;
}
else
if(p.Id("D")) {
DoMouseButton(DOWN, p);
}
else
if(p.Id("U")) {
DoMouseButton(UP, p);
}
else
if(p.Id("K")) {
int code = p.ReadInt();
int which = p.ReadInt();
ReadKeyMods(p);
DoKeyFB(fbKEYtoK(which), 1);
}
else
if(p.Id("k")) {
int code = p.ReadInt();
int which = p.ReadInt();
ReadKeyMods(p);
DoKeyFB(K_KEYUP|fbKEYtoK(which), 1);
}
else
if(p.Id("C")) {
int code = p.ReadInt();
int which = p.ReadInt();
ReadKeyMods(p);
if(which && !keyAlt && !keyCtrl)
DoKeyFB(which, 1);
}
}
catch(CParser::Error) {}
}
return true;
}
Point GetMousePos() {
return MousePos;
}
void Ctrl::EventLoop(Ctrl *ctrl)
{
GuiLock __;
Reply();
ASSERT(IsMainThread());
ASSERT(LoopLevel == 0 || ctrl);
LoopLevel++;
LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN);
Ptr<Ctrl> 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 ");
}
END_UPP_NAMESPACE
#endif

63
rainbow/Turtle/FB.iml Normal file
View file

@ -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)

358
rainbow/Turtle/Gui.h Normal file
View file

@ -0,0 +1,358 @@
#define GUI_TURTLE
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<Cloff> {
Point org;
HRGN hrgn;
Rect drawingclip;
};
Array<Cloff> 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 <ShellAPI.h>
#endif
#endif
#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h"

47
rainbow/Turtle/Image.cpp Normal file
View file

@ -0,0 +1,47 @@
#include <CtrlCore/CtrlCore.h>
#ifdef GUI_TURTLE
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 <Turtle/FB.iml>
#include <Draw/iml_source.h>
#define STD_CURSOR(name, sdl) \
Image Image::name() { static Image img; ONCELOCK { img = FBImg::name(); img.SetAuxData(sdl); } 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

113
rainbow/Turtle/Keys.h Normal file
View file

@ -0,0 +1,113 @@
#define WEBKEY(x) x
K_BACK = WEBKEY(8) + K_DELTA,
K_BACKSPACE = WEBKEY(8) + 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(16) + K_DELTA,
K_CTRL_KEY = WEBKEY(17) + K_DELTA,
K_ALT_KEY = WEBKEY(18) + K_DELTA,
K_CAPSLOCK = WEBKEY(20) + K_DELTA,
K_ESCAPE = WEBKEY(27) + K_DELTA,
K_PRIOR = WEBKEY(33) + K_DELTA,
K_PAGEUP = WEBKEY(33) + K_DELTA,
K_NEXT = WEBKEY(34) + K_DELTA,
K_PAGEDOWN = WEBKEY(34) + K_DELTA,
K_END = WEBKEY(35) + K_DELTA,
K_HOME = WEBKEY(36) + K_DELTA,
K_LEFT = WEBKEY(37) + K_DELTA,
K_UP = WEBKEY(38) + K_DELTA,
K_RIGHT = WEBKEY(39) + K_DELTA,
K_DOWN = WEBKEY(40) + K_DELTA,
K_INSERT = WEBKEY(45) + K_DELTA,
K_DELETE = WEBKEY(46) + K_DELTA,
K_NUMPAD0 = WEBKEY(96) + K_DELTA,
K_NUMPAD1 = WEBKEY(97) + K_DELTA,
K_NUMPAD2 = WEBKEY(98) + K_DELTA,
K_NUMPAD3 = WEBKEY(99) + K_DELTA,
K_NUMPAD4 = WEBKEY(100) + K_DELTA,
K_NUMPAD5 = WEBKEY(101) + K_DELTA,
K_NUMPAD6 = WEBKEY(102) + K_DELTA,
K_NUMPAD7 = WEBKEY(103) + K_DELTA,
K_NUMPAD8 = WEBKEY(104) + K_DELTA,
K_NUMPAD9 = WEBKEY(105) + K_DELTA,
K_MULTIPLY = WEBKEY(106) + K_DELTA,
K_ADD = WEBKEY(107) + K_DELTA,
K_SEPARATOR = WEBKEY(108) + K_DELTA,
K_SUBTRACT = WEBKEY(109) + K_DELTA,
K_DECIMAL = WEBKEY(110) + K_DELTA,
K_DIVIDE = WEBKEY(111) + K_DELTA,
K_SCROLL = WEBKEY(145) + K_DELTA,
K_F1 = WEBKEY(112) + K_DELTA,
K_F2 = WEBKEY(113) + K_DELTA,
K_F3 = WEBKEY(114) + K_DELTA,
K_F4 = WEBKEY(115) + K_DELTA,
K_F5 = WEBKEY(116) + K_DELTA,
K_F6 = WEBKEY(117) + K_DELTA,
K_F7 = WEBKEY(118) + K_DELTA,
K_F8 = WEBKEY(119) + K_DELTA,
K_F9 = WEBKEY(120) + K_DELTA,
K_F10 = WEBKEY(121) + K_DELTA,
K_F11 = WEBKEY(122) + K_DELTA,
K_F12 = WEBKEY(123) + K_DELTA,
K_A = WEBKEY('A') + K_DELTA,
K_B = WEBKEY('B') + K_DELTA,
K_C = WEBKEY('C') + K_DELTA,
K_D = WEBKEY('D') + K_DELTA,
K_E = WEBKEY('E') + K_DELTA,
K_F = WEBKEY('F') + K_DELTA,
K_G = WEBKEY('G') + K_DELTA,
K_H = WEBKEY('H') + K_DELTA,
K_I = WEBKEY('I') + K_DELTA,
K_J = WEBKEY('J') + K_DELTA,
K_K = WEBKEY('K') + K_DELTA,
K_L = WEBKEY('L') + K_DELTA,
K_M = WEBKEY('M') + K_DELTA,
K_N = WEBKEY('N') + K_DELTA,
K_O = WEBKEY('O') + K_DELTA,
K_P = WEBKEY('P') + K_DELTA,
K_Q = WEBKEY('Q') + K_DELTA,
K_R = WEBKEY('R') + K_DELTA,
K_S = WEBKEY('S') + K_DELTA,
K_T = WEBKEY('T') + K_DELTA,
K_U = WEBKEY('U') + K_DELTA,
K_V = WEBKEY('V') + K_DELTA,
K_W = WEBKEY('W') + K_DELTA,
K_X = WEBKEY('X') + K_DELTA,
K_Y = WEBKEY('Y') + K_DELTA,
K_Z = WEBKEY('Z') + K_DELTA,
K_0 = WEBKEY('0') + K_DELTA,
K_1 = WEBKEY('1') + K_DELTA,
K_2 = WEBKEY('2') + K_DELTA,
K_3 = WEBKEY('3') + K_DELTA,
K_4 = WEBKEY('4') + K_DELTA,
K_5 = WEBKEY('5') + K_DELTA,
K_6 = WEBKEY('6') + K_DELTA,
K_7 = WEBKEY('7') + K_DELTA,
K_8 = WEBKEY('8') + K_DELTA,
K_9 = WEBKEY('9') + K_DELTA,
K_CTRL_LBRACKET = K_CTRL|219|K_DELTA,
K_CTRL_RBRACKET = K_CTRL|221|K_DELTA,
K_CTRL_MINUS = K_CTRL|189|K_DELTA,
K_CTRL_GRAVE = K_CTRL|192|K_DELTA,
K_CTRL_SLASH = K_CTRL|191|K_DELTA,
K_CTRL_BACKSLASH = K_CTRL|220|K_DELTA,
K_CTRL_COMMA = K_CTRL|188|K_DELTA,
K_CTRL_PERIOD = K_CTRL|190|K_DELTA,
K_CTRL_SEMICOLON = K_CTRL|59|K_DELTA,
K_CTRL_EQUAL = K_CTRL|61|K_DELTA,
K_CTRL_APOSTROPHE= K_CTRL|222|K_DELTA,
K_BREAK = WEBKEY(3) + K_DELTA, // Is it really?

63
rainbow/Turtle/Local.h Normal file
View file

@ -0,0 +1,63 @@
#include <CtrlLib/CtrlLib.h>
#ifdef GUI_TURTLE
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

12
rainbow/Turtle/Socket.cpp Normal file
View file

@ -0,0 +1,12 @@
#include "Local.h"
#define LLOG(x) DLOG(x)
#ifdef GUI_TURTLE
NAMESPACE_UPP
END_UPP_NAMESPACE
#endif

152
rainbow/Turtle/Top.cpp Normal file
View file

@ -0,0 +1,152 @@
#include "Local.h"
#ifdef GUI_TURTLE
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

16
rainbow/Turtle/Top.h Normal file
View file

@ -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();
//$ };

236
rainbow/Turtle/TopFrame.cpp Normal file
View file

@ -0,0 +1,236 @@
#include "Local.h"
#ifdef GUI_TURTLE
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

View file

@ -0,0 +1 @@
BINARY(turtle_html, "Turtle.html")

131
rainbow/Turtle/Turtle.h Normal file
View file

@ -0,0 +1,131 @@
#define GUI_TURTLE
#define _TODO_ // _DBG_
#include <Draw/Draw.h>
#ifdef PLATFORM_POSIX
#include <CtrlCore/stdids.h>
#endif
NAMESPACE_UPP
#define IMAGECLASS FBImg
#define IMAGEFILE <Turtle/FB.iml>
#include <Draw/iml_header.h>
class 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,
INVERTRECT = 3,
STD_CURSORIMAGE = 4,
SETCURSORIMAGE = 5,
CURSORIMAGE = 6,
};
static Index<int64> img_index[3];
static int GetImageI(int from, Index<int64>& img_index, int maxcount, SystemDraw& w, const Image& img);
static int GetImageI(SystemDraw& w, const Image& img);
static void ResetI() { for(int i = 0; i < 3; i++) img_index[i].Clear(); }
StringBuffer result;
void Put8(int x) { result.Cat(x); }
void Put16(int x);
void Put32(int x);
void Put(Point p);
void Put(Size sz);
void Put(const Rect& r);
void Put(const String& s);
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 <Turtle/Ctrl.h>
#define GUIPLATFORM_PASTECLIP_DECLS \
bool dnd; \
friend struct DnDLoop; \
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Turtle/Top.h>
class PrinterJob { // Dummy only...
NilDraw nil;
Vector<int> pages;
public:
Draw& GetDraw() { return nil; }
operator Draw&() { return GetDraw(); }
const Vector<int>& 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 <Turtle/After.h>

293
rainbow/Turtle/Turtle.html Normal file
View file

@ -0,0 +1,293 @@
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="1000" height="1000" style="border:0px" tabindex="1" oncontextmenu="return false;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
function Log(msg)
{
// if (window.console && console.log)
// console.log(msg); //for firebug
}
function Char(p, ch)
{
if(p.pos < p.data.length && (255 & p.data[p.pos]) == ch) {
p.pos++;
return true;
}
return false;
}
function Get8(p)
{
return p.pos < p.data.length ? (255 & p.data[p.pos++]) : 0;
}
function Get16(p)
{
var l = Get8(p);
var h = Get8(p);
return (h << 8) | l;
}
function Get32(p)
{
var l = Get16(p);
var h = Get16(p);
return (h << 16) | l;
}
function GetString(p)
{
var n = Get32(p);
var s = "";
for(var i = 0; i < n; i++)
s += String.fromCharCode(Get8(p));
return s;
}
function ProcessDraw(s)
{
var x, y, cx, cy, r, g, b, imgData, i, n, px, py;
var p = new Object;
p.data = s;
p.pos = 0;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
while(p.pos < p.data.length) {
Log(p.pos + ": " + p.data[p.pos]);
if(Char(p, 0)) {
x = Get16(p);
y = Get16(p);
cx = Get16(p);
cy = Get16(p);
r = Get8(p);
g = Get8(p);
b = Get8(p);
Log("rect: " + x + ", " + y + ", " + cx + ", " + cy);
var c = "rgb(" + r + "," + g + "," + b + ")";
ctx.fillStyle = c;
Log("color: " + c);
ctx.fillRect(x, y, cx, cy);
}
else
if(Char(p, 3)) {
x = Get16(p);
y = Get16(p);
cx = Get16(p);
cy = Get16(p);
Log("irect: " + x + ", " + y + ", " + cx + ", " + cy);
var imageData = ctx.getImageData(x, y, cx, cy);
var data = imageData.data;
for(var i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i];
data[i + 1] = 255 - data[i + 1];
data[i + 2] = 255 - data[i + 2];
}
ctx.putImageData(imageData, x, y);
}
else
if(Char(p, 2)) {
r = Get16(p);
cx = Get16(p);
cy = Get16(p);
n = cx * cy * 4;
imgData = ctx.createImageData(cx, cy);
for(i = 0; i < n; i++)
imgData.data[i] = Get8(p);
var img = document.createElement('canvas');
img.width = cx;
img.height = cy;
img.getContext("2d").putImageData(imgData, 0, 0);
window.img_cache[r] = img;
Log("Set image: " + r);
}
else
if(Char(p, 1)) {
n = Get16(p);
px = Get16(p);
py = Get16(p);
x = Get16(p);
y = Get16(p);
cx = Get16(p);
cy = Get16(p);
Log("Draw image: " + n);
ctx.drawImage(window.img_cache[n], x, y, cx, cy, px, py, cx, cy);
}
else
if(Char(p, 4)) {
canvas.style.cursor = [
"default", // should not happen
"default", // Arrow
"wait", // Wait
"text", // IBeam
"not-allowed", // No
"move", // SizeAll
"ew-resize", // SizeHorz
"ns-resize", // SizeVert
"nw-resize", // SizeTopLeft
"n-resize", // SizeTop
"ne-resize", // SizeTopRight
"w-resize", // SizeLeft
"e-resize", // SizeRight
"sw-resize", // SizeBottomLeft
"s-resize", // SizeBottom
"se-resize", // SizeBottomRight
"pointer" // Hand
][Get8(p)];
}
else
if(Char(p, 5)) {
i = Get16(p);
cursor_cache[i] = GetString(p);
}
else
if(Char(p, 6)) {
i = Get16(p);
canvas.style.cursor = cursor_cache[i];
Log(cursor_cache[i]);
}
}
}
window.img_cache = {};
window.event_queue = "I\n";
window.cursor_cache = {};
var canvas = document.getElementById("myCanvas");
function key_flags(event)
{
return " " + 1*event.shiftKey + 1*event.ctrlKey + 1*event.altKey + "\n";
}
function mouse_event(event)
{
return " " + event.clientX + " " + event.clientY + " " + (new Date).getTime() + key_flags(event);
}
canvas.onmousemove = function(event)
{
event_queue += "M" + mouse_event(event);
Ping();
event.preventDefault();
}
canvas.onmousedown = function(event)
{
event_queue += "D " + event.button + mouse_event(event);
Ping();
event.preventDefault();
}
canvas.onmouseout = function(event)
{
event_queue += "O\n";
Ping();
event.preventDefault();
}
canvas.onmouseup = function(event)
{
event_queue += "U " + event.button + mouse_event(event);
Ping();
event.preventDefault();
}
canvas.onwheel = function(event)
{
event_queue += "W " + event.deltaY + mouse_event(event);
}
document.onkeydown = function(event)
{
event_queue += "K " + event.keyCode + " " + event.which + key_flags(event);
Ping();
}
document.onkeypress = function(event)
{
event_queue += "C " + event.keyCode + " " + event.which + key_flags(event);
event.preventDefault();
Ping();
}
document.onkeyup = function(event)
{
event_queue += "k " + event.keyCode + " " + event.which + key_flags(event);
event.preventDefault();
Ping();
}
function ResizeCanvas()
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
event_queue += "R " + canvas.width + ' ' + canvas.height + "\n";
Ping();
}
window.onresize = ResizeCanvas;
var Processing = false;
var timerID;
var ws = new WebSocket("ws://localhost:8088");
ws.binaryType = "arraybuffer";
function Ping()
{
if(!Processing) {
Processing = true;
ws.send(event_queue);
event_queue = "";
}
if(timerID != undefined)
clearTimeout(timerID);
timerID = setTimeout(Ping, 20);
// Log("Ping");
}
ws.onopen = function() {
ResizeCanvas();
};
ws.onmessage = function(event) {
if(event.data instanceof ArrayBuffer) {
var a = new Uint8Array(event.data);
ProcessDraw(a);
}
Processing = false;
};
ws.onclose = function(ev) {
alert("Connection closed");
};
ws.onerror = function(ev) {
alert("Connection error: " + ev.reason);
};
</script>
</body>
</html>

30
rainbow/Turtle/Turtle.upp Normal file
View file

@ -0,0 +1,30 @@
description "HTML5 backend\377";
uses
Painter,
CtrlLib;
file
Turtle.h,
Keys.h,
After.h,
Local.h,
Draw.cpp,
Image.cpp,
FB.iml,
Ctrl.h,
DrawDragRect.cpp,
Ctrl.cpp,
Wnd.cpp,
Cursor.cpp,
Socket.cpp,
Event.cpp,
Top.h,
TopFrame.cpp,
Top.cpp,
Clip.cpp,
DnD.cpp,
ChSysInit.cpp,
Turtle.brc,
Turtle.html;

459
rainbow/Turtle/Wnd.cpp Normal file
View file

@ -0,0 +1,459 @@
#include "Local.h"
#ifdef GUI_TURTLE
NAMESPACE_UPP
#define LLOG(x) LOG(x)
#define LDUMP(x) //DDUMP(x)
#define LDUMPC(x) //DDUMPC(x)
#define LTIMING(x) RTIMING(x)
Ptr<Ctrl> Ctrl::desktop;
Vector<Ctrl *> 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 *> Ctrl::GetTopCtrls()
{
Vector<Ctrl *> ctrl;
if(desktop)
ctrl.Add(desktop);
for(int i = 0; i < topctrl.GetCount(); i++)
if(!dynamic_cast<TopWindowFrame *>(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<TopWindowFrame *>(x) ? x->GetOwner() : x;
}
return NULL;
}
Ctrl *Ctrl::GetActiveCtrl()
{
GuiLock __;
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
}
// Vector<Callback> 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<TopWindow *>(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<Rect>& 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<Rect>& rc)
{
GuiLock __;
Array<Rect> 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<TopWindow *>(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<Ctrl> > 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<const TopWindow *>(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<TopWindow *>(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<WString> SplitCmdLine__(const char *cmd)
{
Vector<WString> 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

5
rainbow/Turtle/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _Turtle_icpp_init_stub
#define _Turtle_icpp_init_stub
#include "Painter/init"
#include "CtrlLib/init"
#endif

View file

@ -2,11 +2,13 @@ uses
Core,
Telpp,
plugin/DroidFonts,
RichEdit;
RichEdit,
Turtle,
PdfDraw;
file
WebWord.cpp;
mainconfig
"" = "SSE2 TELPP RAINBOW";
"" = "SSE2 TURTLE RAINBOW";

View file

@ -4,4 +4,6 @@
#include "Telpp/init"
#include "plugin/DroidFonts/init"
#include "RichEdit/init"
#include "Turtle/init"
#include "PdfDraw/init"
#endif

View file

@ -52,3 +52,9 @@
//need to make SDL_keysym.h known before K_ enum
#define GUIPLATFORM_INCLUDE <Telpp/Telpp.h>
#endif
#ifdef flagTURTLE
#define GUIPLATFORM_KEYCODES_INCLUDE <Turtle/Keys.h>
//need to make SDL_keysym.h known before K_ enum
#define GUIPLATFORM_INCLUDE <Turtle/Turtle.h>
#endif