X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ecere%2Fsrc%2Fgui%2FWindow.ec;h=48e7f0aa6a5272a546cfa4870b04b5d06f314aed;hb=dd05e6bd2ba8fc82215aab92bd1a3019e8c96295;hp=c7e17c0397ab517b5d069a597ff55444a6348cff;hpb=d85de44b42286f05fc60ebcea60f16d24337f34e;p=sdk diff --git a/ecere/src/gui/Window.ec b/ecere/src/gui/Window.ec index c7e17c0..48e7f0a 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,15 +522,24 @@ 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: - class_data char * icon; + class_data const char * icon; class_no_expansion class_default_property caption; // class_initialize GuiApplication::Initialize; class_designer FormDesigner; - class_property char * icon + class_property const char * icon { set { class_data(icon) = value; } get { return class_data(icon); } @@ -568,6 +612,27 @@ 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) { stopwatching(parent, font); @@ -606,7 +671,7 @@ private: delete order; ///////////////////////////////// - while(ptr = resources.first) + while((ptr = resources.first)) { delete ptr.resource; resources.Delete(ptr); @@ -625,7 +690,7 @@ private: *&child.parent = null; } - while(slave = slaves.first) + while((slave = slaves.first)) { // Don't want property here *&((Window)slave.data).master = null; @@ -651,7 +716,9 @@ private: delete statusBar; OnDestroyed(); +#if !defined(__EMSCRIPTEN__) delete mutex; +#endif delete icon; if(((subclass(Window))_class).pureVTbl) @@ -688,23 +755,25 @@ private: tempExtents[3].Free(null); delete tempExtents; } + + delete controller; } //#if !defined(ECERE_VANILLA) - char * OnGetString(char * stringOutput, void * fieldData, bool * needClass) + const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass) { if(this == activeDesigner) return "(Desktop)"; else { - char * name = property::name; + const char * name = property::name; return name ? name : ""; } } //#endif #if !defined(ECERE_VANILLA) && !defined(ECERE_NOTRUETYPE) - bool OnGetDataFromString(char * string) + bool OnGetDataFromString(const char * string) { FormDesigner designer = (FormDesigner)activeDesigner.classDesigner; if(string[0]) @@ -743,7 +812,7 @@ private: { int x = absPosition.x + clientStart.x; int y = absPosition.y + clientStart.y; - if(rootWindow.nativeDecorations && rootWindow.windowHandle) + if(rootWindow.nativeDecorations && rootWindow.windowHandle && !is3D) { x -= rootWindow.clientStart.x; y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0); @@ -755,13 +824,21 @@ private: if(rootWindow.is3D) { - x += rootWindow.parent.clientStart.x; - y += rootWindow.parent.clientStart.y; + int dx = rootWindow.parent.parent.clientStart.x; + int dy = rootWindow.parent.parent.clientStart.y; + if(!rootWindow.parent.nativeDecorations) + { + dx += rootWindow.parent.clientStart.x; + dy += rootWindow.parent.clientStart.y; + } + x += dx; + y += dy; + /* - mox.left += rootWindow.parent.clientStart.x; - mox.top += rootWindow.parent.clientStart.y; - mox.right += rootWindow.parent.clientStart.x; - mox.bottom += rootWindow.parent.clientStart.y; + mox.left += dx; + mox.top += dy; + mox.right += dx; + mox.bottom += dy; */ } } @@ -791,24 +868,34 @@ private: { int x = absPosition.x; int y = absPosition.y; - if(rootWindow.nativeDecorations && rootWindow.windowHandle) + if(rootWindow.nativeDecorations && rootWindow.windowHandle && !is3D) { 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; if(rootWindow.is3D) { - x += rootWindow.parent.clientStart.x; - y += rootWindow.parent.clientStart.y; + int dx = rootWindow.parent.parent.clientStart.x; + int dy = rootWindow.parent.parent.clientStart.y; + if(!rootWindow.parent.nativeDecorations) + { + dx += rootWindow.parent.clientStart.x; + dy += rootWindow.parent.clientStart.y; + } + x += dx; + y += dy; + /* - mox.left += rootWindow.parent.clientStart.x; - mox.top += rootWindow.parent.clientStart.y; - mox.right += rootWindow.parent.clientStart.x; - mox.bottom += rootWindow.parent.clientStart.y; + mox.left += dx; + mox.top += dy; + mox.right += dx; + mox.bottom += dy; */ } } @@ -949,12 +1036,12 @@ private: int ph = parent ? parent.clientSize.h : 0; int w = sizeAnchor.size.w, h = sizeAnchor.size.h; int x = anchor.left.distance, y = anchor.top.distance; - float ex, ey; + float ex = 0, ey = 0; MinMaxValue ew = 0, eh = 0; int numCascade; float cascadeW, cascadeH; int numTiling; - int tilingW, tilingH, tilingSplit, tilingLastH; + int tilingW, tilingH, tilingSplit, tilingLastH = 0; int addX = 0, addY = 0; if(parent && rootWindow == this && guiApp && guiApp.interfaceDriver) @@ -1050,7 +1137,7 @@ private: int loX = 0, loY = 0, hiX = pw, hiY = ph; for(win = parent.children.first; win; win = win.next) { - if(!win.isActiveClient && win.visible) + if(!win.nonClient && !win.isActiveClient && win.visible) { Size size = win.size; Point pos = win.position; @@ -1096,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; @@ -1114,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) { @@ -1602,6 +1710,8 @@ private: { if(!parent.noAutoScrollArea) { + // TODO: Review the logic of all this? Each child is going to reposition the parent? + /* Window child; bool found = false; for(child = children.first; child; child = child.next) @@ -1616,7 +1726,8 @@ private: } } } - //if(!found) + if(!found) + */ { Window parent = this.parent; parent.Position( @@ -1642,7 +1753,7 @@ private: int oldCW = clientSize.w, oldCH = clientSize.h; bool clientResized, windowResized, windowMoved; Window child; - bool realResized = size.w != w || size.h != h; + //bool realResized = size.w != w || size.h != h; // TOCHECK: This wasn't in ecere.dll //if(!parent) return true; @@ -1751,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); @@ -1797,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) @@ -1816,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 } } } @@ -1839,9 +1956,9 @@ private: if(guiApp.currentSkin) { MinMaxValue cw = 0, ch = 0; - bool sbvVisible, sbhVisible; - int rangeH, rangeV; - int positionH, positionV; + bool sbvVisible = false, sbhVisible = false; + int rangeH = 0, rangeV = 0; + int positionH = 0, positionV; // First get client area with no respect to scroll bars @@ -2312,18 +2429,18 @@ private: if(hasMaxMin && parent) { - SkinBitmap skin; + //SkinBitmap skin; unichar symbol; bool (* method)(Window window, Button button, int x, int y, Modifiers mods); if(state == maximized) { - skin = restore; + //skin = restore; method = RestoreButtonClicked; symbol = '\x12'; } else { - skin = maximize; + //skin = maximize; method = MaximizeButtonClicked; symbol = '\x18'; } @@ -2345,18 +2462,18 @@ private: if(hasMaxMin && parent) { - SkinBitmap skin; + //SkinBitmap skin; unichar symbol; bool (* method)(Window window, Button button, int x, int y, Modifiers mods); if (state == minimized) { - skin = restore; + //skin = restore; method = RestoreButtonClicked; symbol = '\x12'; } else { - skin = minimize; + //skin = minimize; method = MinimizeButtonClicked; symbol = '\x19'; } @@ -2481,7 +2598,7 @@ private: if(menu) { MenuItem item; - bool disabled; + //bool disabled; if(menu) menu.Clean(this); @@ -2496,7 +2613,6 @@ private: int id; for(id = 0, cycle = activeClient.cycle; cycle && id<10;) { - MenuItem item; Window document = cycle.data; if(!document.style.nonClient && document.style.isActiveClient && document.visible) { @@ -2517,10 +2633,10 @@ private: if((!previous && activeClient) || !activeClient) { - if(!activeClient) + /*if(!activeClient) disabled = true; else - disabled = false; + disabled = false;*/ item = menu.FindItem(MenuWindowCloseAll, 0); if(item) item.disabled = false; item = menu.FindItem(MenuWindowNext, 0); @@ -2567,7 +2683,7 @@ private: void _ShowDecorations(Box box, bool post) { - if(rootWindow == this && nativeDecorations) return; + if(rootWindow == this && nativeDecorations && !is3D) return; if(visible && this != guiApp.desktop) { Surface surface = RedrawFull(box); @@ -2647,6 +2763,7 @@ private: // Default Settings surface.TextFont(usedFont.font); surface.TextOpacity(false); + surface.outlineColor = black; OnRedraw(surface); @@ -2675,6 +2792,7 @@ private: surface.TextFont(usedFont.font); surface.TextOpacity(false); + surface.outlineColor = black; OnDrawOverChildren(surface); @@ -2723,7 +2841,6 @@ private: void ComputeRenderAreaNonOpaque(Extent dirtyExtent, Extent overDirtyExtent, Extent backBufferUpdate) { - bool opaque = IsOpaque(); Window child; int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y; if(rootWindow.nativeDecorations && rootWindow.windowHandle) @@ -2735,7 +2852,6 @@ private: for(child = children.last; child; child = child.prev) { - ColorAlpha background = *(ColorAlpha *)&child.background; bool opaque = child.IsOpaque(); if(!child.style.hidden && child.created && !child.is3D && child.rootWindow) { @@ -3099,6 +3215,7 @@ private: clipExtent.AddBox(box); + display.Lock(true); display.StartUpdate(); if(!rootWindow.fullRender) @@ -3147,6 +3264,7 @@ private: } display.EndUpdate(); + display.Unlock(); dirtyBack.Empty(); dirty = false; @@ -3256,8 +3374,7 @@ private: Window ancestor = null; if(isD) for(ancestor = last; ancestor && ancestor.parent != this; ancestor = ancestor.parent); - // for(child = isD ? (last.previous == children.first ? null : last.previous) : children.last; child; child = child.prev) - for(child = isD ? (ancestor.previous == children.first ? null : ancestor) : children.last; child; child = child.prev) + for(child = (isD ? (last != ancestor ? ancestor : ancestor.previous) : children.last); child; child = child.prev) { if(child != statusBar && child.rootWindow == rootWindow) { @@ -3268,8 +3385,7 @@ private: } if(clickThru) { - //for(child = isD ? (last.previous == children.first ? null : last.previous) : children.last; child; child = child.prev) - for(child = isD ? (ancestor.previous == children.first ? null : ancestor.previous) : children.last; child; child = child.prev) + for(child = (isD ? (last != ancestor ? ancestor : ancestor.previous) : children.last); child; child = child.prev) { if(child != statusBar && child.rootWindow == rootWindow) { @@ -3342,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; } @@ -3479,7 +3595,7 @@ private: // TESTING THIS HERE UpdateDecorations(); - if(result = OnActivate(active, previous, goOnWithActivation, direct) && *goOnWithActivation && master) + if((result = OnActivate(active, previous, goOnWithActivation, direct) && *goOnWithActivation && master)) result = NotifyActivate(master, this, active, previous); else { @@ -3563,7 +3679,7 @@ private: void ConsequentialMouseMove(bool kbMoving) { - if(rootWindow) + if(rootWindow && !noConsequential) { if(kbMoving || !guiApp.windowMoving) { @@ -3656,7 +3772,7 @@ private: if(real) { - bool acquireInput = false; + //bool acquireInput = false; bool maximize = parent.activeChild && parent.activeChild.state == maximized && @@ -3693,7 +3809,7 @@ private: delete this; return false; } - acquireInput = true; + //acquireInput = true; } } @@ -3740,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; @@ -4004,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) { @@ -4258,17 +4443,40 @@ private: msgWindow.SelectMouseCursor(); */ - if(guiApp.windowCaptured || trueWindow) + if(firstPass && (guiApp.windowCaptured || trueWindow)) { Window prevWindow = guiApp.prevWindow; - if(guiApp.prevWindow && trueWindow != guiApp.prevWindow) + List overWindows = guiApp.overWindows; + Iterator it { overWindows }; + + while(it.Next()) + { + Window ww = it.data; + if(trueWindow != ww && !trueWindow.IsDescendantOf(ww)) + { + it.pointer = null; + result = ww.OnMouseLeave(*mods); + if(!result) break; + overWindows.TakeOut(ww); + } + } + + if(result && guiApp.prevWindow && trueWindow != guiApp.prevWindow) { guiApp.prevWindow.mouseInside = false; guiApp.prevWindow = null; - // Eventually fix this not to include captured? - if(!trueWindow.IsDescendantOf(prevWindow) && !prevWindow.OnMouseLeave(*mods)) - result = false; + if(result) + { + if(trueWindow.IsDescendantOf(prevWindow)) + { + if(!overWindows.Find(prevWindow)) + overWindows.Add(prevWindow); + } + // Eventually fix this not to include captured? + else if(!prevWindow.OnMouseLeave(*mods)) + result = false; + } } if(result && trueWindow && !trueWindow.destroyed/* && trueWindow == window*/) { @@ -4292,13 +4500,22 @@ private: } } if(trueWindow && trueWindow._refCount > 1 && !trueWindow.destroyed) + { + for(wi : guiApp.overWindows; wi == trueWindow) + { + OnMouseLeave(0); + guiApp.overWindows.TakeOut(wi); + break; + } guiApp.prevWindow = trueWindow; + } else guiApp.prevWindow = null; } SelectMouseCursor(); - if(window && !guiApp.windowMoving && !wasMoving && !wasScrolling) + if(window && ((!guiApp.windowMoving && !wasMoving) || + (wasMoving && guiApp.windowMoving && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp)) && !wasScrolling) { int clientX = x - (window.absPosition.x + window.clientStart.x); int clientY = y - (window.absPosition.y + window.clientStart.y); @@ -4315,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; } } @@ -4327,6 +4549,7 @@ private: */ if(!result || !w || !w.clickThrough) break; + firstPass = false; } delete w; return result; @@ -4560,10 +4783,10 @@ private: { if(cycleParent.CycleChildren(!key.shift, false, false, true)) { + /* Window child = cycleParent.activeChild; // Scroll the window to include the active control - /* if(cycleParent.sbh && !child.style.dontScrollHorz) { if(child.scrolledPos.x < 0) @@ -4797,8 +5020,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) @@ -4830,7 +5057,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; @@ -4843,7 +5074,7 @@ private: if(!displaySystem) { - displaySystem = DisplaySystem {}; + displaySystem = DisplaySystem { glCapabilities = glCapabilities }; if(!displaySystem.Create(dDriver.name, guiApp.fullScreenMode ? windowHandle : windowHandle /*null*/, guiApp.fullScreenMode)) { delete displaySystem; @@ -4851,7 +5082,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 @@ -4936,7 +5167,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) @@ -5007,7 +5242,8 @@ private: for(ptr = resources.first; ptr; ptr = ptr.next) { - ptr.loaded = display.displaySystem.LoadResource(ptr.resource); + if(!ptr.loaded) // This check prevents a leak in case a watcher on 'font' calls AddResource (ListBox FontResource leak) + ptr.loaded = display.displaySystem.LoadResource(ptr.resource); } if(setFont) AddResource(setFont); @@ -5167,15 +5403,11 @@ private: if(activeChild) guiApp.interfaceDriver.ActivateRootWindow(activeChild); } - /* - TODO: if(!success) - //guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, caption); - guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, class.name); - */ + LogErrorCode(graphicsLoadingFailed, _class.name); // Do this here to avoid problems on Windows - if(stateBackup == maximized) + if(rootWindow == this && parent && stateBackup == maximized) property::state = maximized; return result; } @@ -5425,6 +5657,15 @@ private: guiApp.prevWindow = null; OnMouseLeave(0); } + else + { + for(w : guiApp.overWindows; w == this) + { + OnMouseLeave(0); + guiApp.overWindows.TakeOut(w); + break; + } + } if(guiApp.caretOwner == this) { guiApp.interfaceDriver.SetCaret(0,0,0); @@ -5768,35 +6009,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(); // ------------------------------------------------------ } @@ -5853,7 +6099,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); @@ -5875,7 +6121,7 @@ private: if(child.cycle && !child.style.nonClient && child.style.isActiveClient && child.visible) { DataRow row = listBox.AddRow(); - row.tag = (int64)child; + row.tag = (int64)(intptr)child; child.FigureCaption(caption); row.SetData(null, caption); } @@ -5886,9 +6132,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); @@ -5912,12 +6164,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); @@ -5925,7 +6181,9 @@ private: guiApp.SignalEvent(); else { +#if !defined(__EMSCRIPTEN__) guiApp.waitMutex.Wait(); +#endif guiApp.interfaceDriver.Lock(rootWindow); if(!rootWindow.style.hidden && rootWindow.dirty) { @@ -5937,10 +6195,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 } } } @@ -6050,7 +6312,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; @@ -6071,6 +6333,30 @@ private: } } + void SetupFileMonitor() + { +#if !defined(__EMSCRIPTEN__) + if(!fileMonitor) + { + fileMonitor = FileMonitor + { + this, FileChange { modified = true }; + + bool OnFileNotify(FileChange action, const char * param) + { + incref this; + fileMonitor.StopMonitoring(); + if(OnFileModified(action, param)) + fileMonitor.StartMonitoring(); + delete this; + return true; + } + }; + incref fileMonitor; + } +#endif + } + public: // normal Methods bool Create() @@ -6081,7 +6367,6 @@ public: result = true; else if(guiApp && guiApp.driver != null) { - void * systemParent = null; OldLink slaveHolder; Window last; bool visible = !style.hidden; @@ -6120,8 +6405,10 @@ public: } } +#if !defined(__EMSCRIPTEN__) if(parent == guiApp.desktop && !mutex) mutex = Mutex {}; +#endif if(style.isDocument) { @@ -6291,13 +6578,17 @@ public: /*if(rootWindow == this) guiApp.interfaceDriver.ActivateRootWindow(this); else*/ - if(creationActivation == activate) + if(creationActivation == activate && guiApp.desktop.active) ActivateEx(true, false, true, true, null, null); - else if(creationActivation == flash) - Flash(); + else if(creationActivation == activate || creationActivation == flash) + { + MakeActive(); + if(this == rootWindow) + Flash(); + } } - if(!destroyed) + if(!destroyed && !noConsequential) rootWindow.ConsequentialMouseMove(false); result = true; @@ -6348,6 +6639,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); @@ -6516,7 +6812,6 @@ public: void SetScrollArea(int width, int height, bool snapToStep) { - bool resize = false; if(snapToStep) { int stepX = sbStep.x, stepY = sbStep.y; @@ -6628,7 +6923,7 @@ public: { if(state == newState || OnStateChange(newState, mods)) { - WindowState prevState = state; + //WindowState prevState = state; StopMoving(); @@ -6795,7 +7090,11 @@ public: if(guiApp.desktop.active) Activate(); else if(!active) - Flash(); + { + MakeActive(); + if(this == rootWindow) + Flash(); + } } void Deactivate(void) @@ -6906,7 +7205,8 @@ public: if(/*created && */display) { display.Lock(false); - ptr.loaded = display.displaySystem.LoadResource(resource); + if(!ptr.loaded) // This check prevents a leak in case a watcher on 'font' calls AddResource (ListBox FontResource leak) + ptr.loaded = display.displaySystem.LoadResource(resource); display.Unlock(); } /* @@ -7030,7 +7330,7 @@ public: } } - private void _SetCaption(char * format, va_list args) + private void _SetCaption(const char * format, va_list args) { if(this) { @@ -7050,7 +7350,7 @@ public: } } - /*deprecated*/ void SetText(char * format, ...) + /*deprecated*/ void SetText(const char * format, ...) { va_list args; va_start(args, format); @@ -7058,7 +7358,7 @@ public: va_end(args); } - void SetCaption(char * format, ...) + void SetCaption(const char * format, ...) { va_list args; va_start(args, format); @@ -7089,10 +7389,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) { @@ -7329,9 +7635,12 @@ public: bool MenuFileSave(MenuItem selection, Modifiers mods) { + SetupFileMonitor(); if(fileName) { +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = null; +#endif saving = true; if(OnSaveFile(fileName)) @@ -7339,7 +7648,9 @@ public: //if(OnFileModified != Window::OnFileModified) { saving = false; +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = fileName; +#endif } return true; } @@ -7359,6 +7670,8 @@ public: DialogResult result = (DialogResult)bool::true; FileDialog fileDialog = saveDialog; + SetupFileMonitor(); + if(!fileDialog) fileDialog = FileDialog {}; if(fileDialog) @@ -7372,7 +7685,9 @@ public: sprintf(filePath, "Untitled %d", documentID); fileDialog.filePath = filePath; } +#if !defined(__EMSCRIPTEN__) fileMonitor.fileName = null; +#endif fileDialog.type = save; fileDialog.text = $"Save As"; @@ -7382,7 +7697,7 @@ public: fileDialog.master = master.parent ? master : this; if(fileDialog.Modal() == ok) { - char * filePath = fileDialog.filePath; + const char * filePath = fileDialog.filePath; saving = true; if(OnSaveFile(filePath)) { @@ -7409,11 +7724,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 @@ -7481,11 +7798,10 @@ public: (*&child.normalAnchor).top = y; (*&child.normalAnchor).right.type = none; (*&child.normalAnchor).bottom.type = none; - - child.normalSizeAnchor.isClientW = false; - child.normalSizeAnchor.isClientH = false; - child.normalSizeAnchor.size.w = w; - child.normalSizeAnchor.size.h = h; + (*&child.normalSizeAnchor).isClientW = false; + (*&child.normalSizeAnchor).isClientH = false; + (*&child.normalSizeAnchor).size.w = w; + (*&child.normalSizeAnchor).size.h = h; child.anchored = false; } @@ -7529,7 +7845,7 @@ public: for(document = children.first; document; document = next) { - for(next = document.next; next && !(next.style.isActiveClient; next = next.next); + for(next = document.next; next && !next.style.isActiveClient; next = next.next); if(document.style.isActiveClient) if(!document.Destroy(0) && !document.style.hidden) return false; @@ -7656,10 +7972,10 @@ public: (*&child.normalAnchor).top = y; (*&child.normalAnchor).right.type = none; (*&child.normalAnchor).bottom.type = none; - child.normalSizeAnchor.isClientW = false; - child.normalSizeAnchor.isClientH = false; - child.normalSizeAnchor.size.w = w; - child.normalSizeAnchor.size.h = h; + (*&child.normalSizeAnchor).isClientW = false; + (*&child.normalSizeAnchor).isClientH = false; + (*&child.normalSizeAnchor).size.w = w; + (*&child.normalSizeAnchor).size.h = h; child.anchored = false; } @@ -7721,10 +8037,10 @@ public: (*&child.normalAnchor).top = y; (*&child.normalAnchor).right.type = none; (*&child.normalAnchor).bottom.type = none; - child.normalSizeAnchor.isClientW = false; - child.normalSizeAnchor.isClientH = false; - child.normalSizeAnchor.size.w = w; - child.normalSizeAnchor.size.h = h; + (*&child.normalSizeAnchor).isClientW = false; + (*&child.normalSizeAnchor).isClientH = false; + (*&child.normalSizeAnchor).size.w = w; + (*&child.normalSizeAnchor).size.h = h; child.anchored = false; } @@ -7749,16 +8065,23 @@ public: bool MenuWindowWindows(MenuItem selection, Modifiers mods) { - WindowList dialog { master = this }; - Window document = (Window)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; } @@ -7797,12 +8120,13 @@ 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); virtual void OnDrawOverChildren(Surface surface); - virtual bool OnFileModified(FileChange fileChange, char * param); - virtual bool OnSaveFile(char * fileName); + virtual bool OnFileModified(FileChange fileChange, const char * param); + virtual bool OnSaveFile(const char * fileName); // Virtual Methods -- Children management (To support Stacker, for lack of built-in auto-layout) // Note: A 'client' would refer to isActiveClient, rather than @@ -7819,8 +8143,8 @@ public: *cw = *w; *ch = *h; } - virtual void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving); - virtual void PreShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving); + virtual void ShowDecorations(Font captionFont, Surface surface, const char * name, bool active, bool moving); + virtual void PreShowDecorations(Font captionFont, Surface surface, const char * name, bool active, bool moving); virtual bool IsMouseMoving(int x, int y, int w, int h) { return false; @@ -7843,7 +8167,7 @@ public: // Notifications virtual bool Window::NotifyActivate(Window window, bool active, Window previous); virtual void Window::NotifyDestroyed(Window window, DialogResult result); - virtual void Window::NotifySaved(Window window, char * filePath); + virtual void Window::NotifySaved(Window window, const char * filePath); // Public Methods @@ -8031,15 +8355,14 @@ public: firewatchers font; - if(value.rootWindow && value.rootWindow.display && rootWindow) + if(value.rootWindow && value.rootWindow.display && rootWindow && created) { bool reloadGraphics = (oldParent.rootWindow == oldParent && value.rootWindow) || (!value.rootWindow && rootWindow == this) || (value.rootWindow.display && value.rootWindow.display.displaySystem != rootWindow.display.displaySystem); if(reloadGraphics) UnloadGraphics(false); - if(created) - SetupDisplay(); + SetupDisplay(); if(reloadGraphics) LoadGraphics(false, false); @@ -8119,7 +8442,7 @@ public: get { return master ? master : parent; } }; - property char * caption + property const char * caption { property_category $"Appearance" watchable @@ -8420,8 +8743,8 @@ public: { if(value) { - Window sibling; - /*for(sibling = parent.children.first; sibling; sibling = sibling.next) + /*Window sibling; + for(sibling = parent.children.first; sibling; sibling = sibling.next) if(sibling != this && sibling.style.isDefault) sibling.style.isDefault = false;*/ if(master.defaultControl) @@ -8690,11 +9013,6 @@ public: property_category $"Layout" isset { - Anchor thisAnchor = anchor; - SizeAnchor thisSizeAnchor = sizeAnchor; - bool leftRight = (anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none); - bool topBottom = (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none); - bool isClient = !sizeAnchor.isClientW && !sizeAnchor.isClientH; return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) || (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) && !sizeAnchor.isClientW && !sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h; @@ -9060,10 +9378,14 @@ public: if(true || !parent.activeChild) ActivateEx(true, false, true, true, null, null); */ - if(creationActivation == activate) + if(creationActivation == activate && guiApp.desktop.active) ActivateEx(true, false, true, true, null, null); - else if(creationActivation == flash && !object) - Flash(); + else if((creationActivation == activate || creationActivation == flash) && !object) + { + MakeActive(); + if(this == rootWindow) + Flash(); + } //SetVisibility(!parent.style.hidden && (style.hidden ? false : true)); Update(null); @@ -9084,7 +9406,7 @@ public: property bool isDocument { property_category $"Document" - set { style.isDocument = value; } + set { style.isDocument = value; if(value) SetupFileMonitor(); } get { return style.isDocument; } }; @@ -9221,11 +9543,13 @@ public: get { return (bool)noAutoScrollArea; } }; - property char * fileName + property const char * fileName { property_category $"Document" set { + SetupFileMonitor(); + if(menu && ((!fileName && value) || (fileName && !value))) { MenuItem item = menu.FindItem(MenuFileSave, 0); @@ -9243,8 +9567,10 @@ public: UpdateCaption(); // if(style.isDocument) +#if !defined(__EMSCRIPTEN__) if(!saving) fileMonitor.fileName = value; +#endif } get { return fileName; } }; @@ -9283,14 +9609,36 @@ public: property bool showInTaskBar { property_category $"Window Style" - set { style.showInTaskBar = value; } - get { return (style.showInTaskBar; } + set + { + style.showInTaskBar = value; +#if defined(__WIN32__) + Win32UpdateStyle(this); +#endif + } + get { return style.showInTaskBar; } }; property FileDialog saveDialog { set { saveDialog = value; } }; property bool isActiveClient { property_category $"Behavior" - set { style.isActiveClient = value; } + set + { + if(parent && style.isActiveClient != value && !style.hidden) + { + if(value) + { + if(state == minimized) parent.numIcons++; + parent.numPositions++; + } + else + { + if(state == minimized) parent.numIcons--; + parent.numPositions--; + } + } + style.isActiveClient = value; + } get { return style.isActiveClient; } }; @@ -9306,7 +9654,7 @@ public: }; //#if !defined(ECERE_VANILLA) - property char * name + property const char * name { property_category $"Design" get @@ -9320,7 +9668,7 @@ public: } }; //#endif - property char * displayDriver + property const char * displayDriver { property_category $"Behavior" set @@ -9366,7 +9714,7 @@ public: property Point clientStart { get { value = clientStart; } }; property Point absPosition { get { value = absPosition; } }; property Anchor normalAnchor { get { value = normalAnchor; } }; - // property Size normalSizeAnchor { get { value = normalSizeAnchor; } }; + property SizeAnchor normalSizeAnchor { get { value = normalSizeAnchor; } }; property bool active { get { return (bool)active; } }; property bool created { get { return (bool)created; } }; property bool destroyed { get { return (bool)destroyed; } }; @@ -9406,8 +9754,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 { @@ -9439,7 +9817,7 @@ public: }; property bool manageDisplay { get { return (bool)manageDisplay; } set { manageDisplay = value; } }; - property char * text + property const char * text { property_category $"Deprecated" watchable @@ -9536,23 +9914,15 @@ private: int numIcons; int positionID; +#if !defined(__EMSCRIPTEN__) Mutex mutex; +#endif WindowState lastState; - FileMonitor fileMonitor - { - this, FileChange { modified = true }; +#if !defined(__EMSCRIPTEN__) + FileMonitor fileMonitor; +#endif - bool OnFileNotify(FileChange action, char * param) - { - incref this; - fileMonitor.StopMonitoring(); - if(OnFileModified(action, param)) - fileMonitor.StartMonitoring(); - delete this; - return true; - } - }; FontResource setFont, systemFont; FontResource usedFont; FontResource captionFont; @@ -9568,6 +9938,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 @@ -9601,6 +9973,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 @@ -9608,7 +9981,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 @@ -9616,7 +10011,7 @@ public class CommonControl : Window // creationActivation = doNothing; ToolTip toolTip; - public property String toolTip + public property const String toolTip { property_category $"Appearance" set @@ -9653,7 +10048,7 @@ public class CommonControl : Window public class Percentage : float { - char * OnGetString(char * string, float * fieldData, bool * needClass) + const char * OnGetString(char * string, float * fieldData, bool * needClass) { int c; int last = 0; @@ -9676,7 +10071,7 @@ public class Percentage : float } }; -public void ApplySkin(Class c, char * name, void ** vTbl) +public void ApplySkin(Class c, const char * name, void ** vTbl) { char className[1024]; Class sc; @@ -9717,10 +10112,7 @@ public void ApplySkin(Class c, char * name, void ** vTbl) public void UnapplySkin(Class c) { - char className[1024]; - Class sc; subclass(Window) wc = (subclass(Window))c; - subclass(Window) base = (subclass(Window))c.base; OldLink d; if(wc.pureVTbl && c._vTbl != wc.pureVTbl) @@ -9764,176 +10156,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) + { + 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) - result = ((bool(*)(Window, int, int, Modifiers))(void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick])(controller.window, x, y, mods); + { + 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 @@ -9941,6 +10424,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); @@ -9954,6 +10438,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); @@ -9961,7 +10446,7 @@ public: virtual void V::OnUnloadGraphics(WindowController controller); private: - int (** windowVTbl)(); + public int (** windowVTbl)(); V controlled; Window window;