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 parent.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(parent && !parent.destroyed /*&&
5242 rootWindow && rootWindow.display && !rootWindow.destroyed*/)
5244 if(parent.defaultControl == this)
5245 parent.defaultControl = null;
5246 if((parent.activeChild == this /*|| parent.activeClient == this */|| guiApp.interimWindow == this))
5248 if(order && prevOrder && prevOrder.data != this && active)
5250 //((Window)prevOrder.data).ActivateEx(true, false, false, false /*true*/, null);
5252 ((Window)prevOrder.data).ActivateEx(true, false, false, (rootWindow == this) ? true : false, null, null);
5253 if(parent.activeClient == this)
5255 parent.activeClient = null;
5256 parent.UpdateActiveDocument(null);
5261 if(guiApp.interimWindow == this)
5264 PropagateActive(false, null, &goOn, true);
5268 //if(window.parent.activeChild == window)
5269 parent.activeChild = null;
5270 if(!style.nonClient /*&& style.isActiveClient*/)
5272 Window previous = parent.activeClient;
5273 if(style.isActiveClient)
5274 parent.activeClient = null;
5275 parent.UpdateActiveDocument(previous);
5280 else if(parent.activeClient == this)
5282 parent.activeClient = client;
5283 parent.UpdateActiveDocument(this);
5287 if(guiApp.interimWindow == this)
5289 guiApp.interimWindow = null;
5290 if(guiApp.caretOwner)
5292 Window desktop = guiApp.desktop;
5293 if(desktop.activeChild && desktop.activeChild.menuBar && !desktop.activeChild.menuBar.focus)
5294 guiApp.caretOwner.UpdateCaret(false, false);
5299 if(style.modal && master && master.modalSlave == this)
5300 master.modalSlave = null;
5304 if(!guiApp.caretOwner && parent.caretSize)
5306 guiApp.caretOwner = parent;
5307 parent.UpdateCaret(false, false);
5308 parent.Update(null);
5311 if(style.isActiveClient && visible)
5313 if(state == minimized) parent.numIcons--;
5314 parent.numPositions--;
5316 // Why was this commented out?
5317 GetRidOfVirtualArea();
5323 dirtyArea.Free(null);
5324 dirtyBack.Free(null);
5325 scrollExtent.Free(null);
5327 /* ATTEMPTING TO MOVE THAT ABOVE
5336 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5337 for(;(child = window.children.first);)
5339 for(; child && (child.destroyed || !child.created); child = child.next);
5348 UnloadGraphics(true);
5351 delete previousActive;
5354 // statusBar = null;
5357 if(master && !master.destroyed)
5359 //master.NotifyDestroyed(this, this.returnCode);
5360 NotifyDestroyed(master, this, this.returnCode);
5363 for(timer = guiApp.windowTimers.first; timer; timer = nextTimer)
5365 nextTimer = timer.next;
5366 if(timer.window == this)
5368 // WHY WERE WE SETTING THIS TO NULL? NO MORE WINDOW WHEN RECREATING...
5369 // timer.window = null;
5375 if(this == guiApp.windowMoving)
5378 if(guiApp.windowCaptured == this)
5380 //guiApp.windowCaptured = null;
5382 if(rootWindow != this && rootWindow)
5383 rootWindow.ConsequentialMouseMove(false);
5391 //for(child = children.first; next = child ? child.next : null, child; child = next)
5392 for(;(child = children.first); )
5394 for(; child && (child.destroyed || !child.created); child = child.next);
5404 /* // MOVED THIS UP...
5407 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5408 for(;(child = window.children.first); )
5410 for(; child && (child.destroyed || !child.created); child = child.next);
5419 while((slave = slaves.first))
5421 for(; slave && (((Window)slave.data).destroyed || !((Window)slave.data).created); slave = slave.next);
5423 ((Window)slave.data).DestroyEx(0);
5428 if(guiApp.caretOwner == this)
5429 guiApp.caretOwner = null;
5431 sysButtons[0] = null;
5432 sysButtons[1] = null;
5433 sysButtons[2] = null;
5436 if(rootWindow != this)
5438 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
5441 box.left -= parent.clientStart.x;
5442 box.top -= parent.clientStart.y;
5443 box.right -= parent.clientStart.x;
5444 box.bottom -= parent.clientStart.y;
5446 if(parent) parent.Update(box);
5451 OldLink slave = master.slaves.FindVoid(this);
5452 master.slaves.Delete(slave);
5458 parent.children.Remove(this);
5463 //autoCreate = false;
5466 // SHOULD THIS BE HERE? FIXED CRASH WITH GOTO DIALOG
5467 if(((subclass(Window))_class).pureVTbl)
5469 if(_vTbl == _class._vTbl)
5471 _vTbl = ((subclass(Window))_class).pureVTbl;
5476 for(m = 0; m < _class.vTblSize; m++)
5478 if(_vTbl[m] == _class._vTbl[m])
5479 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
5488 void SetStateEx(WindowState newState, bool activate)
5491 WindowState prevState = state;
5494 if(prevState != newState)
5495 lastState = prevState;
5496 if(style.isActiveClient && !style.hidden && prevState == minimized)
5499 // This block used to be at the end of the function... moved it for flicker problem in X
5500 // ------------------------------------------------------
5504 stateAnchor = normalAnchor;
5505 stateSizeAnchor = normalSizeAnchor;
5508 stateAnchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
5509 stateSizeAnchor = SizeAnchor {};
5513 int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH;
5516 byte * idBuffer = new0 byte[size];
5518 for(child = parent.children.first; child; child = child.next)
5520 if(child != this && child.state == minimized)
5522 if(child.iconID > size - 2)
5524 idBuffer = renew0 idBuffer byte[size*2];
5525 memset(idBuffer + size, 0, size);
5528 idBuffer[child.iconID] = (byte)bool::true;
5531 for(c = 0; c<size; c++)
5536 if(style.isActiveClient && !style.hidden)
5539 stateAnchor = Anchor { left = (iconID % maxIcons) * MINIMIZED_WIDTH, bottom = (iconID / maxIcons) * (guiApp.textMode ? 16 : 24) };
5540 stateSizeAnchor = SizeAnchor { size.w = MINIMIZED_WIDTH };
5545 // TOCHECK: Why was this here?
5546 //position.x = (tx > 0) ? tx & 0xFFFFF : tx;
5547 //position.y = (ty > 0) ? ty & 0xFFFFF : ty;
5549 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5551 Position(x, y, w, h, true, true, true, true, false, true);
5553 if(!style.inactive && !style.interim && this == parent.activeClient)
5554 parent.UpdateActiveDocument(null);
5556 CreateSystemChildren();
5557 // ------------------------------------------------------
5560 int GetPositionID(Window forChild)
5564 byte * idBuffer = new0 byte[size];
5567 for(child = children.first; child; child = child.next)
5569 if(child.style.isActiveClient && !child.style.hidden && child != forChild)
5571 if(child.positionID > size - 2)
5573 idBuffer = renew0 idBuffer byte[size*2];
5574 memset(idBuffer + size, 0, size);
5577 idBuffer[child.positionID] = (byte)bool::true;
5580 for(c = 0; c<size; c++)
5587 // --- Window related graphics ---
5589 void SetPalette(ColorAlpha * newPalette, bool colorMatch)
5591 palette = newPalette;
5592 if(rootWindow.display)
5593 rootWindow.display.SetPalette(palette, colorMatch);
5596 public bool AcquireInput(bool acquired)
5599 if(acquiredInput != acquired)
5601 if(active || (!visible && creationActivation == activate))
5602 result = AcquireInputEx(acquired);
5607 acquiredInput = acquired ? result : !result;
5612 void ListChildren(ListBox listBox)
5616 for(child = children.first; child; child = child.next)
5618 if(child.cycle && !child.style.nonClient && child.style.isActiveClient)
5620 DataRow row = listBox.AddRow();
5621 row.tag = (int)child;
5622 child.FigureCaption(caption);
5623 row.SetData(null, caption);
5628 void UpdateVisual(Box extent)
5630 if(guiApp.driver != null)
5632 if(guiApp.fullScreenMode && guiApp.desktop.display)
5634 guiApp.desktop.mutex.Wait();
5635 guiApp.desktop.display.Lock(true);
5638 if(guiApp.desktop.active)
5640 if(guiApp.desktop.dirty || guiApp.cursorUpdate)
5642 if(guiApp.desktop.display.flags.flipping)
5643 guiApp.desktop.Update(null);
5644 guiApp.desktop.UpdateDisplay();
5645 guiApp.cursorUpdate = true;
5647 if(guiApp.cursorUpdate || guiApp.desktop.dirty)
5649 guiApp.PreserveAndDrawCursor();
5650 // guiApp.desktop.display.ShowScreen();
5651 guiApp.cursorUpdate = false;
5652 guiApp.desktop.dirty = false;
5653 guiApp.RestoreCursorBackground();
5657 guiApp.desktop.display.Unlock();
5658 guiApp.desktop.mutex.Release();
5662 Window rootWindow = this.rootWindow;
5663 rootWindow.mutex.Wait();
5668 guiApp.SignalEvent();
5671 guiApp.waitMutex.Wait();
5672 guiApp.interfaceDriver.Lock(rootWindow);
5673 if(!rootWindow.style.hidden && rootWindow.dirty)
5675 if(rootWindow.display)
5677 rootWindow.UpdateDisplay();
5678 //rootWindow.display.ShowScreen(null);
5680 rootWindow.dirty = false;
5682 guiApp.interfaceDriver.Unlock(rootWindow);
5683 guiApp.waitMutex.Release();
5686 rootWindow.mutex.Release();
5691 void UnlockDisplay(void)
5693 guiApp.interfaceDriver.Unlock(rootWindow);
5696 void LockDisplay(void)
5698 guiApp.interfaceDriver.Lock(rootWindow);
5701 Surface GetSurface(Box box)
5703 return Redraw((box == null) ? this.box : box);
5706 void SetMousePosition(int x, int y)
5708 guiApp.interfaceDriver.SetMousePosition(x + absPosition.x + clientStart.x, y + absPosition.y + clientStart.y);
5712 void IntegrationActivate(bool active)
5714 if(!guiApp.modeSwitching && !guiApp.fullScreenMode)
5716 isForegroundWindow = true;
5717 ActivateEx(active, active, false, false, null, null);
5718 isForegroundWindow = false;
5723 Window QueryCapture(void)
5725 return guiApp.windowCaptured;
5728 int GetDocumentID(void)
5732 byte * idBuffer = new0 byte[size];
5735 for(child = children.first; child; child = child.next)
5737 if(child.style.isDocument)
5739 if(child.documentID-1 > size - 2)
5741 idBuffer = renew0 idBuffer byte[size*2];
5742 memset(idBuffer + size, 0, size);
5745 idBuffer[child.documentID-1] = 1;
5748 for(c = 0; c<size; c++)
5756 void SetInitSize(Size size)
5759 sizeAnchor.size = size;
5760 normalSizeAnchor = sizeAnchor;
5762 // Break the anchors for moveable/resizable windows
5763 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
5765 stateAnchor = normalAnchor;
5766 stateSizeAnchor = normalSizeAnchor;
5768 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5769 Position(x,y, w, h, true, true, true, true, false, true);
5773 void MenuMoveOrSize(bool resize, bool setCursorPosition)
5775 if(this != guiApp.desktop && state != maximized && (resize ? (state != minimized && style.sizable) : (style.fixed || moveable)))
5777 guiApp.windowIsResizing = resize;
5778 guiApp.windowMoving = this;
5779 guiApp.windowMovingStart = guiApp.movingLast = absPosition;
5780 if(guiApp.windowIsResizing)
5782 guiApp.windowMovingStart.x += size.w - 1;
5783 guiApp.windowMovingStart.y += size.h - 1;
5785 guiApp.windowMovingBefore = scrolledPos;
5786 guiApp.windowResizingBefore = size;
5787 guiApp.windowMoving.UpdateDecorations();
5788 if(guiApp.windowIsResizing)
5789 guiApp.resizeEndX = guiApp.resizeEndY = true;
5791 if(setCursorPosition)
5792 guiApp.interfaceDriver.SetMousePosition(guiApp.windowMovingStart.x, guiApp.windowMovingStart.y);
5796 guiApp.interfaceDriver.GetMousePosition(&x, &y);
5797 guiApp.windowMovingStart.x += x - absPosition.x;
5798 guiApp.windowMovingStart.y += y - absPosition.y;
5801 if(guiApp.windowMoving)
5803 if(guiApp.windowMoving.style.nonClient)
5804 guiApp.windowMoving.parent.SetMouseRangeToWindow();
5806 guiApp.windowMoving.parent.SetMouseRangeToClient();
5811 if(this == rootWindow)
5812 guiApp.interfaceDriver.StartMoving(rootWindow, guiApp.windowMovingStart.x, guiApp.windowMovingStart.y, true);
5820 bool result = false;
5824 else if(guiApp && guiApp.driver != null)
5826 void * systemParent = null;
5827 OldLink slaveHolder;
5829 bool visible = !style.hidden;
5833 systemParent = parent;
5834 parent = guiApp.desktop;
5836 last = parent ? parent.children.last : null;
5838 if((parent && parent != guiApp.desktop && !parent.created) ||
5839 (master && master != guiApp.desktop && !master.created))
5843 property::parent = guiApp.desktop;
5844 if(!master) master = parent;
5846 if(style.modal && master.modalSlave)
5850 parent.children.Remove(this);
5853 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
5854 if(slaveHolder.data == this)
5856 master.slaves.Delete(slaveHolder);
5861 if(parent == guiApp.desktop && !mutex)
5864 if(style.isDocument)
5867 parent.numDocuments--;
5868 documentID = parent.GetDocumentID();
5871 if(!style.stayOnTop)
5872 for(; last && last.style.stayOnTop; last = last.prev);
5874 parent.children.Insert((last == this) ? null : last, this);
5875 //parent.children.Add(this);
5878 dispDriver = parent.dispDriver;
5881 master.modalSlave = this;
5883 box = Box { MAXINT, MAXINT, MININT, MININT }; //-MAXINT, -MAXINT };
5888 master.slaves.Add(slaveHolder = OldLink { data = this });
5893 parent.hotKeys.Add(hotKey = HotKeySlot { key = setHotKey, window = this });
5895 if(style.isDefault && !parent.defaultControl)
5896 parent.defaultControl = this;
5898 stateAnchor = normalAnchor = anchor;
5899 stateSizeAnchor = normalSizeAnchor = sizeAnchor;
5901 // TOCHECK: Why is this here?
5902 //position.x = (ax > 0) ? ax & 0xFFFFF : ax;
5903 //position.y = (ay > 0) ? ay & 0xFFFFF : ay;
5905 this.visible = false;
5906 style.hidden = true;
5909 // autoCreate = true;
5917 if(parent == guiApp.desktop)
5918 Log("LoadGraphics %s\n", caption);
5920 if(LoadGraphics(true, false))
5928 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
5935 if(style.hasMenuBar /*&& menu*/)
5941 menu = menu, isMenuBar = true, anchor = Anchor { top = 23, left = 1, right = 1 },
5942 interim = false, inactive = true, nonClient = true, size.h = 24
5950 // Create the system buttons
5951 CreateSystemChildren();
5953 UpdateActiveDocument(null);
5955 if(style.isDocument)
5959 MenuItem item = menu.FindItem(MenuFileSave, 0);
5960 if(item) item.disabled = !modifiedDocument && fileName;
5965 if(parent == guiApp.desktop)
5966 Log("Preemptive SetState %s\n", caption);
5969 // Preemptive Set State to ensure proper anchoring
5970 SetStateEx(state, false);
5972 style.hidden = true;
5978 for(child = children.first; child; child = next)
5981 if(!child.created && (child.autoCreate || child.wasCreated))
5988 for(link = slaves.first; link; link = next)
5990 Window slave = link.data;
5992 if(!slave.created && (slave.autoCreate || slave.wasCreated))
6001 if(parent == guiApp.desktop)
6002 Log("Real SetState %s\n", caption);
6005 if(isActiveClient && visible)
6007 parent.numPositions--;
6008 if(state == minimized) parent.numIcons--;
6011 // Real set state & activate for proper display & activation
6012 property::visible = visible;
6013 // SetState(state & 0x00000003, true, 0);
6018 /*if(rootWindow == this)
6019 guiApp.interfaceDriver.ActivateRootWindow(this);
6021 if(creationActivation == activate)
6022 ActivateEx(true, false, true, true, null, null);
6023 else if(creationActivation == flash)
6028 rootWindow.ConsequentialMouseMove(false);
6039 guiApp.LogErrorCode(IERR_WINDOW_CREATION_FAILED, caption);
6045 // Testing this here... Otherwise a failed LoadGraphics stalls the application
6047 //style.hidden = true; // !visible;
6048 style.hidden = !visible;
6049 if(master.modalSlave == this)
6050 master.modalSlave = null;
6057 void WriteCaption(Surface surface, int x, int y)
6060 Interface::WriteKeyedTextDisabled(surface, x,y, caption, hotKey ? hotKey.key : 0, !isEnabled);
6063 void Update(Box region)
6069 rootWindow = this.rootWindow;
6071 // rootWindow.mutex.Wait();
6072 if(!destroyed && visible && display)
6077 // Testing this to avoid repetitve full update to take time...
6078 if(dirtyArea.count == 1)
6080 BoxItem item = (BoxItem)ACCESS_ITEM(dirtyArea, dirtyArea.first);
6081 if(item.box.left <= box.left &&
6082 item.box.top <= box.top &&
6083 item.box.right >= box.right &&
6084 item.box.bottom >= box.bottom)
6086 rootWindow.dirty = true;
6091 if(display.flags.flipping && !rootWindow.dirty)
6093 if(this == rootWindow)
6097 rootWindow.Update(null);
6102 rootWindow.dirty = true;
6107 realBox.left += clientStart.x;
6108 realBox.top += clientStart.y;
6109 realBox.right += clientStart.x;
6110 realBox.bottom += clientStart.y;
6116 if(realBox.right >= realBox.left &&
6117 realBox.bottom >= realBox.top)
6119 // if(!rootWindow.fullRender)
6120 dirtyArea.UnionBox(realBox, rootWindow.tempExtents[0]);
6122 for(child = children.first; child; child = child.next)
6127 box.left -= child.absPosition.x - absPosition.x;
6128 box.top -= child.absPosition.y - absPosition.y;
6129 box.right -= child.absPosition.x - absPosition.x;
6130 box.bottom -= child.absPosition.y - absPosition.y;
6131 if(box.right >= child.box.left && box.left <= child.box.right &&
6132 box.bottom >= child.box.top && box.top <= child.box.bottom)
6134 box.left -= child.clientStart.x;
6135 box.top -= child.clientStart.y;
6136 box.right -= child.clientStart.x;
6137 box.bottom -= child.clientStart.y;
6143 realBox.left += absPosition.x - rootWindow.absPosition.x;
6144 realBox.top += absPosition.y - rootWindow.absPosition.y;
6145 realBox.right += absPosition.x - rootWindow.absPosition.x;
6146 realBox.bottom += absPosition.y - rootWindow.absPosition.y;
6147 rootWindow.dirtyBack.UnionBox(realBox, rootWindow.tempExtents[0]);
6150 else if(this == guiApp.desktop)
6153 for(window = children.first; window; window = window.next)
6159 Box childBox = region;
6161 childBox.left -= window.absPosition.x - guiApp.desktop.absPosition.x;
6162 childBox.top -= window.absPosition.y - guiApp.desktop.absPosition.y;
6163 childBox.right -= window.absPosition.x - guiApp.desktop.absPosition.x;
6164 childBox.bottom -= window.absPosition.y - guiApp.desktop.absPosition.y;
6166 window.Update(childBox);
6169 window.Update(null);
6174 // rootWindow.mutex.Release();
6181 if(guiApp.windowCaptured != this)
6183 if(guiApp.windowCaptured)
6187 //Logf("Captured %s (%s)\n", caption, class.name);
6188 guiApp.interfaceDriver.SetMouseCapture(rootWindow);
6189 guiApp.windowCaptured = this;
6195 bool Destroy(int code)
6200 if(!CloseConfirmation(false)) return false;
6204 // TOCHECK: Should autoCreate be set to false here?
6207 // Is this needed here? DestroyEx should decref already...
6216 void Move(int x, int y, int w, int h)
6218 normalAnchor = Anchor { left = x, top = y };
6219 normalSizeAnchor = SizeAnchor { size = { w, h } };
6221 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
6223 if(destroyed) return;
6225 stateAnchor = normalAnchor;
6226 stateSizeAnchor = normalSizeAnchor;
6228 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
6229 Position(x,y, w, h, true, true, true, true, false, true);
6233 DialogResult Modal(void)
6239 // FIXES MEMORY LEAK IF Create() FAILED
6245 void SetScrollArea(int width, int height, bool snapToStep)
6247 bool resize = false;
6250 int stepX = sbStep.x, stepY = sbStep.y;
6251 // Needed to make snapped down position match the skin's check of client area
6252 // against realvirtual
6255 SNAPDOWN(stepX, textCellW);
6256 SNAPDOWN(stepY, textCellH);
6257 stepX = Max(stepX, textCellW);
6258 stepY = Max(stepY, textCellH);
6260 if(scrollFlags.snapX)
6261 SNAPUP(width, stepX);
6262 if(scrollFlags.snapY)
6263 SNAPUP(height, stepY);
6266 reqScrollArea.w = width;
6267 reqScrollArea.h = height;
6268 noAutoScrollArea = (width > 0 || height > 0);
6270 UpdateScrollBars(true, true);
6273 void SetScrollPosition(int x, int y)
6276 sbh.Action(setPosition, x, 0);
6280 int seen = clientSize.w, total = reqScrollArea.w;
6282 if(scrollFlags.snapX)
6283 SNAPDOWN(seen, sbStep.x);
6285 if(!total) total = seen;
6286 range = total - seen + 1;
6287 range = Max(range, 1);
6289 if(x >= range) x = range - 1;
6291 if(scrollFlags.snapX)
6292 SNAPUP(x, sbStep.x);
6295 OnHScroll(setPosition, x, 0);
6299 SNAPDOWN(x, textCellW);
6305 sbv.Action(setPosition, y, 0);
6309 int seen = clientSize.h, total = reqScrollArea.h;
6312 if(scrollFlags.snapY)
6313 SNAPDOWN(seen, sbStep.y);
6315 if(!total) total = seen;
6316 range = total - seen + 1;
6317 range = Max(range, 1);
6319 if(y >= range) y = range - 1;
6321 if(scrollFlags.snapY)
6322 SNAPUP(y, sbStep.y);
6325 OnVScroll(setPosition, y, 0);
6328 SNAPDOWN(y, textCellH);
6333 UpdateCaret(false, false);
6336 void SetScrollLineStep(int stepX, int stepY)
6342 SNAPDOWN(stepX, textCellW);
6343 SNAPDOWN(stepY, textCellH);
6344 stepX = Max(stepX, textCellW);
6345 stepY = Max(stepY, textCellH);
6348 sbh.lineStep = stepX;
6350 sbv.lineStep = stepY;
6353 void SetState(WindowState newState, bool activate, Modifiers mods)
6357 if(state == newState || OnStateChange(newState, mods))
6359 WindowState prevState = state;
6363 // This used to be at the end of the brackets... moved for X, testing...
6364 // This has the effect of activating the window through the system...
6365 if(rootWindow == this)
6366 guiApp.interfaceDriver.SetRootWindowState(this, newState, !style.hidden);
6368 SetStateEx(newState, activate);
6370 if(rootWindow == this)
6372 int x = position.x, y = position.y;
6375 x -= guiApp.desktop.absPosition.x;
6376 y -= guiApp.desktop.absPosition.y;
6378 guiApp.interfaceDriver.PositionRootWindow(this, x, y, size.w, size.h, true, true);
6382 //state = prevState;
6384 if(state != maximized && style.hasMaximize)
6387 for(child = parent.children.first; child; child = child.next)
6389 if(child != this && child.state == maximized)
6390 child.SetStateEx(normal, false);
6394 if(!style.nonClient && (sbv || sbh) && this != parent.sbv && this != parent.sbh)
6395 parent.UpdateScrollBars(true, true);
6398 // Do we really need this stuff here?
6399 // Shouldn't the Activate stuff take care of it?
6400 if(parent.rootWindow == parent && style)
6403 parent.FigureCaption(caption);
6404 guiApp.interfaceDriver.SetRootWindowCaption(parent, caption);
6405 parent.UpdateDecorations();
6409 rootWindow.ConsequentialMouseMove(false);
6416 BitmapResource GetIcon(SkinBitmap iconID)
6418 return guiApp.currentSkin.GetBitmap(iconID);
6421 void SetMouseRange(Box range)
6423 if(range || guiApp.fullScreenMode)
6428 clip.left = range.left + absPosition.x + clientStart.x;
6429 clip.top = range.top + absPosition.y + clientStart.y;
6430 clip.right = range.right + absPosition.x + clientStart.x;
6431 clip.bottom = range.bottom + absPosition.y + clientStart.y;
6435 clip.left = guiApp.desktop.box.left;
6436 clip.top = guiApp.desktop.box.top;
6437 clip.right = guiApp.desktop.box.right;
6438 clip.bottom = guiApp.desktop.box.bottom;
6440 guiApp.interfaceDriver.SetMouseRange(rootWindow, clip);
6443 guiApp.interfaceDriver.SetMouseRange(rootWindow, null);
6446 void SetMouseRangeToClient(void)
6448 if(guiApp.fullScreenMode || this != guiApp.desktop)
6450 Box box {0, 0, clientSize.w - 1, clientSize.h - 1 };
6451 box.Clip(clientArea);
6455 SetMouseRange(null);
6458 void SetMouseRangeToWindow(void)
6460 Box box { -clientStart.x, -clientStart.y, size.w-1, size.h-1 };
6461 if(this == guiApp.desktop)
6462 SetMouseRangeToClient();
6467 // x, y: Desktop Coordinates
6468 void ShowSysMenu(int x, int y)
6471 PopupMenu windowMenu { master = this, interim = true, position = { x + 1 - guiApp.desktop.position.x, y + 1 - guiApp.desktop.position.y }, menu = menu };
6474 menu, "Restore", r, NotifySelect = MenuWindowRestore,
6475 disabled = (!style.hasMaximize && !style.hasMinimize) || state == normal, bitmap = guiApp.currentSkin.GetBitmap(restore)
6479 menu, "Move", m, NotifySelect = MenuWindowMove,
6480 disabled = !style.fixed || state == maximized
6484 menu, "Size", s, NotifySelect = MenuWindowSize,
6485 disabled = !style.sizable || state != normal
6489 menu, "Minimize", n, NotifySelect = MenuWindowMinimize,
6490 disabled = !style.hasMinimize || state == minimized, bitmap = guiApp.currentSkin.GetBitmap(minimize)
6494 menu, "Maximize", KeyCode::x, NotifySelect = MenuWindowMaximize,
6495 disabled = !style.hasMaximize || state == maximized, bitmap = guiApp.currentSkin.GetBitmap(maximize)
6499 menu, "Stay On Top", t, NotifySelect = MenuWindowStayOnTop,
6500 disabled = !style.fixed, checkable = true, checked = style.stayOnTop
6502 MenuDivider { menu };
6505 menu, "Close", c, (parent == guiApp.desktop) ? altF4 : ( style.isActiveClient ? ctrlF4 : 0), NotifySelect = MenuWindowClose,
6506 bold = true, disabled = !style.hasClose, bitmap = guiApp.currentSkin.GetBitmap(close)
6508 windowMenu.Create();
6513 ActivateEx(true, true, true, true, null, null);
6516 void MakeActive(void)
6518 ActivateEx(true, false, true, false, null, null);
6521 void SoftActivate(void)
6523 if(guiApp.desktop.active)
6529 void Deactivate(void)
6531 ActivateEx(false, true, true, true, null, null);
6536 guiApp.interfaceDriver.FlashRootWindow(rootWindow);
6539 bool CycleChildren(bool backward, bool clientOnly, bool tabCycleOnly, bool cycleParents)
6541 bool result = false;
6542 if(activeChild && activeChild.cycle)
6544 Window modalWindow, child = activeChild;
6545 if(!clientOnly /*&& parent.tabCycle*/)
6547 Window next = child;
6550 if(next.cycle == (backward ? childrenCycle.first : childrenCycle.last))
6554 if(parent && parent.CycleChildren(backward, false, true, true))
6562 next = next.cycle.prev.data;
6564 next = next.cycle.next.data;
6565 if(!next.disabled && !next.inactive /*isRemote*/ && next.created && !next.nonClient && (!clientOnly || next.style.isActiveClient) && !next.style.hidden && next.FindModal() != activeChild)
6570 if(!clientOnly && child.cycle == (backward ? childrenCycle.first : childrenCycle.last) &&
6571 parent.tabCycle && parent.CycleChildren(backward, false, false))
6575 if(tabCycleOnly && !tabCycle) return false;
6582 child = child.cycle.prev.data;
6584 child = child.cycle.next.data;
6585 if(child == child.parent.activeChild)
6587 else if(!child.disabled && child.created && (!clientOnly || child.style.isActiveClient) && !child.style.hidden && child.FindModal() != activeChild)
6590 modalWindow = child.FindModal();
6593 // Scroll the window to include the active control
6594 if(sbh && !child.style.dontScrollHorz)
6596 if(child.scrolledPos.x < 0)
6597 sbh.Action(setPosition, scroll.x + child.scrolledPos.x, 0);
6598 else if(child.scrolledPos.x + child.size.w > clientSize.w)
6599 sbh.Action(setPosition, scroll.x + child.scrolledPos.x + child.size.w - clientSize.w, 0);
6601 if(sbv && !child.style.dontScrollVert)
6603 if(child.scrolledPos.y < 0)
6604 sbv.Action(setPosition, scroll.y + child.scrolledPos.y, 0);
6605 else if(child.scrolledPos.y + child.size.h > clientSize.h)
6606 sbv.Action(setPosition, scroll.y + child.scrolledPos.y + child.size.h - clientSize.h, 0);
6610 child = modalWindow ? modalWindow : child;
6611 child.ActivateEx(true, true, true, true, null, null);
6612 if(child.tabCycle && child.childrenCycle.first)
6613 child = ((OldLink)(backward ? child.childrenCycle.first : child.childrenCycle.last)).data;
6621 ConsequentialMouseMove(false);
6625 void AddResource(Resource resource)
6629 ResPtr ptr { resource = resource };
6633 // Load Graphics here if window is created already
6634 if(/*created && */display)
6636 display.Lock(false);
6637 ptr.loaded = display.displaySystem.LoadResource(resource);
6641 // Temporary hack to load font right away for listbox in dropbox ...
6642 else if(master && master.display)
6644 master.display.Lock(false);
6645 master.display.displaySystem.LoadResource(resource);
6646 master.display.Unlock();
6652 void RemoveResource(Resource resource)
6657 for(ptr = resources.first; ptr; ptr = ptr.next)
6659 if(ptr.resource == resource)
6665 // Unload Graphics here if window is created already
6666 if(/*created && */display)
6670 display.Lock(false);
6671 display.displaySystem.UnloadResource(resource, ptr.loaded);
6677 resources.Delete(ptr);
6682 void SetCaret(int x, int y, int size)
6689 if(active && !style.interim)
6691 if(visible || !guiApp.caretOwner)
6692 guiApp.caretOwner = size ? this : null;
6694 UpdateCaret(false, false);
6697 guiApp.interfaceDriver.SetCaret(0,0,0);
6698 UpdateCaret(false, true);
6699 guiApp.caretEnabled = false;
6702 else if(style.inactive && active)
6704 guiApp.interfaceDriver.SetCaret(0,0,0);
6705 UpdateCaret(false, true);
6706 guiApp.caretEnabled = false;
6711 void Scroll(int x, int y)
6713 bool opaque = !style.drawBehind || background.a;
6714 if(opaque && display && display.flags.scrolling)
6716 Box box = clientArea;
6717 box.left += clientStart.x;
6718 box.top += clientStart.y;
6719 box.right += clientStart.x;
6720 box.bottom += clientStart.y;
6722 //scrollExtent.Free(null);
6723 scrollExtent.AddBox(box);
6724 scrolledArea.x += x;
6725 scrolledArea.y += y;
6727 //scrollExtent.Free();
6728 //scrollExtent.AddBox(clientArea);
6729 //scrollExtent.Offset(clientStart.x, clientStart.y);
6730 //scrolledArea.x = x;
6731 //scrolledArea.y = y;
6737 rootWindow.dirty = true;
6740 void ReleaseCapture()
6742 if(guiApp && guiApp.windowCaptured && guiApp.windowCaptured == this)
6744 Window oldCaptured = guiApp.windowCaptured;
6745 guiApp.windowCaptured = null;
6746 guiApp.prevWindow = null;
6749 //guiApp.Log("Released Capture\n");
6751 guiApp.interfaceDriver.SetMouseCapture(null);
6753 //oldCaptured.OnMouseCaptureLost();
6756 oldCaptured.ConsequentialMouseMove(false);
6761 void SetText(char * format, ...)
6768 char caption[MAX_F_STRING];
6770 va_start(args, format);
6771 vsprintf(caption, format, args);
6774 this.caption = new char[strlen(caption)+1];
6776 strcpy(this.caption, caption);
6785 bool Grab(Bitmap bitmap, Box box, bool decorations)
6787 bool result = false;
6788 if(display || this == guiApp.desktop)
6790 Box clip = {MININT, MININT, MAXINT, MAXINT};
6796 clip.Clip(clientArea);
6798 clip.Clip(this.box);
6800 if(rootWindow != this)
6802 clip.left += absPosition.y;
6803 clip.top += absPosition.y;
6804 clip.right += absPosition.x;
6805 clip.bottom += absPosition.y;
6808 clip.left += decorations ? 0 : clientStart.x;
6809 clip.top += decorations ? 0 : clientStart.y;
6810 clip.right += decorations ? 0 : clientStart.x;
6811 clip.bottom += decorations ? 0 : clientStart.y;
6813 if(display && display.flags.flipping)
6815 rootWindow.Update(null);
6816 rootWindow.UpdateDisplay();
6823 result = window.display.displaySystem.driver.GrabScreen(null, bitmap, clip.left, clip.top,
6824 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6828 result = display.Grab(bitmap, clip.left, clip.top,
6829 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6831 if(bitmap.pixelFormat != pixelFormat888 && bitmap.pixelFormat != pixelFormat8)
6833 if(!bitmap.Convert(null, pixelFormat888, null))
6840 void GetMousePosition(int * x, int * y)
6842 int mouseX = 0, mouseY = 0;
6843 if(!guiApp.acquiredWindow && (guiApp.desktop.active || !guiApp.fullScreenMode))
6846 guiApp.interfaceDriver.GetMousePosition(&mouseX, &mouseY);
6847 if(this != guiApp.desktop)
6849 mouseX -= absPosition.x + clientStart.x;
6850 mouseY -= absPosition.y + clientStart.y;
6857 DialogResult DoModal()
6859 DialogResult returnCode = 0;
6860 int terminated = terminateX;
6863 while(!destroyed && guiApp.driver != null)
6865 if(terminateX != terminated)
6867 terminated = terminateX;
6868 guiApp.desktop.Destroy(0);
6869 if(guiApp.desktop.created)
6872 //printf("Resetting terminate X to 0\n");
6878 guiApp.UpdateDisplay();
6879 if(!guiApp.ProcessInput(false))
6882 returnCode = this.returnCode;
6895 return !destroyed && guiApp.driver != null && terminateX < 2;
6898 DialogResult DoModalEnd()
6900 DialogResult returnCode = this.returnCode;
6905 // --- Window manipulation ---
6906 /*bool GetDisabled()
6908 bool disabled = this.disabled;
6910 for(window = this; (window = window.master); )
6921 // --- Mouse Manipulation ---
6922 void GetNCMousePosition(int * x, int * y)
6924 GetMousePosition(x, y);
6925 if(x) *x += clientStart.x;
6926 if(y) *y += clientStart.y;
6929 // --- Carets manipulation ---
6930 void GetCaretPosition(Point caretPos)
6932 caretPos = this.caretPos;
6935 int GetCaretSize(void)
6940 bool ButtonCloseDialog(Button button, int x, int y, Modifiers mods)
6946 bool CloseConfirmation(bool parentClosing)
6959 if(!OnClose(parentClosing))
6962 // If you want to skip this, simply set modifiedDocument to false in OnClose
6963 if(result && (/*fileName || */style.isDocument) && modifiedDocument)
6965 DialogResult dialogRes;
6968 sprintf(message, "Save changes to %s?", fileName);
6970 sprintf(message, "Save changes to Untitled %d?", documentID);
6972 dialogRes = MessageBox { master = master, type = yesNoCancel, text = parent.caption, contents = message }.Modal();
6974 if(dialogRes == yes)
6976 // TOFIX: Precomp error if brackets are taken out
6977 result = (DialogResult)MenuFileSave(null, 0) != cancel;
6979 else if(dialogRes == cancel)
6985 for(slave = slaves.first; slave; slave = slave.next)
6986 if(!((Window)slave.data).CloseConfirmation(true))
6988 // ((Window)slave.data).CloseConfirmation(true);
6996 for(child = children.first; child; child = child.next)
6997 if(child.master != this && !child.CloseConfirmation(true))
7007 // Static methods... move them somewhere else?
7008 void ::RestoreCaret()
7010 if(guiApp.caretOwner)
7011 guiApp.caretOwner.UpdateCaret(false, false);
7014 void ::FreeMouseRange()
7016 guiApp.interfaceDriver.SetMouseRange(null, null);
7020 bool MenuFileClose(MenuItem selection, Modifiers mods)
7022 Window document = activeChild;
7024 document.Destroy(0);
7028 bool MenuFileExit(MenuItem selection, Modifiers mods)
7034 bool MenuFileSave(MenuItem selection, Modifiers mods)
7038 fileMonitor.fileName = null;
7041 if(OnSaveFile(fileName))
7043 //if(OnFileModified != Window::OnFileModified)
7046 fileMonitor.fileName = fileName;
7052 MessageBox dialog { master = master, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7053 DialogResult answer = dialog.Modal();
7055 if(answer != yes) return (bool)answer;
7058 return MenuFileSaveAs(selection, mods);
7061 bool MenuFileSaveAs(MenuItem selection, Modifiers mods)
7063 DialogResult result = (DialogResult)bool::true;
7064 FileDialog fileDialog = saveDialog;
7067 fileDialog = FileDialog {};
7072 fileDialog.filePath = fileName;
7075 char filePath[MAX_FILENAME];
7076 sprintf(filePath, "Untitled %d", documentID);
7077 fileDialog.filePath = filePath;
7079 fileMonitor.fileName = null;
7081 fileDialog.type = save;
7082 fileDialog.text = "Save As";
7086 fileDialog.master = master.parent ? master : this;
7087 if(fileDialog.Modal() == ok)
7089 char * filePath = fileDialog.filePath;
7091 if(OnSaveFile(filePath))
7094 property::fileName = filePath;
7095 NotifySaved(master, this, filePath);
7100 MessageBox dialog { master = master.parent ? master : this, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7101 DialogResult answer = dialog.Modal();
7116 //if(OnFileModified != Window::OnFileModified && fileName)
7119 fileMonitor.fileName = fileName;
7123 return (bool)result; // Actually returning result from Yes/NoCancel message box
7126 bool MenuFileSaveAll(MenuItem selection, Modifiers mods)
7128 Window document = activeChild;
7130 for(document = children.first; document; document = next)
7132 next = document.next;
7133 if(document.style.isDocument || document.fileName)
7134 document.MenuFileSave(selection, mods);
7139 bool MenuWindowArrangeIcons(MenuItem selection, Modifiers mods)
7143 for(document = children.first; document; document = document.next)
7144 //if(document.style.isDocument && document.state == minimized)
7145 if(document.style.isActiveClient && document.state == minimized)
7146 document.SetState(minimized, false, mods);
7150 bool MenuWindowCascade(MenuItem selection, Modifiers mods)
7152 Window document = activeChild;
7155 Window firstDocument = null;
7157 OldLink cycle = document.cycle.prev;
7162 if(child.style.isActiveClient && !child.style.hidden)
7166 firstDocument = child;
7167 if(child.state == minimized)
7168 child.SetState(minimized, false, mods);
7171 child.positionID = id++;
7172 child.SetState(normal, false, mods);
7173 child.anchor.left.type = cascade;
7176 child.normalSizeAnchor = *&child.sizeAnchor;
7177 child.normalAnchor = child.anchor;
7179 // Break the anchors for moveable/resizable windows
7180 if(child.style.fixed)
7182 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7184 (*&child.normalAnchor).left = x;
7185 (*&child.normalAnchor).top = y;
7186 (*&child.normalAnchor).right.type = none;
7187 (*&child.normalAnchor).bottom.type = none;
7189 child.normalSizeAnchor.isClientW = false;
7190 child.normalSizeAnchor.isClientH = false;
7191 child.normalSizeAnchor.size.w = w;
7192 child.normalSizeAnchor.size.h = h;
7193 child.anchored = false;
7196 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7198 child.stateAnchor = child.normalAnchor;
7199 child.stateSizeAnchor = child.normalSizeAnchor;
7201 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7202 child.Position(x, y, w, h, true, true, true, true, false, false);
7207 last = children.last;
7208 if(!child.style.stayOnTop)
7209 for(; last && last.style.stayOnTop; last = last.prev);
7210 children.Move(child, last);
7211 childrenOrder.Move(child.order, childrenOrder.last);
7213 if(cycle == document.cycle) break;
7217 firstDocument.Activate();
7222 bool MenuWindowClose(MenuItem selection, Modifiers mods)
7229 // Close all closes all active clients, not all documents
7230 bool MenuWindowCloseAll(MenuItem selection, Modifiers mods)
7232 Window next, document;
7234 for(document = children.first; document; document = next)
7236 for(next = document.next; next && !(next.style.isActiveClient; next = next.next);
7237 if(document.style.isActiveClient)
7238 if(!document.Destroy(0) && !document.style.hidden)
7244 bool MenuWindowMaximize(MenuItem selection, Modifiers mods)
7246 if(style.hasMaximize && state != maximized)
7247 SetState(maximized, 0, 0);
7251 bool MenuWindowMinimize(MenuItem selection, Modifiers mods)
7253 if(style.hasMinimize && state != minimized)
7255 SetState(minimized, 0, 0);
7256 parent.CycleChildren(false, true, false, true);
7261 bool MenuWindowMove(MenuItem selection, Modifiers mods)
7263 MenuMoveOrSize(false, selection ? true : false);
7267 bool MenuWindowNext(MenuItem selection, Modifiers mods)
7269 CycleChildren(false, true, false, true);
7273 bool MenuWindowPrevious(MenuItem selection, Modifiers mods)
7275 CycleChildren(true, true, false, true);
7279 bool MenuWindowSize(MenuItem selection, Modifiers mods)
7281 MenuMoveOrSize(true, true);
7285 bool MenuWindowRestore(MenuItem selection, Modifiers mods)
7288 SetState(normal, 0, 0);
7292 bool MenuWindowSelectWindow(MenuItem selection, Modifiers mods)
7295 int id = selection.id;
7296 OldLink cycle = activeClient.cycle;
7298 //for(c = 0, cycle = activeChild.cycle; c<id; cycle = cycle.next, c++);
7301 Window sibling = cycle.data;
7302 if(sibling.style.isActiveClient)
7310 document = cycle.data;
7311 document.Activate();
7313 //if(activeChild.state == maximized)
7314 // document.SetState(maximized, false, mods);
7315 //else if(document.state == minimized)
7316 // document.SetState(normal, false, mods);
7320 bool MenuWindowStayOnTop(MenuItem selection, Modifiers mods)
7322 stayOnTop = !style.stayOnTop;
7326 bool MenuWindowTileHorz(MenuItem selection, Modifiers mods)
7328 Window document = activeChild;
7331 Window firstDocument = null;
7332 OldLink cycle = document.cycle;
7336 Window child = cycle.data;
7337 if(child.style.isActiveClient && !child.style.hidden)
7339 if(!firstDocument) firstDocument = child;
7340 if(child.state == minimized)
7341 child.SetState(minimized, false, mods);
7344 child.positionID = id++;
7345 child.SetState(normal, false, mods);
7346 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7348 child.anchor.left.type = hTiled;
7351 child.normalSizeAnchor = *&child.sizeAnchor;
7352 child.normalAnchor = child.anchor;
7354 // Break the anchors for moveable/resizable windows
7355 if(child.style.fixed)
7357 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7359 (*&child.normalAnchor).left = x;
7360 (*&child.normalAnchor).top = y;
7361 (*&child.normalAnchor).right.type = none;
7362 (*&child.normalAnchor).bottom.type = none;
7363 child.normalSizeAnchor.isClientW = false;
7364 child.normalSizeAnchor.isClientH = false;
7365 child.normalSizeAnchor.size.w = w;
7366 child.normalSizeAnchor.size.h = h;
7367 child.anchored = false;
7370 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7372 child.stateAnchor = child.normalAnchor;
7373 child.stateSizeAnchor = child.normalSizeAnchor;
7375 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7376 child.Position(x,y, w, h, true, true, true, true, false, true);
7381 if((cycle = cycle.next) == document.cycle) break;
7384 firstDocument.Activate();
7389 bool MenuWindowTileVert(MenuItem selection, Modifiers mods)
7391 Window document = activeChild;
7394 Window firstDocument = null;
7396 OldLink cycle = document.cycle;
7401 //if(child.style.isDocument)
7402 if(child.style.isActiveClient && !child.style.hidden)
7404 if(!firstDocument) firstDocument = child;
7405 if(child.state == minimized)
7406 child.SetState(minimized, false, mods);
7409 child.positionID = id++;
7410 child.SetState(normal, false, mods);
7411 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7413 child.anchor.left.type = vTiled;
7416 child.normalSizeAnchor = *&child.sizeAnchor;
7417 child.normalAnchor = child.anchor;
7419 // Break the anchors for moveable/resizable windows
7420 if(child.style.fixed)
7422 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7424 (*&child.normalAnchor).left = x;
7425 (*&child.normalAnchor).top = y;
7426 (*&child.normalAnchor).right.type = none;
7427 (*&child.normalAnchor).bottom.type = none;
7428 child.normalSizeAnchor.isClientW = false;
7429 child.normalSizeAnchor.isClientH = false;
7430 child.normalSizeAnchor.size.w = w;
7431 child.normalSizeAnchor.size.h = h;
7432 child.anchored = false;
7435 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7437 child.stateAnchor = child.normalAnchor;
7438 child.stateSizeAnchor = child.normalSizeAnchor;
7440 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7441 child.Position(x,y, w, h, true, true, true, true, false, true);
7446 if((cycle = cycle.next) == document.cycle) break;
7449 firstDocument.Activate();
7454 bool MenuWindowWindows(MenuItem selection, Modifiers mods)
7456 WindowList dialog { master = this };
7457 Window document = (Window)dialog.Modal();
7460 if(activeChild.state == maximized)
7461 document.SetState(maximized, false, mods);
7462 else if(document.state == minimized)
7463 document.SetState(normal, false, mods);
7464 document.Activate();
7470 virtual bool OnCreate(void);
7471 virtual void OnDestroy(void);
7472 virtual void OnDestroyed(void);
7473 virtual bool OnClose(bool parentClosing);
7474 virtual bool OnStateChange(WindowState state, Modifiers mods);
7475 virtual bool OnPostCreate(void);
7476 virtual bool OnMoving(int *x, int *y, int w, int h);
7477 virtual bool OnResizing(int *width, int *height);
7478 virtual void OnResize(int width, int height);
7479 virtual void OnPosition(int x, int y, int width, int height);
7480 virtual bool OnLoadGraphics(void);
7481 virtual void OnApplyGraphics(void);
7482 virtual void OnUnloadGraphics(void);
7483 virtual void OnRedraw(Surface surface);
7484 virtual bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct);
7485 virtual void OnActivateClient(Window client, Window previous);
7486 virtual bool OnKeyDown(Key key, unichar ch);
7487 virtual bool OnKeyUp(Key key, unichar ch);
7488 virtual bool OnKeyHit(Key key, unichar ch);
7489 virtual bool OnSysKeyDown(Key key, unichar ch);
7490 virtual bool OnSysKeyUp(Key key, unichar ch);
7491 virtual bool OnSysKeyHit(Key key, unichar ch);
7492 virtual bool OnMouseOver(int x, int y, Modifiers mods);
7493 virtual bool OnMouseLeave(Modifiers mods);
7494 virtual bool OnMouseMove(int x, int y, Modifiers mods);
7495 virtual bool OnLeftButtonDown(int x, int y, Modifiers mods);
7496 virtual bool OnLeftButtonUp(int x, int y, Modifiers mods);
7497 virtual bool OnLeftDoubleClick(int x, int y, Modifiers mods);
7498 virtual bool OnRightButtonDown(int x, int y, Modifiers mods);
7499 virtual bool OnRightButtonUp(int x, int y, Modifiers mods);
7500 virtual bool OnRightDoubleClick(int x, int y, Modifiers mods);
7501 virtual bool OnMiddleButtonDown(int x, int y, Modifiers mods);
7502 virtual bool OnMiddleButtonUp(int x, int y, Modifiers mods);
7503 virtual bool OnMiddleDoubleClick(int x, int y, Modifiers mods);
7504 virtual void OnMouseCaptureLost(void);
7505 virtual void OnHScroll(ScrollBarAction action, int position, Key key);
7506 virtual void OnVScroll(ScrollBarAction action, int position, Key key);
7507 virtual void OnDrawOverChildren(Surface surface);
7508 virtual bool OnFileModified(FileChange fileChange, char * param);
7509 virtual bool OnSaveFile(char * fileName);
7511 // Skins Virtual Functions
7512 virtual void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h);
7513 virtual void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh);
7514 virtual void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
7519 virtual void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7520 virtual void PreShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7521 virtual bool IsMouseMoving(int x, int y, int w, int h);
7522 virtual bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY);
7523 virtual void UpdateNonClient();
7524 virtual void SetBox(Box box);
7525 virtual bool IsInside(int x, int y)
7527 return box.IsPointInside({x, y});
7529 virtual bool IsOpaque()
7531 return (!style.drawBehind || background.a == 255);
7535 virtual bool Window::NotifyActivate(Window window, bool active, Window previous);
7536 virtual void Window::NotifyDestroyed(Window window, DialogResult result);
7537 virtual void Window::NotifySaved(Window window, char * filePath);
7542 property Window parent
7544 property_category "Layout"
7547 if(value || guiApp.desktop)
7550 Window oldParent = parent;
7551 Anchor anchor = this.anchor;
7553 if(value && value.IsDescendantOf(this)) return;
7554 if(value && value == this)
7556 if(!value) value = guiApp.desktop;
7558 if(value == oldParent) return;
7560 if(!master || (master == this.parent && master == guiApp.desktop))
7561 property::master = value;
7565 parent.children.Remove(this);
7569 box.left - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7570 box.top - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y,
7571 box.right - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7572 box.bottom - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y
7576 last = value.children.last;
7578 if(style.isDocument)
7581 parent.numDocuments--;
7582 documentID = value.GetDocumentID();
7585 if(style.isActiveClient && !style.hidden)
7587 if(parent && parent != guiApp.desktop && !(style.hidden))
7589 if(state == minimized) parent.numIcons--;
7590 parent.numPositions--;
7594 if(!style.stayOnTop)
7595 for(; last && last.style.stayOnTop; last = last.prev);
7597 value.children.Insert(last, this);
7599 // *** NEW HERE: ***
7601 parent.childrenCycle.Delete(cycle);
7603 parent.childrenOrder.Delete(order);
7612 parent.hotKeys.Remove(hotKey);
7613 value.hotKeys.Add(hotKey);
7616 if(parent && parent.defaultControl == this)
7617 parent.defaultControl = null;
7619 if(style.isDefault && !value.defaultControl)
7620 value.defaultControl = this;
7624 int x = position.x, y = position.y, w = size.w, h = size.h;
7628 x += parent.absPosition.x - value.absPosition.x + parent.clientStart.x - value.clientStart.x;
7629 y += parent.absPosition.y - value.absPosition.y + parent.clientStart.y - value.clientStart.y;
7631 vpw = value.clientSize.w;
7632 vph = value.clientSize.h;
7638 else if(style.fixed)
7640 if(!style.dontScrollHorz && value.scrollArea.w) vpw = value.scrollArea.w;
7641 if(!style.dontScrollVert && value.scrollArea.h) vph = value.scrollArea.h;
7644 anchor = this.anchor;
7646 if(anchor.left.type == offset) anchor.left.distance = x;
7647 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
7648 if(anchor.top.type == offset) anchor.top.distance = y;
7649 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
7650 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
7651 //else if(anchor.right.type == relative) anchor.right.percent = 1.0-(float) (vpw - (x + w)) / vpw;
7652 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
7653 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
7654 //else if(anchor.bottom.type == relative) anchor.bottom.percent = 1.0-(float) (vph - (y + h)) / vph;
7655 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
7657 if(!anchor.left.type && !anchor.right.type)
7659 anchor.horz.distance = (x + w / 2) - (vpw / 2);
7660 //anchor.horz.type = anchor.horz.distance ? AnchorValueOffset : 0;
7662 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
7663 if(!anchor.top.type && !anchor.bottom.type)
7665 anchor.vert.distance = (y + h / 2) - (vph / 2);
7666 //anchor.vert.type = anchor.vert.distance ? AnchorValueOffset : 0;
7668 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
7676 parent.childrenCycle.Insert(
7677 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
7678 cycle = OldLink { data = this });
7679 parent.childrenOrder.Insert(
7680 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
7681 order = OldLink { data = this });
7684 if(!style.hidden && style.isActiveClient)
7686 positionID = parent.GetPositionID(this);
7687 parent.numPositions++;
7688 if(state == minimized) parent.numIcons--;
7691 // *** FONT INHERITANCE ***
7692 if(!setFont && oldParent)
7693 stopwatching(oldParent, font);
7697 RemoveResource(systemFont);
7700 // TESTING WITH WATCHERS:
7701 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7702 // usedFont = setFont ? setFont : (systemFont);
7706 if(guiApp.currentSkin)
7708 systemFont = guiApp.currentSkin.SystemFont();
7711 usedFont = systemFont;
7712 AddResource(systemFont);
7720 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7729 if(value.rootWindow && value.rootWindow.display && rootWindow)
7731 bool reloadGraphics = (oldParent.rootWindow == oldParent && value.rootWindow) || (!value.rootWindow && rootWindow == this) ||
7732 (value.rootWindow.display && value.rootWindow.display.displaySystem != rootWindow.display.displaySystem);
7735 UnloadGraphics(false);
7738 LoadGraphics(false, false);
7741 if(value.rootWindow != rootWindow)
7742 DisplayModeChanged();
7746 scrolledPos.x = MININT; // Prevent parent update
7747 property::anchor = anchor;
7751 if(guiApp.currentSkin)
7752 guiApp.currentSkin.SetWindowMinimum(this, &skinMinSize.w, &skinMinSize.h);
7754 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7755 Position(x, y, w, h, true, true, true, true, false, true);
7760 // else parent = value;
7763 get { return parent; }
7766 property Window master
7768 property_category "Behavior"
7771 //if(this == value) return;
7772 if(value && value.IsSlaveOf(this)) return;
7778 OldLink slaveHolder;
7779 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
7780 if(slaveHolder.data == this)
7782 master.slaves.Delete(slaveHolder);
7788 value.slaves.Add(OldLink { data = this });
7792 get { return master ? master : parent; }
7795 property char * text
7797 property_category "Appearance"
7804 caption = new char[strlen(value)+1];
7806 strcpy(caption, value);
7811 get { return caption; }
7816 property_category "Behavior"
7825 parent.hotKeys.Add(hotKey = HotKeySlot { });
7829 hotKey.window = this;
7834 parent.hotKeys.Delete(hotKey);
7839 get { return hotKey ? hotKey.key : 0; }
7842 property Color background
7844 property_category "Appearance"
7847 background.color = value;
7852 if(this == rootWindow)
7853 guiApp.interfaceDriver.SetRootWindowColor(this);
7856 get { return background.color; }
7859 property Percentage opacity
7861 property_category "Appearance"
7864 background.a = (byte)Min(Max((int)(value * 255), 0), 255);
7865 drawBehind = background.a ? false : true;
7867 get { return background.a / 255.0f; }
7870 property Color foreground
7872 property_category "Appearance"
7880 get { return foreground; }
7883 property BorderStyle borderStyle
7885 property_category "Appearance"
7888 if(!((BorderBits)value).fixed)
7890 style.hasClose = false;
7891 style.hasMaximize = false;
7892 style.hasMinimize = false;
7894 style.borderBits = value;
7898 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7900 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7901 Position(x, y, w, h, true, true, true, true, false, true);
7902 CreateSystemChildren();
7905 get { return (BorderStyle)style.borderBits; }
7908 property Size minClientSize
7910 property_category "Layout"
7911 set { minSize = value; }
7912 get { value = minSize; }
7915 property Size maxClientSize
7917 property_category "Layout"
7918 set { maxSize = value; }
7919 get { value = maxSize; }
7922 property bool hasMaximize
7924 property_category "Window Style"
7927 style.hasMaximize = value;
7928 if(value) { style.fixed = true; style.contour = true; }
7932 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7934 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7935 Position(x, y, w, h, true, true, true, true, false, true);
7937 CreateSystemChildren();
7940 get { return style.hasMaximize; }
7943 property bool hasMinimize
7945 property_category "Window Style"
7948 style.hasMinimize = value;
7949 if(value) { style.fixed = true; style.contour = true; }
7953 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7955 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7956 Position(x, y, w, h, true, true, true, true, false, true);
7958 CreateSystemChildren();
7961 get { return style.hasMinimize; }
7964 property bool hasClose
7966 property_category "Window Style"
7969 style.hasClose = value;
7970 if(value) { style.fixed = true; style.contour = true; }
7974 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7975 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7976 Position(x, y, w, h, true, true, true, true, false, true);
7977 CreateSystemChildren();
7980 get { return style.hasClose; }
7983 property bool nonClient
7985 property_category "Layout"
7988 style.nonClient = value;
7990 style.stayOnTop = true;
7992 get { return style.nonClient; }
7995 property bool inactive
7997 property_category "Behavior"
8002 // *** NEW HERE: ***
8006 parent.childrenCycle.Delete(cycle);
8008 parent.childrenOrder.Delete(order);
8015 active = false; // true;
8016 if(parent.activeChild == this)
8017 parent.activeChild = null;
8018 if(parent.activeClient == this)
8019 parent.activeClient = null;
8028 parent.childrenCycle.Insert(
8029 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
8030 cycle = OldLink { data = this });
8032 parent.childrenOrder.Insert(
8033 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8034 order = OldLink { data = this });
8037 style.inactive = value;
8039 get { return style.inactive; }
8042 property bool clickThrough
8044 property_category "Behavior"
8045 set { style.clickThrough = value; }
8046 get { return style.clickThrough; }
8049 property bool isRemote
8051 property_category "Behavior"
8052 set { style.isRemote = value; }
8053 get { return style.isRemote; }
8056 property bool noCycle
8058 property_category "Behavior"
8059 set { style.noCycle = value; }
8060 get { return style.noCycle; }
8063 property bool isModal
8065 property_category "Behavior"
8066 set { style.modal = value; }
8067 get { return style.modal; }
8070 property bool interim
8072 property_category "Behavior"
8073 set { style.interim = value; }
8074 get { return style.interim; }
8077 property bool tabCycle
8079 property_category "Behavior"
8080 set { style.tabCycle = value; }
8081 get { return style.tabCycle; }
8084 property bool isDefault
8086 property_category "Behavior"
8094 for(sibling = parent.children.first; sibling; sibling = sibling.next)
8095 if(sibling != this && sibling.style.isDefault)
8096 sibling.style.isDefault = false;
8097 parent.defaultControl = this;
8099 else if(parent.defaultControl == this)
8100 parent.defaultControl = null;
8104 style.isDefault = value;
8106 Position(position.x, position.y, size.w, size.h, true, true, true,true,true, true);
8108 get { return style.isDefault; }
8111 property bool drawBehind
8113 property_category "Window Style"
8114 set { style.drawBehind = value; }
8115 get { return style.drawBehind; }
8118 property bool hasMenuBar
8120 property_category "Window Style"
8130 if(created && !menuBar)
8137 anchor = Anchor { top = 23, left = 1, right = 1 },
8139 inactive = true, nonClient = true
8144 else if(created && menuBar)
8149 style.hasMenuBar = value;
8151 get { return style.hasMenuBar; }
8154 property bool hasStatusBar
8156 property_category "Window Style"
8163 statusBar = StatusBar { this };
8171 style.hasStatusBar = value;
8173 get { return style.hasStatusBar; }
8175 property bool stayOnTop
8177 property_category "Window Style"
8182 if(created && !style.stayOnTop)
8184 if(rootWindow == this)
8185 guiApp.interfaceDriver.OrderRootWindow(this, true);
8186 else if(parent.children.last != this)
8188 parent.children.Move(this, parent.children.last);
8192 style.stayOnTop = true;
8196 if(created && style.stayOnTop)
8198 if(rootWindow == this)
8199 guiApp.interfaceDriver.OrderRootWindow(this, false);
8206 for(order = (this.order == parent.childrenOrder.first) ? null : this.order.prev;
8207 order && ((Window)order.data).style.stayOnTop;
8208 order = (order == parent.childrenOrder.first) ? null : order.prev);
8209 last = order ? order.data : null;
8213 for(last = parent.children.last;
8214 last && last.style.stayOnTop;
8218 parent.children.Move(this, last);
8222 style.stayOnTop = false;
8225 get { return style.stayOnTop; }
8230 property_category "Window Style"
8240 if(menuBar && !value)
8247 if(!menuBar && style.hasMenuBar && value)
8251 this, menu = value, isMenuBar = true,
8252 anchor = Anchor { left = 1, top = 23, right = 1 }, size.h = 24,
8253 inactive = true, nonClient = true
8257 UpdateActiveDocument(null);
8260 get { return menu; }
8263 property FontResource font
8265 property_category "Appearance"
8267 isset { return setFont ? true : false; }
8272 if(value && !setFont) { stopwatching(parent, font); }
8273 else if(!value && setFont)
8279 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
8288 RemoveResource(setFont);
8293 RemoveResource(systemFont);
8300 AddResource(setFont);
8303 usedFont = setFont ? setFont : ((parent && parent.parent) ? parent.usedFont : systemFont);
8306 systemFont = guiApp.currentSkin.SystemFont();
8308 usedFont = systemFont;
8309 AddResource(systemFont);
8317 get { return usedFont; }
8320 property SizeAnchor sizeAnchor
8322 property_category "Layout"
8325 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8326 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8327 sizeAnchor.isClientW != sizeAnchor.isClientH;
8334 normalSizeAnchor = sizeAnchor;
8336 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8338 stateAnchor = normalAnchor;
8339 stateSizeAnchor = normalSizeAnchor;
8341 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8342 Position(x,y, w, h, true, true, true, true, false, true);
8349 { sizeAnchor.isClientW ? clientSize.w : size.w, sizeAnchor.isClientH ? clientSize.h : size.h },
8350 sizeAnchor.isClientW,
8351 sizeAnchor.isClientH
8358 property_category "Layout"
8361 Anchor thisAnchor = anchor;
8362 SizeAnchor thisSizeAnchor = sizeAnchor;
8363 bool leftRight = (anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none);
8364 bool topBottom = (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none);
8365 bool isClient = !sizeAnchor.isClientW && !sizeAnchor.isClientH;
8366 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8367 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8368 !sizeAnchor.isClientW && !sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8374 sizeAnchor.isClientW = false;
8375 sizeAnchor.isClientH = false;
8376 sizeAnchor.size = value;
8378 normalSizeAnchor = sizeAnchor;
8380 if(state == normal /*|| state == Hidden*/) // Hidden is new here ...
8382 stateAnchor = normalAnchor;
8383 stateSizeAnchor = normalSizeAnchor;
8385 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8386 Position(x, y, w, h, true, true, true, true, false, true);
8389 get { value = size; }
8392 property Size clientSize
8394 property_category "Layout"
8397 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8398 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8399 sizeAnchor.isClientW && sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8404 sizeAnchor.isClientW = true;
8405 sizeAnchor.isClientH = true;
8406 sizeAnchor.size = value;
8408 normalSizeAnchor = sizeAnchor;
8410 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8412 stateAnchor = normalAnchor;
8413 stateSizeAnchor = normalSizeAnchor;
8415 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8416 Position(x,y, w, h, true, true, true, true, false, true);
8419 get { value = clientSize; }
8422 property Size initSize { get { value = sizeAnchor.size; } };
8424 property Anchor anchor
8426 property_category "Layout"
8427 isset { return (anchor.left.type != offset || anchor.top.type != offset || anchor.right.type || anchor.bottom.type); }
8433 if(anchor.left.type && anchor.right.type && (!value.left.type || !value.right.type))
8435 normalSizeAnchor.isClientW = sizeAnchor.isClientW = false;
8436 normalSizeAnchor.size.w = sizeAnchor.size.w = size.w;
8438 if(anchor.top.type && anchor.bottom.type && (!value.top.type || !value.bottom.type))
8440 normalSizeAnchor.isClientH = sizeAnchor.isClientH = false;
8441 normalSizeAnchor.size.h = sizeAnchor.size.h = size.h;
8445 if(anchor.right.type && (anchor.horz.type == middleRelative || !anchor.left.type))
8447 anchor.left.distance = 0;
8448 anchor.horz.type = 0;
8450 if(anchor.bottom.type && (anchor.vert.type == middleRelative || !anchor.top.type))
8452 anchor.top.distance = 0;
8453 anchor.vert.type = 0;
8462 normalAnchor = anchor;
8464 // Break the anchors for moveable/resizable windows
8465 /*if(style.fixed ) //&& value.left.type == cascade)
8467 ComputeAnchors(anchor, sizeAnchor, &x, &y, &w, &h);
8469 this.anchor = normalAnchor = Anchor { left = x, top = y };
8470 normalSizeAnchor = SizeAnchor { { w, h } };
8473 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8475 stateAnchor = normalAnchor;
8476 stateSizeAnchor = normalSizeAnchor;
8478 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8479 Position(x, y, w, h, true, true, true, true, false, true);
8488 get { value = this ? anchor : Anchor { }; }
8491 property Point position
8493 property_category "Layout"
8496 if(value == null) return;
8498 anchor.left = value.x;
8499 anchor.top = value.y;
8500 anchor.right.type = none;
8501 anchor.bottom.type = none;
8506 normalAnchor = anchor;
8508 // Break the anchors for moveable/resizable windows
8512 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8514 normalAnchor.left = x;
8515 normalAnchor.top = y;
8516 normalAnchor.right.type = none;
8517 normalAnchor.bottom.type = none;
8518 normalSizeAnchor.size.width = w;
8519 normalSizeAnchor.size.height = h;
8523 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8525 stateAnchor = normalAnchor;
8526 stateSizeAnchor = normalSizeAnchor;
8528 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8529 Position(x,y, w, h, true, true, true, true, false, true);
8533 get { value = position; }
8536 property bool disabled
8538 property_category "Behavior"
8541 if(this && disabled != value)
8548 get { return (bool)disabled; }
8551 property bool isEnabled
8556 for(parent = this; parent; parent = parent.parent)
8563 property WindowState state
8565 property_category "Behavior"
8566 set { SetState(value, false, 0); }
8567 get { return this ? state : 0; }
8570 property bool visible
8572 property_category "Behavior"
8575 if(this && !value && !style.hidden && parent)
8577 Window client = null;
8579 style.hidden = true;
8582 OldLink prevOrder = null;
8584 if(rootWindow == this)
8585 guiApp.interfaceDriver.SetRootWindowState(this, state, false);
8588 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
8591 box.left -= parent.clientStart.x;
8592 box.top -= parent.clientStart.y;
8593 box.right -= parent.clientStart.x;
8594 box.bottom -= parent.clientStart.y;
8598 if(style.modal && master && master.modalSlave == this)
8599 master.modalSlave = null;
8601 if(style.isActiveClient)
8603 parent.numPositions--;
8604 if(state == minimized) parent.numIcons--;
8609 OldLink tmpPrev = order.prev;
8610 client = tmpPrev ? tmpPrev.data : null;
8611 if(client && !client.style.hidden && !client.destroyed && client.created)
8612 prevOrder = tmpPrev;
8615 client = tmpPrev ? tmpPrev.data : null;
8616 if(client == this) { client = null; break; }
8617 if(client && ((client.style.hidden) || client.destroyed || !client.created))
8619 tmpPrev = client.order.prev;
8624 prevOrder = tmpPrev;
8629 // If this window can be an active client, make sure the next window we activate can also be one
8630 if(!style.nonClient && style.isActiveClient)
8632 tmpPrev = prevOrder;
8635 client = tmpPrev ? tmpPrev.data : null;
8636 if(client == this) { client = null; break; }
8637 if(client && (client.style.nonClient || !client.style.isActiveClient || client.style.hidden || client.destroyed || !client.created))
8639 tmpPrev = client.order.prev;
8644 prevOrder = tmpPrev;
8648 if(client && client.style.hidden) client = null;
8652 if((parent.activeChild == this || guiApp.interimWindow == this) && true /*activate*/)
8654 if(order && prevOrder && prevOrder.data != this)
8655 ((Window)prevOrder.data).ActivateEx(true, false, false, true, null, null);
8657 ActivateEx(false, false, false, true, null, null);
8659 // TESTING THIS HERE FOR HIDING ACTIVE CLIENT
8660 if(parent.activeClient == this)
8662 parent.activeClient = null;
8663 parent.UpdateActiveDocument(null);
8666 else if(parent.activeClient == this)
8668 parent.activeClient = client;
8669 parent.UpdateActiveDocument(this);
8672 // *** Not doing this anymore ***
8675 parent.childrenCycle.Delete(cycle);
8677 parent.childrenOrder.Delete(order);
8682 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8687 else if(this && value && style.hidden)
8689 style.hidden = false;
8692 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8693 if(rootWindow == this)
8694 guiApp.interfaceDriver.SetRootWindowState(this, state, true);
8696 if(style.modal && master)
8697 master.modalSlave = this;
8699 if(style.isActiveClient)
8701 positionID = parent.GetPositionID(this);
8702 parent.numPositions++;
8703 if(state == minimized) parent.numIcons++;
8706 // *** NOT DOING THIS ANYMORE ***
8708 if(!(style.inactive))
8710 if(!(style.noCycle))
8712 cycle = parent.childrenCycle.AddAfter(
8713 (parent.activeChild && parent.activeChild.cycle) ?
8714 parent.activeChild.cycle.prev : null, sizeof(OldLink));
8717 order = parent.childrenOrder.AddAfter(
8718 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8725 if(true || !parent.activeChild)
8726 ActivateEx(true, false, true, true, null, null);
8728 if(creationActivation == activate)
8729 ActivateEx(true, false, true, true, null, null);
8730 else if(creationActivation == flash && !object)
8733 //SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8737 ConsequentialMouseMove(false);
8744 get { return (style.hidden || !setVisible) ? false : true; }
8747 property bool isDocument
8749 property_category "Document"
8750 set { style.isDocument = value; }
8751 get { return style.isDocument; }
8754 property bool mergeMenus
8756 property_category "Window Style"
8757 set { mergeMenus = value; }
8758 get { return (bool)mergeMenus; }
8761 property bool hasHorzScroll
8763 property_category "Window Style"
8768 if(!style.hasHorzScroll && created)
8770 CreateSystemChildren();
8771 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8774 else if(style.hasHorzScroll)
8778 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8780 style.hasHorzScroll = value;
8783 get { return style.hasHorzScroll; }
8786 property bool hasVertScroll
8788 property_category "Window Style"
8793 if(!style.hasVertScroll && created)
8795 style.hasVertScroll = true;
8796 CreateSystemChildren();
8797 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8800 else if(style.hasVertScroll)
8804 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8806 style.hasVertScroll = value;
8808 get { return style.hasVertScroll; }
8811 property bool dontHideScroll
8813 property_category "Behavior"
8816 scrollFlags.dontHide = value;
8819 //UpdateScrollBars(true, true);
8820 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8824 // UpdateScrollBars(true, true);
8825 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8828 get { return scrollFlags.dontHide; }
8831 property bool dontScrollVert
8833 property_category "Behavior"
8834 set { style.dontScrollVert = value; }
8835 get { return style.dontScrollVert; }
8837 property bool dontScrollHorz
8839 property_category "Behavior"
8840 set { style.dontScrollHorz = value; }
8841 get { return style.dontScrollHorz; }
8844 property bool snapVertScroll
8846 property_category "Behavior"
8849 scrollFlags.snapY = value;
8850 if(sbv) sbv.snap = value;
8852 get { return scrollFlags.snapY; }
8854 property bool snapHorzScroll
8856 property_category "Behavior"
8859 scrollFlags.snapX = value;
8860 if(sbh) sbh.snap = value;
8862 get { return scrollFlags.snapX; }
8865 property Point scroll
8867 property_category "Behavior"
8871 // TESTING THIS IMPLEMENTATION:
8872 SetScrollPosition(value.x, value.y);
8874 get { value = scroll; }
8877 property bool modifyVirtualArea
8879 property_category "Behavior"
8880 set { modifyVirtArea = value; }
8881 get { return (bool)modifyVirtArea; }
8884 property char * fileName
8886 property_category "Document"
8889 if(menu && ((!fileName && value) || (fileName && !value)))
8891 MenuItem item = menu.FindItem(MenuFileSave, 0);
8892 if(item) item.disabled = !modifiedDocument && value;
8897 if(value && value[0])
8898 fileName = CopyString(value);
8900 if(parent && this == parent.activeClient)
8901 parent.UpdateActiveDocument(null);
8905 // if(style.isDocument)
8907 fileMonitor.fileName = value;
8909 get { return fileName; }
8914 property_category "Data"
8919 property bool modifiedDocument
8921 property_category "Document"
8924 if(style.isDocument || fileName)
8928 MenuItem item = menu.FindItem(MenuFileSave, 0);
8929 if(item) item.disabled = !value && fileName;
8933 if(modifiedDocument != value)
8935 modifiedDocument = value;
8936 if(style.isDocument || fileName)
8940 get { return (bool)modifiedDocument; }
8943 property bool showInTaskBar
8945 property_category "Window Style"
8946 set { style.showInTaskBar = value; }
8947 get { return (style.showInTaskBar; }
8949 property FileDialog saveDialog { set { saveDialog = value; } };
8950 property bool isActiveClient
8952 property_category "Behavior"
8953 set { style.isActiveClient = value; }
8954 get { return style.isActiveClient; }
8957 property Cursor cursor
8959 property_category "Appearance"
8963 SelectMouseCursor();
8965 get { return cursor; }
8968 //#if !defined(ECERE_VANILLA)
8969 property char * name
8971 property_category "Design"
8974 return (this && object) ? object.name : null;
8979 activeDesigner.RenameObject(object, value);
8983 property char * displayDriver
8985 property_category "Behavior"
8988 dispDriver = GetDisplayDriver(value);
8989 //DisplayModeChanged();
8993 return dispDriver ? dispDriver.name : null;
8997 // RUNTIME PROPERTIES
8998 property bool autoCreate { set { autoCreate = value; } get { return (bool)autoCreate; } };
8999 property Size scrollArea
9001 property_category "Behavior"
9005 SetScrollArea(value.w, value.h, false);
9007 SetScrollArea(0,0, true);
9009 get { value = scrollArea; }
9012 return scrollArea.w > clientSize.w || scrollArea.h > clientSize.h;
9017 property_category "Layout"
9018 set { if(this) is3D = value; }
9019 get { return (bool)is3D; }
9022 // Runtime Only Properties (No Set, can display the displayable ones depending on the type?)
9024 // Will be merged with font later
9025 property Font fontObject { get { return usedFont ? usedFont.font : null; } };
9026 property Point clientStart { get { value = clientStart; } };
9027 property Point absPosition { get { value = absPosition; } };
9028 property Anchor normalAnchor { get {value = normalAnchor; } };
9029 // property Size normalSizeAnchor { get { value = normalSizeAnchor; } };
9030 property bool active { get { return (bool)active; } };
9031 property bool created { get { return (bool)created; } };
9032 property bool destroyed { get { return (bool)destroyed; } };
9033 property Window firstSlave { get { return slaves.first ? ((OldLink)slaves.first).data : null; } };
9034 property Window firstChild { get { return children.first; } };
9035 property Window lastChild { get { return children.last; } };
9036 property Window activeClient { get { return activeClient; } };
9037 property Window activeChild { get { return activeChild; } };
9038 property Display display { get { return display ? display : ((parent && parent.rootWindow) ? parent.rootWindow.display : null); } };
9039 property DisplaySystem displaySystem { get { return display ? display.displaySystem : null; } };
9040 property ScrollBar horzScroll { get { return sbh; } };
9041 property ScrollBar vertScroll { get { return sbv; } };
9042 property StatusBar statusBar { get { return statusBar; } };
9043 property Window rootWindow { get { return rootWindow; } };
9044 property bool closing { get { return (bool)closing; } set { closing = value; } };
9045 property int documentID { get { return documentID; } };
9046 property Window previous { get { return prev; } }
9047 property Window next { get { return next; } }
9048 property Window nextSlave { get { OldLink link = master.slaves.FindLink(this); return (link && link.next) ? link.next.data : null; } }
9049 property PopupMenu menuBar { get { return menuBar; } }
9050 property ScrollBar sbv { get { return sbv; } }
9051 property ScrollBar sbh { get { return sbh; } }
9052 property bool fullRender { set { fullRender = value; } get { return (bool)fullRender; } }
9053 property void * systemHandle { get { return windowHandle; } }
9054 property Button minimizeButton { get { return sysButtons[0]; } };
9055 property Button maximizeButton { get { return sysButtons[1]; } };
9056 property Button closeButton { get { return sysButtons[2]; } };
9057 property BitmapResource icon
9059 get { return icon; }
9065 guiApp.interfaceDriver.SetIcon(this, value);
9068 property bool moveable { get { return (bool)moveable; } set { moveable = value; } };
9069 property bool alphaBlend { get { return (bool)alphaBlend; } set { alphaBlend = value; } };
9070 property bool useSharedMemory { get { return (bool)useSharedMemory; } set { useSharedMemory = value; } };
9071 property CreationActivationOption creationActivation { get { return creationActivation; } set { creationActivation = value; } };
9072 property bool nativeDecorations { get { return (bool)nativeDecorations; } set { nativeDecorations = value; } };
9073 property bool manageDisplay { get { return (bool)manageDisplay; } set { manageDisplay = value; } };
9079 WindowBits style; // Window Style
9080 char * caption; // Name / Caption
9081 Window parent; // Parent window
9082 OldList children; // List of children in Z order
9083 Window activeChild; // Child window having focus
9084 Window activeClient;
9085 Window previousActive; // Child active prior to activating the default child
9086 Window master; // Window owning and receiving notifications concerning this window
9087 OldList slaves; // List of windows belonging to this window
9088 Display display; // Display this window is drawn into
9090 Point position; // Position in parent window client area
9091 Point absPosition; // Absolute position
9092 Point clientStart; // Client area position from (0,0) in this window
9094 Size clientSize; // Client area size
9095 Size scrollArea; // Virtual Scroll area size
9096 Size reqScrollArea; // Requested virtual area size
9097 Point scroll; // Virtual area scrolling position
9098 public ScrollBar sbh, sbv; // Scrollbar window handles
9099 Cursor cursor; // Mouse cursor used for this window
9102 StatusBar statusBar;
9103 Button sysButtons[3];
9105 Box clientArea; // Client Area box clipped to parent
9107 HotKeySlot hotKey; // HotKey for this window
9111 ScrollFlags scrollFlags;// Window Scrollbar Flags
9112 int id; // Control ID
9114 ColorAlpha background; // Background color used to draw the window area
9116 subclass(DisplayDriver) dispDriver; // Display driver name for this window
9117 OldList childrenCycle; // Cycling order
9118 OldLink cycle; // Element of parent's cycling order
9119 OldList childrenOrder; // Circular Z-Order
9120 OldLink order; // Element of parent's circular Z-Order
9121 Window modalSlave; // Slave window blocking this window's interaction
9123 Window rootWindow; // Topmost system managed window
9124 void * windowHandle; // System window handle
9126 DialogResult returnCode;// Return code for modal windows
9128 Point sbStep; // Scrollbar line scrolling steps
9131 SizeAnchor stateSizeAnchor;
9133 Anchor normalAnchor;
9134 SizeAnchor normalSizeAnchor;
9136 Size skinMinSize; // Minimal window size based on style
9137 Point scrolledPos; // Scrolled position
9138 Box box; // Window box clipped to parent
9139 Box * against; // What to clip the box to
9141 Extent dirtyArea { /*first = -1, last = -1, free = -1*/ }; // Area marked for update by Update
9142 Extent renderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered
9143 Extent overRenderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered over children
9144 Extent clipExtent { /*first = -1, last = -1, free = -1*/ }; // Temporary extent against which to clip render area
9145 Extent scrollExtent { /*first = -1, last = -1, free = -1*/ }; // Area to scroll
9146 Point scrolledArea; // Distance to scroll area by
9147 Extent dirtyBack { /*first = -1, last = -1, free = -1*/ }; // Only used by root window
9149 OldList hotKeys; // List of the hotkeys of all children
9150 Window defaultControl; // Default child control
9154 ColorAlpha * palette; // Color palette used for this window
9156 int caretSize; // Size of caret, non zero if a caret is present
9157 Point caretPos; // Caret position
9159 void * systemParent; // Parent System Window for embedded windows
9166 WindowState lastState;
9168 FileMonitor fileMonitor
9170 this, FileChange { modified = true };
9172 bool OnFileNotify(FileChange action, char * param)
9175 fileMonitor.StopMonitoring();
9176 if(OnFileModified(action, param))
9177 fileMonitor.StartMonitoring();
9182 FontResource setFont, systemFont;
9183 FontResource usedFont;
9184 FontResource captionFont;
9186 FileDialog saveDialog;
9188 SizeAnchor sizeAnchor;
9190 // FormDesigner data
9193 Extent * tempExtents; //[4];
9194 BitmapResource icon;
9196 CreationActivationOption creationActivation;
9199 bool active:1; // true if window and ancestors are active
9200 bool acquiredInput:1; // true if the window is processing state based input
9201 bool modifiedDocument:1;
9202 bool disabled:1; // true if window cannot interact
9203 bool isForegroundWindow:1;// true while a root window is being activated
9204 bool visible:1; // Visibility flag
9205 bool destroyed:1; // true if window is being destroyed
9206 bool anchored:1; // true if this window is repositioned when the parent resizes
9207 bool dirty:1; // Flag set to true if any descendant must be redrawn
9213 bool modifyVirtArea:1;
9214 bool noAutoScrollArea:1;
9217 bool setVisible:1; // FOR FORM DESIGNER
9223 bool useSharedMemory:1;
9226 bool nativeDecorations:1;
9227 bool manageDisplay:1;
9230 WindowController controller;
9231 public property WindowController controller { get { return controller; } set { delete controller; controller = value; if(controller) incref controller; } }
9234 public class CommonControl : Window
9236 // creationActivation = doNothing;
9239 public class Percentage : float
9241 char * OnGetString(char * string, float * fieldData, bool * needClass)
9245 sprintf(string, "%.2f", this);
9246 c = strlen(string)-1;
9249 if(string[c] != '0')
9250 last = Max(last, c);
9251 if(string[c] == '.')
9264 public void ApplySkin(Class c, char * name, void ** vTbl)
9266 char className[1024];
9271 subclass(Window) wc = (subclass(Window))c;
9272 subclass(Window) base = (subclass(Window))c.base;
9274 sprintf(className, "%sSkin_%s", name, c.name);
9275 wc.pureVTbl = c._vTbl;
9276 c._vTbl = new void *[c.vTblSize];
9277 memcpy(c._vTbl, wc.pureVTbl, c.vTblSize * sizeof(void *));
9278 sc = eSystem_FindClass(c.module.application, className);
9282 for(m = 0; m < c.base.vTblSize; m++)
9284 if(c._vTbl[m] == base.pureVTbl[m])
9285 c._vTbl[m] = vTbl[m];
9290 for(m = 0; m < c.vTblSize; m++)
9292 if(sc._vTbl[m] != wc.pureVTbl[m])
9293 c._vTbl[m] = sc._vTbl[m];
9297 for(d = c.derivatives.first; d; d = d.next)
9299 ApplySkin(d.data, name, c._vTbl);
9303 public void UnapplySkin(Class c)
9305 char className[1024];
9307 subclass(Window) wc = (subclass(Window))c;
9308 subclass(Window) base = (subclass(Window))c.base;
9311 if(wc.pureVTbl && c._vTbl != wc.pureVTbl)
9314 c._vTbl = wc.pureVTbl;
9318 for(d = c.derivatives.first; d; d = d.next)
9320 UnapplySkin(d.data);
9324 void CheckFontIntegrity(Window window)
9329 if(window.usedFont && window.usedFont.font == 0xecececec)
9331 FontResource uf = window.usedFont;
9332 char * className = window._class.name;
9333 char * text = window.text;
9336 for(c = window.firstChild; c; c = c.next)
9337 CheckFontIntegrity(c);
9341 public class ControllableWindow : Window
9343 /*WindowController controller;
9344 public property WindowController controller { get { return controller; } set { delete controller; controller = value; incref controller; } }
9345 ~ControllableWindow() { delete controller; }*/
9348 class WindowControllerInterface : ControllableWindow
9350 bool OnKeyDown(Key key, unichar ch)
9352 bool result = ((int(*)())(void *)controller.OnKeyDown)((void *)controller.controlled, (void *)controller, key, ch);
9354 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown](controller.window, key, ch);
9358 bool OnKeyUp(Key key, unichar ch)
9360 bool result = ((int(*)())(void *)controller.OnKeyUp)((void *)controller.controlled, (void *)controller, key, ch);
9362 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp](controller.window, key, ch);
9366 bool OnKeyHit(Key key, unichar ch)
9368 bool result = ((int(*)())(void *)controller.OnKeyHit)((void *)controller.controlled, (void *)controller, key, ch);
9370 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit](controller.window, key, ch);
9374 bool OnMouseMove(int x, int y, Modifiers mods)
9376 bool result = ((int(*)())(void *)controller.OnMouseMove)((void *)controller.controlled, (void *)controller, x, y, mods);
9378 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove](controller.window, x, y, mods);
9382 bool OnLeftButtonDown(int x, int y, Modifiers mods)
9384 bool result = ((int(*)())(void *)controller.OnLeftButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9386 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown](controller.window, x, y, mods);
9390 bool OnLeftButtonUp(int x, int y, Modifiers mods)
9392 bool result = ((int(*)())(void *)controller.OnLeftButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9394 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp](controller.window, x, y, mods);
9398 bool OnLeftDoubleClick(int x, int y, Modifiers mods)
9400 bool result = ((int(*)())(void *)controller.OnLeftDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9402 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick](controller.window, x, y, mods);
9406 bool OnRightButtonDown(int x, int y, Modifiers mods)
9408 bool result = ((int(*)())(void *)controller.OnRightButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9410 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown](controller.window, x, y, mods);
9414 bool OnRightButtonUp(int x, int y, Modifiers mods)
9416 bool result = ((int(*)())(void *)controller.OnRightButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9418 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp](controller.window, x, y, mods);
9422 bool OnRightDoubleClick(int x, int y, Modifiers mods)
9424 bool result = ((int(*)())(void *)controller.OnRightDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9426 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick](controller.window, x, y, mods);
9430 bool OnMiddleButtonDown(int x, int y, Modifiers mods)
9432 bool result = ((int(*)())(void *)controller.OnMiddleButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9434 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown](controller.window, x, y, mods);
9438 bool OnMiddleButtonUp(int x, int y, Modifiers mods)
9440 bool result = ((int(*)())(void *)controller.OnMiddleButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9442 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp](controller.window, x, y, mods);
9446 bool OnMiddleDoubleClick(int x, int y, Modifiers mods)
9448 bool result = ((int(*)())(void *)controller.OnMiddleDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9450 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick](controller.window, x, y, mods);
9454 void OnResize(int width, int height)
9456 ((int(*)())(void *)controller.OnResize)((void *)controller.controlled, (void *)controller, width, height);
9457 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnResize](controller.window, width, height);
9460 void OnRedraw(Surface surface)
9462 ((int(*)())(void *)controller.OnRedraw)((void *)controller.controlled, (void *)controller, surface);
9463 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw](controller.window, surface);
9468 bool result = ((int(*)())(void *)controller.OnCreate)((void *)controller.controlled, (void *)controller);
9470 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnCreate](controller.window);
9475 public class WindowController<class V>
9478 property Window window
9482 uint size = class(Window).vTblSize;
9485 windowVTbl = new void *[size];
9486 memcpy(windowVTbl, value._vTbl, size * sizeof(void *));
9487 if(value._vTbl == value._class._vTbl)
9489 value._vTbl = new void *[value._class.vTblSize];
9490 memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *));
9494 for(c = 0; c < size; c++)
9496 void * function = class(WindowControllerInterface)._vTbl[c];
9497 if(function != DefaultFunction)
9498 value._vTbl[c] = function;
9500 value._vTbl[c] = windowVTbl[c];
9505 memcpy(value._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *));
9508 get { return window; }
9510 property V controlled
9512 set { controlled = value; }
9513 get { return controlled; }
9515 virtual bool V::OnKeyDown(WindowController controller, Key key, unichar ch);
9516 virtual bool V::OnKeyUp(WindowController controller, Key key, unichar ch);
9517 virtual bool V::OnKeyHit(WindowController controller, Key key, unichar ch);
9518 virtual bool V::OnMouseMove(WindowController controller, int x, int y, Modifiers mods);
9519 virtual bool V::OnLeftButtonDown(WindowController controller, int x, int y, Modifiers mods);
9520 virtual bool V::OnLeftButtonUp(WindowController controller, int x, int y, Modifiers mods);
9521 virtual bool V::OnLeftDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9522 virtual bool V::OnRightButtonDown(WindowController controller, int x, int y, Modifiers mods);
9523 virtual bool V::OnRightButtonUp(WindowController controller, int x, int y, Modifiers mods);
9524 virtual bool V::OnRightDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9525 virtual bool V::OnMiddleButtonDown(WindowController controller, int x, int y, Modifiers mods);
9526 virtual bool V::OnMiddleButtonUp(WindowController controller, int x, int y, Modifiers mods);
9527 virtual bool V::OnMiddleDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9528 virtual void V::OnResize(WindowController controller, int width, int height);
9529 virtual void V::OnRedraw(WindowController controller, Surface surface);
9530 virtual bool V::OnCreate(WindowController controller);
9533 int (** windowVTbl)();