diff --git a/rainbow/Telpp/Ctrl.h b/rainbow/Telpp/Ctrl.h index ba0c5135c..9d667ed32 100644 --- a/rainbow/Telpp/Ctrl.h +++ b/rainbow/Telpp/Ctrl.h @@ -35,6 +35,7 @@ private: static void DragRectDraw0(const Vector& 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); diff --git a/rainbow/Telpp/Event.cpp b/rainbow/Telpp/Event.cpp index cf11e66c4..0ee12debf 100644 --- a/rainbow/Telpp/Event.cpp +++ b/rainbow/Telpp/Event.cpp @@ -46,59 +46,6 @@ Point GetMousePos() { return MousePos; } -bool mouseButtons; - -bool GetMouseLeft() { return mouseButtons & 1; } -bool GetMouseRight() { return mouseButtons & 2; } -bool GetMouseMiddle() { return mouseButtons & 4; } - -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 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) { - return chr + K_DELTA; -/* - 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}; @@ -133,18 +80,6 @@ Ctrl *Ctrl::FindMouseTopCtrl() return desktop->IsEnabled() ? desktop : NULL; } -bool Ctrl::DoKeyFB(dword key, int cnt) -{ - DLOG("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 __; @@ -209,8 +144,24 @@ void Ctrl::PaintCaretCursor(SystemDraw& draw) { if(!IsNull(fbCaretRect)) draw.DrawRect(fbCaretRect, InvertColor); - if(sdlMouseIsIn && !SystemCursor) - draw.DrawImage(fbCursorPos.x, fbCursorPos.y, fbCursorImage); + 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"; + DDUMP(h); + 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() @@ -226,9 +177,72 @@ void Ctrl::DoPaint() } } +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) +{ + DLOG("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) { - mouseButtons = cp.ReadInt(); + ReadKeyMods(cp); MousePos = p; int a = event & ACTION; if(a == UP && Ctrl::ignoreclick) { @@ -257,12 +271,29 @@ void Ctrl::DoMouseFB(int event, Point p, int zdelta, CParser& cp) } } +static int sDistMax(Point a, Point b) +{ + return IsNull(a) ? INT_MAX : max(abs(a.x - b.x), abs(a.y - b.y)); +} + void Ctrl::DoMouseButton(int event, CParser& p) { int button = p.ReadInt(); int x = p.ReadInt(); int y = p.ReadInt(); - DoMouseFB(decode(button, 0, LEFT, 2, RIGHT, MIDDLE)|event, Point(x, y), 0, p); + Point pt(x, y); + 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) @@ -278,9 +309,15 @@ bool Ctrl::ProcessEventQueue(const String& event_queue) if(p.Id("M")) { int x = p.ReadInt(); int y = p.ReadInt(); + int64 tm = p.ReadInt64(); DoMouseFB(MOUSEMOVE, Point(x, y), 0, p); } else + if(p.Id("O")) { + mouseLeft = mouseMiddle = mouseRight = false; + mouseDownTime = 0; + } + else if(p.Id("D")) { DoMouseButton(DOWN, p); } @@ -292,19 +329,23 @@ bool Ctrl::ProcessEventQueue(const String& event_queue) if(p.Id("K")) { int code = p.ReadInt(); int which = p.ReadInt(); - DoKeyFB(which + K_DELTA, 1); + ReadKeyMods(p); + DoKeyFB(fbKEYtoK(which), 1); } else if(p.Id("k")) { int code = p.ReadInt(); int which = p.ReadInt(); - DoKeyFB(K_KEYUP|(which + K_DELTA), 1); + ReadKeyMods(p); + DoKeyFB(K_KEYUP|fbKEYtoK(which), 1); } else if(p.Id("C")) { int code = p.ReadInt(); int which = p.ReadInt(); - DoKeyFB(which, 1); + ReadKeyMods(p); + if(which && !keyAlt && !keyCtrl) + DoKeyFB(which, 1); } } catch(CParser::Error) {} @@ -358,6 +399,7 @@ bool Ctrl::ProcessEvents(bool *quit) return false; } String event_queue = socket.Get((int)http.GetContentLength()); + LLOG("---- Process events"); if(event_queue.GetCount()) LOG(event_queue); content.Clear(); diff --git a/rainbow/Telpp/Image.cpp b/rainbow/Telpp/Image.cpp index f7b274f1a..a3654a1a9 100644 --- a/rainbow/Telpp/Image.cpp +++ b/rainbow/Telpp/Image.cpp @@ -23,7 +23,7 @@ void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, P #include #define STD_CURSOR(name, sdl) \ -Image Image::name() { static Image img; ONCELOCK { img = FBImg::name(); img.SetAuxData(sdl + 1); } return img; } +Image Image::name() { static Image img; ONCELOCK { img = FBImg::name(); img.SetAuxData(sdl); } return img; } STD_CURSOR(Arrow, 1) STD_CURSOR(Wait, 2) diff --git a/rainbow/Telpp/TelDraw.cpp b/rainbow/Telpp/TelDraw.cpp index 928c6bba8..8c6055152 100644 --- a/rainbow/Telpp/TelDraw.cpp +++ b/rainbow/Telpp/TelDraw.cpp @@ -8,6 +8,12 @@ void SystemDraw::Put16(int 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); @@ -25,6 +31,12 @@ void SystemDraw::Put(const Rect& r) Put(r.GetSize()); } +void SystemDraw::Put(const String& s) +{ + Put32(s.GetLength()); + result.Cat(s); +} + Index SystemDraw::img_index; int SystemDraw::GetImageI(SystemDraw& w, const Image& img) @@ -59,11 +71,17 @@ void SystemDraw::PutImage(Point p, const Image& img, const Rect& 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()); + if(color == InvertColor()) { + Put8(INVERTRECT); + Put(r); + } + else { + Put8(RECT); + Put(r); + Put8(color.GetR()); + Put8(color.GetG()); + Put8(color.GetB()); + } } END_UPP_NAMESPACE diff --git a/rainbow/Telpp/Telpp.h b/rainbow/Telpp/Telpp.h index ed998461f..54f37f264 100644 --- a/rainbow/Telpp/Telpp.h +++ b/rainbow/Telpp/Telpp.h @@ -24,6 +24,10 @@ public: RECT = 0, IMAGE = 1, SETIMAGE = 2, + INVERTRECT = 3, + STD_CURSORIMAGE = 4, + SETCURSORIMAGE = 5, + CURSORIMAGE = 6, }; static Index img_index; @@ -35,9 +39,11 @@ public: 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() {} diff --git a/rainbow/Telpp/Telpp.html b/rainbow/Telpp/Telpp.html index cf545efbb..3891227f5 100644 --- a/rainbow/Telpp/Telpp.html +++ b/rainbow/Telpp/Telpp.html @@ -22,7 +22,7 @@ Your browser does not support the HTML5 canvas tag. function Log(msg) { // if (window.console && console.log) - // console.log(msg); //for firebug +// console.log(msg); //for firebug } function Char(p, ch) @@ -46,6 +46,22 @@ function Get16(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; @@ -53,9 +69,9 @@ function ProcessDraw(s) p.text = s; p.pos = 0; - var c = document.getElementById("myCanvas"); - var ctx = c.getContext("2d"); - + var canvas = document.getElementById("myCanvas"); + var ctx = canvas.getContext("2d"); + while(p.pos < p.text.length) { Log(p.pos + ": " + p.text.charCodeAt(p.pos)); if(Char(p, 0)) { @@ -73,6 +89,22 @@ function ProcessDraw(s) 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); @@ -102,11 +134,45 @@ function ProcessDraw(s) 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"); @@ -117,31 +183,40 @@ function key_flags(event) function mouse_event(event) { - return " " + event.clientX + " " + event.clientY + " " + event.buttons + key_flags(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(); } document.onkeydown = function(event) { event_queue += "K " + event.keyCode + " " + event.which + key_flags(event); -// event.preventDefault(); Ping(); } @@ -152,7 +227,6 @@ document.onkeypress = function(event) Ping(); } - document.onkeyup = function(event) { event_queue += "k " + event.keyCode + " " + event.which + key_flags(event); @@ -190,7 +264,8 @@ function Ping() } if(timerID != undefined) clearTimeout(timerID); - setTimeout(Ping, 20); + timerID = setTimeout(Ping, 20); +// Log("Ping"); } ResizeCanvas(); diff --git a/rainbow/UWord/UWord.cpp b/rainbow/UWord/UWord.cpp index 8966d3ab7..59d65ed9e 100644 --- a/rainbow/UWord/UWord.cpp +++ b/rainbow/UWord/UWord.cpp @@ -258,16 +258,61 @@ void UWord::SerializeApp(Stream& s) s % lrufile(); } +struct EventsWnd : TopWindow { + Label l; + String k; + + + Image CursorImage(Point p, dword keyflags) + { + return UWordImg::pdf(); + } + + void Do() { + static int ii; + String x; + if(GetCtrl()) + x << "Ctrl "; + if(GetAlt()) + x << "Alt "; + if(GetShift()) + x << "Shift "; + x << k << ' ' << GetMousePos(); + l = x; + } + + bool Key(dword key, int count) { + k = GetKeyDesc(key) + ' ' + FormatIntHex(key); + if(key < 256) + k << '\"' << (char)key << '\"'; + Do(); + } + + typedef EventsWnd CLASSNAME; + + EventsWnd() { + Add(l.SizePos()); + SetTimeCallback(-100, THISBACK(Do)); + } +}; + GUI_APP_MAIN { StdLogSetup(LOG_COUT|LOG_FILE); SetLanguage(LNG_ENGLISH); SetDefaultCharset(CHARSET_UTF8); - + +#if 1 + EventsWnd().Run(); + return; +#endif + +#if 0 String xxx; EditText(xxx, "Edit", "Edit"); return; +#endif UWordFs().Type("QTF files", "*.qtf") .AllFilesType() diff --git a/rainbow/UWord/UWord.iml b/rainbow/UWord/UWord.iml index c5087e8d2..145eb353a 100644 --- a/rainbow/UWord/UWord.iml +++ b/rainbow/UWord/UWord.iml @@ -2,9 +2,9 @@ PREMULTIPLIED IMAGE_ID(pdf) IMAGE_BEGIN_DATA -IMAGE_DATA(120,156,157,146,129,13,192,32,8,4,29,193,1,216,67,23,113,16,55,112,186,14,226,34,212,198,154,98,85,16,63,33) -IMAGE_DATA(132,196,227,5,53,214,88,195,8,149,49,240,184,25,75,190,41,198,122,118,81,179,188,247,237,80,205,0,125,173,245,255) -IMAGE_DATA(231,222,31,6,158,206,42,251,103,210,99,206,79,238,67,120,36,61,242,193,254,145,244,240,111,214,254,131,22,151,115,206) -IMAGE_DATA(227,134,86,254,185,232,128,255,230,223,208,99,193,238,95,96,161,188,39,251,254,2,27,66,144,255,31,195,166,148,150,188) -IMAGE_DATA(38,110,182,2,234,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_DATA(120,156,99,16,96,16,96,96,97,224,100,192,1,254,147,136,49,244,255,39,18,227,212,15,3,133,133,16,181,56,248,120) +IMAGE_DATA(245,91,88,192,20,65,104,25,25,84,62,169,246,163,211,168,246,203,96,232,71,246,43,97,251,31,33,153,129,93,63,22) +IMAGE_DATA(247,32,233,255,143,100,198,35,50,194,255,63,146,25,22,80,154,212,116,0,195,199,204,205,205,45,254,19,1,112,217,255) +IMAGE_DATA(8,8,200,208,143,240,63,17,0,100,5,222,240,39,160,87,6,24,159,120,227,159,128,222,208,208,80,194,233,15,143,222) +IMAGE_DATA(134,134,6,156,250,73,193,0,234,88,234,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) IMAGE_END_DATA(160, 1)