7 import "GuiApplication"
27 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
31 #if !defined(ECERE_VANILLA) && !defined(ECERE_NOTRUETYPE)
39 default extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
41 public enum DialogResult { cancel, yes, no, ok };
43 public class MouseButtons
46 bool left:1, right:1, middle:1;
49 public struct SizeAnchor
52 bool isClientW, isClientH;
57 #define SNAPDOWN(x, d) \
60 if(x < 0) x -= ((d) - Abs(x) % (d)); else x -= x % (d); \
63 #define SNAPUP(x, d) \
66 if(x > 0) x += ((d) - Abs(x) % (d)); else x += x % (d); \
69 /*static */define MAX_DIRTY_BACK = 10;
71 /////////////////////////////////////////////////////////////////////////////
72 ////////// EXTENT MANIPULATION //////////////////////////////////////////////
73 /////////////////////////////////////////////////////////////////////////////
75 #define ACCESS_ITEM(l, id) \
78 #define FASTLIST_LOOP(l, v) \
79 for(v = (BoxItem)l.first; v; v = (BoxItem)v.next)
81 #define FASTLIST_LOOPN(l, v, n) \
82 for(v = (BoxItem)l.first, n = (BoxItem)(v ? v.next : null); v; v = (BoxItem)next, n = (BoxItem)(v ? v.next : null))
85 #define ACCESS_ITEM(l, id) \
86 ((FastItem)(((id) == -1) ? null : (((byte *)((l).items)) + (id) * (l).itemSize)))
88 #define FASTLIST_LOOP(l, v) \
89 for(v = (void *)ACCESS_ITEM((l), (l).first); v; v = (void *)ACCESS_ITEM((l), v.next))
91 #define FASTLIST_LOOPN(l, v, n) \
92 for( v = (void *)ACCESS_ITEM((l), (l).first), \
93 n = v ? ((void *)ACCESS_ITEM((l), v.next)): null; \
94 v; v = n, n = n ? (void *)ACCESS_ITEM((l), n.next) : null)
97 private class FastItem : struct
102 private struct FastList
107 int count, size, itemSize;
114 first = last = free = -1;
122 // FASTLIST_LOOPN(this, item, next) { Delete(item); };
125 FastItem Add(uint itemSize)
128 if(free == -1 || !size)
135 newSize = (size + (size >> 1));
136 items = (FastItem)renew items byte[newSize * itemSize];
141 this.itemSize = itemSize;
142 items = (FastItem)new byte[newSize * itemSize];
145 for(c = size; c<newSize-1; c++)
147 ACCESS_ITEM(this, c).prev = -1;
148 ACCESS_ITEM(this, c).next = c+1;
150 ACCESS_ITEM(this, c).prev = -1;
151 ACCESS_ITEM(this, c).next = -1;
155 item = ACCESS_ITEM(this, free);
158 ACCESS_ITEM(this, item.prev).next = free;
168 void Delete(FastItem item)
171 ACCESS_ITEM(this, item.prev).next = item.next;
173 ACCESS_ITEM(this, item.next).prev = item.prev;
175 if(ACCESS_ITEM(this, first) == item)
177 if(ACCESS_ITEM(this, last) == item)
182 free = ((byte *)item - (byte *)items) / itemSize;
190 free = first = last = -1;
194 private class BoxItem : Item //FastItem
199 public /*private */struct Extent : OldList //FastList
208 //BoxItem extentBox = (BoxItem)Add(sizeof(class BoxItem));
209 Add(BoxItem { box = box });
212 void Copy(Extent source)
218 FASTLIST_LOOP(source, extentBox)
219 AddBox(extentBox.box);
222 void IntersectBox(Box box)
224 // Clip all boxes of extent against inside of the new box
225 BoxItem extentBox, next;
227 FASTLIST_LOOPN(this, extentBox, next)
229 if(box.left > extentBox.box.left) extentBox.box.left = box.left;
230 if(box.top > extentBox.box.top) extentBox.box.top = box.top;
231 if(box.right < extentBox.box.right) extentBox.box.right = box.right;
232 if(box.bottom < extentBox.box.bottom) extentBox.box.bottom = box.bottom;
233 if(extentBox.box.right < extentBox.box.left || extentBox.box.bottom < extentBox.box.top)
238 void ExcludeBox(Box box, Extent temp)
245 FASTLIST_LOOP(temp, extentBox)
247 if(extentBox.box.left < box.right && extentBox.box.right > box.left &&
248 extentBox.box.top < box.bottom && extentBox.box.bottom > box.top)
251 if(extentBox.box.top < box.top && extentBox.box.bottom >= box.top)
255 extentBox.box.left, extentBox.box.top,
256 extentBox.box.right, Min(extentBox.box.bottom, box.top -1)
262 if(extentBox.box.bottom > box.bottom && extentBox.box.top <= box.bottom)
266 extentBox.box.left, Max(extentBox.box.top,box.bottom +1),
267 extentBox.box.right, extentBox.box.bottom
273 if(extentBox.box.bottom >= box.top && extentBox.box.top <= box.bottom)
276 if(extentBox.box.left < box.left && extentBox.box.right >= box.left)
280 extentBox.box.left, Max(extentBox.box.top, box.top),
281 Min(extentBox.box.right, box.left-1), Min(extentBox.box.bottom, box.bottom)
287 if(extentBox.box.right > box.right && extentBox.box.left <= box.right)
291 Max(extentBox.box.left, box.right+1), Max(extentBox.box.top, box.top),
292 extentBox.box.right, Min(extentBox.box.bottom, box.bottom)
300 AddBox(extentBox.box);
306 void UnionBox(Box box, Extent temp)
308 BoxItem extentBox, next;
310 // First pass: check if this box is not already covered by one of the extent's box
311 FASTLIST_LOOP(this, extentBox)
313 if(extentBox.box.left <= box.left && extentBox.box.right >= box.right &&
314 extentBox.box.top <= box.top && extentBox.box.bottom >= box.bottom)
321 // Second pass: only keep boxes not completely covered in the new box
322 FASTLIST_LOOPN(this, extentBox, next)
324 if(extentBox.box.left >= box.left && extentBox.box.right <= box.right &&
325 extentBox.box.top >= box.top && extentBox.box.bottom <= box.bottom)
329 // Add the exclusion to the extent
330 ExcludeBox(box, temp);
333 if(box.bottom >= box.top && box.right >= box.left)
335 // Optimization: if the resulting boxes touch, add them smarter
336 FASTLIST_LOOP(this, extentBox)
338 if(box.top == extentBox.box.top && box.bottom == extentBox.box.bottom)
340 if(Abs(box.right - extentBox.box.left) <= 1)
342 extentBox.box.left = box.left;
345 else if(Abs(box.left - extentBox.box.right) <= 1)
347 extentBox.box.right = box.right;
351 else if(box.left == extentBox.box.left && box.right == extentBox.box.right)
353 if(Abs(box.bottom - extentBox.box.top) <= 1)
355 extentBox.box.top = box.top;
358 else if(Abs(box.top - extentBox.box.bottom) <= 1)
360 extentBox.box.bottom = box.bottom;
372 void Union(Extent b, Extent temp)
376 FASTLIST_LOOP(b, extentBox)
377 UnionBox(extentBox.box, temp);
380 void Intersection(Extent b, Extent temp, Extent temp2, Extent temp3)
387 FASTLIST_LOOP(b, extentBox)
390 temp2.IntersectBox(extentBox.box);
397 void Exclusion(Extent b, Extent temp)
400 FASTLIST_LOOP(b, extentBox)
401 ExcludeBox(extentBox.box, temp);
404 void Offset(int x, int y)
407 FASTLIST_LOOP(this, extentBox)
409 extentBox.box.left += x;
410 extentBox.box.top += y;
411 extentBox.box.right += x;
412 extentBox.box.bottom += y;
417 private define MINIMIZED_WIDTH = 160;
418 private define CASCADE_SPACE = 16;
420 // namespace Windows;
422 private class ScrollFlags
424 bool snapX:1, snapY:1, dontHide:1;
427 public class BorderBits { public: bool contour:1, fixed:1, sizable:1, deep:1, bevel:1; };
429 class WindowBits : BorderBits
431 BorderBits borderBits:5:0;
432 bool hidden:1, isActiveClient:1, hasHorzScroll:1, hasVertScroll:1, stayOnTop:1, modal:1, unused1:1, isDefault:1, inactive:1, isRemote:1, drawBehind:1;
433 bool interim:1, tabCycle:1, noCycle:1, dontScrollHorz:1, dontScrollVert:1, hasMaximize:1, hasMinimize:1, hasClose:1;
434 bool embedded:1, unused2:1, hasMenuBar:1, isDocument:1, showInTaskBar:1, hasStatusBar:1, nonClient:1, clickThrough:1;
437 public enum BorderStyle : BorderBits
440 contour = BorderBits { contour = true },
441 fixed = BorderBits { fixed = true } | contour,
442 sizable = BorderBits { sizable = true } | fixed,
443 deep = BorderBits { deep = true },
444 bevel = BorderBits { bevel = true },
445 sizableDeep = sizable|deep,
446 sizableBevel = sizable|bevel,
447 fixedDeep = fixed|deep,
448 fixedBevel = fixed|bevel,
449 deepContour = deep|contour
452 public enum CreationActivationOption
454 activate, flash, doNothing
457 public enum WindowState { normal, minimized, maximized };
459 private class ResPtr : struct
466 private class HotKeySlot : struct
468 HotKeySlot prev, next;
476 class_data char * icon;
478 class_default_property text;
479 // class_initialize GuiApplication::Initialize;
480 class_designer FormDesigner;
481 class_property char * icon
483 set { class_data(icon) = value; }
484 get { return class_data(icon); }
489 if(guiApp) guiApp.Initialize(true);
491 if(guiApp && guiApp.currentSkin && ((subclass(Window))_class).pureVTbl)
493 if(_vTbl == ((subclass(Window))_class).pureVTbl)
495 _vTbl = _class._vTbl;
497 else if(_vTbl != _class._vTbl)
500 for(m = 0; m < _class.vTblSize; m++)
502 if(_vTbl[m] == ((subclass(Window))_class).pureVTbl[m])
503 _vTbl[m] = _class._vTbl[m];
508 //tempExtents[0] = { /*first = -1, last = -1, free = -1*/ };
509 //tempExtents[1] = { /*first = -1, last = -1, free = -1*/ };
510 //tempExtents[2] = { /*first = -1, last = -1, free = -1*/ };
511 //tempExtents[3] = { /*first = -1, last = -1, free = -1*/ };
515 // caption = CopyString(class.name);
517 children.offset = (byte*)&prev - (byte*)this;
518 childrenOrder.circ = true;
519 childrenCycle.circ = true;
521 maxSize = Size { MAXINT, MAXINT };
525 //style.isActiveClient = true;
528 modifyVirtArea = true;
529 manageDisplay = true;
531 // scrollFlags = ScrollFlags { snapX = true, snapY = true };
532 sbStep.x = sbStep.y = 8;
534 if(guiApp) // dynamic_cast<GuiApplication>(thisModule)
536 cursor = guiApp.GetCursor(arrow);
537 property::parent = guiApp.desktop;
548 stopwatching(parent, font);
552 // Prevent destructor from being called again...
558 /////////////////////////////////
561 OldLink slave = master.slaves.FindLink(this);
562 master.slaves.Delete(slave);
569 parent.childrenCycle.Remove(cycle);
571 parent.childrenOrder.Remove(order);
572 parent.children.Remove(this);
577 /////////////////////////////////
579 while(ptr = resources.first)
582 resources.Delete(ptr);
589 for(child = children.first; child; child = child.next)
591 // child.stopwatching(this, font);
593 eInstance_StopWatching(this, __ecereProp___ecereNameSpace__ecere__gui__Window_font, child);
594 // Don't want property here
595 *&child.parent = null;
598 while(slave = slaves.first)
600 // Don't want property here
601 *&((Window)slave.data).master = null;
602 slaves.Delete(slave);
605 // Because we do a decref in DestroyEx...
613 // Why was this commented?
614 //if(this != guiApp.desktop)
627 if(((subclass(Window))_class).pureVTbl)
629 if(_vTbl == _class._vTbl)
631 _vTbl = ((subclass(Window))_class).pureVTbl;
636 for(m = 0; m < _class.vTblSize; m++)
638 if(_vTbl[m] == _class._vTbl[m])
639 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
643 if(_vTbl == ((subclass(Window))_class).pureVTbl || _vTbl == _class._vTbl)
646 dirtyArea.Free(null);
647 renderArea.Free(null);
648 overRenderArea.Free(null);
649 clipExtent.Free(null);
650 scrollExtent.Free(null);
651 dirtyBack.Free(null);
655 tempExtents[0].Free(null);
656 tempExtents[1].Free(null);
657 tempExtents[2].Free(null);
658 tempExtents[3].Free(null);
663 //#if !defined(ECERE_VANILLA)
664 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
666 if(this == activeDesigner)
670 char * name = property::name;
671 return name ? name : "";
676 #if !defined(ECERE_VANILLA) && !defined(ECERE_NOTRUETYPE)
677 bool OnGetDataFromString(char * string)
679 FormDesigner designer = (FormDesigner)activeDesigner.classDesigner;
682 if(!strcmp(string, "this") || !strcmp(string, designer.form.name))
683 this = designer.form;
684 else if(!strcmpi(string, "(Desktop)"))
685 this = activeDesigner;
687 return activeDesigner.FindObject(&this, string);
693 // --- Window updates system ---
695 // Setup a bitmap for Redrawing on client area of Window
696 Surface Redraw(Box box)
698 Surface surface = null;
700 Box clientArea = this.clientArea;
704 mox.left -= clientStart.x;
705 mox.top -= clientStart.y;
706 mox.right -= clientStart.x;
707 mox.bottom -= clientStart.y;
709 mox.Clip(clientArea);
710 // mox.ClipOffset(against, scrolledPos.x, scrolledPos.y);
712 if((!guiApp.fullScreenMode || guiApp.desktop.active) && display && mox.right >= mox.left && mox.bottom >= mox.top)
714 int x = absPosition.x + clientStart.x;
715 int y = absPosition.y + clientStart.y;
716 if(!guiApp.fullScreenMode || is3D)
718 x -= rootWindow.absPosition.x;
719 y -= rootWindow.absPosition.y;
723 x += rootWindow.parent.clientStart.x;
724 y += rootWindow.parent.clientStart.y;
726 mox.left += rootWindow.parent.clientStart.x;
727 mox.top += rootWindow.parent.clientStart.y;
728 mox.right += rootWindow.parent.clientStart.x;
729 mox.bottom += rootWindow.parent.clientStart.y;
733 surface = display.GetSurface(x, y, mox);
736 surface.width = clientSize.w;
737 surface.height = clientSize.h;
743 // Setup a bitmap for Redrawing on full Window
744 Surface RedrawFull(Box box)
746 Surface surface = null;
754 if((!guiApp.fullScreenMode || guiApp.desktop.active) && display && box.right >= box.left && box.bottom >= box.top)
756 int x = absPosition.x;
757 int y = absPosition.y;
758 if(!guiApp.fullScreenMode || is3D)
760 x -= rootWindow.absPosition.x;
761 y -= rootWindow.absPosition.y;
765 x += rootWindow.parent.clientStart.x;
766 y += rootWindow.parent.clientStart.y;
768 mox.left += rootWindow.parent.clientStart.x;
769 mox.top += rootWindow.parent.clientStart.y;
770 mox.right += rootWindow.parent.clientStart.x;
771 mox.bottom += rootWindow.parent.clientStart.y;
775 surface = display.GetSurface(x, y, mox);
778 surface.width = size.w;
779 surface.height = size.h;
785 void FigureCaption(char * caption)
789 strcpy(caption, this.caption);
790 if(style.isDocument || fileName)
792 if(caption[0]) strcat(caption, " - ");
794 strcat(caption, fileName);
798 sprintf(title, "Untitled %d", documentID);
799 strcat(caption, title);
802 strcat(caption, " *");
804 if(activeClient && menuBar &&
805 activeClient.state == maximized)
807 if(activeClient.caption)
809 if(caption[0]) strcat(caption, " - ");
810 strcat(caption, activeClient.caption);
812 if(activeClient.style.isDocument || activeClient.fileName)
814 if(caption[0]) strcat(caption, " - ");
815 strcat(caption, "[");
816 if(activeClient.fileName)
817 strcat(caption, activeClient.fileName);
821 sprintf(title, "Untitled %d", activeClient.documentID);
822 strcat(caption, title);
824 if(activeClient.modifiedDocument)
825 strcat(caption, " *");
826 strcat(caption, "]");
831 // Code for returning dirty from ScrollDisplay:
833 for(d = 0; d<scrollExtent.count; d++)
835 Box * box = &scrollExtent.boxes[d];
841 Min(box.right, box.left-scroll.x),box.bottom
843 dirtyArea.UnionBox(update);
849 Max(box.left, box.right-scroll.x), box.top,
850 box.right, box.bottom
852 dirtyArea.UnionBox(update);
860 box.right, Min(box.bottom, box.top-scroll.y),
862 dirtyArea.UnionBox(update);
868 box.left, Max(box.top, box.bottom-scroll.y),
869 box.right, box.bottom
871 dirtyArea.UnionBox(update);
876 void UpdateDecorations(void)
878 // TODO: *** TEMPORARY HACK ***
885 Update({ -clientStart.x, -clientStart.y, -clientStart.x + size.w-1, 0 });
887 Update({ -clientStart.x, clientSize.h, -clientStart.x + size.w-1, -clientStart.y + size.h-1 });
889 Update({ -clientStart.x,0, -1, clientSize.h-1 });
891 Update({ clientSize.w, 0, -clientStart.x + size.w-1, clientSize.h-1 });
894 // Returns w & h for Position
895 void ComputeAnchors(Anchor anchor, SizeAnchor sizeAnchor, int *ox, int *oy, int *ow, int *oh)
897 Window parent = this.parent ? this.parent : guiApp.desktop;
898 int vpw = parent ? parent.clientSize.w : 0;
899 int vph = parent ? parent.clientSize.h : 0;
900 int pw = parent ? parent.clientSize.w : 0;
901 int ph = parent ? parent.clientSize.h : 0;
902 int w = sizeAnchor.size.w, h = sizeAnchor.size.h;
903 int x = anchor.left.distance, y = anchor.top.distance;
905 MinMaxValue ew = 0, eh = 0;
907 float cascadeW, cascadeH;
909 int tilingW, tilingH, tilingSplit, tilingLastH;
910 int addX = 0, addY = 0;
912 if(parent && rootWindow == this && guiApp && guiApp.interfaceDriver)
914 Window masterWindow = this;
915 Box box { addX, addY, addX + vpw - 1, addY + vph - 1 };
918 if(master == guiApp.desktop)
919 masterWindow = guiApp.desktop.activeChild;
921 masterWindow = master.rootWindow;
922 if(!masterWindow) masterWindow = this;
924 guiApp.interfaceDriver.GetScreenArea(masterWindow, box);
925 if((anchor.left.type == offset && anchor.right.type == offset) || anchor.left.type == none)
928 pw = vpw = box.right - box.left + 1;
930 if((anchor.top.type == offset && anchor.bottom.type == offset) || anchor.top.type == none)
933 ph = vph = box.bottom - box.top + 1;
949 vpw = pw = parent.size.w;
950 vph = ph = parent.size.h;
952 else if(!style.fixed /*|| style.isDocument*/)
954 if(!style.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
955 if(!style.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
957 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
960 Desktop3D_FixSize(&pw, &ph);
961 Desktop3D_FixSize(&vpw, &vph);
964 if(pw < skinMinSize.w) pw = skinMinSize.w;
965 if(ph < skinMinSize.h) ph = skinMinSize.h;
966 if(vpw < skinMinSize.w) vpw = skinMinSize.w;
967 if(vph < skinMinSize.h) vph = skinMinSize.h;
969 // TODO: Must fix what we're snapping
974 SNAPUP(x, textCellW);
976 else if(anchor.right.type)
978 SNAPDOWN(x, textCellW);
983 SNAPUP(y, textCellH);
985 else if(anchor.bottom.type)
987 SNAPDOWN(y, textCellH);
991 GetDecorationsSize(&ew, &eh);
993 if(anchor.left.type >= cascade && (state == normal /*|| state == Hidden*/))
995 if(parent.sbv && !parent.sbv.style.hidden)
996 pw += guiApp.currentSkin.VerticalSBW();
997 if(parent.sbh && !parent.sbh.style.hidden)
998 ph += guiApp.currentSkin.HorizontalSBH();
1000 if(anchor.left.type == cascade)
1002 w = (int)(pw * 0.80);
1003 h = (int)(ph * 0.80);
1005 else if(anchor.left.type >= vTiled)
1010 numTiling = parent.numPositions - parent.numIcons;
1011 if(parent.numIcons) ph -= guiApp.textMode ? 16 : 24;
1012 if(anchor.left.type == vTiled)
1014 tilingH = (int)sqrt(numTiling);
1015 tilingW = numTiling / tilingH;
1019 tilingW = (int)sqrt(numTiling);
1020 tilingH = numTiling / tilingW;
1023 leftOver = numTiling - tilingH * tilingW;
1026 tilingSplit = (tilingW - leftOver) * tilingH;
1027 tilingLastH = tilingH+1;
1030 tilingSplit = numTiling;
1032 if(positionID >= tilingSplit)
1034 x = pw * (tilingSplit / tilingH + (positionID - tilingSplit) / tilingLastH)/tilingW;
1035 y = ph * ((positionID - tilingSplit) % tilingLastH) / tilingLastH;
1036 x2 = pw * (tilingSplit/tilingH + (positionID - tilingSplit) / tilingLastH + 1)/tilingW;
1037 y2 = ph * (((positionID - tilingSplit) % tilingLastH) + 1) / tilingLastH;
1041 x = pw * (positionID / tilingH) / tilingW;
1042 y = ph * (positionID % tilingH) / tilingH;
1043 x2 = pw * (positionID / tilingH + 1) / tilingW;
1044 y2 = ph * ((positionID % tilingH) + 1) / tilingH;
1048 SNAPDOWN(x, textCellW);
1049 SNAPDOWN(y, textCellH);
1050 SNAPDOWN(x2, textCellW);
1051 SNAPDOWN(y2, textCellH);
1059 if(sizeAnchor.isClientW) w += ew;
1060 if(sizeAnchor.isClientH) h += eh;
1062 if(anchor.left.type == offset)
1063 x = anchor.left.distance;
1064 else if(anchor.left.type == relative)
1065 x = (anchor.left.percent < 0) ? ((int)(vpw * anchor.left.percent - 0.5)) : (int)(vpw * anchor.left.percent + 0.5);
1066 else if(anchor.right.type == relative)
1067 // ex = (anchor.right.percent < 0) ? ((int)(vpw * anchor.right.percent + 0)) : ((int)(vpw * anchor.right.percent + 0));
1068 ex = (anchor.right.percent < 0) ? ((int)(vpw * (1.0-anchor.right.percent) + 0)) : ((int)(vpw * (1.0-anchor.right.percent) + 0));
1069 else if(anchor.right.type == offset)
1070 ex = vpw - anchor.right.distance;
1072 if(anchor.top.type == offset)
1073 y = anchor.top.distance;
1074 else if(anchor.top.type == relative)
1075 y = (anchor.top.percent < 0) ? ((int)(vph * anchor.top.percent - 0.5)) : ((int)(vph * anchor.top.percent + 0.5));
1076 else if(anchor.bottom.type == relative)
1077 //ey = (anchor.bottom.percent < 0) ? ((int)(vph * anchor.bottom.percent + 0)) : ((int)(vph * anchor.bottom.percent + 0));
1078 ey = (anchor.bottom.percent < 0) ? ((int)(vph * (1.0-anchor.bottom.percent) + 0)) : ((int)(vph * (1.0-anchor.bottom.percent) + 0));
1079 else if(anchor.bottom.type == offset)
1080 ey = vph - anchor.bottom.distance;
1082 if(anchor.left.type && anchor.right.type)
1084 switch(anchor.right.type)
1087 ex = pw * (1.0f-anchor.right.percent);
1088 w = Max((int)(ex + 0.5) - x, 0);
1091 ex = vpw - anchor.right.distance;
1092 w = Max((int)(ex + 0.5) - x, 0);
1096 if(anchor.top.type && anchor.bottom.type)
1098 switch(anchor.bottom.type)
1101 ey = ph * (1.0f-anchor.bottom.percent);
1102 h = Max((int)(ey + 0.5) - y, 0);
1105 ey = vph - anchor.bottom.distance;
1106 h = Max((int)(ey + 0.5) - y, 0);
1115 if(state == normal /*|| state == Hidden*/)
1117 bool addSbV = false, addSbH = false;
1119 if(sizeAnchor.isClientW || (anchor.left.type && anchor.right.type)) w = Max(w, 1); else w = Max(w, 0);
1120 if(sizeAnchor.isClientH || (anchor.top.type && anchor.bottom.type)) h = Max(h, 1); else h = Max(h, 0);
1122 w = Max(w, minSize.w);
1123 h = Max(h, minSize.h);
1124 w = Min(w, maxSize.w);
1125 h = Min(h, maxSize.h);
1127 if((sizeAnchor.isClientW || !w || (anchor.left.type && anchor.right.type)) && reqScrollArea.h > h /*&& w*/ && sbv)
1129 if(w) w -= guiApp.currentSkin.VerticalSBW();
1132 if((sizeAnchor.isClientH || !h || (anchor.top.type && anchor.bottom.type)) && reqScrollArea.w > w /*&& h*/ && sbh)
1134 if(h) h -= guiApp.currentSkin.HorizontalSBH();
1138 if(!OnResizing(&w, &h))
1144 if((addSbV)) // || reqScrollArea.h > h) && sbv)
1145 w += guiApp.currentSkin.VerticalSBW();
1146 if((addSbH)) // || reqScrollArea.w > w) && sbh)
1147 h += guiApp.currentSkin.HorizontalSBH();
1149 w = Max(w, skinMinSize.w);
1150 h = Max(h, skinMinSize.h);
1163 SNAPDOWN(w, textCellW);
1164 SNAPDOWN(h, textCellH);
1167 if(anchor.left.type == cascade && (state == normal /*|| state == Hidden*/))
1169 if(parent.numIcons) ph -= guiApp.textMode ? 16 : 24;
1172 (pw - w) / CASCADE_SPACE,
1173 (ph - h) / CASCADE_SPACE);
1179 cascW = (pw - w) / (numCascade-1);
1180 cascH = (ph - h) / (numCascade-1);
1181 SNAPDOWN(cascW, textCellW);
1182 SNAPDOWN(cascH, textCellH);
1183 cascadeW = (float)cascW;
1184 cascadeH = (float)cascH;
1188 numCascade = Max(numCascade, 2);
1189 cascadeW = (float)(pw - w) / (numCascade-1);
1190 cascadeH = (float)(ph - h) / (numCascade-1);
1193 x = (int)((positionID % numCascade) * cascadeW);
1194 y = (int)((positionID % numCascade) * cascadeH);
1196 else if(anchor.left.type < vTiled)
1198 if(!anchor.left.type || anchor.horz.type == middleRelative)
1200 if(!anchor.right.type)
1202 if(anchor.horz.type == middleRelative)
1203 x = (int)(vpw * (0.5 + anchor.horz.percent) - w / 2);
1205 x = vpw / 2 + anchor.horz.distance - w / 2;
1211 // case A_EDGE: x = x - w; break;
1213 if(!anchor.top.type || anchor.vert.type == middleRelative)
1215 if(!anchor.bottom.type)
1217 if(anchor.vert.type == middleRelative)
1218 y = (int)(vph * (0.5 + anchor.vert.percent) - h / 2);
1220 y = vph / 2 + anchor.vert.distance - h / 2;
1226 // case A_EDGE: y = y - h; break;
1229 if((state == normal /*|| state == Hidden*/) && !OnMoving(&x, &y, w, h))
1237 SNAPDOWN(x, textCellW);
1238 SNAPDOWN(y, textCellH);
1250 if(anchored && style.fixed && style.isActiveClient)
1255 void UpdateCaret(bool forceUpdate, bool erase)
1257 static Window lastWindow = null;
1258 static int caretX, caretY, caretSize;
1260 if(guiApp && guiApp.caretOwner == this)
1262 int x = caretPos.x - scroll.x;
1263 int y = caretPos.y - scroll.y;
1265 if((erase || this.caretSize) &&
1266 x >= clientArea.left && x <= clientArea.right &&
1267 y >= clientArea.top && y <= clientArea.bottom)
1271 guiApp.interfaceDriver.SetCaret(
1272 x + absPosition.x + clientStart.x,
1273 y + absPosition.y + clientStart.y, this.caretSize);
1274 guiApp.caretEnabled = true;
1276 if(erase || lastWindow != this || caretX != x || caretY != y || caretSize != this.caretSize || forceUpdate)
1280 if(lastWindow != this)
1282 updateBox.left = x + 1;
1284 updateBox.right = x + 2;
1285 updateBox.bottom = y + this.caretSize - 1;
1289 updateBox.left = Min(x + 1, caretX + 1);
1290 updateBox.top = Min(y, caretY);
1291 updateBox.right = Max(x + 2, caretX + 2);
1292 updateBox.bottom = Max(y + this.caretSize - 1, caretY + caretSize - 1);
1295 guiApp.caretOwner.Update(updateBox);
1302 caretSize = this.caretSize;
1308 guiApp.interfaceDriver.SetCaret(0,0,0);
1309 guiApp.caretEnabled = false;
1315 void SetPosition(int x, int y, int w, int h, bool modifyArea, bool modifyThisArea, bool modifyClientArea)
1320 scrolledPos.x = position.x = x;
1321 scrolledPos.y = position.y = y;
1323 clientSize.w = size.w = w;
1324 clientSize.h = size.h = h;
1326 if(parent && !style.nonClient)
1328 //if(!style.fixed || style.isDocument)
1330 if(!style.dontScrollHorz) scrolledPos.x -= parent.scroll.x;
1331 if(!style.dontScrollVert) scrolledPos.y -= parent.scroll.y;
1335 clientStart.x = clientStart.y = 0;
1337 SetWindowArea(&clientStart.x, &clientStart.y, &size.w, &size.h, &clientSize.w, &clientSize.h);
1339 //if(!activeClient || activeClient.state != maximized)
1340 if(!noAutoScrollArea)
1342 // Check if scroll area must be modified
1343 if(guiApp && !guiApp.modeSwitching && (sbv || sbh))
1345 bool foundChild = false;
1347 int cw = clientSize.w;// + ((!sbv || sbv.range > 1) ? guiApp.currentSkin.VerticalSBW() : 0);
1348 int ch = clientSize.h;// + ((!sbh || sbh.rangw > 1) ? guiApp.currentSkin.HorizontalSBH() : 0);
1349 for(child = children.first; child; child = child.next)
1351 if(child.modifyVirtArea && !child.style.hidden && child.created && /*!child.anchored &&*/
1352 !child.style.dontScrollHorz && !child.style.dontScrollVert && !child.style.nonClient)
1354 if(child.stateAnchor.right.type == none && child.stateAnchor.left.type == offset)
1355 w = Max(w, child.position.x + child.size.w);
1356 else if(child.stateAnchor.right.type == none && child.stateAnchor.left.type == none)
1357 w = Max(w, Max(child.position.x, 0) + child.size.w);
1358 if(child.stateAnchor.bottom.type == none && child.stateAnchor.top.type == offset)
1359 h = Max(h, child.position.y + child.size.h);
1360 else if(child.stateAnchor.bottom.type == none && child.stateAnchor.top.type == none)
1361 h = Max(h, Max(child.position.y, 0) + child.size.h);
1366 if(foundChild && (w > cw || h > ch))
1368 //if((w > reqScrollArea.w) || (h > reqScrollArea.w))
1370 int stepX = sbStep.x, stepY = sbStep.y;
1371 // Needed to make snapped down position match the skin's check of client area
1372 // against realvirtual
1375 SNAPDOWN(stepX, textCellW);
1376 SNAPDOWN(stepY, textCellH);
1377 stepX = Max(stepX, textCellW);
1378 stepY = Max(stepY, textCellH);
1380 if(scrollFlags.snapX)
1382 if(scrollFlags.snapY)
1385 reqScrollArea.w = w;
1386 reqScrollArea.h = h;
1389 else if(reqScrollArea.w || reqScrollArea.h)
1391 reqScrollArea.w = 0;
1392 reqScrollArea.h = 0;
1393 SetScrollPosition(0,0);
1398 // Automatic MDI Client Scrolling Area Adjustment
1399 if(parent && !parent.noAutoScrollArea)
1401 if(modifyArea && modifyVirtArea /*&& !anchored*/ && (parent.sbv || parent.sbh) &&
1402 !style.dontScrollHorz && !style.dontScrollVert && !style.nonClient)
1404 Window parent = this.parent;
1405 int w = parent.reqScrollArea.w;
1406 int h = parent.reqScrollArea.h;
1408 if(stateAnchor.right.type == none && stateAnchor.left.type == offset)
1409 w = Max(w, position.x + size.w);
1410 else if(stateAnchor.right.type == none && stateAnchor.left.type == none)
1411 w = Max(w, Max(position.x, 0) + size.w);
1412 if(stateAnchor.bottom.type == none && stateAnchor.top.type == offset)
1413 h = Max(h, position.y + size.h);
1414 else if(stateAnchor.bottom.type == none && stateAnchor.top.type == none)
1415 h = Max(h, Max(position.y, 0) + size.h);
1417 if((w > parent.clientSize.w && w > parent.reqScrollArea.w) ||
1418 (h > parent.clientSize.h && h > parent.reqScrollArea.h))
1420 /*bool resize = false;
1421 int stepX = parent.sbStep.x, stepY = parent.sbStep.y;
1422 // Needed to make snapped down position match the skin's check of client area
1423 // against realvirtual
1426 SNAPDOWN(stepX, textCellW);
1427 SNAPDOWN(stepY, textCellH);
1428 stepX = Max(stepX, textCellW);
1429 stepY = Max(stepY, textCellH);
1431 if(parent.scrollFlags.snapX)
1433 if(parent.scrollFlags.snapY)
1435 if(parent.reqScrollArea.w != w || parent.reqScrollArea.h != h)
1437 parent.reqScrollArea.w = w;
1438 parent.reqScrollArea.h = h;*/
1440 // parent.UpdateScrollBars(true, true);
1441 parent.Position(parent.position.x, parent.position.y, parent.size.w, parent.size.h,
1442 false, true, true, true, false, false);
1447 GetRidOfVirtualArea();
1451 UpdateScrollBars(modifyThisArea, false);
1452 else if(guiApp.currentSkin)
1455 &clientStart.x, &clientStart.y, &size.w, &size.h, &clientSize.w, &clientSize.h);
1457 if(sbv && (scrollFlags.dontHide || sbv.range > 1))
1458 clientSize.w -= guiApp.currentSkin.VerticalSBW();
1459 if(sbh && (scrollFlags.dontHide || sbh.range > 1))
1460 clientSize.h -= guiApp.currentSkin.HorizontalSBH();
1463 scrollArea.w = Max(clientSize.w, reqScrollArea.w);
1464 scrollArea.h = Max(clientSize.h, reqScrollArea.h);
1466 absPosition = scrolledPos;
1467 if(guiApp && guiApp.driver != null && guiApp.interfaceDriver)
1468 guiApp.interfaceDriver.OffsetWindow(this, &absPosition.x, &absPosition.y);
1470 if(this != guiApp.desktop && parent)
1472 absPosition.x += parent.absPosition.x;
1473 absPosition.y += parent.absPosition.y;
1474 if(!style.nonClient && this != guiApp.desktop)
1476 absPosition.x += parent.clientStart.x;
1477 absPosition.y += parent.clientStart.y;
1481 box = Box { 0, 0, size.w - 1, size.h - 1 };
1486 // Clip against parent's client area
1487 box.ClipOffset(against, scrolledPos.x, scrolledPos.y);
1489 // Compute client area in this window coordinate system
1490 clientArea.left = 0;
1492 clientArea.right = clientSize.w - 1;
1493 clientArea.bottom = clientSize.h - 1;
1495 // Clip against parent's client area
1497 clientArea.ClipOffset(against, scrolledPos.x + clientStart.x, scrolledPos.y + clientStart.y);
1501 //absPosition.x -= parent.clientStart.x;
1502 //absPosition.y -= parent.clientStart.y;
1505 // Adjust all children
1506 for(child = children.first; child; child = child.next)
1507 child.SetPosition(child.position.x, child.position.y, child.size.w, child.size.h, false, true, true);
1509 UpdateCaret(false, false);
1512 void GetRidOfVirtualArea(void)
1514 if(parent && !parent.destroyed && style.fixed &&
1515 !style.dontScrollHorz && !style.dontScrollVert && !style.nonClient &&
1516 parent.reqScrollArea.w && parent.reqScrollArea.h)
1518 if(!parent.noAutoScrollArea)
1522 for(child = children.first; child; child = child.next)
1524 if(child.modifyVirtArea && !child.style.dontScrollHorz && !child.style.dontScrollVert && !child.style.nonClient)
1526 if(child.position.x + child.size.w > parent.clientSize.w + ((!parent.sbv || parent.sbv.style.hidden) ? 0 : guiApp.currentSkin.VerticalSBW()) ||
1527 child.position.y + child.size.h > parent.clientSize.h + ((!parent.sbh || parent.sbh.style.hidden) ? 0 : guiApp.currentSkin.HorizontalSBH()))
1536 Window parent = this.parent;
1538 parent.position.x, parent.position.y, parent.size.w, parent.size.h,
1539 false, true, true, true, false, false);
1541 parent.SetScrollArea(0,0,true);
1542 parent.SetScrollPosition(0,0);
1548 public void ExternalPosition(int x, int y, int w, int h)
1550 Position(x, y, w, h, false, true, true, true, false, false);
1553 // (w, h): Full window size
1554 bool Position(int x, int y, int w, int h, bool force, bool processAnchors, bool modifyArea, bool updateScrollBars, bool thisOnly, bool changeRootWindow)
1556 bool result = false;
1557 int oldCW = clientSize.w, oldCH = clientSize.h;
1558 bool clientResized, windowResized, windowMoved;
1560 bool realResized = size.w != w || size.h != h;
1562 // TOCHECK: This wasn't in ecere.dll
1563 //if(!parent) return true;
1564 if(destroyed) return false;
1566 windowMoved = position.x != x || position.y != y || force;
1568 // windowResized = realResized || force;
1569 windowResized = size.w != w || size.h != h || force;
1571 if(rootWindow != this && display && !display.flags.flipping && scrolledPos.x != MININT)
1577 scrolledPos.x - parent.clientStart.x + this.box.left, scrolledPos.y - parent.clientStart.y + this.box.top,
1578 scrolledPos.x - parent.clientStart.x + this.box.right,
1579 scrolledPos.y - parent.clientStart.y + this.box.bottom
1585 Box box { scrolledPos.x + this.box.left, scrolledPos.y + this.box.top, scrolledPos.x + this.box.right, scrolledPos.y + this.box.bottom};
1590 SetPosition(x, y, w, h, true, modifyArea, updateScrollBars);
1592 clientResized = oldCW != clientSize.w || oldCH != clientSize.h || force;
1594 if(display && rootWindow != this)
1597 if(guiApp && guiApp.windowMoving)
1599 if(guiApp.windowMoving.style.nonClient)
1600 guiApp.windowMoving.parent.SetMouseRangeToWindow();
1602 guiApp.windowMoving.parent.SetMouseRangeToClient();
1614 // Process Anchored Children
1618 for(child = children.first; child; child = child.next)
1621 ((child.stateAnchor.left.type != offset ||
1622 child.stateAnchor.top.type != offset ||
1623 child.stateAnchor.right.type != none ||
1624 child.stateAnchor.bottom.type != none) ||
1625 child.state == maximized || child.state == minimized))
1627 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor,
1629 // child.Position(x, y, w, h, false, true, true, true, false);
1630 // This must be true cuz otherwise we're gonna miss everything since we SetPosition recursively already
1631 child.Position(x, y, w, h, true, true, true, true, false, true /*false*/);
1637 // Is this gonna cause other problems? Commented out for the FileDialog end bevel bug
1638 //if(updateScrollBars)
1640 OnResize(clientSize.w, clientSize.h);
1642 if((clientResized || windowMoved) && created)
1643 OnPosition(position.x, position.y, clientSize.w, clientSize.h);
1645 if(guiApp.interimWindow && guiApp.interimWindow.master.rootWindow == this)
1647 Window master = guiApp.interimWindow.master;
1648 master.OnPosition(master.position.x, master.position.y, master.clientSize.w, master.clientSize.h);
1651 if(rootWindow == this && !is3D)
1655 x -= guiApp.desktop.absPosition.x;
1656 y -= guiApp.desktop.absPosition.y;
1658 //guiApp.Log("Position %s\n", caption);
1659 if(windowResized || windowMoved)
1660 if(display && !display.flags.memBackBuffer && changeRootWindow)
1661 guiApp.interfaceDriver.PositionRootWindow(this, x, y, w, h, windowMoved, windowResized); //realResized);
1663 if(!guiApp.fullScreenMode && this != guiApp.desktop && (windowResized || windowMoved))
1664 for(child = parent.children.first; child && child != this; child = child.next)
1665 if(child.rootWindow)
1666 guiApp.interfaceDriver.UpdateRootWindow(child.rootWindow);
1670 if(windowMoved || windowResized)
1672 display.Lock(true /*false*/);
1675 display.Position(absPosition.x, absPosition.y);
1678 // result = realResized ? display.Resize(size.w, size.h) : true;
1679 result = manageDisplay ? display.Resize(size.w, size.h) : true;
1683 else if(clientResized)
1685 // --- Major Slow Down / Fix OpenGL Resizing Main Window Lag
1688 if(!guiApp.fullScreenMode && !guiApp.modeSwitching && this == rootWindow)
1692 if(windowMoved || windowResized)
1697 if(guiApp.driver && changeRootWindow)
1699 if(windowResized || windowMoved)
1700 if(!display || display.flags.memBackBuffer)
1701 guiApp.interfaceDriver.PositionRootWindow(this,
1702 x, y, w, h, windowMoved, windowResized);
1703 guiApp.interfaceDriver.UpdateRootWindow(this);
1705 for(child = children.first; child; child = child.next)
1707 if(child.is3D && child.created)
1709 // Copy Display Content
1710 child.display.displaySystem = display.displaySystem;
1711 child.display.window = display.window;
1712 child.display.current = display.current;
1713 child.display.width = display.width;
1714 child.display.height = display.height;
1715 child.display.driverData = display.driverData;
1716 child.display.mutex = null;
1727 void UpdateScrollBars(bool flag, bool fullThing)
1730 bool resizeH = false, resizeV = false;
1731 bool scrolled = false;
1732 rvw = (activeChild && activeChild.state == maximized) ? 0 : reqScrollArea.w;
1733 rvh = (activeChild && activeChild.state == maximized) ? 0 : reqScrollArea.h;
1735 if(destroyed) return;
1736 if(guiApp.currentSkin)
1738 MinMaxValue cw = 0, ch = 0;
1739 bool sbvVisible, sbhVisible;
1741 int positionH, positionV;
1743 // First get client area with no respect to scroll bars
1748 &clientStart.x, &clientStart.y, &size.w, &size.h, &cw, &ch);
1750 if(scrollFlags.dontHide)
1753 cw -= guiApp.currentSkin.VerticalSBW();
1755 ch -= guiApp.currentSkin.HorizontalSBH();
1757 // Update the scrollbar visibility
1763 sbh.disabled = rangeH <= 1;
1764 if(sbh.style.hidden)
1774 sbv.disabled = rangeV <= 1;
1775 if(sbv.style.hidden)
1783 // Then start off with horizontal scrollbar range
1786 positionH = sbh.thumbPosition;
1791 ch -= guiApp.currentSkin.HorizontalSBH();
1794 // Do the same for vertical scrollbar
1797 positionV = sbv.thumbPosition;
1803 cw -= guiApp.currentSkin.VerticalSBW();
1804 // Maybe we need to set the range on the horizontal scrollbar again
1809 sbh.Action(setRange, positionH, 0);
1810 if(rangeH <= 1 && sbh.range > 1)
1812 ch -= guiApp.currentSkin.HorizontalSBH();
1816 sbv.Action(setRange, positionV, 0);
1823 // Update the scrollbar visibility
1824 if(!scrollFlags.dontHide)
1826 if(sbh && ((rangeH <= 1 && !sbh.style.hidden) || (rangeH > 1 && sbh.style.hidden)))
1830 if(sbv && ((rangeV <= 1 && !sbv.style.hidden) || (rangeV > 1 && sbv.style.hidden)))
1837 if(guiApp.currentSkin)
1844 sbhVisible = sbh.style.hidden ? true : false;
1846 sbvVisible = sbv.style.hidden ? true : false;
1848 // Do our resize here
1849 if(flag && (resizeH || resizeV) && fullThing)
1851 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, false);
1856 OnResize(clientSize.w, clientSize.h);
1862 sbh.visible = sbhVisible;
1864 sbv.visible = sbvVisible;
1866 scrollArea.w = Max(clientSize.w, reqScrollArea.w);
1867 scrollArea.h = Max(clientSize.h, reqScrollArea.h);
1870 sbh.pageStep = clientSize.w;
1872 sbv.pageStep = clientSize.h;
1874 // Notify doesn't handle setRange anymore... process it here
1877 int positionH = sbh.thumbPosition;
1878 if(scroll.x != positionH)
1880 OnHScroll(setRange, positionH, 0);
1884 SNAPDOWN(positionH, textCellW);
1885 scroll.x = positionH;
1891 int seen = clientSize.w, total = reqScrollArea.w;
1894 if(scrollFlags.snapX)
1895 SNAPDOWN(seen, sbStep.x);
1897 if(!total) total = seen;
1898 range = total - seen + 1;
1900 range = Max(range, 1);
1902 if(x >= range) x = range - 1;
1904 if(scrollFlags.snapX)
1905 SNAPUP(x, sbStep.x);
1909 OnHScroll(setRange, x, 0);
1914 SNAPDOWN(x, textCellW);
1920 int positionV = sbv.thumbPosition;
1921 if(scroll.y != positionV)
1923 OnVScroll(setRange, positionV, 0);
1927 SNAPDOWN(positionV, textCellH);
1928 scroll.y = positionV;
1934 int seen = clientSize.h, total = reqScrollArea.h;
1937 if(scrollFlags.snapY)
1938 SNAPDOWN(seen, sbStep.y);
1940 if(!total) total = seen;
1941 range = total - seen + 1;
1942 range = Max(range, 1);
1944 if(y >= range) y = range - 1;
1946 if(scrollFlags.snapY)
1947 SNAPUP(y, sbStep.y);
1951 OnVScroll(setRange, y, 0);
1956 SNAPDOWN(y, textCellH);
1962 if(scrolled || (resizeH || resizeV)) // This ensures children anchored to bottom/right gets repositioned correctly
1965 for(child = children.first; child; child = child.next)
1967 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
1970 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
1971 child.Position(x, y, w, h, false, true, false, true, false, false);
1978 // Process Scrollbars
1980 if(sbh) // && !sbh.style.hidden
1982 sbh.Move(clientStart.x, clientStart.y + clientSize.h, clientSize.w,0);
1983 // Need to set the range again (should improve...) since the scrollbars didn't have
1984 // the right size when UpdateScrollArea set the range on it
1987 sbh.seen = clientSize.w;
1991 if(sbv) // && !sbv.state.hidden
1993 sbv.Move(clientStart.x + clientSize.w, clientStart.y, 0, clientSize.h);
1994 // Need to set the range again (should improve...) since the scrollbars didn't have
1995 // the right size when UpdateScrollArea set the range on it
1998 sbv.seen = clientSize.h;
2003 // TESTING THIS LOWER
2004 if(scrolled || (resizeH || resizeV)) // This ensures children anchored to bottom/right gets repositioned correctly
2007 for(child = children.first; child; child = child.next)
2009 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2012 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
2013 child.Position(x, y, w, h, false, true, false, true, false, false);
2019 bool MaximizeButtonClicked(Button button, int x, int y, Modifiers mods)
2021 SetState(maximized, false, mods);
2025 bool RestoreButtonClicked(Button button, int x, int y, Modifiers mods)
2027 SetState(normal, false, mods);
2031 bool MinimizeButtonClicked(Button button, int x, int y, Modifiers mods)
2033 SetState(minimized, false, mods);
2034 parent.CycleChildren(false, true, false, true);
2038 void ScrollBarNotification(ScrollBar control, ScrollBarAction action, int position, Key keyFlags)
2041 // Scroll bar notifications
2042 if(action != setRange)
2044 bool changed = false;
2048 if(scroll.x != position)
2050 OnHScroll(action, position, keyFlags);
2055 SNAPDOWN(position, textCellW);
2057 scroll.x = position;
2061 if(scroll.y != position)
2063 OnVScroll(action, position, keyFlags);
2068 SNAPDOWN(position, textCellH);
2070 scroll.y = position;
2074 bool childMove = false;
2075 for(child = children.first; child; child = child.next)
2077 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2080 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
2081 child.Position(x, y, w, h, false, true, false, true, false, false);
2085 // Testing this patch out to solve MDI workspace redraw bugs
2086 // We were already supposed to be updating parent's affected area in Position() but it doesn't seem to be working
2087 // Scroll offsets to blame?
2091 UpdateCaret(false, false);
2095 // Testing this patch out to solve MDI workspace redraw bugs
2096 for(child = children.first; child; child = child.next)
2098 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2107 void CreateSystemChildren(void)
2109 Window parent = this;
2110 bool scrollBarChanged = false;
2111 bool hasClose = false, hasMaxMin = false;
2112 Point scroll = this.scroll;
2114 if(state == maximized && this.parent.menuBar)
2116 if(this.parent.activeClient == this)
2117 parent = this.parent.menuBar;
2124 if(style.hasClose) hasClose = true;
2125 if(style.hasMaximize || style.hasMinimize)
2132 if(sysButtons[2] && (!hasClose || sysButtons[2].parent != parent))
2134 sysButtons[2].Destroy(0);
2135 sysButtons[2] = null;
2137 if(sysButtons[1] && (!hasMaxMin || sysButtons[1].parent != parent))
2139 sysButtons[1].Destroy(0);
2140 sysButtons[1] = null;
2142 if(sysButtons[0] && (!hasMaxMin || sysButtons[0].parent != parent))
2144 sysButtons[0].Destroy(0);
2145 sysButtons[0] = null;
2148 if(hasClose && parent)
2155 parent, master = this,
2156 inactive = true, nonClient = true, visible = false;
2158 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2164 if(this.parent == guiApp.desktop)
2165 sysButtons[2].hotKey = altF4;
2166 else if(style.isActiveClient)
2167 sysButtons[2].hotKey = ctrlF4;
2168 sysButtons[2].Create();
2171 sysButtons[2].symbol = 'X';
2172 sysButtons[2].disabled = !style.hasClose;
2175 if(hasMaxMin && parent)
2179 bool (* method)(Window window, Button button, int x, int y, Modifiers mods);
2180 if(state == maximized)
2183 method = RestoreButtonClicked;
2189 method = MaximizeButtonClicked;
2197 parent, master = this,
2198 hotKey = altEnter, inactive = true, nonClient = true, visible = false
2200 sysButtons[1].Create();
2202 sysButtons[1].NotifyClicked = method;
2204 sysButtons[1].symbol = symbol;
2205 sysButtons[1].disabled = !style.hasMaximize;
2208 if(hasMaxMin && parent)
2212 bool (* method)(Window window, Button button, int x, int y, Modifiers mods);
2213 if (state == minimized)
2216 method = RestoreButtonClicked;
2222 method = MinimizeButtonClicked;
2230 parent, master = this,
2231 hotKey = altM, inactive = true, nonClient = true, visible = false
2233 sysButtons[0].Create();
2235 sysButtons[0].NotifyClicked = method;
2237 sysButtons[0].symbol = symbol;
2238 sysButtons[0].disabled = !style.hasMinimize;
2241 // Create the scrollbars
2242 if(style.hasHorzScroll && !sbh)
2248 direction = horizontal,
2252 snap = scrollFlags.snapX,
2253 NotifyScrolling = ScrollBarNotification
2256 scrollBarChanged = true;
2258 else if(sbh && !style.hasHorzScroll)
2264 if(style.hasVertScroll && !sbv)
2270 direction = vertical,
2274 snap = scrollFlags.snapY,
2275 NotifyScrolling = ScrollBarNotification
2278 scrollBarChanged = true;
2280 else if(sbv && !style.hasVertScroll)
2285 if(scrollBarChanged)
2287 SetScrollLineStep(sbStep.x, sbStep.y);
2288 UpdateScrollBars(true, true);
2292 if(scrollBarChanged)
2294 if(sbh) sbh.thumbPosition = scroll.x;
2295 if(sbv) sbv.thumbPosition = scroll.y;
2299 void UpdateCaption(void)
2301 if(rootWindow == this)
2304 FigureCaption(caption);
2305 guiApp.interfaceDriver.SetRootWindowCaption(this, caption);
2307 UpdateDecorations();
2310 if(parent.rootWindow == parent && parent.activeClient == this) // Added this last check
2313 parent.FigureCaption(caption);
2314 guiApp.interfaceDriver.SetRootWindowCaption(parent, caption);
2316 parent.UpdateDecorations();
2320 void UpdateActiveDocument(Window previous)
2322 Window activeClient = this.activeClient;
2323 Window activeChild = this.activeChild;
2330 activeClient.CreateSystemChildren();
2332 previous.CreateSystemChildren();
2343 if(activeClient && activeClient.menu && activeClient.state != minimized)
2347 //activeClient.menu.Clean(activeClient);
2348 menu.Merge(activeClient.menu, true, activeClient);
2352 if(activeChild && activeChild != activeClient && activeChild.menu && activeChild.state != minimized)
2355 menu.Merge(activeChild.menu, true, activeChild);
2358 // Build window list
2361 Menu windowMenu = menu.FindMenu("Window");
2366 for(id = 0, cycle = activeClient.cycle; cycle && id<10;)
2369 Window document = cycle.data;
2370 if(!document.style.nonClient && document.style.isActiveClient)
2372 char name[2048], caption[2048];
2373 document.FigureCaption(caption);
2374 sprintf(name, "%d %s", id+1, caption);
2375 windowMenu.AddDynamic(MenuItem
2377 copyText = true, text = name, hotKey = Key { k1 + id }, id = id++,
2378 NotifySelect = MenuWindowSelectWindow
2382 if(activeClient.cycle == cycle) break;
2387 if((!previous && activeClient) || !activeClient)
2393 item = menu.FindItem(MenuWindowCloseAll, 0);
2394 if(item) item.disabled = false;
2395 item = menu.FindItem(MenuWindowNext, 0);
2396 if(item) item.disabled = false;
2397 item = menu.FindItem(MenuWindowPrevious, 0);
2398 if(item) item.disabled = false;
2399 item = menu.FindItem(MenuWindowCascade, 0);
2400 if(item) item.disabled = false;
2401 item = menu.FindItem(MenuWindowTileHorz, 0);
2402 if(item) item.disabled = false;
2403 item = menu.FindItem(MenuWindowTileVert, 0);
2404 if(item) item.disabled = false;
2405 item = menu.FindItem(MenuWindowArrangeIcons, 0);
2406 if(item) item.disabled = false;
2407 item = menu.FindItem(MenuWindowWindows, 0);
2408 if(item) item.disabled = false;
2411 item = menu.FindItem(MenuFileClose, 0);
2412 if(item) item.disabled = !activeClient || !activeClient.style.hasClose;
2413 item = menu.FindItem(MenuFileSaveAll, 0);
2414 if(item) item.disabled = numDocuments < 1;
2416 // This is called again for a child window change, with same active client
2417 OnActivateClient(activeClient, previous);
2420 void _ShowDecorations(Box box, bool post)
2422 if(nativeDecorations) return;
2423 if(visible && this != guiApp.desktop)
2425 Surface surface = RedrawFull(box);
2429 FigureCaption(caption);
2432 ShowDecorations(captionFont.font,
2435 active, //parent.activeClient == this
2436 guiApp.windowMoving == this);
2438 PreShowDecorations(captionFont.font,
2441 active, //parent.activeClient == this
2442 guiApp.windowMoving == this);
2449 void UpdateExtent(Box refresh)
2451 Surface surface = null;
2453 if(!manageDisplay) { OnRedraw(null);return; }
2454 _ShowDecorations(refresh, false);
2456 surface = Redraw(refresh);
2457 // Opaque background: just fill before EW_REDRAW (clear?)
2460 surface.SetBackground(background);
2461 surface.SetForeground(foreground);
2462 surface.DrawingChar(' ');
2463 if(this == rootWindow)
2465 if(style.drawBehind || background.a)
2466 surface.Clear(colorBuffer);
2468 else if(background.a)
2472 background.color = { (byte)GetRandom(0,255), (byte)GetRandom(0,255), (byte)GetRandom(0,255) };
2473 surface.SetForeground((background.color.r > 128 || background.color.g > 128) ? black : white);
2476 if(display.flags.alpha && background.a < 255 && background)
2478 surface.Area(0,0,clientSize.w, clientSize.h);
2479 /*if(style.clearDepthBuffer)
2480 surface.Clear(depthBuffer);*/
2482 else if(/*style.clearDepthBuffer || */background.a)
2484 // surface.Clear((style.clearDepthBuffer ? depthBuffer : 0) | (background.a ? colorBuffer : 0));
2485 surface.Clear(colorBuffer);
2490 surface.TextFont(usedFont.font);
2491 surface.TextOpacity(false);
2495 // Draw the caret ...
2496 if(!disabled && this == guiApp.caretOwner && guiApp.caretEnabled /*&& !guiApp.interimWindow*/ && !guiApp.currentSkin.textMode)
2498 // surface.SetBackground(0xFFFFFF - background.color);
2499 surface.SetBackground(~background.color);
2501 caretPos.x - scroll.x + 1, caretPos.y - scroll.y,
2502 caretPos.x - scroll.x + 2, caretPos.y - scroll.y + caretSize - 1);
2508 void DrawOverChildren(Box refresh)
2510 Surface surface = Redraw(refresh);
2514 surface.DrawingChar(' ');
2515 surface.SetBackground(background);
2516 surface.SetForeground(foreground);
2518 surface.TextFont(usedFont.font);
2519 surface.TextOpacity(false);
2521 OnDrawOverChildren(surface);
2526 _ShowDecorations(refresh, true);
2529 void ComputeClipExtents(void)
2532 Extent clipExtent { /*first = -1, last = -1, free = -1*/ };
2534 clipExtent.Copy(this.clipExtent);
2536 for(child = children.last; child; child = child.prev)
2538 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2540 bool opaque = child.IsOpaque(); // TODO: acess background directly
2541 int dx = child.absPosition.x - absPosition.x, dy = child.absPosition.y - absPosition.y;
2543 child.clipExtent.Copy(clipExtent);
2544 child.clipExtent.Offset(-dx, -dy);
2545 child.clipExtent.IntersectBox(child.box);
2547 child.ComputeClipExtents();
2549 if(opaque && !child.style.nonClient)
2551 // Adjust the box for the parent:
2552 Box box { child.box.left + dx, child.box.top + dy, child.box.right + dx, child.box.bottom + dy };
2553 clipExtent.ExcludeBox(box, rootWindow.tempExtents[0]);
2558 // ??? Only do this for overlapped window or if parent has with clip children flag
2560 // Do this if window has clip children flag on (default false?)
2561 // this.clipExtent = clipExtent;
2563 clipExtent.Free(null);
2566 void ComputeRenderAreaNonOpaque(Extent dirtyExtent, Extent overDirtyExtent, Extent backBufferUpdate)
2568 bool opaque = IsOpaque();
2570 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2572 for(child = children.last; child; child = child.prev)
2574 ColorAlpha background = *(ColorAlpha *)&child.background;
2575 bool opaque = child.IsOpaque();
2576 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2580 int offsetX = child.absPosition.x - rootWindow.absPosition.x, offsetY = child.absPosition.y - rootWindow.absPosition.y;
2581 // Adjust renderArea to the root window level
2582 Extent * renderArea = &rootWindow.tempExtents[1];
2584 Extent childRenderArea;
2586 if(backBufferUpdate != null)
2588 childRenderArea.Copy(backBufferUpdate);
2589 childRenderArea.Offset(-offsetX, -offsetY);
2592 childRenderArea.Copy(child.dirtyArea);
2594 // Add extent forced by transparency to the dirty area, adjusting dirty extent to the window
2595 renderArea.Copy(dirtyExtent);
2596 renderArea.Offset(-offsetX, -offsetY);
2597 childRenderArea.Union(renderArea);
2600 // Intersect with the clip extent
2601 childRenderArea.Intersection(child.clipExtent);
2604 renderArea->Copy(child.dirtyArea /*childRenderArea*/);
2605 renderArea->Offset(offsetX, offsetY);
2606 dirtyExtent.Union(renderArea, rootWindow.tempExtents[0]);
2607 // overDirtyExtent.Union(renderArea);
2608 renderArea->Empty();
2609 // childRenderArea.Free();
2611 //child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2616 for(child = children.last; child; child = child.prev)
2618 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2620 child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2625 void ComputeRenderArea(Extent dirtyExtent, Extent overDirtyExtent, Extent backBufferUpdate)
2627 bool opaque = IsOpaque();
2628 Extent * dirtyExtentWindow = &rootWindow.tempExtents[1];
2630 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2633 for(child = children.last; child; child = child.prev)
2635 //child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2637 ColorAlpha background = *(ColorAlpha *)&child.background;
2638 bool opaque = child.IsOpaque();
2639 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2643 int offsetX = child.absPosition.x - rootWindow.absPosition.x, offsetY = child.absPosition.y - rootWindow.absPosition.y;
2644 // Adjust renderArea to the root window level
2646 renderArea.Copy(child.dirtyArea);
2647 renderArea.Offset(offsetX, offsetY);
2648 dirtyExtent.Union(renderArea);
2649 overDirtyExtent.Union(renderArea);
2655 for(child = children.last; child; child = child.prev)
2657 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2659 child.ComputeRenderArea(dirtyExtent, overDirtyExtent, backBufferUpdate);
2663 if(backBufferUpdate != null)
2665 renderArea.Copy(backBufferUpdate);
2666 renderArea.Offset(-offsetX, -offsetY);
2668 overRenderArea.Copy(backBufferUpdate);
2669 overRenderArea.Offset(-offsetX, -offsetY);
2675 renderArea.Copy(dirtyArea);
2677 overRenderArea.Copy(dirtyArea);
2680 // Add extent forced by transparency to the dirty area, adjusting dirty extent to the window
2681 dirtyExtentWindow->Copy(dirtyExtent);
2682 dirtyExtentWindow->Offset(-offsetX, -offsetY);
2683 renderArea.Union(dirtyExtentWindow, rootWindow.tempExtents[0]);
2684 dirtyExtentWindow->Empty();
2686 // Intersect with the clip extent
2687 renderArea.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2690 if(renderArea.count > 10)
2693 printf("\nToo many extents (%d):\n", renderArea.count);
2695 //extent.UnionBox({ 112, 6, 304, 7 }, rootWindow.tempExtents[0]);
2696 //extent.UnionBox({ 112, 8, 304, 17 }, rootWindow.tempExtents[0]);
2701 for(c = 0; c<10; c++)
2704 FASTLIST_LOOP(renderArea, extentBox)
2706 extent.UnionBox(extentBox.box, rootWindow.tempExtents[0]);
2708 renderArea.Copy(extent);
2710 FASTLIST_LOOP(renderArea, extentBox)
2713 printf("(%d, %d) - (%d, %d)\n",
2714 extentBox.box.left, extentBox.box.top,
2715 extentBox.box.right, extentBox.box.bottom);
2719 printf("\nNow %d\n", renderArea.count);
2725 // WHY WAS THIS COMMENTED ??
2727 // Add extent forced by DrawOverChildren to the dirty area, adjusting dirty extent to the window
2728 dirtyExtentWindow->Copy(overDirtyExtent);
2729 dirtyExtentWindow->Offset(-offsetX, -offsetY);
2730 overRenderArea.Union(dirtyExtentWindow, rootWindow.tempExtents[0]);
2731 dirtyExtentWindow->Empty();
2733 // Intersect with the clip extent
2734 overRenderArea.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2740 if(scrollExtent.count)
2742 // Subtract render extent from scrolling extent
2743 scrollExtent.Exclusion(renderArea, rootWindow.tempExtents[0]);
2745 if(backBufferUpdate == null)
2747 Extent * dirty = &rootWindow.tempExtents[3];
2750 // Intersect scrolling extent with clip extent
2751 scrollExtent.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2753 // offset this scroll to be at the root window level
2754 scrollExtent.Offset(offsetX, offsetY);
2755 // Add area that was scrolled to the dirty extents of the back buffer
2756 rootWindow.dirtyBack.Union(scrollExtent, rootWindow.tempExtents[0]);
2760 // Will need scrolledArea.x & scrolledArea.y to support multiple scrolls
2761 FASTLIST_LOOP(scrollExtent, scrollBox)
2762 display.Scroll(scrollBox.box, scrolledArea.x, scrolledArea.y, dirty);
2767 scrollExtent.Empty();
2769 // Add the exposed extent to the window render area
2770 dirty->Offset(-offsetX, -offsetY);
2771 renderArea.Union(dirty, rootWindow.tempExtents[0]);
2776 // Subtract the window's box from the transparency forced extent
2777 dirtyExtent.ExcludeBox({box.left + offsetX, box.top + offsetY, box.right + offsetX, box.bottom + offsetY }, rootWindow.tempExtents[0]);
2783 renderArea.Copy(this.renderArea);
2784 renderArea.Offset(offsetX, offsetY);
2785 dirtyExtent.Union(renderArea);
2791 Extent renderArea { };
2793 renderArea.Copy(overRenderArea);
2794 renderArea.Offset(offsetX, offsetY);
2795 overDirtyExtent.Union(renderArea, rootWindow.tempExtents[0]);
2800 if(backBufferUpdate != null)
2802 // Remove render area from dirty area
2803 dirtyArea.Exclusion(renderArea, rootWindow.tempExtents[0]);
2805 dirtyArea.Exclusion(overRenderArea, rootWindow.tempExtents[0]);
2812 // Remove the window render area from the dirty extents of the back buffer
2813 rootWindow.dirtyBack.Exclusion(renderArea);
2817 void Render(Extent updateExtent)
2821 Window rootWindow = this.rootWindow;
2822 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2824 if(rootWindow.fullRender)
2833 background = Color { (byte)GetRandom(0,255), (byte)GetRandom(0,255), (byte)GetRandom(0,255) };
2834 foreground = (background.color.r > 128 || background.color.g > 128) ? black : white;
2839 /*if(renderArea.count)
2840 printf("\n\nRendering %s (%x):\n------------------------------------------\n", _class.name, this);*/
2843 FASTLIST_LOOP(renderArea, extentBox)
2845 Box box = extentBox.box;
2848 /*printf("(%d, %d) - (%d, %d)\n",
2849 extentBox.box.left, extentBox.box.top,
2850 extentBox.box.right, extentBox.box.bottom);*/
2855 box.left += offsetX;
2857 box.right += offsetX;
2858 box.bottom += offsetY;
2860 if(updateExtent != null)
2861 updateExtent.UnionBox(box, rootWindow.tempExtents[0]);
2865 for(child = children.first; child; child = child.next)
2866 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow && !child.nonClient)
2867 child.Render(updateExtent);
2869 if(rootWindow.fullRender)
2870 DrawOverChildren(box);
2873 // TO DO: There's an issue about draw over children...
2874 // TO DO: Don't wanna go through this if method isn't used
2875 FASTLIST_LOOP(/*renderArea */overRenderArea, extentBox)
2877 Box box = extentBox.box;
2879 DrawOverChildren(box);
2881 box.left += offsetX;
2883 box.right += offsetX;
2884 box.bottom += offsetY;
2886 if(updateExtent != null)
2887 updateExtent.UnionBox(box, rootWindow.tempExtents[0]);
2890 for(child = children.first; child; child = child.next)
2891 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow && child.nonClient)
2892 child.Render(updateExtent);
2895 overRenderArea.Empty();
2898 public void UpdateDisplay(void)
2900 if(!manageDisplay) { OnRedraw(null);return; }
2901 if(rootWindow && this != rootWindow)
2902 rootWindow.UpdateDisplay();
2905 Extent dirtyExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that needs to be forced due to transparency
2906 Extent overExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that forced for DrawOverChildren
2909 dirtyExtent.Clear();
2912 clipExtent.AddBox(box);
2914 display.StartUpdate();
2916 if(!rootWindow.fullRender)
2918 ComputeClipExtents();
2919 ComputeRenderAreaNonOpaque(dirtyExtent, overExtent, null);
2920 ComputeRenderArea(dirtyExtent, overExtent, null);
2923 clipExtent.Free(null);
2925 dirtyExtent.Free(null);
2926 overExtent.Free(null);
2928 if(display.flags.flipping)
2931 display.Update(null);
2935 Extent updateExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that needs to be updated
2936 updateExtent.Clear();
2938 Render(updateExtent);
2940 updateExtent.UnionBox(this.box, tempExtents[0]);
2943 //printf("\n\nUpdate:\n------------------------------------------\n");
2946 FASTLIST_LOOP(updateExtent, extentBox)
2949 /*printf("Updating (%d, %d) - (%d, %d)\n",
2950 extentBox.box.left, extentBox.box.top,
2951 extentBox.box.right, extentBox.box.bottom);*/
2954 display.Update(extentBox.box);
2957 updateExtent.Free(null);
2960 display.EndUpdate();
2968 void UpdateBackDisplay(Box box)
2974 Extent intersection { /*first = -1, last = -1, free = -1*/ };
2976 //printf("UpdateBackDisplay going through!\n");
2977 display.StartUpdate();
2981 intersection.Copy(dirtyBack);
2982 intersection.IntersectBox(box);
2984 dirtyExtent.Clear();
2987 clipExtent.AddBox(box);
2989 if(!rootWindow.fullRender)
2991 ComputeClipExtents();
2992 ComputeRenderArea(dirtyExtent, overExtent, intersection);
2995 clipExtent.Free(null);
2997 intersection.Free(null);
2998 dirtyExtent.Free(null);
2999 overExtent.Free(null);
3004 if(display.flags.flipping)
3005 display.Update(null);
3008 rootWindow.display.Update(box);
3011 display.EndUpdate();
3015 dirtyBack.ExcludeBox(box, rootWindow.tempExtents[0]);
3016 if(dirtyBack.count > MAX_DIRTY_BACK)
3018 BoxItem extentBox, next;
3019 BoxItem first = (BoxItem)ACCESS_ITEM(dirtyBack, dirtyBack.first);
3020 FASTLIST_LOOPN(dirtyBack, extentBox, next)
3022 if(extentBox != first)
3024 if(extentBox.box.left < first.box.left)
3025 first.box.left = extentBox.box.left;
3026 if(extentBox.box.top < first.box.top)
3027 first.box.top = extentBox.box.top;
3028 if(extentBox.box.right > first.box.right)
3029 first.box.right = extentBox.box.right;
3030 if(extentBox.box.bottom > first.box.bottom)
3031 first.box.bottom = extentBox.box.bottom;
3032 dirtyBack.Delete(extentBox);
3041 // --- Window positioning ---
3042 // --- Window identification ---
3044 // Returns window at position "Position"
3045 Window GetAtPosition(int x, int y, bool clickThru, bool acceptDisabled, Window last)
3047 Window child, result = null;
3049 box.left += absPosition.x;
3050 box.right += absPosition.x;
3051 box.top += absPosition.y;
3052 box.bottom += absPosition.y;
3054 if(!destroyed && visible && (acceptDisabled || !disabled))
3056 int lx = x - absPosition.x;
3057 int ly = y - absPosition.y;
3058 if(IsInside(lx, ly))
3059 // if(box.IsPointInside(Point{x, y}))
3061 if(!clickThru || !style.clickThrough) result = (this == last) ? null : this;
3062 // If the window is disabled, stop looking in children (for acceptDisabled mode)
3065 for(child = (last && last.parent == this) ? last.previous : children.last; child; child = child.prev)
3067 if(child != statusBar && child.rootWindow == rootWindow)
3069 Window childResult = child.GetAtPosition(x, y, clickThru, acceptDisabled, last);
3076 for(child = (last && last.parent == this) ? last.previous : children.last; child; child = child.prev)
3078 if(child != statusBar && child.rootWindow == rootWindow)
3080 Window childResult = child.GetAtPosition(x, y, false, acceptDisabled, last);
3092 Window FindModal(void)
3094 Window modalWindow = this, check;
3095 Window check2 = null;
3096 for(check = this; check.master; check = check.master)
3098 if(check.master.modalSlave && check.master.modalSlave.created && check != check.master.modalSlave)
3100 modalWindow = check.master.modalSlave;
3101 check = modalWindow;
3103 // TESTING THIS FOR DROPBOX...
3104 if(!rootWindow || !rootWindow.style.interim)
3106 for(check2 = check; check2.activeChild; check2 = check2.activeChild)
3108 if(check2.modalSlave && check2.modalSlave.created)
3110 modalWindow = check2.modalSlave;
3118 if(modalWindow == this)
3120 for(check = this; check.activeChild; check = check.activeChild)
3122 if(check.modalSlave)
3124 modalWindow = check.modalSlave;
3130 for(; modalWindow.modalSlave && modalWindow.modalSlave.created; modalWindow = modalWindow.modalSlave);
3131 return (modalWindow == this || this == guiApp.interimWindow || IsDescendantOf(modalWindow)) ? null : modalWindow;
3134 void StopMoving(void)
3136 if(this == guiApp.windowMoving)
3138 guiApp.windowMoving = null;
3139 UpdateDecorations();
3140 SetMouseRange(null);
3143 if(rootWindow.active)
3144 guiApp.interfaceDriver.StopMoving(rootWindow);
3147 guiApp.resizeX = guiApp.resizeY = guiApp.resizeEndX = guiApp.resizeEndY = false;
3148 guiApp.windowIsResizing = false;
3152 void SelectMouseCursor(void)
3157 Window cursorWindow = null;
3158 bool rx, ry, rex, rey;
3160 guiApp.desktop.GetMousePosition(&x, &y);
3161 mouseWindow = rootWindow ? rootWindow.GetAtPosition(x,y, true, false, null) : null;
3163 if((guiApp.windowMoving && !guiApp.windowIsResizing) || guiApp.windowScrolling)
3164 guiApp.SetCurrentCursor(guiApp.systemCursors[moving]);
3165 else if(mouseWindow)
3167 modalWindow = mouseWindow.FindModal();
3168 x -= mouseWindow.absPosition.x;
3169 y -= mouseWindow.absPosition.y;
3170 if(guiApp.windowIsResizing)
3172 rex = guiApp.resizeEndX;
3173 rey = guiApp.resizeEndY;
3174 rx = guiApp.resizeX;
3175 ry = guiApp.resizeY;
3176 if((rex && rey) || (rx && ry))
3177 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNWSE]);
3178 else if((rex && ry) || (rx && rey))
3179 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNESW]);
3180 else if((ry || rey) && (!rx && !rex))
3181 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNS]);
3182 else if((rx || rex) && (!ry && !rey))
3183 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeWE]);
3185 else if(!modalWindow && !guiApp.windowCaptured &&
3186 mouseWindow.IsMouseResizing(x, y, mouseWindow.size.w, mouseWindow.size.h,
3187 &rx, &ry, &rex, &rey))
3189 if((rex && rey) || (rx && ry))
3190 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNWSE]);
3191 else if((rex && ry) || (rx && rey))
3192 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNESW]);
3193 else if((ry || rey) && (!rx && !rex))
3194 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNS]);
3195 else if((rx || rex) && (!ry && !rey))
3196 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeWE]);
3198 else if(!guiApp.windowCaptured && !modalWindow && !guiApp.interimWindow)
3200 if(!mouseWindow.clientArea.IsPointInside({x - mouseWindow.clientStart.x, y - mouseWindow.clientStart.y}))
3201 cursorWindow = mouseWindow.parent;
3203 cursorWindow = mouseWindow;
3205 else if(!guiApp.interimWindow)
3206 cursorWindow = guiApp.windowCaptured;
3209 for(; !cursorWindow.cursor && !cursorWindow.style.nonClient; cursorWindow = cursorWindow.parent);
3210 guiApp.SetCurrentCursor(cursorWindow.cursor ? cursorWindow.cursor : guiApp.systemCursors[arrow]);
3212 else if(modalWindow)
3214 guiApp.SetCurrentCursor(guiApp.systemCursors[arrow]);
3216 else if(guiApp.interimWindow)
3218 if(guiApp.interimWindow.cursor)
3219 guiApp.SetCurrentCursor(guiApp.interimWindow.cursor);
3221 guiApp.SetCurrentCursor(mouseWindow.cursor ? mouseWindow.cursor : guiApp.systemCursors[arrow]);
3226 // --- State based input ---
3227 bool AcquireInputEx(bool state)
3232 guiApp.interfaceDriver.GetMousePosition(&guiApp.acquiredMouseX, &guiApp.acquiredMouseY);
3233 guiApp.interfaceDriver.SetMousePosition(clientSize.w/2 + absPosition.x, clientSize.h/2 + absPosition.y);
3235 result = guiApp.interfaceDriver.AcquireInput(rootWindow, state);
3237 guiApp.acquiredWindow = state ? this : null;
3240 SetMouseRangeToClient();
3241 guiApp.interfaceDriver.SetMouseCursor((SystemCursor)-1);
3246 SelectMouseCursor();
3248 if(!state) guiApp.interfaceDriver.SetMousePosition(guiApp.acquiredMouseX, guiApp.acquiredMouseY);
3252 // --- Window activation ---
3253 bool PropagateActive(bool active, Window previous, bool * goOnWithActivation, bool direct)
3256 if(!parent || !parent.style.inactive)
3258 Window parent = this.parent;
3261 if(rootWindow == this)
3262 Log(active ? "active\n" : "inactive\n");
3265 // Testing this here...
3266 if(!parent || parent == guiApp.desktop || parent.active)
3268 this.active = active;
3271 // TESTING THIS HERE
3272 UpdateDecorations();
3273 if(result = OnActivate(active, previous, goOnWithActivation, direct) && *goOnWithActivation && master)
3274 result = NotifyActivate(master, this, active, previous);
3277 this.active = !active;
3282 if(!parent || parent == guiApp.desktop || parent.active)
3284 this.active = active;
3286 AcquireInputEx(active);
3291 if(guiApp.caretOwner)
3295 guiApp.caretOwner.caretPos.x - guiApp.caretOwner.scroll.x + 1,
3296 guiApp.caretOwner.caretPos.y - guiApp.caretOwner.scroll.y + 1,
3297 guiApp.caretOwner.caretPos.x - guiApp.caretOwner.scroll.x + 2,
3298 guiApp.caretOwner.caretPos.y - guiApp.caretOwner.scroll.y + guiApp.caretOwner.caretSize - 1
3300 guiApp.caretOwner.Update(extent);
3303 if(visible || !guiApp.caretOwner)
3304 guiApp.caretOwner = this;
3305 UpdateCaret(false, false);
3311 this.active = false;
3313 AcquireInputEx(active);
3315 if(!active && guiApp.caretOwner == this)
3317 UpdateCaret(false, true);
3318 guiApp.caretOwner = null;
3319 guiApp.interfaceDriver.SetCaret(0,0,0);
3320 guiApp.caretEnabled = false;
3325 if(!active && parent && parent.activeChild && parent.activeChild != this)
3326 if(!parent.activeChild.PropagateActive(false, previous, goOnWithActivation, true) || !*goOnWithActivation)
3332 if(!active && menuBar)
3335 menuBar.OnActivate(false, null, &goOn, true);
3336 menuBar.NotifyActivate(menuBar.master, menuBar, false, null);
3340 if(!activeChild.PropagateActive(active, previous, goOnWithActivation, false) || !*goOnWithActivation)
3349 void ConsequentialMouseMove(bool kbMoving)
3353 if(kbMoving || !guiApp.windowMoving)
3357 if(rootWindow == guiApp.desktop || rootWindow.parent == guiApp.desktop)
3359 guiApp.interfaceDriver.GetMousePosition(&x, &y);
3361 if(guiApp.windowMoving || rootWindow.GetAtPosition(x, y, true, false, null))
3362 rootWindow.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &mods, true, false);
3368 bool IsDescendantOf(Window ancestor)
3371 for(window = this; window && window != ancestor; window = window.parent);
3372 return window == ancestor;
3375 bool IsSlaveOf(Window master)
3378 for(window = this; window && window != master; window = window.master);
3379 return window == master;
3382 bool ActivateEx(bool active, bool activateParent, bool moveInactive, bool activateRoot, Window external, Window externalSwap)
3386 if(this && !destroyed /*&& state != Hidden*/)
3388 Window swap = externalSwap;
3396 if(activateParent &&
3397 (parent.activeChild != this ||
3398 (guiApp.interimWindow && !IsDescendantOf(guiApp.interimWindow))) &&
3399 active && style.modal &&
3400 parent != master && master)
3401 master.ActivateEx(true, true, false, activateRoot, external, externalSwap);
3407 bool real = parent.activeChild != this;
3409 // TEST THIS: New activateParent check here!!! CAUSED MENUS NOT GOING AWAY
3410 if(/*activateParent && */guiApp.interimWindow &&
3411 !IsDescendantOf(guiApp.interimWindow) &&
3412 !IsSlaveOf(guiApp.interimWindow))
3414 Window interimWindow = guiApp.interimWindow;
3415 while(interimWindow && interimWindow != this)
3417 Window master = interimWindow.master;
3419 guiApp.interimWindow = null;
3420 if(guiApp.caretOwner)
3421 guiApp.caretOwner.UpdateCaret(false, false);
3423 incref interimWindow;
3424 if(!interimWindow.PropagateActive(false, this, &goOn, true))
3429 delete interimWindow;
3430 interimWindow = (master && master.style.interim) ? master : null;
3435 guiApp.interimWindow = this;
3436 /*guiApp.interfaceDriver.SetCaret(0,0,0);
3437 guiApp.caretEnabled = false;*/
3438 UpdateCaret(false, true);
3443 bool acquireInput = false;
3445 parent.activeChild &&
3446 parent.activeChild.state == maximized &&
3447 parent != guiApp.desktop;
3449 if(!style.inactive) // (!style.isRemote || parent.active || parent.style.hidden))
3454 swap = parent.activeChild;
3455 if(swap && swap.destroyed) swap = null;
3456 if(swap && swap != this)
3459 if(!swap.PropagateActive(false, this, &goOn, true))
3460 swap = parent.activeChild;
3471 if(!parent || parent.activeChild != this || style.interim)
3474 result = PropagateActive(true, swap, &goOn, true);
3475 if(!result && !goOn)
3480 acquireInput = true;
3484 if(style.hasMaximize && parent != guiApp.desktop)
3487 SetState(maximized, false, 0);
3488 else if(state != maximized)
3491 for(child = parent.children.first; child; child = child.next)
3493 if(this != child && child.state == maximized)
3494 child.SetState(normal, false, 0);
3501 if(!style.inactive && !style.interim /*&& (!style.isRemote || parent.active || parent.style.hidden)*/)
3503 Window previous = parent.activeClient;
3504 parent.activeChild = this;
3505 if(!style.nonClient /*&& style.isActiveClient*/)
3507 if(style.isActiveClient && !style.hidden)
3508 parent.activeClient = this;
3509 parent.UpdateActiveDocument(previous);
3514 //if(!style.isRemote)
3516 if(rootWindow != this)
3518 if(activateParent && !parent.active /*parent != parent.parent.activeChild*/)
3519 parent.ActivateEx(true, true, moveInactive, activateRoot, external, externalSwap);
3521 else if(!guiApp.fullScreenMode)
3523 Window modalRoot = FindModal();
3524 if(!modalRoot) modalRoot = this;
3525 if(!modalRoot.isForegroundWindow)
3527 modalRoot.isForegroundWindow = true;
3528 // To check : Why is parent null?
3529 if(activateRoot && modalRoot.parent && !modalRoot.parent.display && external != modalRoot)
3531 guiApp.interfaceDriver.ActivateRootWindow(modalRoot);
3533 modalRoot.isForegroundWindow = false;
3538 if(result && real && (!style.inactive || moveInactive) && parent)
3540 Window last = parent.children.last;
3542 if(!style.stayOnTop)
3543 for(; last && last.style.stayOnTop; last = last.prev);
3545 parent.children.Move(this, last);
3547 // Definitely don't want that: why not?
3551 parent.childrenOrder.Move(order, parent.childrenOrder.last);
3557 if(!parent || style.interim || (parent.activeChild == this && !style.inactive))
3564 parent.activeChild = null;
3565 if(!style.nonClient /*&& style.isActiveClient*/)
3567 Window previous = parent.activeClient;
3568 if(style.isActiveClient)
3569 parent.activeClient = null;
3570 parent.UpdateActiveDocument(previous);
3574 if(this == guiApp.interimWindow)
3576 guiApp.interimWindow = null;
3577 if(guiApp.caretOwner)
3578 guiApp.caretOwner.UpdateCaret(false, false);
3580 if(!PropagateActive(false, externalSwap, &goOn, true) || !goOn)
3587 if(!active || !swap)
3588 UpdateDecorations();
3590 swap.UpdateDecorations();
3592 if(active && rootWindow != this)
3593 ConsequentialMouseMove(false);
3600 // --- Input Messages ---
3601 void ::UpdateMouseMove(int mouseX, int mouseY, bool consequential)
3603 static bool reEntrancy = false;
3604 if(reEntrancy) return;
3608 guiApp.cursorUpdate = true;
3609 if(guiApp.windowScrolling && !consequential)
3611 guiApp.windowScrolling.SetScrollPosition(
3612 (guiApp.windowScrolling.sbh) ?
3613 (guiApp.windowScrollingBefore.x - mouseX + guiApp.windowScrollingStart.x) : 0,
3614 (guiApp.windowScrolling.sbv) ?
3615 (guiApp.windowScrollingBefore.y - mouseY + guiApp.windowScrollingStart.y) : 0);
3617 if(guiApp.windowMoving)
3619 if(mouseX != guiApp.movingLast.x || mouseY != guiApp.movingLast.y)
3621 Window window = guiApp.windowMoving;
3623 int w = window.size.w;
3624 int h = window.size.h;
3629 rx = mouseX - guiApp.windowMovingStart.x;
3630 ry = mouseY - guiApp.windowMovingStart.y;
3633 window.GetDecorationsSize(&ew, &eh);
3635 if(guiApp.windowIsResizing)
3637 x = window.scrolledPos.x;
3638 y = window.scrolledPos.y;
3642 aw = Max(guiApp.windowResizingBefore.w - rx,window.skinMinSize.w);
3643 rx = guiApp.windowResizingBefore.w - aw;
3644 rx = Min(guiApp.windowMovingBefore.x + rx, window.parent.clientSize.w-1) - guiApp.windowMovingBefore.x;
3645 w = guiApp.windowResizingBefore.w - rx;
3649 ah = Max(guiApp.windowResizingBefore.h - ry,window.skinMinSize.h);
3650 ry = guiApp.windowResizingBefore.h - ah;
3651 ry = Min(guiApp.windowMovingBefore.y + ry, window.parent.clientSize.h-1) - guiApp.windowMovingBefore.y;
3652 ry = Max(ry, -guiApp.windowMovingBefore.y);
3653 h = guiApp.windowResizingBefore.h - ry;
3655 if(guiApp.resizeEndX)
3657 w = guiApp.windowResizingBefore.w + rx;
3660 if(guiApp.resizeEndY) h = guiApp.windowResizingBefore.h + ry;
3668 w = Max(w, window.minSize.w);
3669 h = Max(h, window.minSize.h);
3670 w = Min(w, window.maxSize.w);
3671 h = Min(h, window.maxSize.h);
3673 if(!window.OnResizing(&w, &h))
3675 w = window.clientSize.w;
3676 h = window.clientSize.h;
3679 w = Max(w, window.skinMinSize.w);
3680 h = Max(h, window.skinMinSize.h);
3687 SNAPDOWN(w, textCellW);
3688 SNAPDOWN(h, textCellH);
3693 aw = Max(w,window.skinMinSize.w);
3694 rx = guiApp.windowResizingBefore.w - aw;
3695 rx = Min(guiApp.windowMovingBefore.x + rx, window.parent.clientSize.w-1) - guiApp.windowMovingBefore.x;
3696 w = guiApp.windowResizingBefore.w - rx;
3700 ah = Max(h,window.skinMinSize.h);
3701 ry = guiApp.windowResizingBefore.h - ah;
3702 ry = Min(guiApp.windowMovingBefore.y + ry, window.parent.clientSize.h-1) - guiApp.windowMovingBefore.y;
3703 ry = Max(ry, -guiApp.windowMovingBefore.y);
3704 h = guiApp.windowResizingBefore.h - ry;
3709 if(!guiApp.windowIsResizing || guiApp.resizeX)
3710 x = guiApp.windowMovingBefore.x + rx;
3711 if(!guiApp.windowIsResizing || guiApp.resizeY)
3712 y = guiApp.windowMovingBefore.y + ry;
3714 if(!guiApp.windowIsResizing)
3717 if(window.parent == guiApp.desktop && guiApp.virtualScreen.w)
3719 x = Min(x, (guiApp.virtualScreen.w + guiApp.virtualScreenPos.x) -1);
3720 y = Min(y, (guiApp.virtualScreen.h + guiApp.virtualScreenPos.y) -1);
3721 x = Max(x,-(w-1) + guiApp.virtualScreenPos.x);
3722 y = Max(y,-(h-1) + guiApp.virtualScreenPos.y);
3726 x = Min(x, (window.parent.reqScrollArea.w ? window.parent.reqScrollArea.w : window.parent.clientSize.w) -1);
3727 y = Min(y, (window.parent.reqScrollArea.h ? window.parent.reqScrollArea.h : window.parent.clientSize.h) -1);
3733 if(!guiApp.windowIsResizing || (guiApp.resizeX || guiApp.resizeY))
3735 if(!window.OnMoving(&x, &y, w, h))
3737 x = window.scrolledPos.x;
3738 y = window.scrolledPos.y;
3744 SNAPDOWN(x, textCellW);
3745 SNAPDOWN(y, textCellH);
3748 if(!window.style.nonClient)
3750 if(!window.style.fixed /*|| window.style.isDocument*/)
3752 if(!window.style.dontScrollHorz)
3753 x += window.parent.scroll.x;
3754 if(!window.style.dontScrollVert)
3755 y += window.parent.scroll.y;
3759 // Break the anchors for moveable/resizable windows
3760 // Will probably cause problem with IDE windows... Will probably need a way to specify if anchors should break
3761 if(window.style.fixed)
3763 if(window.state == normal)
3765 window.normalAnchor = Anchor { left = x, top = y };
3766 window.normalSizeAnchor = SizeAnchor { { w, h } };
3767 window.anchored = false;
3771 window.stateAnchor = Anchor { left = x, top = y };
3772 window.stateSizeAnchor = SizeAnchor { { w, h } };
3774 window.Position(x, y, w, h, false, true, guiApp.windowIsResizing, guiApp.windowIsResizing, false, true);
3775 // TOCHECK: Investigate why the following only redraws the scrollbars
3776 //window.Position(x, y, w, h, false, true, true, true, false, true);
3778 guiApp.movingLast.x = mouseX;
3779 guiApp.movingLast.y = mouseY;
3785 public bool MouseMessage(uint method, int x, int y, Modifiers * mods, bool consequential, bool activate)
3788 bool wasMoving = guiApp.windowMoving ? true : false;
3789 bool wasScrolling = guiApp.windowScrolling ? true : false;
3791 while(result && w != this)
3793 Window msgWindow = GetAtPosition(x,y, false, true, w);
3794 Window trueWindow = GetAtPosition(x,y, false, false, w);
3795 bool windowDragged = false;
3800 window = (w && !w.disabled) ? w : null;
3802 if(trueWindow) incref trueWindow;
3804 if(consequential) mods->isSideEffect = true;
3806 UpdateMouseMove(x, y, consequential);
3808 if(guiApp.windowCaptured && (guiApp.windowCaptured.rootWindow == this))
3810 if(!guiApp.windowCaptured.isEnabled)
3811 guiApp.windowCaptured.ReleaseCapture();
3813 window = guiApp.windowCaptured;
3816 if(trueWindow && activate &&
3817 (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown ||
3818 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown ||
3819 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown ||
3820 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick))
3822 Window modalWindow = trueWindow.FindModal();
3824 if(mods->alt && !mods->ctrl && !mods->shift)
3826 Window moved = trueWindow;
3827 for(moved = trueWindow; moved; moved = moved.parent)
3828 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown || ((moved.style.fixed || moved.moveable) && moved.state != maximized))
3833 windowDragged = true;
3835 // Cancel the ALT menu toggling...
3836 window.rootWindow.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown, 0, 0);
3841 if(window && activate &&
3842 (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown ||
3843 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown ||
3844 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown ||
3845 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick))
3847 Window modalWindow = window.FindModal();
3849 /*if(mods->alt && !mods->shift && !mods->ctrl)
3851 Window moved = window;
3852 for(moved = window; moved; moved = moved.parent)
3853 if(method == OnRightButtonDown || ((moved.style.fixed || moved.moveable) && moved.state != maximized))
3858 windowDragged = true;
3860 // Cancel the ALT menu toggling...
3861 window.rootWindow.KeyMessage(OnKeyDown, 0, 0);
3867 Window activateWindow = modalWindow ? modalWindow : window;
3868 if(activateWindow && !activateWindow.isRemote)
3870 bool doActivation = true;
3871 //bool needToDoActivation = false;
3872 Window check = activateWindow;
3874 for(check = activateWindow; check && check != guiApp.desktop; check = check.parent)
3876 if(!check.style.inactive)
3878 //needToDoActivation = true;
3880 doActivation = false;
3885 if(!needToDoActivation)
3886 doActivation = false;
3889 if((doActivation && (activateWindow.parent != guiApp.desktop || guiApp.fullScreen)) ||
3890 (guiApp.interimWindow && !window.IsDescendantOf(guiApp.interimWindow)))
3894 incref activateWindow;
3895 if(!activateWindow.ActivateEx(true, true, false, true, null, null))
3897 delete activateWindow;
3901 if(activateWindow._refCount == 1)
3903 delete activateWindow;
3907 delete activateWindow;
3909 mods->isActivate = true;
3913 if(!modalWindow && window && !window.destroyed)
3915 if(!guiApp.windowCaptured || windowDragged)
3917 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown)
3919 bool moving = ((window.state != maximized &&
3920 window.IsMouseMoving(
3921 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h)))
3922 || (guiApp.windowMoving && !guiApp.windowIsResizing);
3924 if(!moving && window.IsMouseResizing(
3925 x - window.absPosition.x,
3926 y - window.absPosition.y,
3927 window.size.w, window.size.h,
3928 &guiApp.resizeX, &guiApp.resizeY, &guiApp.resizeEndX, &guiApp.resizeEndY))
3930 guiApp.windowIsResizing = true;
3931 guiApp.windowResizingBefore.w = window.size.w;
3932 guiApp.windowResizingBefore.h = window.size.h;
3934 if(guiApp.windowIsResizing || windowDragged || moving)
3937 guiApp.windowMoving = window;
3938 guiApp.windowMovingStart.x = guiApp.movingLast.x = x;
3939 guiApp.windowMovingStart.y = guiApp.movingLast.y = y;
3940 guiApp.windowMovingBefore.x = window.position.x;//s;
3941 guiApp.windowMovingBefore.y = window.position.y;//s;
3942 if(guiApp.windowMoving == guiApp.windowMoving.rootWindow)
3943 guiApp.interfaceDriver.StartMoving(guiApp.windowMoving.rootWindow, 0,0,false);
3946 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown)
3948 if(window.style.fixed &&
3950 window.IsMouseMoving(
3951 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h)))
3953 window.ShowSysMenu(x, y);
3957 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown)
3959 if(window.sbv || window.sbh)
3962 guiApp.windowScrolling = window;
3963 guiApp.windowScrollingStart.x = x;
3964 guiApp.windowScrollingStart.y = y;
3965 guiApp.windowScrollingBefore.x = window.scroll.x;
3966 guiApp.windowScrollingBefore.y = window.scroll.y;
3969 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick)
3971 if(window.style.hasMaximize &&
3972 window.IsMouseMoving(
3973 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h))
3976 (window.state == maximized) ? normal : maximized, false, *mods);
3984 if(guiApp.windowMoving)
3986 if(guiApp.windowMoving.parent)
3988 if(guiApp.windowMoving.style.nonClient)
3989 guiApp.windowMoving.parent.SetMouseRangeToWindow();
3991 guiApp.windowMoving.parent.SetMouseRangeToClient();
3995 window.UpdateDecorations();
3998 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp)
4000 // Log("\n*** LEFT BUTTON UP ***\n");
4001 if(guiApp.windowMoving)
4002 guiApp.windowMoving.StopMoving();
4004 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp)
4006 if(guiApp.windowScrolling)
4008 Window windowScrolling = guiApp.windowScrolling;
4009 guiApp.windowScrolling = null;
4010 windowScrolling.ReleaseCapture();
4014 if(!result || (window && window.destroyed)) window = null;
4016 if(window && window.FindModal())
4019 if(trueWindow && trueWindow.FindModal())
4027 msgWindow = GetAtPosition(x,y, true, false);
4029 msgWindow.SelectMouseCursor();
4032 if(guiApp.windowCaptured || trueWindow)
4034 Window prevWindow = guiApp.prevWindow;
4035 if(guiApp.prevWindow && trueWindow != guiApp.prevWindow)
4037 guiApp.prevWindow.mouseInside = false;
4038 guiApp.prevWindow = null;
4040 // Eventually fix this not to include captured?
4041 if(!prevWindow.OnMouseLeave(*mods))
4044 if(result && trueWindow && !trueWindow.destroyed/* && trueWindow == window*/)
4046 Box box = trueWindow.box;
4047 box.left += trueWindow.absPosition.x;
4048 box.right += trueWindow.absPosition.x;
4049 box.top += trueWindow.absPosition.y;
4050 box.bottom += trueWindow.absPosition.y;
4052 if(box.IsPointInside({x, y}) && trueWindow != /*guiApp.*/prevWindow /*!trueWindow.mouseInside*/)
4054 int overX = x - (trueWindow.absPosition.x + trueWindow.clientStart.x);
4055 int overY = y - (trueWindow.absPosition.y + trueWindow.clientStart.y);
4057 overX = Max(Min(overX, 32767),-32768);
4058 overY = Max(Min(overY, 32767),-32768);
4060 trueWindow.mouseInside = true;
4061 if(!trueWindow.OnMouseOver(overX, overY, *mods))
4065 if(trueWindow && trueWindow._refCount > 1 && !trueWindow.destroyed)
4066 guiApp.prevWindow = trueWindow;
4068 guiApp.prevWindow = null;
4070 SelectMouseCursor();
4072 if(window && !guiApp.windowMoving && !wasMoving && !wasScrolling)
4074 int clientX = x - (window.absPosition.x + window.clientStart.x);
4075 int clientY = y - (window.absPosition.y + window.clientStart.y);
4077 bool (* MouseMethod)(Window instance, int x, int y, Modifiers mods);
4079 clientX = Max(Min(clientX, 32767),-32768);
4080 clientY = Max(Min(clientY, 32767),-32768);
4082 MouseMethod = (void *)window._vTbl[method];
4084 if(MouseMethod /*&& !consequential*/ && !window.disabled)
4087 if(!MouseMethod(window, clientX, clientY, *mods))
4094 if(result && w && w.clickThrough && w.parent)
4099 if(!result || !w || !w.clickThrough)
4106 // --- Mouse cursor management ---
4108 bool KeyMessage(uint method, Key key, unichar character)
4113 if(guiApp.interimWindow)
4114 this = guiApp.interimWindow;
4117 if((SmartKey)key != alt && (SmartKey)key != Key::control && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown && parent && this != parent.menuBar)
4121 if(!style.inactive || rootWindow != this)
4123 bool (*KeyMethod)(Window window, Key key, unichar ch) = (void *)_vTbl[method];
4124 Window modalWindow = FindModal();
4125 Window interimMaster = master ? master.rootWindow : null;
4129 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4130 status = OnSysKeyDown(key, character);
4131 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit)
4132 status = OnSysKeyHit(key, character);
4133 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4134 status = OnSysKeyUp(key, character);
4141 // Process Key Message for Internal UI Keyboard actions
4142 if(status && !destroyed && menuBar && state != minimized)
4145 if((SmartKey)key != alt)
4146 menuBar.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown, 0, 0);
4149 SmartKey sk = (SmartKey) key;
4150 if((character && !key.alt && !key.ctrl) || sk == left || sk == right || sk == up || sk == down || sk == home || sk == end || sk == escape || sk == alt)
4152 status = menuBar.KeyMessage(method, key, character);
4157 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4158 menuBar.OnKeyHit(escape, 0);
4160 if(!menuBar.focus && guiApp.caretOwner)
4161 guiApp.caretOwner.UpdateCaret(true, false);
4164 if(!destroyed && status)
4166 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4170 case left: case up: case right: case down:
4171 if(guiApp.windowMoving == this)
4174 int w = guiApp.windowMoving.size.w;
4175 int h = guiApp.windowMoving.size.h;
4176 int x = guiApp.windowMoving.scrolledPos.x;
4177 int y = guiApp.windowMoving.scrolledPos.y;
4181 if(key == down || key == up)
4182 step = Max(step, textCellH);
4184 step = Max(step, textCellW);
4187 if(guiApp.windowIsResizing)
4191 case left: w-=step; break;
4192 case right: w+=step; break;
4193 case up: h-=step; break;
4194 case down: h+=step; break;
4201 case left: x-=step; break;
4202 case right: x+=step; break;
4203 case up: y-=step; break;
4204 case down: y+=step; break;
4208 if(guiApp.resizeX) x += w - guiApp.windowMoving.size.w;
4209 if(guiApp.resizeY) y += h - guiApp.windowMoving.size.h;
4211 if(!guiApp.windowIsResizing || guiApp.resizeX)
4212 x = (x - guiApp.windowMovingBefore.x) + guiApp.windowMovingStart.x;
4214 x = (w - guiApp.windowResizingBefore.w) + guiApp.windowMovingStart.x;
4216 if(!guiApp.windowIsResizing || guiApp.resizeY)
4217 y = (y - guiApp.windowMovingBefore.y) + guiApp.windowMovingStart.y;
4219 y = (h - guiApp.windowResizingBefore.h) + guiApp.windowMovingStart.y;
4221 guiApp.interfaceDriver.SetMousePosition(x, y);
4222 ConsequentialMouseMove(true);
4230 if(guiApp.windowMoving && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4232 guiApp.windowMoving.StopMoving();
4233 ConsequentialMouseMove(false);
4241 ShowSysMenu(absPosition.x, absPosition.y);
4249 if(!destroyed && status && state != minimized)
4251 // Process all the way down the children
4252 if(activeChild && !activeChild.disabled)
4254 status = activeChild.KeyMessage(method, key, character);
4256 if(status && activeClient && activeChild != activeClient && !activeClient.disabled && (key.alt || key.ctrl) &&
4257 key.code != left && key.code != right && key.code != up && key.code != down)
4259 status = activeClient.KeyMessage(method, key, character);
4263 if(!destroyed && status && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4265 if((SmartKey)key == enter && !key.alt && !key.ctrl && defaultControl && !defaultControl.disabled && state != minimized)
4266 // && defaultControl != activeChild)
4268 delete previousActive;
4269 previousActive = activeChild;
4270 if(previousActive) incref previousActive;
4272 ConsequentialMouseMove(false);
4273 if((defaultControl.active ||
4274 defaultControl.ActivateEx(true, true, false, true, null, null)) && !defaultControl.disabled)
4275 defaultControl.KeyMessage(method, defaultKey, character);
4281 if(!destroyed && status && (!modalWindow || this == guiApp.desktop))
4283 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4290 ShowSysMenu(absPosition.x, absPosition.y);
4297 if(this != guiApp.desktop)
4299 if(!guiApp.windowMoving && !guiApp.windowCaptured)
4301 if(state != maximized && (key.shift ? style.sizeable : style.fixed))
4303 MenuMoveOrSize(key.shift, true);
4307 else if(guiApp.windowMoving)
4309 guiApp.windowMoving.StopMoving();
4310 ConsequentialMouseMove(false);
4318 if(!destroyed && status && state != minimized)
4320 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4324 case tab: case shiftTab:
4326 Window cycleParent = this;
4327 if(this == guiApp.interimWindow && !master.style.interim && !cycleParent.style.tabCycle)
4328 cycleParent = master.parent;
4330 if(!guiApp.windowCaptured && cycleParent.style.tabCycle)
4332 if(cycleParent.CycleChildren(!key.shift, false, false, true))
4334 Window child = cycleParent.activeChild;
4336 // Scroll the window to include the active control
4338 if(cycleParent.sbh && !child.style.dontScrollHorz)
4340 if(child.scrolledPos.x < 0)
4341 cycleParent.sbh.Action(Position,
4342 cycleParent.scroll.x + child.scrolledPos.x, 0);
4343 else if(child.scrolledPos.x + child.size.w > cycleParent.clientSize.w)
4344 cycleParent.sbh.Action(Position,
4345 cycleParent.scroll.x + child.scrolledPos.x + child.size.w - cycleParent.clientSize.w, 0);
4347 if(cycleParent.sbv && !child.style.dontScrollVert)
4349 if(child.scrolledPos.y < 0)
4350 cycleParent.sbv.Action(Position,
4351 cycleParent.scroll.y + child.scrolledPos.y, 0);
4352 else if(child.scrolledPos.y + child.size.w > window.clientSize.h)
4353 cycleParent.sbv.Action(Position,
4354 cycleParent.scroll.y + child.scrolledPos.y+child.size.h - cycleParent.clientSize.h, 0);
4357 cycleParent.ConsequentialMouseMove(false);
4363 case f6: case shiftF6:
4364 if(!guiApp.windowMoving /*!guiApp.windowCaptured*/)
4366 // NOT NEEDED... guiApp.windowMoving.ReleaseCapture();
4367 if(parent == guiApp.desktop)
4368 if(guiApp.desktop.CycleChildren(key.shift, true, false, true))
4373 if(style.tabCycle ||
4374 CycleChildren(key.shift, true, false, true))
4382 // mIRC Style Window Shortcuts
4383 case alt1: case alt2: case alt3: case alt4: case alt5:
4384 case alt6: case alt7: case alt8: case alt9: case alt0:
4389 for(document = children.first; document; document = document.next)
4391 if(document.style.isDocument && document.documentID - 1 == key.code - k1)
4393 if(document == activeChild)
4395 if(document.state == minimized)
4396 document.SetState(normal, false, key);
4399 document.SetState(minimized, false, key);
4400 CycleChildren(false, true, false);
4405 if(activeChild.state == maximized && document.style.hasMaximize)
4406 document.SetState(maximized, false, key);
4407 else if(document.state == minimized)
4408 document.SetState(normal, false, key);
4409 document.Activate();
4424 if(!destroyed && status)
4426 if(state == minimized)
4431 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4433 if((SmartKey)key == enter && !key.alt && !key.ctrl && defaultControl && previousActive)
4435 if(defaultControl.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp, key, character))
4436 previousActive.ActivateEx(true, false, false, true, null, null);
4437 delete previousActive;
4443 if(!destroyed && status)
4445 status = ProcessHotKeys(method, key, character);
4447 if(!destroyed && status && !modalWindow && state != minimized)
4450 status = KeyMethod(this, key, character);
4451 if(!destroyed && status && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4452 status = OnKeyHit(key, character);
4453 if(!destroyed && status && (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit))
4455 bool result = false;
4458 case ctrlUp: case ctrlDown:
4459 if(sbv && !guiApp.windowScrolling)
4460 result = sbv.Action((key == ctrlUp) ? up : down, 0, key);
4462 case wheelUp: case wheelDown:
4463 if(sbv && !guiApp.windowScrolling)
4465 result = sbv.Action((key == wheelUp) ? wheelUp : wheelDown, 0, key);
4466 // Do we want to do a consequential move regardless of result in this case?
4467 ConsequentialMouseMove(false);
4470 case ctrlPageUp: case ctrlPageDown:
4471 if(sbh && !guiApp.windowScrolling)
4472 result = sbh.Action((key == ctrlPageUp) ? up : down, 0, key);
4477 ConsequentialMouseMove(false);
4482 if(status && !destroyed && menuBar && state != minimized)
4483 status = menuBar.KeyMessage(method, key, character);
4485 if(style.interim && /*destroyed && */status && interimMaster)
4487 // Testing this... for Ctrl-O to open dialog when autocompletion listbox is popped...
4488 status = interimMaster.KeyMessage(method, key, character);
4495 bool ProcessHotKeys(uint method, Key key, unichar character)
4500 for(hotKey = hotKeys.first; hotKey; hotKey = hotKey.next)
4501 if((hotKey.key == key || (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp && hotKey.key.code == key.code)) &&
4502 !hotKey.window.disabled && !hotKey.window.style.hidden && (hotKey.window.style.nonClient || state != minimized))
4504 Window hotKeyWindow = hotKey.window;
4505 Window prevActiveWindow = activeChild;
4507 if(prevActiveWindow) incref prevActiveWindow;
4508 incref hotKeyWindow;
4509 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown && !hotKeyWindow.style.nonClient)
4510 if(!hotKeyWindow.ActivateEx(true, true, false, true, null, null))
4513 delete hotKeyWindow;
4514 delete prevActiveWindow;
4518 if(hotKeyWindow.style.nonClient && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit)
4519 method = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
4520 if(!hotKeyWindow.KeyMessage(method, Key::hotKey, character))
4522 // ********* WORKING ON THIS ***********
4523 if(prevActiveWindow && !guiApp.interimWindow)
4524 prevActiveWindow.ActivateEx(true, false, false, false, null, null);
4527 else if(hotKeyWindow.style.inactive)
4528 status = hotKeyWindow.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp, Key::hotKey, character);
4530 delete prevActiveWindow;
4531 delete hotKeyWindow;
4532 // For Key Ups, don't set status to false... (e.g.: Releasing Enter vs AltEnter hot key)
4533 if(method != __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4537 if(status && tabCycle)
4540 for(child = children.first; child; child = child.next)
4542 if(child.tabCycle && !child.ProcessHotKeys(method, key, character))
4553 // --- Windows and graphics initialization / termination ---
4554 bool SetupRoot(void)
4558 // Setup relationship with outside world (bb root || !bb)
4559 if((!guiApp.fullScreenMode && parent == guiApp.desktop) || this == guiApp.desktop ||
4560 (displayDriver && displayDriver != parent.displayDriver))
4564 tempExtents = new0 Extent[4];
4569 /*if(guiApp.fullScreenMode)
4570 rootWindow = guiApp.desktop;
4572 //rootWindow = parent.created ? parent.rootWindow : null;
4573 rootWindow = parent.rootWindow;
4576 against = &parent.box;
4578 against = &parent.clientArea;
4581 for(child = children.first; child; child = child.next)
4584 return (rootWindow && (rootWindow == this || rootWindow.created)) ? true : false;
4587 bool Setup(bool positionChildren)
4589 bool result = false;
4592 if((!guiApp.fullScreenMode && parent == guiApp.desktop) || (guiApp.fullScreenMode && (this == guiApp.desktop || (displayDriver && displayDriver != parent.displayDriver))))
4594 subclass(DisplayDriver) dDriver = dispDriver ? dispDriver : GetDisplayDriver(guiApp.defaultDisplayDriver);
4595 DisplaySystem displaySystem = dDriver ? dDriver.displaySystem : null;
4597 windowHandle = dDriver.printer ? null : guiApp.interfaceDriver.CreateRootWindow(this);
4599 // This was here, is it really needed?
4600 //guiApp.interfaceDriver.ActivateRootWindow(this);
4604 displaySystem = DisplaySystem {};
4605 if(!displaySystem.Create(dDriver.name, guiApp.fullScreenMode ? windowHandle : windowHandle /*null*/, guiApp.fullScreenMode))
4607 delete displaySystem;
4612 display = Display { alphaBlend = alphaBlend, useSharedMemory = useSharedMemory, windowDriverData = windowData };
4613 if(display.Create(displaySystem, windowHandle))
4620 guiApp.interfaceDriver.SetIcon(this, icon);
4622 else if(this != guiApp.desktop)
4624 display = rootWindow ? rootWindow.display : null;
4630 if(guiApp.acquiredWindow && rootWindow == guiApp.acquiredWindow.rootWindow)
4631 guiApp.interfaceDriver.AcquireInput(guiApp.acquiredWindow.rootWindow, true);
4633 for(child = children.first; child; child = child.next)
4635 if(child.created && !child.Setup(false))
4641 bool SetupDisplay(void)
4643 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
4644 if(is3D) return Window3D_SetupDisplay(this); else
4651 class_data void ** pureVTbl;
4653 bool LoadGraphics(bool creation, bool resetAnchors)
4655 bool result = false;
4656 bool success = false;
4660 if(!rootWindow.created)
4664 if(((subclass(Window))_class).pureVTbl)
4666 if(_vTbl == _class._vTbl)
4668 _vTbl = ((subclass(Window))_class).pureVTbl;
4673 for(m = 0; m < _class.vTblSize; m++)
4675 if(_vTbl[m] == _class._vTbl[m])
4676 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
4680 if(guiApp.currentSkin && ((subclass(Window))_class).pureVTbl)
4682 if(_vTbl == ((subclass(Window))_class).pureVTbl)
4684 _vTbl = _class._vTbl;
4689 for(m = 0; m < _class.vTblSize; m++)
4691 if(_vTbl[m] == ((subclass(Window))_class).pureVTbl[m])
4692 _vTbl[m] = _class._vTbl[m];
4697 if(guiApp.fullScreenMode || this != guiApp.desktop)
4699 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
4705 display.Lock(false);
4706 if(rootWindow == this)
4708 // Set Color Palette
4709 display.SetPalette(palette, true);
4713 if(guiApp.fullScreenMode && this == guiApp.desktop)
4718 for(c=0; c<SystemCursor::enumSize; c++)
4719 if(!guiApp.systemCursors[c].bitmap)
4721 guiApp.systemCursors[c].bitmapName = guiApp.currentSkin.CursorsBitmaps(c,
4722 &guiApp.systemCursors[c].hotSpotX,&guiApp.systemCursors[c].hotSpotY, &guiApp.systemCursors[c].paletteShades);
4723 if(guiApp.systemCursors[c].bitmapName)
4725 guiApp.systemCursors[c].bitmap = eBitmap_LoadT(guiApp.systemCursors[c].bitmapName, null,
4726 guiApp.systemCursors[c].paletteShades ? null : guiApp.desktop.display.displaySystem);
4727 if(guiApp.systemCursors[c].bitmap)
4728 guiApp.systemCursors[c].bitmap.paletteShades = guiApp.systemCursors[c].paletteShades;
4733 for(cursor = guiApp.customCursors.first; cursor; cursor = cursor.next)
4735 cursor.bitmap = eBitmap_LoadT(cursor.bitmapName, null,
4736 cursor.paletteShades ? null : guiApp.desktop.display.displaySystem);
4738 cursor.bitmap.paletteShades = cursor.paletteShades;
4742 guiApp.cursorUpdate = true;
4745 ConsequentialMouseMove(false);
4751 // Load Window Graphic Resources
4754 if(usedFont == setFont || usedFont == window.systemFont)
4755 RemoveResource(usedFont);
4758 RemoveResource(setFont); // TESTING setFont instead of usedFont);
4761 RemoveResource(systemFont);
4764 RemoveResource(captionFont);
4766 for(ptr = resources.first; ptr; ptr = ptr.next)
4768 ptr.loaded = display.displaySystem.LoadResource(ptr.resource);
4771 AddResource(setFont);
4773 AddResource(systemFont);
4775 usedFont = setFont ? setFont : ((parent && parent.parent) ? parent.usedFont : systemFont);
4782 //if(master && master.font)
4783 if(parent && parent.font)
4787 faceName = parent.font.faceName,
4788 size = parent.font.size,
4789 bold = parent.font.bold,
4790 italic = parent.font.italic,
4791 underline = parent.font.underline
4793 //font = parent.font;
4794 watch(parent) { font { } };
4797 font = guiApp.currentSkin.SystemFont();
4804 captionFont = guiApp.currentSkin.CaptionFont();
4805 AddResource(captionFont);
4807 if(OnLoadGraphics())
4813 //SetScrollLineStep(sbStep.x, sbStep.y);
4815 if(this != guiApp.desktop)
4819 normalAnchor = anchor;
4820 normalSizeAnchor = sizeAnchor;
4823 // Break the anchors for moveable/resizable windows
4825 if(style.fixed && style.isDocument)
4827 ComputeAnchors(ax, ay, aw, ah, &x, &y, &w, &h);
4839 stateAnchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
4840 stateSizeAnchor = SizeAnchor {};
4845 int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH;
4850 left = (iconID % maxIcons) * MINIMIZED_WIDTH,
4851 bottom = (iconID / maxIcons) * (guiApp.textMode ? 16 : 24)
4854 stateSizeAnchor = SizeAnchor { size.w = MINIMIZED_WIDTH };
4858 stateAnchor = normalAnchor;
4859 stateSizeAnchor = normalSizeAnchor;
4862 position = Point { };
4863 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
4874 if(Position(x, y, w, h, true, false, true, true, true, true))
4876 if((this != guiApp.desktop || guiApp.fullScreenMode) && rootWindow == this)
4879 guiApp.interfaceDriver.SetRootWindowState(this, normal, true);
4896 success = result = true;
4899 if(!creation && result)
4901 // Load menu bar first because sys buttons are on it...
4904 if(!menuBar.LoadGraphics(false, resetAnchors))
4910 for(child = children.first; child; child = child.next)
4912 if(child.created && child != menuBar && !child.LoadGraphics(false, resetAnchors))
4919 CreateSystemChildren();
4923 if(this == guiApp.desktop && !guiApp.fullScreenMode)
4926 guiApp.interfaceDriver.ActivateRootWindow(activeChild);
4931 //guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, caption);
4932 guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, class.name);
4937 void UnloadGraphics(bool destroyWindows)
4941 // Free children's graphics
4942 for(child = children.first; child; child = child.next)
4943 child.UnloadGraphics(destroyWindows);
4946 display.Lock(false);
4949 if(guiApp.fullScreenMode && this == guiApp.desktop)
4954 for(c=0; c<SystemCursor::enumSize; c++)
4955 if(guiApp.systemCursors[c].bitmap)
4956 delete guiApp.systemCursors[c].bitmap;
4958 for(cursor = guiApp.customCursors.first; cursor; cursor = cursor.next)
4959 delete cursor.bitmap;
4961 guiApp.cursorBackground.Free();
4964 if(display && display.displaySystem)
4968 for(ptr = resources.first; ptr; ptr = ptr.next)
4972 display.displaySystem.UnloadResource(ptr.resource, ptr.loaded);
4977 // Free window graphics
4980 // Free skin graphics
4981 if(rootWindow == this)
4983 DisplaySystem displaySystem = display.displaySystem;
4986 display.driverData = null;
4987 display.displaySystem = null;
4991 if(displaySystem && !displaySystem.numDisplays && !is3D)
4992 delete displaySystem;
5001 if(guiApp.acquiredWindow && this == guiApp.acquiredWindow.rootWindow)
5002 guiApp.interfaceDriver.AcquireInput(guiApp.acquiredWindow.rootWindow, false);
5004 if(this == guiApp.desktop || parent == guiApp.desktop)
5006 if((guiApp.fullScreenMode || this != guiApp.desktop) && rootWindow == this && windowHandle && destroyWindows)
5007 guiApp.interfaceDriver.DestroyRootWindow(this);
5011 // --- Window Hiding ---
5013 void SetVisibility(bool state)
5015 bool visible = (style.hidden || !created) ? false : state;
5016 if(visible != this.visible)
5020 this.visible = visible;
5021 for(child = children.first; child; child = child.next)
5022 child.SetVisibility(visible);
5024 ConsequentialMouseMove(false);
5028 // --- Windows and graphics initialization / termination ---
5030 bool DisplayModeChanged(void)
5032 bool result = false;
5033 if(!guiApp.fullScreenMode && !guiApp.modeSwitching/* && guiApp.desktop.active*/)
5035 guiApp.modeSwitching = true;
5036 UnloadGraphics(false);
5038 if(LoadGraphics(false, false))
5040 guiApp.modeSwitching = false;
5045 // --- Window updates system ---
5047 void UpdateDirty(Box updateBox)
5049 if(!manageDisplay) { OnRedraw(null);return; }
5052 if(display && (!guiApp.fullScreenMode || guiApp.desktop.active) && !guiApp.modeSwitching)
5055 if(display.flags.flipping)
5058 rootWindow.UpdateDisplay();
5061 UpdateBackDisplay(updateBox);
5063 if(guiApp.fullScreenMode)
5065 guiApp.cursorUpdate = true;
5066 guiApp.PreserveAndDrawCursor();
5068 if(guiApp.fullScreenMode)
5069 guiApp.RestoreCursorBackground();
5075 // This function is strictly called as a result of system window activation
5076 bool ExternalActivate(bool active, bool activateRoot, Window window, Window swap)
5079 Window interimMaster = null;
5080 Window interimWindow = guiApp.interimWindow;
5081 if(interimWindow && interimWindow.master)
5082 interimMaster = interimWindow.master.rootWindow;
5084 if(active && state == minimized)
5085 // SetState(normal, false, 0);
5086 SetState(lastState, false, 0);
5088 if(interimMaster && swap == interimMaster && interimMaster.IsSlaveOf(window))
5092 /* WTH is this doing here?
5093 while(swap && swap.activeChild)
5095 swap = swap.activeChild;
5098 // TESTING THIS BEFORE...
5099 if(interimWindow && this == interimMaster)
5103 // Window interimSwap = this;
5104 Window menuBar = this.menuBar;
5105 if(menuBar && interimWindow.master == menuBar)
5108 while(interimSwap && interimSwap.activeChild)
5109 interimSwap = interimSwap.activeChild;
5111 result = interimWindow.ActivateEx(false, false, false, activateRoot, null,
5112 (menuBar && interimWindow.master == menuBar) ? menuBar : interimSwap);
5114 result = /*interimWindow.*/ActivateEx(false, false, false, activateRoot, null, menuBar);
5115 //result = ActivateEx(true, true, false, activateRoot, window, null);
5120 // Testing & FindModal() here: broke reactivating when a modal dialog is up (didn't root activate dialog)
5121 result = ActivateEx(active, active, false, activateRoot /*&& FindModal()*/, window, swap);
5123 if(interimWindow == this && interimMaster && !active)
5125 while(interimMaster && interimMaster.interim && interimMaster.master)
5127 // printf("Going up one master %s\n", interimMaster._class.name);
5128 interimMaster = interimMaster.master.rootWindow;
5130 // printf("Unactivating interim master %s (%x)\n", interimMaster._class.name, interimMaster);
5131 interimMaster.ActivateEx(active, active, false, activateRoot, window, swap);
5137 bool DestroyEx(int returnCode)
5140 Timer timer, nextTimer;
5142 OldLink prevOrder = null;
5143 Window client = null;
5145 if(parent) stopwatching(parent, font);
5147 // if(window.modalSlave) return false;
5148 if(destroyed || !created)
5155 OldLink slave = master.slaves.FindVoid(this);
5156 master.slaves.Delete(slave);
5159 // TOFIX IMMEDIATELY: COMMENTED THIS OUT... causes problem second time creating file dialog
5165 this.returnCode = (DialogResult)returnCode;
5167 AcquireInput(false);
5172 master.hotKeys.Delete(hotKey);
5176 if(guiApp.prevWindow == this)
5178 guiApp.prevWindow = null;
5181 if(guiApp.caretOwner == this)
5183 guiApp.interfaceDriver.SetCaret(0,0,0);
5184 UpdateCaret(false, true);
5185 guiApp.caretEnabled = false;
5190 parent.childrenCycle.Remove(cycle);
5194 OldLink tmpPrev = order.prev;
5195 if(tmpPrev && !(((Window)tmpPrev.data).style.hidden) && !(((Window)tmpPrev.data).destroyed) && (((Window)tmpPrev.data).created))
5196 prevOrder = tmpPrev;
5199 client = tmpPrev ? tmpPrev.data : null;
5200 if(client == this) { client = null; break; }
5201 if(client && (client.style.hidden || client.destroyed || !client.created))
5202 tmpPrev = client.order.prev;
5206 prevOrder = tmpPrev;
5211 // If this window can be an active client, make sure the next window we activate can also be one
5212 if(!style.nonClient && style.isActiveClient)
5214 tmpPrev = prevOrder;
5217 client = tmpPrev ? tmpPrev.data : null;
5218 if(client == this) { client = null; break; }
5219 if(client && (client.style.nonClient || !client.style.isActiveClient || client.style.hidden || client.destroyed || !client.created))
5220 tmpPrev = client.order.prev;
5224 prevOrder = tmpPrev;
5228 if(client && client.style.hidden) client = null;
5230 // parent.childrenOrder.Remove(order);
5233 // TESTING THIS HERE!
5237 // If no display, don't bother deactivating stuff (causes unneeded problems when trying
5238 // to create a window inside a rootwindow that's being destroyed)
5239 // DISABLED THIS BECAUSE OF CREATING WINDOW IN DESKTOP IN WINDOWED MODE
5241 if(master && !master.destroyed /*&&
5242 rootWindow && rootWindow.display && !rootWindow.destroyed*/)
5244 if(master.defaultControl == this)
5245 master.defaultControl = null;
5247 if(parent && !parent.destroyed /*&&
5248 rootWindow && rootWindow.display && !rootWindow.destroyed*/)
5250 if((parent.activeChild == this /*|| parent.activeClient == this */|| guiApp.interimWindow == this))
5252 if(order && prevOrder && prevOrder.data != this && active)
5254 //((Window)prevOrder.data).ActivateEx(true, false, false, false /*true*/, null);
5256 ((Window)prevOrder.data).ActivateEx(true, false, false, (rootWindow == this) ? true : false, null, null);
5257 if(parent.activeClient == this)
5259 parent.activeClient = null;
5260 parent.UpdateActiveDocument(null);
5265 if(guiApp.interimWindow == this)
5268 PropagateActive(false, null, &goOn, true);
5272 //if(window.parent.activeChild == window)
5273 parent.activeChild = null;
5274 if(!style.nonClient /*&& style.isActiveClient*/)
5276 Window previous = parent.activeClient;
5277 if(style.isActiveClient)
5278 parent.activeClient = null;
5279 parent.UpdateActiveDocument(previous);
5284 else if(parent.activeClient == this)
5286 parent.activeClient = client;
5287 parent.UpdateActiveDocument(this);
5291 if(guiApp.interimWindow == this)
5293 guiApp.interimWindow = null;
5294 if(guiApp.caretOwner)
5296 Window desktop = guiApp.desktop;
5297 if(desktop.activeChild && desktop.activeChild.menuBar && !desktop.activeChild.menuBar.focus)
5298 guiApp.caretOwner.UpdateCaret(false, false);
5303 if(style.modal && master && master.modalSlave == this)
5304 master.modalSlave = null;
5308 if(!guiApp.caretOwner && parent.caretSize)
5310 guiApp.caretOwner = parent;
5311 parent.UpdateCaret(false, false);
5312 parent.Update(null);
5315 if(style.isActiveClient && visible)
5317 if(state == minimized) parent.numIcons--;
5318 parent.numPositions--;
5320 // Why was this commented out?
5321 GetRidOfVirtualArea();
5327 dirtyArea.Free(null);
5328 dirtyBack.Free(null);
5329 scrollExtent.Free(null);
5331 /* ATTEMPTING TO MOVE THAT ABOVE
5340 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5341 for(;(child = window.children.first);)
5343 for(; child && (child.destroyed || !child.created); child = child.next);
5352 UnloadGraphics(true);
5355 delete previousActive;
5358 // statusBar = null;
5361 if(master && !master.destroyed)
5363 //master.NotifyDestroyed(this, this.returnCode);
5364 NotifyDestroyed(master, this, this.returnCode);
5367 for(timer = guiApp.windowTimers.first; timer; timer = nextTimer)
5369 nextTimer = timer.next;
5370 if(timer.window == this)
5372 // WHY WERE WE SETTING THIS TO NULL? NO MORE WINDOW WHEN RECREATING...
5373 // timer.window = null;
5379 if(this == guiApp.windowMoving)
5382 if(guiApp.windowCaptured == this)
5384 //guiApp.windowCaptured = null;
5386 if(rootWindow != this && rootWindow)
5387 rootWindow.ConsequentialMouseMove(false);
5395 //for(child = children.first; next = child ? child.next : null, child; child = next)
5396 for(;(child = children.first); )
5398 for(; child && (child.destroyed || !child.created); child = child.next);
5408 /* // MOVED THIS UP...
5411 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5412 for(;(child = window.children.first); )
5414 for(; child && (child.destroyed || !child.created); child = child.next);
5423 while((slave = slaves.first))
5425 for(; slave && (((Window)slave.data).destroyed || !((Window)slave.data).created); slave = slave.next);
5427 ((Window)slave.data).DestroyEx(0);
5432 if(guiApp.caretOwner == this)
5433 guiApp.caretOwner = null;
5435 sysButtons[0] = null;
5436 sysButtons[1] = null;
5437 sysButtons[2] = null;
5440 if(rootWindow != this)
5442 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
5445 box.left -= parent.clientStart.x;
5446 box.top -= parent.clientStart.y;
5447 box.right -= parent.clientStart.x;
5448 box.bottom -= parent.clientStart.y;
5450 if(parent) parent.Update(box);
5455 OldLink slave = master.slaves.FindVoid(this);
5456 master.slaves.Delete(slave);
5462 parent.children.Remove(this);
5467 //autoCreate = false;
5470 // SHOULD THIS BE HERE? FIXED CRASH WITH GOTO DIALOG
5471 if(((subclass(Window))_class).pureVTbl)
5473 if(_vTbl == _class._vTbl)
5475 _vTbl = ((subclass(Window))_class).pureVTbl;
5480 for(m = 0; m < _class.vTblSize; m++)
5482 if(_vTbl[m] == _class._vTbl[m])
5483 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
5492 void SetStateEx(WindowState newState, bool activate)
5495 WindowState prevState = state;
5498 if(prevState != newState)
5499 lastState = prevState;
5500 if(style.isActiveClient && !style.hidden && prevState == minimized)
5503 // This block used to be at the end of the function... moved it for flicker problem in X
5504 // ------------------------------------------------------
5508 stateAnchor = normalAnchor;
5509 stateSizeAnchor = normalSizeAnchor;
5512 stateAnchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
5513 stateSizeAnchor = SizeAnchor {};
5517 int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH;
5520 byte * idBuffer = new0 byte[size];
5522 for(child = parent.children.first; child; child = child.next)
5524 if(child != this && child.state == minimized)
5526 if(child.iconID > size - 2)
5528 idBuffer = renew0 idBuffer byte[size*2];
5529 memset(idBuffer + size, 0, size);
5532 idBuffer[child.iconID] = (byte)bool::true;
5535 for(c = 0; c<size; c++)
5540 if(style.isActiveClient && !style.hidden)
5543 stateAnchor = Anchor { left = (iconID % maxIcons) * MINIMIZED_WIDTH, bottom = (iconID / maxIcons) * (guiApp.textMode ? 16 : 24) };
5544 stateSizeAnchor = SizeAnchor { size.w = MINIMIZED_WIDTH };
5549 // TOCHECK: Why was this here?
5550 //position.x = (tx > 0) ? tx & 0xFFFFF : tx;
5551 //position.y = (ty > 0) ? ty & 0xFFFFF : ty;
5553 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5555 Position(x, y, w, h, true, true, true, true, false, true);
5557 if(!style.inactive && !style.interim && this == parent.activeClient)
5558 parent.UpdateActiveDocument(null);
5560 CreateSystemChildren();
5561 // ------------------------------------------------------
5564 int GetPositionID(Window forChild)
5568 byte * idBuffer = new0 byte[size];
5571 for(child = children.first; child; child = child.next)
5573 if(child.style.isActiveClient && !child.style.hidden && child != forChild)
5575 if(child.positionID > size - 2)
5577 idBuffer = renew0 idBuffer byte[size*2];
5578 memset(idBuffer + size, 0, size);
5581 idBuffer[child.positionID] = (byte)bool::true;
5584 for(c = 0; c<size; c++)
5591 // --- Window related graphics ---
5593 void SetPalette(ColorAlpha * newPalette, bool colorMatch)
5595 palette = newPalette;
5596 if(rootWindow.display)
5597 rootWindow.display.SetPalette(palette, colorMatch);
5600 public bool AcquireInput(bool acquired)
5603 if(acquiredInput != acquired)
5605 if(active || (!visible && creationActivation == activate))
5606 result = AcquireInputEx(acquired);
5611 acquiredInput = acquired ? result : !result;
5616 void ListChildren(ListBox listBox)
5620 for(child = children.first; child; child = child.next)
5622 if(child.cycle && !child.style.nonClient && child.style.isActiveClient)
5624 DataRow row = listBox.AddRow();
5625 row.tag = (int)child;
5626 child.FigureCaption(caption);
5627 row.SetData(null, caption);
5632 void UpdateVisual(Box extent)
5634 if(guiApp.driver != null)
5636 if(guiApp.fullScreenMode && guiApp.desktop.display)
5638 guiApp.desktop.mutex.Wait();
5639 guiApp.desktop.display.Lock(true);
5642 if(guiApp.desktop.active)
5644 if(guiApp.desktop.dirty || guiApp.cursorUpdate)
5646 if(guiApp.desktop.display.flags.flipping)
5647 guiApp.desktop.Update(null);
5648 guiApp.desktop.UpdateDisplay();
5649 guiApp.cursorUpdate = true;
5651 if(guiApp.cursorUpdate || guiApp.desktop.dirty)
5653 guiApp.PreserveAndDrawCursor();
5654 // guiApp.desktop.display.ShowScreen();
5655 guiApp.cursorUpdate = false;
5656 guiApp.desktop.dirty = false;
5657 guiApp.RestoreCursorBackground();
5661 guiApp.desktop.display.Unlock();
5662 guiApp.desktop.mutex.Release();
5666 Window rootWindow = this.rootWindow;
5667 rootWindow.mutex.Wait();
5672 guiApp.SignalEvent();
5675 guiApp.waitMutex.Wait();
5676 guiApp.interfaceDriver.Lock(rootWindow);
5677 if(!rootWindow.style.hidden && rootWindow.dirty)
5679 if(rootWindow.display)
5681 rootWindow.UpdateDisplay();
5682 //rootWindow.display.ShowScreen(null);
5684 rootWindow.dirty = false;
5686 guiApp.interfaceDriver.Unlock(rootWindow);
5687 guiApp.waitMutex.Release();
5690 rootWindow.mutex.Release();
5695 void UnlockDisplay(void)
5697 guiApp.interfaceDriver.Unlock(rootWindow);
5700 void LockDisplay(void)
5702 guiApp.interfaceDriver.Lock(rootWindow);
5705 Surface GetSurface(Box box)
5707 return Redraw((box == null) ? this.box : box);
5710 void SetMousePosition(int x, int y)
5712 guiApp.interfaceDriver.SetMousePosition(x + absPosition.x + clientStart.x, y + absPosition.y + clientStart.y);
5716 void IntegrationActivate(bool active)
5718 if(!guiApp.modeSwitching && !guiApp.fullScreenMode)
5720 isForegroundWindow = true;
5721 ActivateEx(active, active, false, false, null, null);
5722 isForegroundWindow = false;
5727 Window QueryCapture(void)
5729 return guiApp.windowCaptured;
5732 int GetDocumentID(void)
5736 byte * idBuffer = new0 byte[size];
5739 for(child = children.first; child; child = child.next)
5741 if(child.style.isDocument)
5743 if(child.documentID-1 > size - 2)
5745 idBuffer = renew0 idBuffer byte[size*2];
5746 memset(idBuffer + size, 0, size);
5749 idBuffer[child.documentID-1] = 1;
5752 for(c = 0; c<size; c++)
5760 void SetInitSize(Size size)
5763 sizeAnchor.size = size;
5764 normalSizeAnchor = sizeAnchor;
5766 // Break the anchors for moveable/resizable windows
5767 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
5769 stateAnchor = normalAnchor;
5770 stateSizeAnchor = normalSizeAnchor;
5772 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5773 Position(x,y, w, h, true, true, true, true, false, true);
5777 void MenuMoveOrSize(bool resize, bool setCursorPosition)
5779 if(this != guiApp.desktop && state != maximized && (resize ? (state != minimized && style.sizable) : (style.fixed || moveable)))
5781 guiApp.windowIsResizing = resize;
5782 guiApp.windowMoving = this;
5783 guiApp.windowMovingStart = guiApp.movingLast = absPosition;
5784 if(guiApp.windowIsResizing)
5786 guiApp.windowMovingStart.x += size.w - 1;
5787 guiApp.windowMovingStart.y += size.h - 1;
5789 guiApp.windowMovingBefore = scrolledPos;
5790 guiApp.windowResizingBefore = size;
5791 guiApp.windowMoving.UpdateDecorations();
5792 if(guiApp.windowIsResizing)
5793 guiApp.resizeEndX = guiApp.resizeEndY = true;
5795 if(setCursorPosition)
5796 guiApp.interfaceDriver.SetMousePosition(guiApp.windowMovingStart.x, guiApp.windowMovingStart.y);
5800 guiApp.interfaceDriver.GetMousePosition(&x, &y);
5801 guiApp.windowMovingStart.x += x - absPosition.x;
5802 guiApp.windowMovingStart.y += y - absPosition.y;
5805 if(guiApp.windowMoving)
5807 if(guiApp.windowMoving.style.nonClient)
5808 guiApp.windowMoving.parent.SetMouseRangeToWindow();
5810 guiApp.windowMoving.parent.SetMouseRangeToClient();
5815 if(this == rootWindow)
5816 guiApp.interfaceDriver.StartMoving(rootWindow, guiApp.windowMovingStart.x, guiApp.windowMovingStart.y, true);
5824 bool result = false;
5828 else if(guiApp && guiApp.driver != null)
5830 void * systemParent = null;
5831 OldLink slaveHolder;
5833 bool visible = !style.hidden;
5837 systemParent = parent;
5838 parent = guiApp.desktop;
5840 last = parent ? parent.children.last : null;
5842 if((parent && parent != guiApp.desktop && !parent.created) ||
5843 (master && master != guiApp.desktop && !master.created))
5847 property::parent = guiApp.desktop;
5848 if(!master) master = parent;
5850 if(style.modal && master.modalSlave)
5854 parent.children.Remove(this);
5857 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
5858 if(slaveHolder.data == this)
5860 master.slaves.Delete(slaveHolder);
5865 if(parent == guiApp.desktop && !mutex)
5868 if(style.isDocument)
5871 parent.numDocuments--;
5872 documentID = parent.GetDocumentID();
5875 if(!style.stayOnTop)
5876 for(; last && last.style.stayOnTop; last = last.prev);
5878 parent.children.Insert((last == this) ? null : last, this);
5879 //parent.children.Add(this);
5882 dispDriver = parent.dispDriver;
5885 master.modalSlave = this;
5887 box = Box { MAXINT, MAXINT, MININT, MININT }; //-MAXINT, -MAXINT };
5892 master.slaves.Add(slaveHolder = OldLink { data = this });
5897 master.hotKeys.Add(hotKey = HotKeySlot { key = setHotKey, window = this });
5899 if(style.isDefault && !master.defaultControl)
5900 master.defaultControl = this;
5902 stateAnchor = normalAnchor = anchor;
5903 stateSizeAnchor = normalSizeAnchor = sizeAnchor;
5905 // TOCHECK: Why is this here?
5906 //position.x = (ax > 0) ? ax & 0xFFFFF : ax;
5907 //position.y = (ay > 0) ? ay & 0xFFFFF : ay;
5909 this.visible = false;
5910 style.hidden = true;
5913 // autoCreate = true;
5921 if(parent == guiApp.desktop)
5922 Log("LoadGraphics %s\n", caption);
5924 if(LoadGraphics(true, false))
5932 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
5939 if(style.hasMenuBar /*&& menu*/)
5945 menu = menu, isMenuBar = true, anchor = Anchor { top = 23, left = 1, right = 1 },
5946 interim = false, inactive = true, nonClient = true, size.h = 24
5954 // Create the system buttons
5955 CreateSystemChildren();
5957 UpdateActiveDocument(null);
5959 if(style.isDocument)
5963 MenuItem item = menu.FindItem(MenuFileSave, 0);
5964 if(item) item.disabled = !modifiedDocument && fileName;
5969 if(parent == guiApp.desktop)
5970 Log("Preemptive SetState %s\n", caption);
5973 // Preemptive Set State to ensure proper anchoring
5974 SetStateEx(state, false);
5976 style.hidden = true;
5982 for(child = children.first; child; child = next)
5985 if(!child.created && (child.autoCreate || child.wasCreated))
5992 for(link = slaves.first; link; link = next)
5994 Window slave = link.data;
5996 if(!slave.created && (slave.autoCreate || slave.wasCreated))
6005 if(parent == guiApp.desktop)
6006 Log("Real SetState %s\n", caption);
6009 if(isActiveClient && visible)
6011 parent.numPositions--;
6012 if(state == minimized) parent.numIcons--;
6015 // Real set state & activate for proper display & activation
6016 property::visible = visible;
6017 // SetState(state & 0x00000003, true, 0);
6022 /*if(rootWindow == this)
6023 guiApp.interfaceDriver.ActivateRootWindow(this);
6025 if(creationActivation == activate)
6026 ActivateEx(true, false, true, true, null, null);
6027 else if(creationActivation == flash)
6032 rootWindow.ConsequentialMouseMove(false);
6043 guiApp.LogErrorCode(IERR_WINDOW_CREATION_FAILED, caption);
6049 // Testing this here... Otherwise a failed LoadGraphics stalls the application
6051 //style.hidden = true; // !visible;
6052 style.hidden = !visible;
6053 if(master.modalSlave == this)
6054 master.modalSlave = null;
6061 void WriteCaption(Surface surface, int x, int y)
6064 Interface::WriteKeyedTextDisabled(surface, x,y, caption, hotKey ? hotKey.key : 0, !isEnabled);
6067 void Update(Box region)
6073 rootWindow = this.rootWindow;
6075 // rootWindow.mutex.Wait();
6076 if(!destroyed && visible && display)
6081 // Testing this to avoid repetitve full update to take time...
6082 if(dirtyArea.count == 1)
6084 BoxItem item = (BoxItem)ACCESS_ITEM(dirtyArea, dirtyArea.first);
6085 if(item.box.left <= box.left &&
6086 item.box.top <= box.top &&
6087 item.box.right >= box.right &&
6088 item.box.bottom >= box.bottom)
6090 rootWindow.dirty = true;
6095 if(display.flags.flipping && !rootWindow.dirty)
6097 if(this == rootWindow)
6101 rootWindow.Update(null);
6106 rootWindow.dirty = true;
6111 realBox.left += clientStart.x;
6112 realBox.top += clientStart.y;
6113 realBox.right += clientStart.x;
6114 realBox.bottom += clientStart.y;
6120 if(realBox.right >= realBox.left &&
6121 realBox.bottom >= realBox.top)
6123 // if(!rootWindow.fullRender)
6124 dirtyArea.UnionBox(realBox, rootWindow.tempExtents[0]);
6126 for(child = children.first; child; child = child.next)
6131 box.left -= child.absPosition.x - absPosition.x;
6132 box.top -= child.absPosition.y - absPosition.y;
6133 box.right -= child.absPosition.x - absPosition.x;
6134 box.bottom -= child.absPosition.y - absPosition.y;
6135 if(box.right >= child.box.left && box.left <= child.box.right &&
6136 box.bottom >= child.box.top && box.top <= child.box.bottom)
6138 box.left -= child.clientStart.x;
6139 box.top -= child.clientStart.y;
6140 box.right -= child.clientStart.x;
6141 box.bottom -= child.clientStart.y;
6147 realBox.left += absPosition.x - rootWindow.absPosition.x;
6148 realBox.top += absPosition.y - rootWindow.absPosition.y;
6149 realBox.right += absPosition.x - rootWindow.absPosition.x;
6150 realBox.bottom += absPosition.y - rootWindow.absPosition.y;
6151 rootWindow.dirtyBack.UnionBox(realBox, rootWindow.tempExtents[0]);
6154 else if(this == guiApp.desktop)
6157 for(window = children.first; window; window = window.next)
6163 Box childBox = region;
6165 childBox.left -= window.absPosition.x - guiApp.desktop.absPosition.x;
6166 childBox.top -= window.absPosition.y - guiApp.desktop.absPosition.y;
6167 childBox.right -= window.absPosition.x - guiApp.desktop.absPosition.x;
6168 childBox.bottom -= window.absPosition.y - guiApp.desktop.absPosition.y;
6170 window.Update(childBox);
6173 window.Update(null);
6178 // rootWindow.mutex.Release();
6185 if(guiApp.windowCaptured != this)
6187 if(guiApp.windowCaptured)
6191 //Logf("Captured %s (%s)\n", caption, class.name);
6192 guiApp.interfaceDriver.SetMouseCapture(rootWindow);
6193 guiApp.windowCaptured = this;
6199 bool Destroy(int code)
6204 if(!CloseConfirmation(false)) return false;
6208 // TOCHECK: Should autoCreate be set to false here?
6211 // Is this needed here? DestroyEx should decref already...
6220 void Move(int x, int y, int w, int h)
6222 normalAnchor = Anchor { left = x, top = y };
6223 normalSizeAnchor = SizeAnchor { size = { w, h } };
6225 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
6227 if(destroyed) return;
6229 stateAnchor = normalAnchor;
6230 stateSizeAnchor = normalSizeAnchor;
6232 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
6233 Position(x,y, w, h, true, true, true, true, false, true);
6237 DialogResult Modal(void)
6243 // FIXES MEMORY LEAK IF Create() FAILED
6249 void SetScrollArea(int width, int height, bool snapToStep)
6251 bool resize = false;
6254 int stepX = sbStep.x, stepY = sbStep.y;
6255 // Needed to make snapped down position match the skin's check of client area
6256 // against realvirtual
6259 SNAPDOWN(stepX, textCellW);
6260 SNAPDOWN(stepY, textCellH);
6261 stepX = Max(stepX, textCellW);
6262 stepY = Max(stepY, textCellH);
6264 if(scrollFlags.snapX)
6265 SNAPUP(width, stepX);
6266 if(scrollFlags.snapY)
6267 SNAPUP(height, stepY);
6270 reqScrollArea.w = width;
6271 reqScrollArea.h = height;
6272 noAutoScrollArea = (width > 0 || height > 0);
6274 UpdateScrollBars(true, true);
6277 void SetScrollPosition(int x, int y)
6280 sbh.Action(setPosition, x, 0);
6284 int seen = clientSize.w, total = reqScrollArea.w;
6286 if(scrollFlags.snapX)
6287 SNAPDOWN(seen, sbStep.x);
6289 if(!total) total = seen;
6290 range = total - seen + 1;
6291 range = Max(range, 1);
6293 if(x >= range) x = range - 1;
6295 if(scrollFlags.snapX)
6296 SNAPUP(x, sbStep.x);
6299 OnHScroll(setPosition, x, 0);
6303 SNAPDOWN(x, textCellW);
6309 sbv.Action(setPosition, y, 0);
6313 int seen = clientSize.h, total = reqScrollArea.h;
6316 if(scrollFlags.snapY)
6317 SNAPDOWN(seen, sbStep.y);
6319 if(!total) total = seen;
6320 range = total - seen + 1;
6321 range = Max(range, 1);
6323 if(y >= range) y = range - 1;
6325 if(scrollFlags.snapY)
6326 SNAPUP(y, sbStep.y);
6329 OnVScroll(setPosition, y, 0);
6332 SNAPDOWN(y, textCellH);
6337 UpdateCaret(false, false);
6340 void SetScrollLineStep(int stepX, int stepY)
6346 SNAPDOWN(stepX, textCellW);
6347 SNAPDOWN(stepY, textCellH);
6348 stepX = Max(stepX, textCellW);
6349 stepY = Max(stepY, textCellH);
6352 sbh.lineStep = stepX;
6354 sbv.lineStep = stepY;
6357 void SetState(WindowState newState, bool activate, Modifiers mods)
6361 if(state == newState || OnStateChange(newState, mods))
6363 WindowState prevState = state;
6367 // This used to be at the end of the brackets... moved for X, testing...
6368 // This has the effect of activating the window through the system...
6369 if(rootWindow == this)
6370 guiApp.interfaceDriver.SetRootWindowState(this, newState, !style.hidden);
6372 SetStateEx(newState, activate);
6374 if(rootWindow == this)
6376 int x = position.x, y = position.y;
6379 x -= guiApp.desktop.absPosition.x;
6380 y -= guiApp.desktop.absPosition.y;
6382 guiApp.interfaceDriver.PositionRootWindow(this, x, y, size.w, size.h, true, true);
6386 //state = prevState;
6388 if(state != maximized && style.hasMaximize)
6391 for(child = parent.children.first; child; child = child.next)
6393 if(child != this && child.state == maximized)
6394 child.SetStateEx(normal, false);
6398 if(!style.nonClient && (sbv || sbh) && this != parent.sbv && this != parent.sbh)
6399 parent.UpdateScrollBars(true, true);
6402 // Do we really need this stuff here?
6403 // Shouldn't the Activate stuff take care of it?
6404 if(parent.rootWindow == parent && style)
6407 parent.FigureCaption(caption);
6408 guiApp.interfaceDriver.SetRootWindowCaption(parent, caption);
6409 parent.UpdateDecorations();
6413 rootWindow.ConsequentialMouseMove(false);
6420 BitmapResource GetIcon(SkinBitmap iconID)
6422 return guiApp.currentSkin.GetBitmap(iconID);
6425 void SetMouseRange(Box range)
6427 if(range || guiApp.fullScreenMode)
6432 clip.left = range.left + absPosition.x + clientStart.x;
6433 clip.top = range.top + absPosition.y + clientStart.y;
6434 clip.right = range.right + absPosition.x + clientStart.x;
6435 clip.bottom = range.bottom + absPosition.y + clientStart.y;
6439 clip.left = guiApp.desktop.box.left;
6440 clip.top = guiApp.desktop.box.top;
6441 clip.right = guiApp.desktop.box.right;
6442 clip.bottom = guiApp.desktop.box.bottom;
6444 guiApp.interfaceDriver.SetMouseRange(rootWindow, clip);
6447 guiApp.interfaceDriver.SetMouseRange(rootWindow, null);
6450 void SetMouseRangeToClient(void)
6452 if(guiApp.fullScreenMode || this != guiApp.desktop)
6454 Box box {0, 0, clientSize.w - 1, clientSize.h - 1 };
6455 box.Clip(clientArea);
6459 SetMouseRange(null);
6462 void SetMouseRangeToWindow(void)
6464 Box box { -clientStart.x, -clientStart.y, size.w-1, size.h-1 };
6465 if(this == guiApp.desktop)
6466 SetMouseRangeToClient();
6471 // x, y: Desktop Coordinates
6472 void ShowSysMenu(int x, int y)
6475 PopupMenu windowMenu { master = this, interim = true, position = { x + 1 - guiApp.desktop.position.x, y + 1 - guiApp.desktop.position.y }, menu = menu };
6478 menu, "Restore", r, NotifySelect = MenuWindowRestore,
6479 disabled = (!style.hasMaximize && !style.hasMinimize) || state == normal, bitmap = guiApp.currentSkin.GetBitmap(restore)
6483 menu, "Move", m, NotifySelect = MenuWindowMove,
6484 disabled = !style.fixed || state == maximized
6488 menu, "Size", s, NotifySelect = MenuWindowSize,
6489 disabled = !style.sizable || state != normal
6493 menu, "Minimize", n, NotifySelect = MenuWindowMinimize,
6494 disabled = !style.hasMinimize || state == minimized, bitmap = guiApp.currentSkin.GetBitmap(minimize)
6498 menu, "Maximize", KeyCode::x, NotifySelect = MenuWindowMaximize,
6499 disabled = !style.hasMaximize || state == maximized, bitmap = guiApp.currentSkin.GetBitmap(maximize)
6503 menu, "Stay On Top", t, NotifySelect = MenuWindowStayOnTop,
6504 disabled = !style.fixed, checkable = true, checked = style.stayOnTop
6506 MenuDivider { menu };
6509 menu, "Close", c, (parent == guiApp.desktop) ? altF4 : ( style.isActiveClient ? ctrlF4 : 0), NotifySelect = MenuWindowClose,
6510 bold = true, disabled = !style.hasClose, bitmap = guiApp.currentSkin.GetBitmap(close)
6512 windowMenu.Create();
6517 ActivateEx(true, true, true, true, null, null);
6520 void MakeActive(void)
6522 ActivateEx(true, false, true, false, null, null);
6525 void SoftActivate(void)
6527 if(guiApp.desktop.active)
6533 void Deactivate(void)
6535 ActivateEx(false, true, true, true, null, null);
6540 guiApp.interfaceDriver.FlashRootWindow(rootWindow);
6543 bool CycleChildren(bool backward, bool clientOnly, bool tabCycleOnly, bool cycleParents)
6545 bool result = false;
6546 if(activeChild && activeChild.cycle)
6548 Window modalWindow, child = activeChild;
6549 if(!clientOnly /*&& parent.tabCycle*/)
6551 Window next = child;
6554 if(next.cycle == (backward ? childrenCycle.first : childrenCycle.last))
6558 if(parent && parent.CycleChildren(backward, false, true, true))
6566 next = next.cycle.prev.data;
6568 next = next.cycle.next.data;
6569 if(!next.disabled && !next.inactive /*isRemote*/ && next.created && !next.nonClient && (!clientOnly || next.style.isActiveClient) && !next.style.hidden && next.FindModal() != activeChild)
6574 if(!clientOnly && child.cycle == (backward ? childrenCycle.first : childrenCycle.last) &&
6575 parent.tabCycle && parent.CycleChildren(backward, false, false))
6579 if(tabCycleOnly && !tabCycle) return false;
6586 child = child.cycle.prev.data;
6588 child = child.cycle.next.data;
6589 if(child == child.parent.activeChild)
6591 else if(!child.disabled && child.created && (!clientOnly || child.style.isActiveClient) && !child.style.hidden && child.FindModal() != activeChild)
6594 modalWindow = child.FindModal();
6597 // Scroll the window to include the active control
6598 if(sbh && !child.style.dontScrollHorz)
6600 if(child.scrolledPos.x < 0)
6601 sbh.Action(setPosition, scroll.x + child.scrolledPos.x, 0);
6602 else if(child.scrolledPos.x + child.size.w > clientSize.w)
6603 sbh.Action(setPosition, scroll.x + child.scrolledPos.x + child.size.w - clientSize.w, 0);
6605 if(sbv && !child.style.dontScrollVert)
6607 if(child.scrolledPos.y < 0)
6608 sbv.Action(setPosition, scroll.y + child.scrolledPos.y, 0);
6609 else if(child.scrolledPos.y + child.size.h > clientSize.h)
6610 sbv.Action(setPosition, scroll.y + child.scrolledPos.y + child.size.h - clientSize.h, 0);
6614 child = modalWindow ? modalWindow : child;
6615 child.ActivateEx(true, true, true, true, null, null);
6616 if(child.tabCycle && child.childrenCycle.first)
6617 child = ((OldLink)(backward ? child.childrenCycle.first : child.childrenCycle.last)).data;
6625 ConsequentialMouseMove(false);
6629 void AddResource(Resource resource)
6633 ResPtr ptr { resource = resource };
6637 // Load Graphics here if window is created already
6638 if(/*created && */display)
6640 display.Lock(false);
6641 ptr.loaded = display.displaySystem.LoadResource(resource);
6645 // Temporary hack to load font right away for listbox in dropbox ...
6646 else if(master && master.display)
6648 master.display.Lock(false);
6649 master.display.displaySystem.LoadResource(resource);
6650 master.display.Unlock();
6656 void RemoveResource(Resource resource)
6661 for(ptr = resources.first; ptr; ptr = ptr.next)
6663 if(ptr.resource == resource)
6669 // Unload Graphics here if window is created already
6670 if(/*created && */display)
6674 display.Lock(false);
6675 display.displaySystem.UnloadResource(resource, ptr.loaded);
6681 resources.Delete(ptr);
6686 void SetCaret(int x, int y, int size)
6693 if(active && !style.interim)
6695 if(visible || !guiApp.caretOwner)
6696 guiApp.caretOwner = size ? this : null;
6698 UpdateCaret(false, false);
6701 guiApp.interfaceDriver.SetCaret(0,0,0);
6702 UpdateCaret(false, true);
6703 guiApp.caretEnabled = false;
6706 else if(style.inactive && active)
6708 guiApp.interfaceDriver.SetCaret(0,0,0);
6709 UpdateCaret(false, true);
6710 guiApp.caretEnabled = false;
6715 void Scroll(int x, int y)
6717 bool opaque = !style.drawBehind || background.a;
6718 if(opaque && display && display.flags.scrolling)
6720 Box box = clientArea;
6721 box.left += clientStart.x;
6722 box.top += clientStart.y;
6723 box.right += clientStart.x;
6724 box.bottom += clientStart.y;
6726 //scrollExtent.Free(null);
6727 scrollExtent.AddBox(box);
6728 scrolledArea.x += x;
6729 scrolledArea.y += y;
6731 //scrollExtent.Free();
6732 //scrollExtent.AddBox(clientArea);
6733 //scrollExtent.Offset(clientStart.x, clientStart.y);
6734 //scrolledArea.x = x;
6735 //scrolledArea.y = y;
6741 rootWindow.dirty = true;
6744 void ReleaseCapture()
6746 if(guiApp && guiApp.windowCaptured && guiApp.windowCaptured == this)
6748 Window oldCaptured = guiApp.windowCaptured;
6749 guiApp.windowCaptured = null;
6750 guiApp.prevWindow = null;
6753 //guiApp.Log("Released Capture\n");
6755 guiApp.interfaceDriver.SetMouseCapture(null);
6757 //oldCaptured.OnMouseCaptureLost();
6760 oldCaptured.ConsequentialMouseMove(false);
6765 void SetText(char * format, ...)
6772 char caption[MAX_F_STRING];
6774 va_start(args, format);
6775 vsprintf(caption, format, args);
6778 this.caption = new char[strlen(caption)+1];
6780 strcpy(this.caption, caption);
6789 bool Grab(Bitmap bitmap, Box box, bool decorations)
6791 bool result = false;
6792 if(display || this == guiApp.desktop)
6794 Box clip = {MININT, MININT, MAXINT, MAXINT};
6800 clip.Clip(clientArea);
6802 clip.Clip(this.box);
6804 if(rootWindow != this)
6806 clip.left += absPosition.y;
6807 clip.top += absPosition.y;
6808 clip.right += absPosition.x;
6809 clip.bottom += absPosition.y;
6812 clip.left += decorations ? 0 : clientStart.x;
6813 clip.top += decorations ? 0 : clientStart.y;
6814 clip.right += decorations ? 0 : clientStart.x;
6815 clip.bottom += decorations ? 0 : clientStart.y;
6817 if(display && display.flags.flipping)
6819 rootWindow.Update(null);
6820 rootWindow.UpdateDisplay();
6827 result = window.display.displaySystem.driver.GrabScreen(null, bitmap, clip.left, clip.top,
6828 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6832 result = display.Grab(bitmap, clip.left, clip.top,
6833 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6835 if(bitmap.pixelFormat != pixelFormat888 && bitmap.pixelFormat != pixelFormat8)
6837 if(!bitmap.Convert(null, pixelFormat888, null))
6844 void GetMousePosition(int * x, int * y)
6846 int mouseX = 0, mouseY = 0;
6847 if(!guiApp.acquiredWindow && (guiApp.desktop.active || !guiApp.fullScreenMode))
6850 guiApp.interfaceDriver.GetMousePosition(&mouseX, &mouseY);
6851 if(this != guiApp.desktop)
6853 mouseX -= absPosition.x + clientStart.x;
6854 mouseY -= absPosition.y + clientStart.y;
6861 DialogResult DoModal()
6863 DialogResult returnCode = 0;
6864 int terminated = terminateX;
6867 while(!destroyed && guiApp.driver != null)
6869 if(terminateX != terminated)
6871 terminated = terminateX;
6872 guiApp.desktop.Destroy(0);
6873 if(guiApp.desktop.created)
6876 //printf("Resetting terminate X to 0\n");
6882 guiApp.UpdateDisplay();
6883 if(!guiApp.ProcessInput(false))
6886 returnCode = this.returnCode;
6899 return !destroyed && guiApp.driver != null && terminateX < 2;
6902 DialogResult DoModalEnd()
6904 DialogResult returnCode = this.returnCode;
6909 // --- Window manipulation ---
6910 /*bool GetDisabled()
6912 bool disabled = this.disabled;
6914 for(window = this; (window = window.master); )
6925 // --- Mouse Manipulation ---
6926 void GetNCMousePosition(int * x, int * y)
6928 GetMousePosition(x, y);
6929 if(x) *x += clientStart.x;
6930 if(y) *y += clientStart.y;
6933 // --- Carets manipulation ---
6934 void GetCaretPosition(Point caretPos)
6936 caretPos = this.caretPos;
6939 int GetCaretSize(void)
6944 bool ButtonCloseDialog(Button button, int x, int y, Modifiers mods)
6950 bool CloseConfirmation(bool parentClosing)
6963 if(!OnClose(parentClosing))
6966 // If you want to skip this, simply set modifiedDocument to false in OnClose
6967 if(result && (/*fileName || */style.isDocument) && modifiedDocument)
6969 DialogResult dialogRes;
6972 sprintf(message, "Save changes to %s?", fileName);
6974 sprintf(message, "Save changes to Untitled %d?", documentID);
6976 dialogRes = MessageBox { master = master, type = yesNoCancel, text = parent.caption, contents = message }.Modal();
6978 if(dialogRes == yes)
6980 // TOFIX: Precomp error if brackets are taken out
6981 result = (DialogResult)MenuFileSave(null, 0) != cancel;
6983 else if(dialogRes == cancel)
6989 for(slave = slaves.first; slave; slave = slave.next)
6990 if(!((Window)slave.data).CloseConfirmation(true))
6992 // ((Window)slave.data).CloseConfirmation(true);
7000 for(child = children.first; child; child = child.next)
7001 if(child.master != this && !child.CloseConfirmation(true))
7011 // Static methods... move them somewhere else?
7012 void ::RestoreCaret()
7014 if(guiApp.caretOwner)
7015 guiApp.caretOwner.UpdateCaret(false, false);
7018 void ::FreeMouseRange()
7020 guiApp.interfaceDriver.SetMouseRange(null, null);
7024 bool MenuFileClose(MenuItem selection, Modifiers mods)
7026 Window document = activeChild;
7028 document.Destroy(0);
7032 bool MenuFileExit(MenuItem selection, Modifiers mods)
7038 bool MenuFileSave(MenuItem selection, Modifiers mods)
7042 fileMonitor.fileName = null;
7045 if(OnSaveFile(fileName))
7047 //if(OnFileModified != Window::OnFileModified)
7050 fileMonitor.fileName = fileName;
7056 MessageBox dialog { master = master, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7057 DialogResult answer = dialog.Modal();
7059 if(answer != yes) return (bool)answer;
7062 return MenuFileSaveAs(selection, mods);
7065 bool MenuFileSaveAs(MenuItem selection, Modifiers mods)
7067 DialogResult result = (DialogResult)bool::true;
7068 FileDialog fileDialog = saveDialog;
7071 fileDialog = FileDialog {};
7076 fileDialog.filePath = fileName;
7079 char filePath[MAX_FILENAME];
7080 sprintf(filePath, "Untitled %d", documentID);
7081 fileDialog.filePath = filePath;
7083 fileMonitor.fileName = null;
7085 fileDialog.type = save;
7086 fileDialog.text = "Save As";
7090 fileDialog.master = master.parent ? master : this;
7091 if(fileDialog.Modal() == ok)
7093 char * filePath = fileDialog.filePath;
7095 if(OnSaveFile(filePath))
7098 property::fileName = filePath;
7099 NotifySaved(master, this, filePath);
7104 MessageBox dialog { master = master.parent ? master : this, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7105 DialogResult answer = dialog.Modal();
7120 //if(OnFileModified != Window::OnFileModified && fileName)
7123 fileMonitor.fileName = fileName;
7127 return (bool)result; // Actually returning result from Yes/NoCancel message box
7130 bool MenuFileSaveAll(MenuItem selection, Modifiers mods)
7132 Window document = activeChild;
7134 for(document = children.first; document; document = next)
7136 next = document.next;
7137 if(document.style.isDocument || document.fileName)
7138 document.MenuFileSave(selection, mods);
7143 bool MenuWindowArrangeIcons(MenuItem selection, Modifiers mods)
7147 for(document = children.first; document; document = document.next)
7148 //if(document.style.isDocument && document.state == minimized)
7149 if(document.style.isActiveClient && document.state == minimized)
7150 document.SetState(minimized, false, mods);
7154 bool MenuWindowCascade(MenuItem selection, Modifiers mods)
7156 Window document = activeChild;
7159 Window firstDocument = null;
7161 OldLink cycle = document.cycle.prev;
7166 if(child.style.isActiveClient && !child.style.hidden)
7170 firstDocument = child;
7171 if(child.state == minimized)
7172 child.SetState(minimized, false, mods);
7175 child.positionID = id++;
7176 child.SetState(normal, false, mods);
7177 child.anchor.left.type = cascade;
7180 child.normalSizeAnchor = *&child.sizeAnchor;
7181 child.normalAnchor = child.anchor;
7183 // Break the anchors for moveable/resizable windows
7184 if(child.style.fixed)
7186 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7188 (*&child.normalAnchor).left = x;
7189 (*&child.normalAnchor).top = y;
7190 (*&child.normalAnchor).right.type = none;
7191 (*&child.normalAnchor).bottom.type = none;
7193 child.normalSizeAnchor.isClientW = false;
7194 child.normalSizeAnchor.isClientH = false;
7195 child.normalSizeAnchor.size.w = w;
7196 child.normalSizeAnchor.size.h = h;
7197 child.anchored = false;
7200 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7202 child.stateAnchor = child.normalAnchor;
7203 child.stateSizeAnchor = child.normalSizeAnchor;
7205 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7206 child.Position(x, y, w, h, true, true, true, true, false, false);
7211 last = children.last;
7212 if(!child.style.stayOnTop)
7213 for(; last && last.style.stayOnTop; last = last.prev);
7214 children.Move(child, last);
7215 childrenOrder.Move(child.order, childrenOrder.last);
7217 if(cycle == document.cycle) break;
7221 firstDocument.Activate();
7226 bool MenuWindowClose(MenuItem selection, Modifiers mods)
7233 // Close all closes all active clients, not all documents
7234 bool MenuWindowCloseAll(MenuItem selection, Modifiers mods)
7236 Window next, document;
7238 for(document = children.first; document; document = next)
7240 for(next = document.next; next && !(next.style.isActiveClient; next = next.next);
7241 if(document.style.isActiveClient)
7242 if(!document.Destroy(0) && !document.style.hidden)
7248 bool MenuWindowMaximize(MenuItem selection, Modifiers mods)
7250 if(style.hasMaximize && state != maximized)
7251 SetState(maximized, 0, 0);
7255 bool MenuWindowMinimize(MenuItem selection, Modifiers mods)
7257 if(style.hasMinimize && state != minimized)
7259 SetState(minimized, 0, 0);
7260 parent.CycleChildren(false, true, false, true);
7265 bool MenuWindowMove(MenuItem selection, Modifiers mods)
7267 MenuMoveOrSize(false, selection ? true : false);
7271 bool MenuWindowNext(MenuItem selection, Modifiers mods)
7273 CycleChildren(false, true, false, true);
7277 bool MenuWindowPrevious(MenuItem selection, Modifiers mods)
7279 CycleChildren(true, true, false, true);
7283 bool MenuWindowSize(MenuItem selection, Modifiers mods)
7285 MenuMoveOrSize(true, true);
7289 bool MenuWindowRestore(MenuItem selection, Modifiers mods)
7292 SetState(normal, 0, 0);
7296 bool MenuWindowSelectWindow(MenuItem selection, Modifiers mods)
7299 int id = selection.id;
7300 OldLink cycle = activeClient.cycle;
7302 //for(c = 0, cycle = activeChild.cycle; c<id; cycle = cycle.next, c++);
7305 Window sibling = cycle.data;
7306 if(sibling.style.isActiveClient)
7314 document = cycle.data;
7315 document.Activate();
7317 //if(activeChild.state == maximized)
7318 // document.SetState(maximized, false, mods);
7319 //else if(document.state == minimized)
7320 // document.SetState(normal, false, mods);
7324 bool MenuWindowStayOnTop(MenuItem selection, Modifiers mods)
7326 stayOnTop = !style.stayOnTop;
7330 bool MenuWindowTileHorz(MenuItem selection, Modifiers mods)
7332 Window document = activeChild;
7335 Window firstDocument = null;
7336 OldLink cycle = document.cycle;
7340 Window child = cycle.data;
7341 if(child.style.isActiveClient && !child.style.hidden)
7343 if(!firstDocument) firstDocument = child;
7344 if(child.state == minimized)
7345 child.SetState(minimized, false, mods);
7348 child.positionID = id++;
7349 child.SetState(normal, false, mods);
7350 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7352 child.anchor.left.type = hTiled;
7355 child.normalSizeAnchor = *&child.sizeAnchor;
7356 child.normalAnchor = child.anchor;
7358 // Break the anchors for moveable/resizable windows
7359 if(child.style.fixed)
7361 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7363 (*&child.normalAnchor).left = x;
7364 (*&child.normalAnchor).top = y;
7365 (*&child.normalAnchor).right.type = none;
7366 (*&child.normalAnchor).bottom.type = none;
7367 child.normalSizeAnchor.isClientW = false;
7368 child.normalSizeAnchor.isClientH = false;
7369 child.normalSizeAnchor.size.w = w;
7370 child.normalSizeAnchor.size.h = h;
7371 child.anchored = false;
7374 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7376 child.stateAnchor = child.normalAnchor;
7377 child.stateSizeAnchor = child.normalSizeAnchor;
7379 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7380 child.Position(x,y, w, h, true, true, true, true, false, true);
7385 if((cycle = cycle.next) == document.cycle) break;
7388 firstDocument.Activate();
7393 bool MenuWindowTileVert(MenuItem selection, Modifiers mods)
7395 Window document = activeChild;
7398 Window firstDocument = null;
7400 OldLink cycle = document.cycle;
7405 //if(child.style.isDocument)
7406 if(child.style.isActiveClient && !child.style.hidden)
7408 if(!firstDocument) firstDocument = child;
7409 if(child.state == minimized)
7410 child.SetState(minimized, false, mods);
7413 child.positionID = id++;
7414 child.SetState(normal, false, mods);
7415 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7417 child.anchor.left.type = vTiled;
7420 child.normalSizeAnchor = *&child.sizeAnchor;
7421 child.normalAnchor = child.anchor;
7423 // Break the anchors for moveable/resizable windows
7424 if(child.style.fixed)
7426 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7428 (*&child.normalAnchor).left = x;
7429 (*&child.normalAnchor).top = y;
7430 (*&child.normalAnchor).right.type = none;
7431 (*&child.normalAnchor).bottom.type = none;
7432 child.normalSizeAnchor.isClientW = false;
7433 child.normalSizeAnchor.isClientH = false;
7434 child.normalSizeAnchor.size.w = w;
7435 child.normalSizeAnchor.size.h = h;
7436 child.anchored = false;
7439 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7441 child.stateAnchor = child.normalAnchor;
7442 child.stateSizeAnchor = child.normalSizeAnchor;
7444 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7445 child.Position(x,y, w, h, true, true, true, true, false, true);
7450 if((cycle = cycle.next) == document.cycle) break;
7453 firstDocument.Activate();
7458 bool MenuWindowWindows(MenuItem selection, Modifiers mods)
7460 WindowList dialog { master = this };
7461 Window document = (Window)dialog.Modal();
7464 if(activeChild.state == maximized)
7465 document.SetState(maximized, false, mods);
7466 else if(document.state == minimized)
7467 document.SetState(normal, false, mods);
7468 document.Activate();
7474 virtual bool OnCreate(void);
7475 virtual void OnDestroy(void);
7476 virtual void OnDestroyed(void);
7477 virtual bool OnClose(bool parentClosing);
7478 virtual bool OnStateChange(WindowState state, Modifiers mods);
7479 virtual bool OnPostCreate(void);
7480 virtual bool OnMoving(int *x, int *y, int w, int h);
7481 virtual bool OnResizing(int *width, int *height);
7482 virtual void OnResize(int width, int height);
7483 virtual void OnPosition(int x, int y, int width, int height);
7484 virtual bool OnLoadGraphics(void);
7485 virtual void OnApplyGraphics(void);
7486 virtual void OnUnloadGraphics(void);
7487 virtual void OnRedraw(Surface surface);
7488 virtual bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct);
7489 virtual void OnActivateClient(Window client, Window previous);
7490 virtual bool OnKeyDown(Key key, unichar ch);
7491 virtual bool OnKeyUp(Key key, unichar ch);
7492 virtual bool OnKeyHit(Key key, unichar ch);
7493 virtual bool OnSysKeyDown(Key key, unichar ch);
7494 virtual bool OnSysKeyUp(Key key, unichar ch);
7495 virtual bool OnSysKeyHit(Key key, unichar ch);
7496 virtual bool OnMouseOver(int x, int y, Modifiers mods);
7497 virtual bool OnMouseLeave(Modifiers mods);
7498 virtual bool OnMouseMove(int x, int y, Modifiers mods);
7499 virtual bool OnLeftButtonDown(int x, int y, Modifiers mods);
7500 virtual bool OnLeftButtonUp(int x, int y, Modifiers mods);
7501 virtual bool OnLeftDoubleClick(int x, int y, Modifiers mods);
7502 virtual bool OnRightButtonDown(int x, int y, Modifiers mods);
7503 virtual bool OnRightButtonUp(int x, int y, Modifiers mods);
7504 virtual bool OnRightDoubleClick(int x, int y, Modifiers mods);
7505 virtual bool OnMiddleButtonDown(int x, int y, Modifiers mods);
7506 virtual bool OnMiddleButtonUp(int x, int y, Modifiers mods);
7507 virtual bool OnMiddleDoubleClick(int x, int y, Modifiers mods);
7508 virtual void OnMouseCaptureLost(void);
7509 virtual void OnHScroll(ScrollBarAction action, int position, Key key);
7510 virtual void OnVScroll(ScrollBarAction action, int position, Key key);
7511 virtual void OnDrawOverChildren(Surface surface);
7512 virtual bool OnFileModified(FileChange fileChange, char * param);
7513 virtual bool OnSaveFile(char * fileName);
7515 // Skins Virtual Functions
7516 virtual void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h);
7517 virtual void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh);
7518 virtual void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
7523 virtual void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7524 virtual void PreShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7525 virtual bool IsMouseMoving(int x, int y, int w, int h);
7526 virtual bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY);
7527 virtual void UpdateNonClient();
7528 virtual void SetBox(Box box);
7529 virtual bool IsInside(int x, int y)
7531 return box.IsPointInside({x, y});
7533 virtual bool IsOpaque()
7535 return (!style.drawBehind || background.a == 255);
7539 virtual bool Window::NotifyActivate(Window window, bool active, Window previous);
7540 virtual void Window::NotifyDestroyed(Window window, DialogResult result);
7541 virtual void Window::NotifySaved(Window window, char * filePath);
7546 property Window parent
7548 property_category "Layout"
7551 if(value || guiApp.desktop)
7554 Window oldParent = parent;
7555 Anchor anchor = this.anchor;
7557 if(value && value.IsDescendantOf(this)) return;
7558 if(value && value == this)
7560 if(!value) value = guiApp.desktop;
7562 if(value == oldParent) return;
7564 if(!master || (master == this.parent && master == guiApp.desktop))
7565 property::master = value;
7569 parent.children.Remove(this);
7573 box.left - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7574 box.top - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y,
7575 box.right - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7576 box.bottom - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y
7580 last = value.children.last;
7582 if(style.isDocument)
7585 parent.numDocuments--;
7586 documentID = value.GetDocumentID();
7589 if(style.isActiveClient && !style.hidden)
7591 if(parent && parent != guiApp.desktop && !(style.hidden))
7593 if(state == minimized) parent.numIcons--;
7594 parent.numPositions--;
7598 if(!style.stayOnTop)
7599 for(; last && last.style.stayOnTop; last = last.prev);
7601 value.children.Insert(last, this);
7603 // *** NEW HERE: ***
7605 parent.childrenCycle.Delete(cycle);
7607 parent.childrenOrder.Delete(order);
7615 int x = position.x, y = position.y, w = size.w, h = size.h;
7619 x += parent.absPosition.x - value.absPosition.x + parent.clientStart.x - value.clientStart.x;
7620 y += parent.absPosition.y - value.absPosition.y + parent.clientStart.y - value.clientStart.y;
7622 vpw = value.clientSize.w;
7623 vph = value.clientSize.h;
7629 else if(style.fixed)
7631 if(!style.dontScrollHorz && value.scrollArea.w) vpw = value.scrollArea.w;
7632 if(!style.dontScrollVert && value.scrollArea.h) vph = value.scrollArea.h;
7635 anchor = this.anchor;
7637 if(anchor.left.type == offset) anchor.left.distance = x;
7638 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
7639 if(anchor.top.type == offset) anchor.top.distance = y;
7640 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
7641 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
7642 //else if(anchor.right.type == relative) anchor.right.percent = 1.0-(float) (vpw - (x + w)) / vpw;
7643 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
7644 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
7645 //else if(anchor.bottom.type == relative) anchor.bottom.percent = 1.0-(float) (vph - (y + h)) / vph;
7646 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
7648 if(!anchor.left.type && !anchor.right.type)
7650 anchor.horz.distance = (x + w / 2) - (vpw / 2);
7651 //anchor.horz.type = anchor.horz.distance ? AnchorValueOffset : 0;
7653 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
7654 if(!anchor.top.type && !anchor.bottom.type)
7656 anchor.vert.distance = (y + h / 2) - (vph / 2);
7657 //anchor.vert.type = anchor.vert.distance ? AnchorValueOffset : 0;
7659 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
7667 parent.childrenCycle.Insert(
7668 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
7669 cycle = OldLink { data = this });
7670 parent.childrenOrder.Insert(
7671 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
7672 order = OldLink { data = this });
7675 if(!style.hidden && style.isActiveClient)
7677 positionID = parent.GetPositionID(this);
7678 parent.numPositions++;
7679 if(state == minimized) parent.numIcons--;
7682 // *** FONT INHERITANCE ***
7683 if(!setFont && oldParent)
7684 stopwatching(oldParent, font);
7688 RemoveResource(systemFont);
7691 // TESTING WITH WATCHERS:
7692 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7693 // usedFont = setFont ? setFont : (systemFont);
7697 if(guiApp.currentSkin)
7699 systemFont = guiApp.currentSkin.SystemFont();
7702 usedFont = systemFont;
7703 AddResource(systemFont);
7711 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7720 if(value.rootWindow && value.rootWindow.display && rootWindow)
7722 bool reloadGraphics = (oldParent.rootWindow == oldParent && value.rootWindow) || (!value.rootWindow && rootWindow == this) ||
7723 (value.rootWindow.display && value.rootWindow.display.displaySystem != rootWindow.display.displaySystem);
7726 UnloadGraphics(false);
7729 LoadGraphics(false, false);
7732 if(value.rootWindow != rootWindow)
7733 DisplayModeChanged();
7737 scrolledPos.x = MININT; // Prevent parent update
7738 property::anchor = anchor;
7742 if(guiApp.currentSkin)
7743 guiApp.currentSkin.SetWindowMinimum(this, &skinMinSize.w, &skinMinSize.h);
7745 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7746 Position(x, y, w, h, true, true, true, true, false, true);
7751 // else parent = value;
7754 get { return parent; }
7757 property Window master
7759 property_category "Behavior"
7762 //if(this == value) return;
7763 if(value && value.IsSlaveOf(this)) return;
7769 OldLink slaveHolder;
7770 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
7771 if(slaveHolder.data == this)
7773 master.slaves.Delete(slaveHolder);
7780 value.slaves.Add(OldLink { data = this });
7785 master.hotKeys.Remove(hotKey);
7786 value.hotKeys.Add(hotKey);
7789 if(master && master.defaultControl == this)
7790 master.defaultControl = null;
7792 if(style.isDefault && !value.defaultControl)
7793 value.defaultControl = this;
7799 get { return master ? master : parent; }
7802 property char * text
7804 property_category "Appearance"
7811 caption = new char[strlen(value)+1];
7813 strcpy(caption, value);
7818 get { return caption; }
7823 property_category "Behavior"
7832 master.hotKeys.Add(hotKey = HotKeySlot { });
7836 hotKey.window = this;
7841 master.hotKeys.Delete(hotKey);
7846 get { return hotKey ? hotKey.key : 0; }
7849 property Color background
7851 property_category "Appearance"
7854 background.color = value;
7859 if(this == rootWindow)
7860 guiApp.interfaceDriver.SetRootWindowColor(this);
7863 get { return background.color; }
7866 property Percentage opacity
7868 property_category "Appearance"
7871 background.a = (byte)Min(Max((int)(value * 255), 0), 255);
7872 drawBehind = background.a ? false : true;
7874 get { return background.a / 255.0f; }
7877 property Color foreground
7879 property_category "Appearance"
7887 get { return foreground; }
7890 property BorderStyle borderStyle
7892 property_category "Appearance"
7895 if(!((BorderBits)value).fixed)
7897 style.hasClose = false;
7898 style.hasMaximize = false;
7899 style.hasMinimize = false;
7901 style.borderBits = value;
7905 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7907 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7908 Position(x, y, w, h, true, true, true, true, false, true);
7909 CreateSystemChildren();
7912 get { return (BorderStyle)style.borderBits; }
7915 property Size minClientSize
7917 property_category "Layout"
7918 set { minSize = value; }
7919 get { value = minSize; }
7922 property Size maxClientSize
7924 property_category "Layout"
7925 set { maxSize = value; }
7926 get { value = maxSize; }
7929 property bool hasMaximize
7931 property_category "Window Style"
7934 style.hasMaximize = value;
7935 if(value) { style.fixed = true; style.contour = true; }
7939 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7941 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7942 Position(x, y, w, h, true, true, true, true, false, true);
7944 CreateSystemChildren();
7947 get { return style.hasMaximize; }
7950 property bool hasMinimize
7952 property_category "Window Style"
7955 style.hasMinimize = value;
7956 if(value) { style.fixed = true; style.contour = true; }
7960 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7962 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7963 Position(x, y, w, h, true, true, true, true, false, true);
7965 CreateSystemChildren();
7968 get { return style.hasMinimize; }
7971 property bool hasClose
7973 property_category "Window Style"
7976 style.hasClose = value;
7977 if(value) { style.fixed = true; style.contour = true; }
7981 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7982 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7983 Position(x, y, w, h, true, true, true, true, false, true);
7984 CreateSystemChildren();
7987 get { return style.hasClose; }
7990 property bool nonClient
7992 property_category "Layout"
7995 style.nonClient = value;
7997 style.stayOnTop = true;
7999 get { return style.nonClient; }
8002 property bool inactive
8004 property_category "Behavior"
8009 // *** NEW HERE: ***
8013 parent.childrenCycle.Delete(cycle);
8015 parent.childrenOrder.Delete(order);
8022 active = false; // true;
8023 if(parent.activeChild == this)
8024 parent.activeChild = null;
8025 if(parent.activeClient == this)
8026 parent.activeClient = null;
8035 parent.childrenCycle.Insert(
8036 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
8037 cycle = OldLink { data = this });
8039 parent.childrenOrder.Insert(
8040 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8041 order = OldLink { data = this });
8044 style.inactive = value;
8046 get { return style.inactive; }
8049 property bool clickThrough
8051 property_category "Behavior"
8052 set { style.clickThrough = value; }
8053 get { return style.clickThrough; }
8056 property bool isRemote
8058 property_category "Behavior"
8059 set { style.isRemote = value; }
8060 get { return style.isRemote; }
8063 property bool noCycle
8065 property_category "Behavior"
8066 set { style.noCycle = value; }
8067 get { return style.noCycle; }
8070 property bool isModal
8072 property_category "Behavior"
8073 set { style.modal = value; }
8074 get { return style.modal; }
8077 property bool interim
8079 property_category "Behavior"
8080 set { style.interim = value; }
8081 get { return style.interim; }
8084 property bool tabCycle
8086 property_category "Behavior"
8087 set { style.tabCycle = value; }
8088 get { return style.tabCycle; }
8091 property bool isDefault
8093 property_category "Behavior"
8101 /*for(sibling = parent.children.first; sibling; sibling = sibling.next)
8102 if(sibling != this && sibling.style.isDefault)
8103 sibling.style.isDefault = false;*/
8104 if(master.defaultControl)
8105 master.defaultControl.style.isDefault = false;
8106 master.defaultControl = this;
8108 else if(master.defaultControl == this)
8109 master.defaultControl = null;
8113 style.isDefault = value;
8115 Position(position.x, position.y, size.w, size.h, true, true, true,true,true, true);
8117 get { return style.isDefault; }
8120 property bool drawBehind
8122 property_category "Window Style"
8123 set { style.drawBehind = value; }
8124 get { return style.drawBehind; }
8127 property bool hasMenuBar
8129 property_category "Window Style"
8139 if(created && !menuBar)
8146 anchor = Anchor { top = 23, left = 1, right = 1 },
8148 inactive = true, nonClient = true
8153 else if(created && menuBar)
8158 style.hasMenuBar = value;
8160 get { return style.hasMenuBar; }
8163 property bool hasStatusBar
8165 property_category "Window Style"
8172 statusBar = StatusBar { this };
8180 style.hasStatusBar = value;
8182 get { return style.hasStatusBar; }
8184 property bool stayOnTop
8186 property_category "Window Style"
8191 if(created && !style.stayOnTop)
8193 if(rootWindow == this)
8194 guiApp.interfaceDriver.OrderRootWindow(this, true);
8195 else if(parent.children.last != this)
8197 parent.children.Move(this, parent.children.last);
8201 style.stayOnTop = true;
8205 if(created && style.stayOnTop)
8207 if(rootWindow == this)
8208 guiApp.interfaceDriver.OrderRootWindow(this, false);
8215 for(order = (this.order == parent.childrenOrder.first) ? null : this.order.prev;
8216 order && ((Window)order.data).style.stayOnTop;
8217 order = (order == parent.childrenOrder.first) ? null : order.prev);
8218 last = order ? order.data : null;
8222 for(last = parent.children.last;
8223 last && last.style.stayOnTop;
8227 parent.children.Move(this, last);
8231 style.stayOnTop = false;
8234 get { return style.stayOnTop; }
8239 property_category "Window Style"
8249 if(menuBar && !value)
8256 if(!menuBar && style.hasMenuBar && value)
8260 this, menu = value, isMenuBar = true,
8261 anchor = Anchor { left = 1, top = 23, right = 1 }, size.h = 24,
8262 inactive = true, nonClient = true
8266 UpdateActiveDocument(null);
8269 get { return menu; }
8272 property FontResource font
8274 property_category "Appearance"
8276 isset { return setFont ? true : false; }
8281 if(value && !setFont) { stopwatching(parent, font); }
8282 else if(!value && setFont)
8288 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
8297 RemoveResource(setFont);
8302 RemoveResource(systemFont);
8309 AddResource(setFont);
8312 usedFont = setFont ? setFont : ((parent && parent.parent) ? parent.usedFont : systemFont);
8315 systemFont = guiApp.currentSkin.SystemFont();
8317 usedFont = systemFont;
8318 AddResource(systemFont);
8326 get { return usedFont; }
8329 property SizeAnchor sizeAnchor
8331 property_category "Layout"
8334 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8335 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8336 sizeAnchor.isClientW != sizeAnchor.isClientH;
8343 normalSizeAnchor = sizeAnchor;
8345 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8347 stateAnchor = normalAnchor;
8348 stateSizeAnchor = normalSizeAnchor;
8350 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8351 Position(x,y, w, h, true, true, true, true, false, true);
8358 { sizeAnchor.isClientW ? clientSize.w : size.w, sizeAnchor.isClientH ? clientSize.h : size.h },
8359 sizeAnchor.isClientW,
8360 sizeAnchor.isClientH
8367 property_category "Layout"
8370 Anchor thisAnchor = anchor;
8371 SizeAnchor thisSizeAnchor = sizeAnchor;
8372 bool leftRight = (anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none);
8373 bool topBottom = (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none);
8374 bool isClient = !sizeAnchor.isClientW && !sizeAnchor.isClientH;
8375 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8376 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8377 !sizeAnchor.isClientW && !sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8383 sizeAnchor.isClientW = false;
8384 sizeAnchor.isClientH = false;
8385 sizeAnchor.size = value;
8387 normalSizeAnchor = sizeAnchor;
8389 if(state == normal /*|| state == Hidden*/) // Hidden is new here ...
8391 stateAnchor = normalAnchor;
8392 stateSizeAnchor = normalSizeAnchor;
8394 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8395 Position(x, y, w, h, true, true, true, true, false, true);
8398 get { value = size; }
8401 property Size clientSize
8403 property_category "Layout"
8406 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8407 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8408 sizeAnchor.isClientW && sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8413 sizeAnchor.isClientW = true;
8414 sizeAnchor.isClientH = true;
8415 sizeAnchor.size = value;
8417 normalSizeAnchor = sizeAnchor;
8419 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8421 stateAnchor = normalAnchor;
8422 stateSizeAnchor = normalSizeAnchor;
8424 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8425 Position(x,y, w, h, true, true, true, true, false, true);
8428 get { value = clientSize; }
8431 property Size initSize { get { value = sizeAnchor.size; } };
8433 property Anchor anchor
8435 property_category "Layout"
8436 isset { return (anchor.left.type != offset || anchor.top.type != offset || anchor.right.type || anchor.bottom.type); }
8442 if(anchor.left.type && anchor.right.type && (!value.left.type || !value.right.type))
8444 normalSizeAnchor.isClientW = sizeAnchor.isClientW = false;
8445 normalSizeAnchor.size.w = sizeAnchor.size.w = size.w;
8447 if(anchor.top.type && anchor.bottom.type && (!value.top.type || !value.bottom.type))
8449 normalSizeAnchor.isClientH = sizeAnchor.isClientH = false;
8450 normalSizeAnchor.size.h = sizeAnchor.size.h = size.h;
8454 if(anchor.right.type && (anchor.horz.type == middleRelative || !anchor.left.type))
8456 anchor.left.distance = 0;
8457 anchor.horz.type = 0;
8459 if(anchor.bottom.type && (anchor.vert.type == middleRelative || !anchor.top.type))
8461 anchor.top.distance = 0;
8462 anchor.vert.type = 0;
8471 normalAnchor = anchor;
8473 // Break the anchors for moveable/resizable windows
8474 /*if(style.fixed ) //&& value.left.type == cascade)
8476 ComputeAnchors(anchor, sizeAnchor, &x, &y, &w, &h);
8478 this.anchor = normalAnchor = Anchor { left = x, top = y };
8479 normalSizeAnchor = SizeAnchor { { w, h } };
8482 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8484 stateAnchor = normalAnchor;
8485 stateSizeAnchor = normalSizeAnchor;
8487 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8488 Position(x, y, w, h, true, true, true, true, false, true);
8497 get { value = this ? anchor : Anchor { }; }
8500 property Point position
8502 property_category "Layout"
8505 if(value == null) return;
8507 anchor.left = value.x;
8508 anchor.top = value.y;
8509 anchor.right.type = none;
8510 anchor.bottom.type = none;
8515 normalAnchor = anchor;
8517 // Break the anchors for moveable/resizable windows
8521 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8523 normalAnchor.left = x;
8524 normalAnchor.top = y;
8525 normalAnchor.right.type = none;
8526 normalAnchor.bottom.type = none;
8527 normalSizeAnchor.size.width = w;
8528 normalSizeAnchor.size.height = h;
8532 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8534 stateAnchor = normalAnchor;
8535 stateSizeAnchor = normalSizeAnchor;
8537 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8538 Position(x,y, w, h, true, true, true, true, false, true);
8542 get { value = position; }
8545 property bool disabled
8547 property_category "Behavior"
8550 if(this && disabled != value)
8557 get { return (bool)disabled; }
8560 property bool isEnabled
8565 for(parent = this; parent; parent = parent.parent)
8572 property WindowState state
8574 property_category "Behavior"
8575 set { SetState(value, false, 0); }
8576 get { return this ? state : 0; }
8579 property bool visible
8581 property_category "Behavior"
8584 if(this && !value && !style.hidden && parent)
8586 Window client = null;
8588 style.hidden = true;
8591 OldLink prevOrder = null;
8593 if(rootWindow == this)
8594 guiApp.interfaceDriver.SetRootWindowState(this, state, false);
8597 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
8600 box.left -= parent.clientStart.x;
8601 box.top -= parent.clientStart.y;
8602 box.right -= parent.clientStart.x;
8603 box.bottom -= parent.clientStart.y;
8607 if(style.modal && master && master.modalSlave == this)
8608 master.modalSlave = null;
8610 if(style.isActiveClient)
8612 parent.numPositions--;
8613 if(state == minimized) parent.numIcons--;
8618 OldLink tmpPrev = order.prev;
8619 client = tmpPrev ? tmpPrev.data : null;
8620 if(client && !client.style.hidden && !client.destroyed && client.created)
8621 prevOrder = tmpPrev;
8624 client = tmpPrev ? tmpPrev.data : null;
8625 if(client == this) { client = null; break; }
8626 if(client && ((client.style.hidden) || client.destroyed || !client.created))
8628 tmpPrev = client.order.prev;
8633 prevOrder = tmpPrev;
8638 // If this window can be an active client, make sure the next window we activate can also be one
8639 if(!style.nonClient && style.isActiveClient)
8641 tmpPrev = prevOrder;
8644 client = tmpPrev ? tmpPrev.data : null;
8645 if(client == this) { client = null; break; }
8646 if(client && (client.style.nonClient || !client.style.isActiveClient || client.style.hidden || client.destroyed || !client.created))
8648 tmpPrev = client.order.prev;
8653 prevOrder = tmpPrev;
8657 if(client && client.style.hidden) client = null;
8661 if((parent.activeChild == this || guiApp.interimWindow == this) && true /*activate*/)
8663 if(order && prevOrder && prevOrder.data != this)
8664 ((Window)prevOrder.data).ActivateEx(true, false, false, true, null, null);
8666 ActivateEx(false, false, false, true, null, null);
8668 // TESTING THIS HERE FOR HIDING ACTIVE CLIENT
8669 if(parent.activeClient == this)
8671 parent.activeClient = null;
8672 parent.UpdateActiveDocument(null);
8675 else if(parent.activeClient == this)
8677 parent.activeClient = client;
8678 parent.UpdateActiveDocument(this);
8681 // *** Not doing this anymore ***
8684 parent.childrenCycle.Delete(cycle);
8686 parent.childrenOrder.Delete(order);
8691 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8696 else if(this && value && style.hidden)
8698 style.hidden = false;
8701 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8702 if(rootWindow == this)
8703 guiApp.interfaceDriver.SetRootWindowState(this, state, true);
8705 if(style.modal && master)
8706 master.modalSlave = this;
8708 if(style.isActiveClient)
8710 positionID = parent.GetPositionID(this);
8711 parent.numPositions++;
8712 if(state == minimized) parent.numIcons++;
8715 // *** NOT DOING THIS ANYMORE ***
8717 if(!(style.inactive))
8719 if(!(style.noCycle))
8721 cycle = parent.childrenCycle.AddAfter(
8722 (parent.activeChild && parent.activeChild.cycle) ?
8723 parent.activeChild.cycle.prev : null, sizeof(OldLink));
8726 order = parent.childrenOrder.AddAfter(
8727 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8734 if(true || !parent.activeChild)
8735 ActivateEx(true, false, true, true, null, null);
8737 if(creationActivation == activate)
8738 ActivateEx(true, false, true, true, null, null);
8739 else if(creationActivation == flash && !object)
8742 //SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8746 ConsequentialMouseMove(false);
8753 get { return (style.hidden || !setVisible) ? false : true; }
8756 property bool isDocument
8758 property_category "Document"
8759 set { style.isDocument = value; }
8760 get { return style.isDocument; }
8763 property bool mergeMenus
8765 property_category "Window Style"
8766 set { mergeMenus = value; }
8767 get { return (bool)mergeMenus; }
8770 property bool hasHorzScroll
8772 property_category "Window Style"
8777 if(!style.hasHorzScroll && created)
8779 CreateSystemChildren();
8780 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8783 else if(style.hasHorzScroll)
8787 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8789 style.hasHorzScroll = value;
8792 get { return style.hasHorzScroll; }
8795 property bool hasVertScroll
8797 property_category "Window Style"
8802 if(!style.hasVertScroll && created)
8804 style.hasVertScroll = true;
8805 CreateSystemChildren();
8806 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8809 else if(style.hasVertScroll)
8813 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8815 style.hasVertScroll = value;
8817 get { return style.hasVertScroll; }
8820 property bool dontHideScroll
8822 property_category "Behavior"
8825 scrollFlags.dontHide = value;
8828 //UpdateScrollBars(true, true);
8829 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8833 // UpdateScrollBars(true, true);
8834 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8837 get { return scrollFlags.dontHide; }
8840 property bool dontScrollVert
8842 property_category "Behavior"
8843 set { style.dontScrollVert = value; }
8844 get { return style.dontScrollVert; }
8846 property bool dontScrollHorz
8848 property_category "Behavior"
8849 set { style.dontScrollHorz = value; }
8850 get { return style.dontScrollHorz; }
8853 property bool snapVertScroll
8855 property_category "Behavior"
8858 scrollFlags.snapY = value;
8859 if(sbv) sbv.snap = value;
8861 get { return scrollFlags.snapY; }
8863 property bool snapHorzScroll
8865 property_category "Behavior"
8868 scrollFlags.snapX = value;
8869 if(sbh) sbh.snap = value;
8871 get { return scrollFlags.snapX; }
8874 property Point scroll
8876 property_category "Behavior"
8880 // TESTING THIS IMPLEMENTATION:
8881 SetScrollPosition(value.x, value.y);
8883 get { value = scroll; }
8886 property bool modifyVirtualArea
8888 property_category "Behavior"
8889 set { modifyVirtArea = value; }
8890 get { return (bool)modifyVirtArea; }
8893 property char * fileName
8895 property_category "Document"
8898 if(menu && ((!fileName && value) || (fileName && !value)))
8900 MenuItem item = menu.FindItem(MenuFileSave, 0);
8901 if(item) item.disabled = !modifiedDocument && value;
8906 if(value && value[0])
8907 fileName = CopyString(value);
8909 if(parent && this == parent.activeClient)
8910 parent.UpdateActiveDocument(null);
8914 // if(style.isDocument)
8916 fileMonitor.fileName = value;
8918 get { return fileName; }
8923 property_category "Data"
8928 property bool modifiedDocument
8930 property_category "Document"
8933 if(style.isDocument || fileName)
8937 MenuItem item = menu.FindItem(MenuFileSave, 0);
8938 if(item) item.disabled = !value && fileName;
8942 if(modifiedDocument != value)
8944 modifiedDocument = value;
8945 if(style.isDocument || fileName)
8949 get { return (bool)modifiedDocument; }
8952 property bool showInTaskBar
8954 property_category "Window Style"
8955 set { style.showInTaskBar = value; }
8956 get { return (style.showInTaskBar; }
8958 property FileDialog saveDialog { set { saveDialog = value; } };
8959 property bool isActiveClient
8961 property_category "Behavior"
8962 set { style.isActiveClient = value; }
8963 get { return style.isActiveClient; }
8966 property Cursor cursor
8968 property_category "Appearance"
8972 SelectMouseCursor();
8974 get { return cursor; }
8977 //#if !defined(ECERE_VANILLA)
8978 property char * name
8980 property_category "Design"
8983 return (this && object) ? object.name : null;
8988 activeDesigner.RenameObject(object, value);
8992 property char * displayDriver
8994 property_category "Behavior"
8997 dispDriver = GetDisplayDriver(value);
8998 //DisplayModeChanged();
9002 return dispDriver ? dispDriver.name : null;
9006 // RUNTIME PROPERTIES
9007 property bool autoCreate { set { autoCreate = value; } get { return (bool)autoCreate; } };
9008 property Size scrollArea
9010 property_category "Behavior"
9014 SetScrollArea(value.w, value.h, false);
9016 SetScrollArea(0,0, true);
9018 get { value = scrollArea; }
9021 return scrollArea.w > clientSize.w || scrollArea.h > clientSize.h;
9026 property_category "Layout"
9027 set { if(this) is3D = value; }
9028 get { return (bool)is3D; }
9031 // Runtime Only Properties (No Set, can display the displayable ones depending on the type?)
9033 // Will be merged with font later
9034 property Font fontObject { get { return usedFont ? usedFont.font : null; } };
9035 property Point clientStart { get { value = clientStart; } };
9036 property Point absPosition { get { value = absPosition; } };
9037 property Anchor normalAnchor { get {value = normalAnchor; } };
9038 // property Size normalSizeAnchor { get { value = normalSizeAnchor; } };
9039 property bool active { get { return (bool)active; } };
9040 property bool created { get { return (bool)created; } };
9041 property bool destroyed { get { return (bool)destroyed; } };
9042 property Window firstSlave { get { return slaves.first ? ((OldLink)slaves.first).data : null; } };
9043 property Window firstChild { get { return children.first; } };
9044 property Window lastChild { get { return children.last; } };
9045 property Window activeClient { get { return activeClient; } };
9046 property Window activeChild { get { return activeChild; } };
9047 property Display display { get { return display ? display : ((parent && parent.rootWindow) ? parent.rootWindow.display : null); } };
9048 property DisplaySystem displaySystem { get { return display ? display.displaySystem : null; } };
9049 property ScrollBar horzScroll { get { return sbh; } };
9050 property ScrollBar vertScroll { get { return sbv; } };
9051 property StatusBar statusBar { get { return statusBar; } };
9052 property Window rootWindow { get { return rootWindow; } };
9053 property bool closing { get { return (bool)closing; } set { closing = value; } };
9054 property int documentID { get { return documentID; } };
9055 property Window previous { get { return prev; } }
9056 property Window next { get { return next; } }
9057 property Window nextSlave { get { OldLink link = master.slaves.FindLink(this); return (link && link.next) ? link.next.data : null; } }
9058 property PopupMenu menuBar { get { return menuBar; } }
9059 property ScrollBar sbv { get { return sbv; } }
9060 property ScrollBar sbh { get { return sbh; } }
9061 property bool fullRender { set { fullRender = value; } get { return (bool)fullRender; } }
9062 property void * systemHandle { get { return windowHandle; } }
9063 property Button minimizeButton { get { return sysButtons[0]; } };
9064 property Button maximizeButton { get { return sysButtons[1]; } };
9065 property Button closeButton { get { return sysButtons[2]; } };
9066 property BitmapResource icon
9068 get { return icon; }
9074 guiApp.interfaceDriver.SetIcon(this, value);
9077 property bool moveable { get { return (bool)moveable; } set { moveable = value; } };
9078 property bool alphaBlend { get { return (bool)alphaBlend; } set { alphaBlend = value; } };
9079 property bool useSharedMemory { get { return (bool)useSharedMemory; } set { useSharedMemory = value; } };
9080 property CreationActivationOption creationActivation { get { return creationActivation; } set { creationActivation = value; } };
9081 property bool nativeDecorations { get { return (bool)nativeDecorations; } set { nativeDecorations = value; } };
9082 property bool manageDisplay { get { return (bool)manageDisplay; } set { manageDisplay = value; } };
9088 WindowBits style; // Window Style
9089 char * caption; // Name / Caption
9090 Window parent; // Parent window
9091 OldList children; // List of children in Z order
9092 Window activeChild; // Child window having focus
9093 Window activeClient;
9094 Window previousActive; // Child active prior to activating the default child
9095 Window master; // Window owning and receiving notifications concerning this window
9096 OldList slaves; // List of windows belonging to this window
9097 Display display; // Display this window is drawn into
9099 Point position; // Position in parent window client area
9100 Point absPosition; // Absolute position
9101 Point clientStart; // Client area position from (0,0) in this window
9103 Size clientSize; // Client area size
9104 Size scrollArea; // Virtual Scroll area size
9105 Size reqScrollArea; // Requested virtual area size
9106 Point scroll; // Virtual area scrolling position
9107 public ScrollBar sbh, sbv; // Scrollbar window handles
9108 Cursor cursor; // Mouse cursor used for this window
9111 StatusBar statusBar;
9112 Button sysButtons[3];
9114 Box clientArea; // Client Area box clipped to parent
9116 HotKeySlot hotKey; // HotKey for this window
9120 ScrollFlags scrollFlags;// Window Scrollbar Flags
9121 int id; // Control ID
9123 ColorAlpha background; // Background color used to draw the window area
9125 subclass(DisplayDriver) dispDriver; // Display driver name for this window
9126 OldList childrenCycle; // Cycling order
9127 OldLink cycle; // Element of parent's cycling order
9128 OldList childrenOrder; // Circular Z-Order
9129 OldLink order; // Element of parent's circular Z-Order
9130 Window modalSlave; // Slave window blocking this window's interaction
9132 Window rootWindow; // Topmost system managed window
9133 void * windowHandle; // System window handle
9135 DialogResult returnCode;// Return code for modal windows
9137 Point sbStep; // Scrollbar line scrolling steps
9140 SizeAnchor stateSizeAnchor;
9142 Anchor normalAnchor;
9143 SizeAnchor normalSizeAnchor;
9145 Size skinMinSize; // Minimal window size based on style
9146 Point scrolledPos; // Scrolled position
9147 Box box; // Window box clipped to parent
9148 Box * against; // What to clip the box to
9150 Extent dirtyArea { /*first = -1, last = -1, free = -1*/ }; // Area marked for update by Update
9151 Extent renderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered
9152 Extent overRenderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered over children
9153 Extent clipExtent { /*first = -1, last = -1, free = -1*/ }; // Temporary extent against which to clip render area
9154 Extent scrollExtent { /*first = -1, last = -1, free = -1*/ }; // Area to scroll
9155 Point scrolledArea; // Distance to scroll area by
9156 Extent dirtyBack { /*first = -1, last = -1, free = -1*/ }; // Only used by root window
9158 OldList hotKeys; // List of the hotkeys of all children
9159 Window defaultControl; // Default child control
9163 ColorAlpha * palette; // Color palette used for this window
9165 int caretSize; // Size of caret, non zero if a caret is present
9166 Point caretPos; // Caret position
9168 void * systemParent; // Parent System Window for embedded windows
9175 WindowState lastState;
9177 FileMonitor fileMonitor
9179 this, FileChange { modified = true };
9181 bool OnFileNotify(FileChange action, char * param)
9184 fileMonitor.StopMonitoring();
9185 if(OnFileModified(action, param))
9186 fileMonitor.StartMonitoring();
9191 FontResource setFont, systemFont;
9192 FontResource usedFont;
9193 FontResource captionFont;
9195 FileDialog saveDialog;
9197 SizeAnchor sizeAnchor;
9199 // FormDesigner data
9202 Extent * tempExtents; //[4];
9203 BitmapResource icon;
9205 CreationActivationOption creationActivation;
9208 bool active:1; // true if window and ancestors are active
9209 bool acquiredInput:1; // true if the window is processing state based input
9210 bool modifiedDocument:1;
9211 bool disabled:1; // true if window cannot interact
9212 bool isForegroundWindow:1;// true while a root window is being activated
9213 bool visible:1; // Visibility flag
9214 bool destroyed:1; // true if window is being destroyed
9215 bool anchored:1; // true if this window is repositioned when the parent resizes
9216 bool dirty:1; // Flag set to true if any descendant must be redrawn
9222 bool modifyVirtArea:1;
9223 bool noAutoScrollArea:1;
9226 bool setVisible:1; // FOR FORM DESIGNER
9232 bool useSharedMemory:1;
9235 bool nativeDecorations:1;
9236 bool manageDisplay:1;
9239 WindowController controller;
9240 public property WindowController controller { get { return controller; } set { delete controller; controller = value; if(controller) incref controller; } }
9243 public class CommonControl : Window
9245 // creationActivation = doNothing;
9248 public class Percentage : float
9250 char * OnGetString(char * string, float * fieldData, bool * needClass)
9254 sprintf(string, "%.2f", this);
9255 c = strlen(string)-1;
9258 if(string[c] != '0')
9259 last = Max(last, c);
9260 if(string[c] == '.')
9273 public void ApplySkin(Class c, char * name, void ** vTbl)
9275 char className[1024];
9280 subclass(Window) wc = (subclass(Window))c;
9281 subclass(Window) base = (subclass(Window))c.base;
9283 sprintf(className, "%sSkin_%s", name, c.name);
9284 wc.pureVTbl = c._vTbl;
9285 c._vTbl = new void *[c.vTblSize];
9286 memcpy(c._vTbl, wc.pureVTbl, c.vTblSize * sizeof(void *));
9287 sc = eSystem_FindClass(c.module.application, className);
9291 for(m = 0; m < c.base.vTblSize; m++)
9293 if(c._vTbl[m] == base.pureVTbl[m])
9294 c._vTbl[m] = vTbl[m];
9299 for(m = 0; m < c.vTblSize; m++)
9301 if(sc._vTbl[m] != wc.pureVTbl[m])
9302 c._vTbl[m] = sc._vTbl[m];
9306 for(d = c.derivatives.first; d; d = d.next)
9308 ApplySkin(d.data, name, c._vTbl);
9312 public void UnapplySkin(Class c)
9314 char className[1024];
9316 subclass(Window) wc = (subclass(Window))c;
9317 subclass(Window) base = (subclass(Window))c.base;
9320 if(wc.pureVTbl && c._vTbl != wc.pureVTbl)
9323 c._vTbl = wc.pureVTbl;
9327 for(d = c.derivatives.first; d; d = d.next)
9329 UnapplySkin(d.data);
9333 void CheckFontIntegrity(Window window)
9338 if(window.usedFont && window.usedFont.font == 0xecececec)
9340 FontResource uf = window.usedFont;
9341 char * className = window._class.name;
9342 char * text = window.text;
9345 for(c = window.firstChild; c; c = c.next)
9346 CheckFontIntegrity(c);
9350 public class ControllableWindow : Window
9352 /*WindowController controller;
9353 public property WindowController controller { get { return controller; } set { delete controller; controller = value; incref controller; } }
9354 ~ControllableWindow() { delete controller; }*/
9357 class WindowControllerInterface : ControllableWindow
9359 bool OnKeyDown(Key key, unichar ch)
9361 bool result = ((int(*)())(void *)controller.OnKeyDown)((void *)controller.controlled, (void *)controller, key, ch);
9363 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown](controller.window, key, ch);
9367 bool OnKeyUp(Key key, unichar ch)
9369 bool result = ((int(*)())(void *)controller.OnKeyUp)((void *)controller.controlled, (void *)controller, key, ch);
9371 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp](controller.window, key, ch);
9375 bool OnKeyHit(Key key, unichar ch)
9377 bool result = ((int(*)())(void *)controller.OnKeyHit)((void *)controller.controlled, (void *)controller, key, ch);
9379 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit](controller.window, key, ch);
9383 bool OnMouseMove(int x, int y, Modifiers mods)
9385 bool result = ((int(*)())(void *)controller.OnMouseMove)((void *)controller.controlled, (void *)controller, x, y, mods);
9387 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove](controller.window, x, y, mods);
9391 bool OnLeftButtonDown(int x, int y, Modifiers mods)
9393 bool result = ((int(*)())(void *)controller.OnLeftButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9395 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown](controller.window, x, y, mods);
9399 bool OnLeftButtonUp(int x, int y, Modifiers mods)
9401 bool result = ((int(*)())(void *)controller.OnLeftButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9403 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp](controller.window, x, y, mods);
9407 bool OnLeftDoubleClick(int x, int y, Modifiers mods)
9409 bool result = ((int(*)())(void *)controller.OnLeftDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9411 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick](controller.window, x, y, mods);
9415 bool OnRightButtonDown(int x, int y, Modifiers mods)
9417 bool result = ((int(*)())(void *)controller.OnRightButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9419 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown](controller.window, x, y, mods);
9423 bool OnRightButtonUp(int x, int y, Modifiers mods)
9425 bool result = ((int(*)())(void *)controller.OnRightButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9427 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp](controller.window, x, y, mods);
9431 bool OnRightDoubleClick(int x, int y, Modifiers mods)
9433 bool result = ((int(*)())(void *)controller.OnRightDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9435 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick](controller.window, x, y, mods);
9439 bool OnMiddleButtonDown(int x, int y, Modifiers mods)
9441 bool result = ((int(*)())(void *)controller.OnMiddleButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9443 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown](controller.window, x, y, mods);
9447 bool OnMiddleButtonUp(int x, int y, Modifiers mods)
9449 bool result = ((int(*)())(void *)controller.OnMiddleButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9451 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp](controller.window, x, y, mods);
9455 bool OnMiddleDoubleClick(int x, int y, Modifiers mods)
9457 bool result = ((int(*)())(void *)controller.OnMiddleDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9459 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick](controller.window, x, y, mods);
9463 void OnResize(int width, int height)
9465 ((int(*)())(void *)controller.OnResize)((void *)controller.controlled, (void *)controller, width, height);
9466 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnResize](controller.window, width, height);
9469 void OnRedraw(Surface surface)
9471 ((int(*)())(void *)controller.OnRedraw)((void *)controller.controlled, (void *)controller, surface);
9472 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw](controller.window, surface);
9477 bool result = ((int(*)())(void *)controller.OnCreate)((void *)controller.controlled, (void *)controller);
9479 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnCreate](controller.window);
9484 public class WindowController<class V>
9487 property Window window
9491 uint size = class(Window).vTblSize;
9494 windowVTbl = new void *[size];
9495 memcpy(windowVTbl, value._vTbl, size * sizeof(void *));
9496 if(value._vTbl == value._class._vTbl)
9498 value._vTbl = new void *[value._class.vTblSize];
9499 memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *));
9503 for(c = 0; c < size; c++)
9505 void * function = class(WindowControllerInterface)._vTbl[c];
9506 if(function != DefaultFunction)
9507 value._vTbl[c] = function;
9509 value._vTbl[c] = windowVTbl[c];
9514 memcpy(value._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *));
9517 get { return window; }
9519 property V controlled
9521 set { controlled = value; }
9522 get { return controlled; }
9524 virtual bool V::OnKeyDown(WindowController controller, Key key, unichar ch);
9525 virtual bool V::OnKeyUp(WindowController controller, Key key, unichar ch);
9526 virtual bool V::OnKeyHit(WindowController controller, Key key, unichar ch);
9527 virtual bool V::OnMouseMove(WindowController controller, int x, int y, Modifiers mods);
9528 virtual bool V::OnLeftButtonDown(WindowController controller, int x, int y, Modifiers mods);
9529 virtual bool V::OnLeftButtonUp(WindowController controller, int x, int y, Modifiers mods);
9530 virtual bool V::OnLeftDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9531 virtual bool V::OnRightButtonDown(WindowController controller, int x, int y, Modifiers mods);
9532 virtual bool V::OnRightButtonUp(WindowController controller, int x, int y, Modifiers mods);
9533 virtual bool V::OnRightDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9534 virtual bool V::OnMiddleButtonDown(WindowController controller, int x, int y, Modifiers mods);
9535 virtual bool V::OnMiddleButtonUp(WindowController controller, int x, int y, Modifiers mods);
9536 virtual bool V::OnMiddleDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9537 virtual void V::OnResize(WindowController controller, int width, int height);
9538 virtual void V::OnRedraw(WindowController controller, Surface surface);
9539 virtual bool V::OnCreate(WindowController controller);
9542 int (** windowVTbl)();