X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ecere%2Fsrc%2Fgui%2FWindow.ec;h=596563401a88a3b481c47ee7e546e840dbc35b77;hb=HEAD;hp=48fdc8100dfcb036596e92091735d5ab9214f696;hpb=aaf3691a9ea6aef29d04429ef3ecf63806b73857;p=sdk diff --git a/ecere/src/gui/Window.ec b/ecere/src/gui/Window.ec index 48fdc81..5965634 100644 --- a/ecere/src/gui/Window.ec +++ b/ecere/src/gui/Window.ec @@ -25,6 +25,10 @@ import "EditBox" import "DataBox" import "ToolTip" +#if defined(__WIN32__) +import "Win32Interface" +#endif + #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D) import "Desktop3D" #endif @@ -38,6 +42,37 @@ import "MessageBox" import "WindowList" import "i18n" +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) +#define property _property +#define new _new +#define class _class +#define uint _uint + +#define Window X11Window +#define Cursor X11Cursor +#define Font X11Font +#define Display X11Display +#define Time X11Time +#define KeyCode X11KeyCode +#define Picture X11Picture + +#include + +#undef Window +#undef Cursor +#undef Font +#undef Display +#undef Time +#undef KeyCode +#undef Picture + +#undef uint +#undef new +#undef property +#undef class + +#endif + // Had to define this here for native decorations support, because the menu bar is part of total decoration's size, but not part of the system decorations #ifdef HIGH_DPI define skinMenuHeight = 40; @@ -487,6 +522,15 @@ private class HotKeySlot : struct Key key; }; +public struct TouchPointerInfo +{ + int id; + Point point; + float size, pressure; +}; + +public enum TouchPointerEvent { move, up, down, pointerUp, pointerDown }; + public class Window { private: @@ -568,15 +612,26 @@ private: OldLink slave; ResPtr ptr; +#if !defined(__EMSCRIPTEN__) if(fileMonitor) { int i, lockCount = guiApp.lockMutex.lockCount; +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) + if(xGlobalDisplay) + XUnlockDisplay(xGlobalDisplay); +#endif + for(i = 0; i < lockCount; i++) guiApp.lockMutex.Release(); delete fileMonitor; for(i = 0; i < lockCount; i++) guiApp.lockMutex.Wait(); +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) + if(xGlobalDisplay) + XLockDisplay(xGlobalDisplay); +#endif } +#endif if(parent) { @@ -661,7 +716,9 @@ private: delete statusBar; OnDestroyed(); +#if !defined(__EMSCRIPTEN__) delete mutex; +#endif delete icon; if(((subclass(Window))_class).pureVTbl) @@ -816,7 +873,9 @@ private: x -= rootWindow.clientStart.x; y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0); } +#if !defined(__EMSCRIPTEN__) if(!guiApp.fullScreenMode || is3D) +#endif { x -= rootWindow.absPosition.x; y -= rootWindow.absPosition.y; @@ -1124,13 +1183,23 @@ private: if(parent.numIcons) ph -= guiApp.textMode ? 16 : 24; if(anchor.left.type == vTiled) { - tilingH = (int)sqrt(numTiling); - tilingW = numTiling / tilingH; + if(numTiling) + { + tilingH = (int)sqrt(numTiling); + tilingW = numTiling / tilingH; + } + else + tilingH = tilingW = 0; } else { - tilingW = (int)sqrt(numTiling); - tilingH = numTiling / tilingW; + if(numTiling) + { + tilingW = (int)sqrt(numTiling); + tilingH = numTiling / tilingW; + } + else + tilingH = tilingW = 0; } leftOver = numTiling - tilingH * tilingW; @@ -1142,19 +1211,30 @@ private: else tilingSplit = numTiling; - if(positionID >= tilingSplit) + if(tilingW && tilingH) { - x = xOffset + pw * (tilingSplit / tilingH + (positionID - tilingSplit) / tilingLastH)/tilingW; - y = yOffset + ph * ((positionID - tilingSplit) % tilingLastH) / tilingLastH; - x2 = xOffset + pw * (tilingSplit/tilingH + (positionID - tilingSplit) / tilingLastH + 1)/tilingW; - y2 = yOffset + ph * (((positionID - tilingSplit) % tilingLastH) + 1) / tilingLastH; + if(positionID >= tilingSplit) + { + x = xOffset + pw * (tilingSplit / tilingH + (positionID - tilingSplit) / tilingLastH)/tilingW; + y = yOffset + ph * ((positionID - tilingSplit) % tilingLastH) / tilingLastH; + x2 = xOffset + pw * (tilingSplit/tilingH + (positionID - tilingSplit) / tilingLastH + 1)/tilingW; + y2 = yOffset + ph * (((positionID - tilingSplit) % tilingLastH) + 1) / tilingLastH; + } + else + { + x = xOffset + pw * (positionID / tilingH) / tilingW; + y = yOffset + ph * (positionID % tilingH) / tilingH; + x2 = xOffset + pw * (positionID / tilingH + 1) / tilingW; + y2 = yOffset + ph * ((positionID % tilingH) + 1) / tilingH; + } } else { - x = xOffset + pw * (positionID / tilingH) / tilingW; - y = yOffset + ph * (positionID % tilingH) / tilingH; - x2 = xOffset + pw * (positionID / tilingH + 1) / tilingW; - y2 = yOffset + ph * ((positionID % tilingH) + 1) / tilingH; + // How can this happen? From ec2 parsing test + x = 0; + y = 0; + x2 = 0; + y2 = 0; } if(guiApp.textMode) { @@ -1782,7 +1862,11 @@ private: if(display && !display.flags.memBackBuffer && changeRootWindow) guiApp.interfaceDriver.PositionRootWindow(this, x, y, w, h, windowMoved, windowResized); //realResized); - if(!guiApp.fullScreenMode && this != guiApp.desktop && (windowResized || windowMoved)) + if( +#if !defined(__EMSCRIPTEN__) + !guiApp.fullScreenMode && +#endif + this != guiApp.desktop && (windowResized || windowMoved)) for(child = parent.children.first; child && child != this; child = child.next) if(child.rootWindow) guiApp.interfaceDriver.UpdateRootWindow(child.rootWindow); @@ -1828,7 +1912,7 @@ private: display.Unlock(); } } - if(guiApp.driver && changeRootWindow && windowHandle) + if(guiApp.driver && !guiApp.modeSwitching && changeRootWindow && windowHandle) { if(windowResized || windowMoved) if(!display || display.flags.memBackBuffer) @@ -1847,7 +1931,9 @@ private: child.display.width = display.width; child.display.height = display.height; child.display.driverData = display.driverData; +#if !defined(__EMSCRIPTEN__) child.display.mutex = null; +#endif } } } @@ -1870,7 +1956,7 @@ private: if(guiApp.currentSkin) { MinMaxValue cw = 0, ch = 0; - bool sbvVisible, sbhVisible; + bool sbvVisible = false, sbhVisible = false; int rangeH = 0, rangeV = 0; int positionH = 0, positionV; @@ -2677,6 +2763,7 @@ private: // Default Settings surface.TextFont(usedFont.font); surface.TextOpacity(false); + surface.outlineColor = black; OnRedraw(surface); @@ -2705,6 +2792,7 @@ private: surface.TextFont(usedFont.font); surface.TextOpacity(false); + surface.outlineColor = black; OnDrawOverChildren(surface); @@ -3127,6 +3215,7 @@ private: clipExtent.AddBox(box); + display.Lock(true); display.StartUpdate(); if(!rootWindow.fullRender) @@ -3175,6 +3264,7 @@ private: } display.EndUpdate(); + display.Unlock(); dirtyBack.Empty(); dirty = false; @@ -3368,7 +3458,7 @@ private: if(rootWindow.active) guiApp.interfaceDriver.StopMoving(rootWindow); } - ReleaseCapture(); + guiApp.windowCaptured.ReleaseCapture(); guiApp.resizeX = guiApp.resizeY = guiApp.resizeEndX = guiApp.resizeEndY = false; guiApp.windowIsResizing = false; } @@ -3589,7 +3679,7 @@ private: void ConsequentialMouseMove(bool kbMoving) { - if(rootWindow) + if(rootWindow && !noConsequential) { if(kbMoving || !guiApp.windowMoving) { @@ -3766,7 +3856,10 @@ private: if(activateParent && parent && !parent.active /*parent != parent.parent.activeChild*/) parent.ActivateEx(true, true, moveInactive, activateRoot, external, externalSwap); } - else if(!guiApp.fullScreenMode) + else +#if !defined(__EMSCRIPTEN__) + if(!guiApp.fullScreenMode) +#endif { Window modalRoot = FindModal(); if(!modalRoot) modalRoot = this; @@ -4030,11 +4123,77 @@ private: reEntrancy = false; } + public bool MultiTouchMessage(TouchPointerEvent event, Array infos, Modifiers * mods, bool consequential, bool activate) + { + bool result = true; + if((infos && infos.count) || (event == up || event == pointerUp)) + { + Window w = null; + while(result && w != this) + { + // TODO: How to handle this? + int x = (infos && infos.count) ? infos[0].point.x : 0; + int y = (infos && infos.count) ? infos[0].point.y : 0; + Window msgWindow = GetAtPosition(x,y, false, true, w); + Window window; + delete w; + w = msgWindow; + if(w) incref w; + window = (w && !w.disabled) ? w : null; + + if(guiApp.windowCaptured && (guiApp.windowCaptured.rootWindow == this)) + { + if(!guiApp.windowCaptured.isEnabled) + guiApp.windowCaptured.ReleaseCapture(); + else + window = guiApp.windowCaptured; + } + + if(consequential) mods->isSideEffect = true; + if(!result || (window && window.destroyed)) window = null; + + if(window) + { + if(window.OnMultiTouch && !window.disabled) + { + Array in = null; + if(infos && infos.count) + { + in = { size = infos.size }; + memcpy(in.array, infos.array, sizeof(TouchPointerInfo) * infos.size); + + for(i : in) + { + i.point.x -= (window.absPosition.x + window.clientStart.x); + i.point.y -= (window.absPosition.y + window.clientStart.y); + + i.point.x = Max(Min(i.point.x, 32767),-32768); + i.point.y = Max(Min(i.point.y, 32767),-32768); + } + } + + incref window; + if(!window.OnMultiTouch(event, in, *mods)) + result = false; + + delete in; + delete window; + } + } + if(!result || !w || !w.clickThrough) + break; + } + delete w; + } + return result; + } + public bool MouseMessage(uint method, int x, int y, Modifiers * mods, bool consequential, bool activate) { bool result = true; bool wasMoving = guiApp.windowMoving ? true : false; bool wasScrolling = guiApp.windowScrolling ? true : false; + bool firstPass = true; Window w = null; while(result && w != this) { @@ -4284,7 +4443,7 @@ private: msgWindow.SelectMouseCursor(); */ - if(guiApp.windowCaptured || trueWindow) + if(firstPass && (guiApp.windowCaptured || trueWindow)) { Window prevWindow = guiApp.prevWindow; List overWindows = guiApp.overWindows; @@ -4292,13 +4451,13 @@ private: while(it.Next()) { - Window w = it.data; - if(trueWindow != w && !trueWindow.IsDescendantOf(w)) + Window ww = it.data; + if(trueWindow != ww && !trueWindow.IsDescendantOf(ww)) { it.pointer = null; - result = w.OnMouseLeave(*mods); + result = ww.OnMouseLeave(*mods); if(!result) break; - overWindows.TakeOut(w); + overWindows.TakeOut(ww); } } @@ -4342,10 +4501,10 @@ private: } if(trueWindow && trueWindow._refCount > 1 && !trueWindow.destroyed) { - for(w : guiApp.overWindows; w == trueWindow) + for(wi : guiApp.overWindows; wi == trueWindow) { OnMouseLeave(0); - guiApp.overWindows.TakeOut(w); + guiApp.overWindows.TakeOut(wi); break; } guiApp.prevWindow = trueWindow; @@ -4373,6 +4532,11 @@ private: incref window; if(!MouseMethod(window, clientX, clientY, *mods)) result = false; + +#ifdef __ANDROID__ + if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp) + window.OnMouseLeave(*mods); +#endif delete window; } } @@ -4385,6 +4549,7 @@ private: */ if(!result || !w || !w.clickThrough) break; + firstPass = false; } delete w; return result; @@ -4415,7 +4580,9 @@ private: if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown) status = OnSysKeyDown(key, character); - else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit) + if(status && + (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown || + method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit)) status = OnSysKeyHit(key, character); else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp) status = OnSysKeyUp(key, character); @@ -4855,8 +5022,12 @@ private: Window child; // Setup relationship with outside world (bb root || !bb) +#if defined(__EMSCRIPTEN__) + if(this == guiApp.desktop) +#else if((!guiApp.fullScreenMode && parent == guiApp.desktop) || this == guiApp.desktop || (_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver)) +#endif { rootWindow = this; if(!tempExtents) @@ -4888,7 +5059,11 @@ private: bool result = false; Window child; +#if defined(__EMSCRIPTEN__) + if(this == guiApp.desktop) +#else if((!guiApp.fullScreenMode && parent == guiApp.desktop) || (guiApp.fullScreenMode && (this == guiApp.desktop || (_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver)))) +#endif { subclass(DisplayDriver) dDriver = (dispDriver && !formDesigner) ? dispDriver : GetDisplayDriver(guiApp.defaultDisplayDriver); DisplaySystem displaySystem = dDriver ? dDriver.displaySystem : null; @@ -4901,7 +5076,7 @@ private: if(!displaySystem) { - displaySystem = DisplaySystem {}; + displaySystem = DisplaySystem { glCapabilities = glCapabilities }; if(!displaySystem.Create(dDriver.name, guiApp.fullScreenMode ? windowHandle : windowHandle /*null*/, guiApp.fullScreenMode)) { delete displaySystem; @@ -4909,7 +5084,7 @@ private: } if(displaySystem) { - display = Display { alphaBlend = alphaBlend, useSharedMemory = useSharedMemory, windowDriverData = windowData }; + display = Display { alphaBlend = alphaBlend, useSharedMemory = useSharedMemory, glCapabilities = glCapabilities, windowDriverData = windowData }; if(display.Create(displaySystem, windowHandle)) result = true; else @@ -4994,7 +5169,11 @@ private: } } - if(guiApp.fullScreenMode || this != guiApp.desktop) + if( +#if !defined(__EMSCRIPTEN__) + guiApp.fullScreenMode || +#endif + this != guiApp.desktop) { SetWindowMinimum(&skinMinSize.w, &skinMinSize.h); if(display) @@ -5832,35 +6011,38 @@ private: break; case minimized: { - int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH; - Window child; - int size = 256; - byte * idBuffer = new0 byte[size]; - int c; - for(child = parent.children.first; child; child = child.next) + if(hasMinimize) { - if(child != this && child.state == minimized) + int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH; + Window child; + int size = 256; + byte * idBuffer = new0 byte[size]; + int c; + for(child = parent.children.first; child; child = child.next) { - if(child.iconID > size - 2) + if(child != this && child.state == minimized) { - idBuffer = renew0 idBuffer byte[size*2]; - memset(idBuffer + size, 0, size); - size *= 2; + if(child.iconID > size - 2) + { + idBuffer = renew0 idBuffer byte[size*2]; + memset(idBuffer + size, 0, size); + size *= 2; + } + idBuffer[child.iconID] = (byte)bool::true; } - idBuffer[child.iconID] = (byte)bool::true; } - } - for(c = 0; c 0) ? ty & 0xFFFFF : ty; ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h); - Position(x, y, w, h, true, true, true, true, false, true); + if(state != minimized || hasMinimize) + Position(x, y, w, h, true, true, true, true, false, true); if(!style.inactive && !style.interim && parent && this == parent.activeClient) parent.UpdateActiveDocument(null); } - CreateSystemChildren(); + if(state != minimized || hasMinimize) + CreateSystemChildren(); // ------------------------------------------------------ } @@ -5917,7 +6101,7 @@ private: public bool AcquireInput(bool acquired) { bool result = true; - if(acquiredInput != acquired) + if((guiApp.acquiredWindow && acquiredInput) != acquired) { if(active || (!visible && creationActivation == activate)) result = AcquireInputEx(acquired); @@ -5950,9 +6134,15 @@ private: { if(guiApp.driver != null) { +#if !defined(__EMSCRIPTEN__) if(guiApp.fullScreenMode && guiApp.desktop.display) +#else + if(true) +#endif { +#if !defined(__EMSCRIPTEN__) guiApp.desktop.mutex.Wait(); +#endif guiApp.desktop.display.Lock(true); Update(extent); @@ -5976,12 +6166,16 @@ private: } guiApp.desktop.display.Unlock(); +#if !defined(__EMSCRIPTEN__) guiApp.desktop.mutex.Release(); +#endif } else { Window rootWindow = this.rootWindow; +#if !defined(__EMSCRIPTEN__) rootWindow.mutex.Wait(); +#endif display.Lock(true); Update(extent); @@ -5989,7 +6183,9 @@ private: guiApp.SignalEvent(); else { +#if !defined(__EMSCRIPTEN__) guiApp.waitMutex.Wait(); +#endif guiApp.interfaceDriver.Lock(rootWindow); if(!rootWindow.style.hidden && rootWindow.dirty) { @@ -6001,10 +6197,14 @@ private: rootWindow.dirty = false; } guiApp.interfaceDriver.Unlock(rootWindow); +#if !defined(__EMSCRIPTEN__) guiApp.waitMutex.Release(); +#endif } display.Unlock(); +#if !defined(__EMSCRIPTEN__) rootWindow.mutex.Release(); +#endif } } } @@ -6114,7 +6314,7 @@ private: guiApp.interfaceDriver.SetMousePosition(guiApp.windowMovingStart.x, guiApp.windowMovingStart.y); else { - int x, y; + int x = 0, y = 0; guiApp.interfaceDriver.GetMousePosition(&x, &y); guiApp.windowMovingStart.x += x - absPosition.x; guiApp.windowMovingStart.y += y - absPosition.y; @@ -6137,6 +6337,7 @@ private: void SetupFileMonitor() { +#if !defined(__EMSCRIPTEN__) if(!fileMonitor) { fileMonitor = FileMonitor @@ -6155,6 +6356,7 @@ private: }; incref fileMonitor; } +#endif } public: @@ -6205,8 +6407,10 @@ public: } } +#if !defined(__EMSCRIPTEN__) if(parent == guiApp.desktop && !mutex) mutex = Mutex {}; +#endif if(style.isDocument) { @@ -6386,7 +6590,7 @@ public: } } - if(!destroyed) + if(!destroyed && !noConsequential) rootWindow.ConsequentialMouseMove(false); result = true; @@ -6437,6 +6641,11 @@ public: Box realBox; // Testing this to avoid repetitve full update to take time... + if(rootWindow.fullRender) + { + rootWindow.dirty = true; + return; + } if(dirtyArea.count == 1) { BoxItem item = (BoxItem)ACCESS_ITEM(dirtyArea, dirtyArea.first); @@ -7182,10 +7391,16 @@ public: clip.bottom += absPosition.y; } - clip.left += decorations ? 0 : clientStart.x; - clip.top += decorations ? 0 : clientStart.y; - clip.right += decorations ? 0 : clientStart.x; - clip.bottom += decorations ? 0 : clientStart.y; + if(!nativeDecorations) + { + clip.left += decorations ? 0 : clientStart.x; + clip.top += decorations ? 0 : clientStart.y; + clip.right += decorations ? 0 : clientStart.x; + clip.bottom += decorations ? 0 : clientStart.y; + } + + if(decorations && this == guiApp.desktop) + clip = { 0, 0, guiApp.virtualScreen.w, guiApp.virtualScreen.h }; if(display && display.flags.flipping) { @@ -7425,7 +7640,9 @@ public: SetupFileMonitor(); if(fileName) { +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = null; +#endif saving = true; if(OnSaveFile(fileName)) @@ -7433,7 +7650,9 @@ public: //if(OnFileModified != Window::OnFileModified) { saving = false; +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = fileName; +#endif } return true; } @@ -7468,7 +7687,9 @@ public: sprintf(filePath, "Untitled %d", documentID); fileDialog.filePath = filePath; } +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = null; +#endif fileDialog.type = save; fileDialog.text = $"Save As"; @@ -7505,11 +7726,13 @@ public: break; } } +#if !defined(__EMSCRIPTEN__) //if(OnFileModified != Window::OnFileModified && fileName) { if(fileName) fileMonitor.fileName = fileName; } +#endif delete fileDialog; } return (bool)result; // Actually returning result from Yes/NoCancel message box @@ -7844,16 +8067,23 @@ public: bool MenuWindowWindows(MenuItem selection, Modifiers mods) { - WindowList dialog { master = this }; - Window document = (Window)(intptr)dialog.Modal(); - if(document) + WindowList { - if(activeChild.state == maximized) - document.SetState(maximized, false, mods); - else if(document.state == minimized) - document.SetState(normal, false, mods); - document.Activate(); - } + master = this; isModal = true; + + void NotifyDestroyed(Window window, DialogResult result) + { + Window document = (Window)(intptr)result; + if(document) + { + if(activeChild.state == maximized) + document.SetState(maximized, false, 0); + else if(document.state == minimized) + document.SetState(normal, false, 0); + document.Activate(); + } + } + }.Create(); return true; } @@ -7892,6 +8122,7 @@ public: virtual bool OnMiddleButtonDown(int x, int y, Modifiers mods); virtual bool OnMiddleButtonUp(int x, int y, Modifiers mods); virtual bool OnMiddleDoubleClick(int x, int y, Modifiers mods); + virtual bool OnMultiTouch(TouchPointerEvent event, Array infos, Modifiers mods); virtual void OnMouseCaptureLost(void); virtual void OnHScroll(ScrollBarAction action, int position, Key key); virtual void OnVScroll(ScrollBarAction action, int position, Key key); @@ -7907,10 +8138,11 @@ public: virtual void OnChildResized(Window child, int x, int y, int w, int h); // Skins Virtual Functions - virtual void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h); - virtual void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh); + virtual void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h) { *w = 0, *h = 0; } + virtual void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh) { *mw = 0, *mh = 0; } virtual void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch) { + *x = 0, *y = 0; *cw = *w; *ch = *h; } @@ -9338,8 +9570,10 @@ public: UpdateCaption(); // if(style.isDocument) +#if !defined(__EMSCRIPTEN__) if(!saving) fileMonitor.fileName = value; +#endif } get { return fileName; } }; @@ -9378,7 +9612,13 @@ public: property bool showInTaskBar { property_category $"Window Style" - set { style.showInTaskBar = value; } + set + { + style.showInTaskBar = value; +#if defined(__WIN32__) + Win32UpdateStyle(this); +#endif + } get { return style.showInTaskBar; } }; property FileDialog saveDialog { set { saveDialog = value; } }; @@ -9517,8 +9757,38 @@ public: } }; property bool moveable { get { return (bool)moveable; } set { moveable = value; } }; - property bool alphaBlend { get { return (bool)alphaBlend; } set { alphaBlend = value; } }; + property bool alphaBlend { get { return (bool)alphaBlend; } set { alphaBlend = value; if(value) nativeDecorations = false; /* Native Decorations are not supported with alphaBlend */ } }; property bool useSharedMemory { get { return (bool)useSharedMemory; } set { useSharedMemory = value; } }; + property GLCapabilities glCapabilities + { + get { return glCapabilities; } + set + { + bool reload = display != null && + (glCapabilities.nonPow2Textures != value.nonPow2Textures || + glCapabilities.intAndDouble != value.intAndDouble || + glCapabilities.vertexBuffer != value.vertexBuffer || + glCapabilities.compatible != value.compatible || + glCapabilities.legacyFormats != value.legacyFormats || + glCapabilities.debug != value.debug || + glCapabilities.vertexPointer != value.vertexPointer || + glCapabilities.quads != value.quads); + guiApp.modeSwitching = true; + if(reload) + UnloadGraphics(false); + + glCapabilities = value; + + if(reload) + { + if(SetupDisplay()) + LoadGraphics(false, false); + } + else if(display) + display.glCapabilities = value; + guiApp.modeSwitching = false; + } + }; property CreationActivationOption creationActivation { get { return creationActivation; } set { creationActivation = value; } }; property bool nativeDecorations { @@ -9647,10 +9917,14 @@ private: int numIcons; int positionID; +#if !defined(__EMSCRIPTEN__) Mutex mutex; +#endif WindowState lastState; +#if !defined(__EMSCRIPTEN__) FileMonitor fileMonitor; +#endif FontResource setFont, systemFont; FontResource usedFont; @@ -9667,6 +9941,8 @@ private: BitmapResource icon; void * windowData; CreationActivationOption creationActivation; + GLCapabilities glCapabilities; + glCapabilities = { true, true, true, true, true, true, true, true, true /*false*/, true, true, true, true, true, true, true }; struct { bool active:1; // true if window and ancestors are active @@ -9700,6 +9976,7 @@ private: bool manageDisplay:1; bool formDesigner:1; // True if we this is running in the form editor bool requireRemaximize:1; + bool noConsequential:1; }; // Checks used internally for them not to take effect in FormDesigner @@ -9707,7 +9984,29 @@ private: property subclass(DisplayDriver) _displayDriver { get { return !formDesigner ? dispDriver : null; } } WindowController controller; - public property WindowController controller { get { return controller; } set { delete controller; controller = value; if(controller) incref controller; } } + + public property WindowController controller + { + get { return controller; } + set + { + if(controller) + controller.setWindow(null); + delete controller; + controller = value; + if(controller) + { + incref controller; + controller.setWindow(this); + } + } + } + + public property bool noConsequential + { + set { noConsequential = value; } + get { return noConsequential; } + } }; public class CommonControl : Window @@ -9860,176 +10159,267 @@ class WindowControllerInterface : ControllableWindow { bool OnKeyDown(Key key, unichar ch) { - bool result = ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyDown)((Window)controller.controlled, controller, key, ch); + bool result = controller.OnKeyDown ? ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyDown)((Window)controller.controlled, controller, key, ch) : true; if(result) - result = ((bool (*)(Window, Key, unichar))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown])(controller.window, key, ch); + { + bool (* onKeyDown)(Window, Key, unichar) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown]; + if(onKeyDown) + result = onKeyDown(controller.window, key, ch); + } return result; } bool OnKeyUp(Key key, unichar ch) { - bool result = ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyUp)((Window)controller.controlled, controller, key, ch); + bool result = controller.OnKeyUp ? ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyUp)((Window)controller.controlled, controller, key, ch) : true; if(result) - result = ((bool(*)(Window, Key, unichar))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp])(controller.window, key, ch); + { + bool (* onKeyUp)(Window, Key, unichar) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp]; + if(onKeyUp) + result = onKeyUp(controller.window, key, ch); + } return result; } bool OnKeyHit(Key key, unichar ch) { - bool result = ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyHit)((Window)controller.controlled, controller, key, ch); + bool result = controller.OnKeyHit ? ((bool(*)(Window, WindowController, Key, unichar))(void *)controller.OnKeyHit)((Window)controller.controlled, controller, key, ch) : true; if(result) - result = ((bool(*)(Window, Key, unichar))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit])(controller.window, key, ch); + { + bool (* onKeyHit)(Window, Key, unichar) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit]; + if(onKeyHit) + result = onKeyHit(controller.window, key, ch); + } return result; } bool OnMouseMove(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMouseMove)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnMouseMove ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMouseMove)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove])(controller.window, x, y, mods); + { + bool(* onMouseMove)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove]; + if(onMouseMove) + result = onMouseMove(controller.window, x, y, mods); + } return result; } bool OnLeftButtonDown(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftButtonDown)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnLeftButtonDown ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftButtonDown)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown])(controller.window, x, y, mods); + { + bool(* onLeftButtonDown)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown]; + if(onLeftButtonDown) + result = onLeftButtonDown(controller.window, x, y, mods); + } return result; } bool OnLeftButtonUp(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftButtonUp)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnLeftButtonUp ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftButtonUp)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp])(controller.window, x, y, mods); + { + bool(* onLeftButtonUp)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp]; + if(onLeftButtonUp) + result = onLeftButtonUp(controller.window, x, y, mods); + } return result; } bool OnLeftDoubleClick(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftDoubleClick)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnLeftDoubleClick ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnLeftDoubleClick)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick])(controller.window, x, y, mods); + { + bool(* onLeftDoubleClick)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick]; + if(onLeftDoubleClick) + result = onLeftDoubleClick(controller.window, x, y, mods); + } return result; } bool OnRightButtonDown(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightButtonDown)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnRightButtonDown ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightButtonDown)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown])(controller.window, x, y, mods); + { + bool(* onRightButtonDown)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown]; + if(onRightButtonDown) + result = onRightButtonDown(controller.window, x, y, mods); + } return result; } bool OnRightButtonUp(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightButtonUp)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnRightButtonUp ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightButtonUp)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp])(controller.window, x, y, mods); + { + bool(* onRightButtonUp)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp]; + if(onRightButtonUp) + result = onRightButtonUp(controller.window, x, y, mods); + } return result; } bool OnRightDoubleClick(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightDoubleClick)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnRightDoubleClick ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnRightDoubleClick)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick])(controller.window, x, y, mods); + { + bool(* onRightDoubleClick)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick]; + if(onRightDoubleClick) + result = onRightDoubleClick(controller.window, x, y, mods); + } return result; } bool OnMiddleButtonDown(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleButtonDown)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnMiddleButtonDown ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleButtonDown)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown])(controller.window, x, y, mods); + { + bool(* onMiddleButtonDown)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown]; + if(onMiddleButtonDown) + result = onMiddleButtonDown(controller.window, x, y, mods); + } return result; } bool OnMiddleButtonUp(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleButtonUp)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnMiddleButtonUp ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleButtonUp)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp])(controller.window, x, y, mods); + { + bool(* onMiddleButtonUp)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp]; + if(onMiddleButtonUp) + result = onMiddleButtonUp(controller.window, x, y, mods); + } return result; } bool OnMiddleDoubleClick(int x, int y, Modifiers mods) { - bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleDoubleClick)((Window)controller.controlled, controller, x, y, mods); + bool result = controller.OnMiddleDoubleClick ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMiddleDoubleClick)((Window)controller.controlled, controller, x, y, mods) : true; if(result) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick])(controller.window, x, y, mods); + { + bool(* onMiddleDoubleClick)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick]; + if(onMiddleDoubleClick) + onMiddleDoubleClick(controller.window, x, y, mods); + } + return result; + } + + bool OnMultiTouch(TouchPointerEvent event, Array infos, Modifiers mods) + { + bool result = controller.OnMultiTouch ? ((bool(*)(Window, WindowController, TouchPointerEvent event, Array infos, Modifiers))(void *)controller.OnMultiTouch)((Window)controller.controlled, controller, event, infos, mods) : true; + if(result) + { + bool(* onMultiTouch)(Window, TouchPointerEvent, Array, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMultiTouch]; + if(onMultiTouch) + onMultiTouch(controller.window, event, infos, mods); + } return result; } void OnResize(int width, int height) { - ((void(*)(Window, WindowController, int, int))(void *)controller.OnResize)((Window)controller.controlled, controller, width, height); - ((void(*)(Window, int, int))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnResize])(controller.window, width, height); + if(controller.OnResize) + ((void(*)(Window, WindowController, int, int))(void *)controller.OnResize)((Window)controller.controlled, controller, width, height); + { + void(* onResize)(Window, int, int) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnResize]; + if(onResize) + onResize(controller.window, width, height); + } } void OnRedraw(Surface surface) { - ((void(*)(Window, WindowController, Surface))(void *)controller.OnRedraw)((Window)controller.controlled, controller, surface); - ((void(*)(Window, Surface))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw])(controller.window, surface); + if(controller.OnRedraw) + ((void(*)(Window, WindowController, Surface))(void *)controller.OnRedraw)((Window)controller.controlled, controller, surface); + { + void(* onRedraw)(Window, Surface) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw]; + if(onRedraw) + onRedraw(controller.window, surface); + } } bool OnCreate() { - bool result = ((bool(*)(Window, WindowController))(void *)controller.OnCreate)((Window)controller.controlled, controller); + bool result = controller.OnCreate ? ((bool(*)(Window, WindowController))(void *)controller.OnCreate)((Window)controller.controlled, controller) : true; if(result) - result = ((bool(*)(Window))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnCreate])(controller.window); + { + bool(* onCreate)(Window) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnCreate]; + if(onCreate) + result = onCreate(controller.window); + } return result; } bool OnLoadGraphics() { - bool result = ((bool(*)(Window, WindowController))(void *)controller.OnLoadGraphics)((Window)controller.controlled, controller); + bool result = controller.OnLoadGraphics ? ((bool(*)(Window, WindowController))(void *)controller.OnLoadGraphics)((Window)controller.controlled, controller) : true; if(result) - result = ((bool(*)(Window))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLoadGraphics])(controller.window); + { + bool(* onLoadGraphics)(Window) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLoadGraphics]; + if(onLoadGraphics) + result = onLoadGraphics(controller.window); + } return result; } void OnUnloadGraphics() { - ((void(*)(Window, WindowController))(void *)controller.OnUnloadGraphics)((Window)controller.controlled, controller); - ((void(*)(Window))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnUnloadGraphics])(controller.window); + if(controller.OnUnloadGraphics) + ((void(*)(Window, WindowController))(void *)controller.OnUnloadGraphics)((Window)controller.controlled, controller); + { + void(* onUnloadGraphics)(Window) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnUnloadGraphics]; + if(onUnloadGraphics) + onUnloadGraphics(controller.window); + } } } public class WindowController { -public: - property Window window + void setWindow(Window value) { - set + uint size = class(Window).vTblSize; + if(value) { - uint size = class(Window).vTblSize; - if(value) + delete windowVTbl; + windowVTbl = new void *[size]; + memcpy(windowVTbl, value._vTbl, size * sizeof(void *)); + if(value._vTbl == value._class._vTbl) { - windowVTbl = new void *[size]; - memcpy(windowVTbl, value._vTbl, size * sizeof(void *)); - if(value._vTbl == value._class._vTbl) - { - value._vTbl = new void *[value._class.vTblSize]; - memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *)); - } + value._vTbl = new void *[value._class.vTblSize]; + memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *)); + } + { + int c; + for(c = 0; c < size; c++) { - int c; - for(c = 0; c < size; c++) - { - void * function = class(WindowControllerInterface)._vTbl[c]; - if(function != DefaultFunction) - value._vTbl[c] = function; - else - value._vTbl[c] = windowVTbl[c]; - } + void * function = class(WindowControllerInterface)._vTbl[c]; + if(function && function != DefaultFunction) + value._vTbl[c] = function; + else + value._vTbl[c] = windowVTbl[c]; } } - else - memcpy(value._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *)); - window = value; } + else if(window) + { + memcpy(window._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *)); + delete windowVTbl; + } + window = value; + } +public: + property Window window + { get { return window; } } property V controlled @@ -10037,6 +10427,7 @@ public: set { controlled = value; } get { return controlled; } } + // TODO: Add OnStateChange so we can implement SavedConfigWindow as a WindowController instead virtual bool V::OnKeyDown(WindowController controller, Key key, unichar ch); virtual bool V::OnKeyUp(WindowController controller, Key key, unichar ch); virtual bool V::OnKeyHit(WindowController controller, Key key, unichar ch); @@ -10050,6 +10441,7 @@ public: virtual bool V::OnMiddleButtonDown(WindowController controller, int x, int y, Modifiers mods); virtual bool V::OnMiddleButtonUp(WindowController controller, int x, int y, Modifiers mods); virtual bool V::OnMiddleDoubleClick(WindowController controller, int x, int y, Modifiers mods); + virtual bool V::OnMultiTouch(WindowController controller, TouchPointerEvent event, Array infos, Modifiers mods); virtual void V::OnResize(WindowController controller, int width, int height); virtual void V::OnRedraw(WindowController controller, Surface surface); virtual bool V::OnCreate(WindowController controller); @@ -10057,7 +10449,7 @@ public: virtual void V::OnUnloadGraphics(WindowController controller); private: - int (** windowVTbl)(); + public int (** windowVTbl)(); V controlled; Window window;