7 import "GuiApplication"
27 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
31 #if !defined(ECERE_VANILLA) && !defined(ECERE_NOTRUETYPE)
40 // Had to define this here for native decorations support, because the menu bar is part of total decoration's size, but not part of the system decorations
41 define skinMenuHeight = 25;
42 define statusBarHeight = 18;
44 default extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
46 public enum DialogResult { cancel, yes, no, ok };
48 public class MouseButtons
51 bool left:1, right:1, middle:1;
54 public struct SizeAnchor
57 bool isClientW, isClientH;
62 #define SNAPDOWN(x, d) \
65 if(x < 0) x -= ((d) - Abs(x) % (d)); else x -= x % (d); \
68 #define SNAPUP(x, d) \
71 if(x > 0) x += ((d) - Abs(x) % (d)); else x += x % (d); \
74 /*static */define MAX_DIRTY_BACK = 10;
76 /////////////////////////////////////////////////////////////////////////////
77 ////////// EXTENT MANIPULATION //////////////////////////////////////////////
78 /////////////////////////////////////////////////////////////////////////////
80 #define ACCESS_ITEM(l, id) \
83 #define FASTLIST_LOOP(l, v) \
84 for(v = (BoxItem)l.first; v; v = (BoxItem)v.next)
86 #define FASTLIST_LOOPN(l, v, n) \
87 for(v = (BoxItem)l.first, n = (BoxItem)(v ? v.next : null); v; v = (BoxItem)next, n = (BoxItem)(v ? v.next : null))
90 #define ACCESS_ITEM(l, id) \
91 ((FastItem)(((id) == -1) ? null : (((byte *)((l).items)) + (id) * (l).itemSize)))
93 #define FASTLIST_LOOP(l, v) \
94 for(v = (void *)ACCESS_ITEM((l), (l).first); v; v = (void *)ACCESS_ITEM((l), v.next))
96 #define FASTLIST_LOOPN(l, v, n) \
97 for( v = (void *)ACCESS_ITEM((l), (l).first), \
98 n = v ? ((void *)ACCESS_ITEM((l), v.next)): null; \
99 v; v = n, n = n ? (void *)ACCESS_ITEM((l), n.next) : null)
102 private class FastItem : struct
107 private struct FastList
112 int count, size, itemSize;
119 first = last = free = -1;
127 // FASTLIST_LOOPN(this, item, next) { Delete(item); };
130 FastItem Add(uint itemSize)
133 if(free == -1 || !size)
140 newSize = (size + (size >> 1));
141 items = (FastItem)renew items byte[newSize * itemSize];
146 this.itemSize = itemSize;
147 items = (FastItem)new byte[newSize * itemSize];
150 for(c = size; c<newSize-1; c++)
152 ACCESS_ITEM(this, c).prev = -1;
153 ACCESS_ITEM(this, c).next = c+1;
155 ACCESS_ITEM(this, c).prev = -1;
156 ACCESS_ITEM(this, c).next = -1;
160 item = ACCESS_ITEM(this, free);
163 ACCESS_ITEM(this, item.prev).next = free;
173 void Delete(FastItem item)
176 ACCESS_ITEM(this, item.prev).next = item.next;
178 ACCESS_ITEM(this, item.next).prev = item.prev;
180 if(ACCESS_ITEM(this, first) == item)
182 if(ACCESS_ITEM(this, last) == item)
187 free = ((byte *)item - (byte *)items) / itemSize;
195 free = first = last = -1;
199 private class BoxItem : Item //FastItem
204 public /*private */struct Extent : OldList //FastList
213 //BoxItem extentBox = (BoxItem)Add(sizeof(class BoxItem));
214 Add(BoxItem { box = box });
217 void Copy(Extent source)
223 //FASTLIST_LOOP(source, extentBox)
224 for(extentBox = (BoxItem)source.first; extentBox; extentBox = (BoxItem)extentBox.next)
225 AddBox(extentBox.box);
228 void IntersectBox(Box box)
230 // Clip all boxes of extent against inside of the new box
231 BoxItem extentBox, next;
233 //FASTLIST_LOOPN(this, extentBox, next) // Macros still mess up the parser!
234 for(extentBox = (BoxItem)this.first; extentBox; extentBox = next)
236 next = (BoxItem)extentBox.next;
237 if(box.left > extentBox.box.left) extentBox.box.left = box.left;
238 if(box.top > extentBox.box.top) extentBox.box.top = box.top;
239 if(box.right < extentBox.box.right) extentBox.box.right = box.right;
240 if(box.bottom < extentBox.box.bottom) extentBox.box.bottom = box.bottom;
241 if(extentBox.box.right < extentBox.box.left || extentBox.box.bottom < extentBox.box.top)
246 void ExcludeBox(Box box, Extent temp)
253 for(extentBox = (BoxItem)temp.first; extentBox; extentBox = (BoxItem)extentBox.next)
255 if(extentBox.box.left < box.right && extentBox.box.right > box.left &&
256 extentBox.box.top < box.bottom && extentBox.box.bottom > box.top)
259 if(extentBox.box.top < box.top && extentBox.box.bottom >= box.top)
263 extentBox.box.left, extentBox.box.top,
264 extentBox.box.right, Min(extentBox.box.bottom, box.top -1)
270 if(extentBox.box.bottom > box.bottom && extentBox.box.top <= box.bottom)
274 extentBox.box.left, Max(extentBox.box.top,box.bottom +1),
275 extentBox.box.right, extentBox.box.bottom
281 if(extentBox.box.bottom >= box.top && extentBox.box.top <= box.bottom)
284 if(extentBox.box.left < box.left && extentBox.box.right >= box.left)
288 extentBox.box.left, Max(extentBox.box.top, box.top),
289 Min(extentBox.box.right, box.left-1), Min(extentBox.box.bottom, box.bottom)
295 if(extentBox.box.right > box.right && extentBox.box.left <= box.right)
299 Max(extentBox.box.left, box.right+1), Max(extentBox.box.top, box.top),
300 extentBox.box.right, Min(extentBox.box.bottom, box.bottom)
308 AddBox(extentBox.box);
314 void UnionBox(Box box, Extent temp)
316 BoxItem extentBox, next;
318 // First pass: check if this box is not already covered by one of the extent's box
319 for(extentBox = (BoxItem)this.first; extentBox; extentBox = (BoxItem)extentBox.next)
321 if(extentBox.box.left <= box.left && extentBox.box.right >= box.right &&
322 extentBox.box.top <= box.top && extentBox.box.bottom >= box.bottom)
329 // Second pass: only keep boxes not completely covered in the new box
330 for(extentBox = (BoxItem)this.first; extentBox; extentBox = next)
332 next = (BoxItem)extentBox.next;
333 if(extentBox.box.left >= box.left && extentBox.box.right <= box.right &&
334 extentBox.box.top >= box.top && extentBox.box.bottom <= box.bottom)
338 // Add the exclusion to the extent
339 ExcludeBox(box, temp);
342 if(box.bottom >= box.top && box.right >= box.left)
344 // Optimization: if the resulting boxes touch, add them smarter
345 for(extentBox = (BoxItem)this.first; extentBox; extentBox = (BoxItem)extentBox.next)
347 if(box.top == extentBox.box.top && box.bottom == extentBox.box.bottom)
349 if(Abs(box.right - extentBox.box.left) <= 1)
351 extentBox.box.left = box.left;
354 else if(Abs(box.left - extentBox.box.right) <= 1)
356 extentBox.box.right = box.right;
360 else if(box.left == extentBox.box.left && box.right == extentBox.box.right)
362 if(Abs(box.bottom - extentBox.box.top) <= 1)
364 extentBox.box.top = box.top;
367 else if(Abs(box.top - extentBox.box.bottom) <= 1)
369 extentBox.box.bottom = box.bottom;
381 void Union(Extent b, Extent temp)
385 for(extentBox = (BoxItem)b.first; extentBox; extentBox = (BoxItem)extentBox.next)
386 UnionBox(extentBox.box, temp);
389 void Intersection(Extent b, Extent temp, Extent temp2, Extent temp3)
396 for(extentBox = (BoxItem)b.first; extentBox; extentBox = (BoxItem)extentBox.next)
399 temp2.IntersectBox(extentBox.box);
406 void Exclusion(Extent b, Extent temp)
409 for(extentBox = (BoxItem)b.first; extentBox; extentBox = (BoxItem)extentBox.next)
410 ExcludeBox(extentBox.box, temp);
413 void Offset(int x, int y)
416 for(extentBox = (BoxItem)this.first; extentBox; extentBox = (BoxItem)extentBox.next)
418 extentBox.box.left += x;
419 extentBox.box.top += y;
420 extentBox.box.right += x;
421 extentBox.box.bottom += y;
426 private define MINIMIZED_WIDTH = 160;
427 private define CASCADE_SPACE = 16;
429 // namespace Windows;
431 private class ScrollFlags
433 bool snapX:1, snapY:1, dontHide:1;
436 public class BorderBits { public: bool contour:1, fixed:1, sizable:1, deep:1, bevel:1, thin:1; };
438 class WindowBits : BorderBits
440 BorderBits borderBits:6:0;
441 bool hidden:1, isActiveClient:1, hasHorzScroll:1, hasVertScroll:1, stayOnTop:1, modal:1, isDefault:1, inactive:1, isRemote:1, drawBehind:1;
442 bool interim:1, tabCycle:1, noCycle:1, dontScrollHorz:1, dontScrollVert:1, hasMaximize:1, hasMinimize:1, hasClose:1;
443 bool embedded:1, hasMenuBar:1, isDocument:1, showInTaskBar:1, hasStatusBar:1, nonClient:1, clickThrough:1;
446 public enum BorderStyle : BorderBits
449 contour = BorderBits { contour = true },
450 fixed = BorderBits { fixed = true } | contour,
451 sizable = BorderBits { sizable = true } | fixed,
452 thin = BorderBits { fixed = true, thin = true } | contour,
453 sizableThin = BorderBits { sizable = true } | thin,
454 deep = BorderBits { deep = true },
455 bevel = BorderBits { bevel = true },
456 sizableDeep = sizable|deep,
457 sizableBevel = sizable|bevel,
458 fixedDeep = fixed|deep,
459 fixedBevel = fixed|bevel,
460 deepContour = deep|contour
463 public enum CreationActivationOption
465 activate, flash, doNothing
468 public enum WindowState { normal, minimized, maximized };
470 private class ResPtr : struct
477 private class HotKeySlot : struct
479 HotKeySlot prev, next;
487 class_data char * icon;
489 class_default_property text;
490 // class_initialize GuiApplication::Initialize;
491 class_designer FormDesigner;
492 class_property char * icon
494 set { class_data(icon) = value; }
495 get { return class_data(icon); }
500 if(guiApp) guiApp.Initialize(true);
502 if(guiApp && guiApp.currentSkin && ((subclass(Window))_class).pureVTbl)
504 if(_vTbl == ((subclass(Window))_class).pureVTbl)
506 _vTbl = _class._vTbl;
508 else if(_vTbl != _class._vTbl)
511 for(m = 0; m < _class.vTblSize; m++)
513 if(_vTbl[m] == ((subclass(Window))_class).pureVTbl[m])
514 _vTbl[m] = _class._vTbl[m];
519 //tempExtents[0] = { /*first = -1, last = -1, free = -1*/ };
520 //tempExtents[1] = { /*first = -1, last = -1, free = -1*/ };
521 //tempExtents[2] = { /*first = -1, last = -1, free = -1*/ };
522 //tempExtents[3] = { /*first = -1, last = -1, free = -1*/ };
526 // caption = CopyString(class.name);
528 children.offset = (byte*)&prev - (byte*)this;
529 childrenOrder.circ = true;
530 childrenCycle.circ = true;
532 maxSize = Size { MAXINT, MAXINT };
536 //style.isActiveClient = true;
539 modifyVirtArea = true;
540 manageDisplay = true;
542 // scrollFlags = ScrollFlags { snapX = true, snapY = true };
543 sbStep.x = sbStep.y = 8;
545 if(guiApp) // dynamic_cast<GuiApplication>(thisModule)
547 cursor = guiApp.GetCursor(arrow);
548 property::parent = guiApp.desktop;
559 stopwatching(parent, font);
563 // Prevent destructor from being called again...
569 /////////////////////////////////
572 OldLink slave = master.slaves.FindLink(this);
573 master.slaves.Delete(slave);
580 parent.childrenCycle.Remove(cycle);
582 parent.childrenOrder.Remove(order);
583 parent.children.Remove(this);
588 /////////////////////////////////
590 while(ptr = resources.first)
593 resources.Delete(ptr);
600 for(child = children.first; child; child = child.next)
602 // child.stopwatching(this, font);
604 eInstance_StopWatching(this, __ecereProp___ecereNameSpace__ecere__gui__Window_font, child);
605 // Don't want property here
606 *&child.parent = null;
609 while(slave = slaves.first)
611 // Don't want property here
612 *&((Window)slave.data).master = null;
613 slaves.Delete(slave);
616 // Because we do a decref in DestroyEx...
624 // Why was this commented?
625 //if(this != guiApp.desktop)
638 if(((subclass(Window))_class).pureVTbl)
640 if(_vTbl == _class._vTbl)
642 _vTbl = ((subclass(Window))_class).pureVTbl;
647 for(m = 0; m < _class.vTblSize; m++)
649 if(_vTbl[m] == _class._vTbl[m])
650 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
654 if(_vTbl == ((subclass(Window))_class).pureVTbl || _vTbl == _class._vTbl)
657 dirtyArea.Free(null);
658 renderArea.Free(null);
659 overRenderArea.Free(null);
660 clipExtent.Free(null);
661 scrollExtent.Free(null);
662 dirtyBack.Free(null);
666 tempExtents[0].Free(null);
667 tempExtents[1].Free(null);
668 tempExtents[2].Free(null);
669 tempExtents[3].Free(null);
674 //#if !defined(ECERE_VANILLA)
675 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
677 if(this == activeDesigner)
681 char * name = property::name;
682 return name ? name : "";
687 #if !defined(ECERE_VANILLA) && !defined(ECERE_NOTRUETYPE)
688 bool OnGetDataFromString(char * string)
690 FormDesigner designer = (FormDesigner)activeDesigner.classDesigner;
693 if(!strcmp(string, "this") || !strcmp(string, designer.form.name))
694 this = designer.form;
695 else if(!strcmpi(string, "(Desktop)"))
696 this = activeDesigner;
698 return activeDesigner.FindObject(&this, string);
704 // --- Window updates system ---
706 // Setup a bitmap for Redrawing on client area of Window
707 Surface Redraw(Box box)
709 Surface surface = null;
711 Box clientArea = this.clientArea;
715 mox.left -= clientStart.x;
716 mox.top -= clientStart.y;
717 mox.right -= clientStart.x;
718 mox.bottom -= clientStart.y;
720 mox.Clip(clientArea);
721 // mox.ClipOffset(against, scrolledPos.x, scrolledPos.y);
723 if((!guiApp.fullScreenMode || guiApp.desktop.active) && display && mox.right >= mox.left && mox.bottom >= mox.top)
725 int x = absPosition.x + clientStart.x;
726 int y = absPosition.y + clientStart.y;
727 if(rootWindow.nativeDecorations)
729 x -= rootWindow.clientStart.x;
730 y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
732 if(!guiApp.fullScreenMode || is3D)
734 x -= rootWindow.absPosition.x;
735 y -= rootWindow.absPosition.y;
739 x += rootWindow.parent.clientStart.x;
740 y += rootWindow.parent.clientStart.y;
742 mox.left += rootWindow.parent.clientStart.x;
743 mox.top += rootWindow.parent.clientStart.y;
744 mox.right += rootWindow.parent.clientStart.x;
745 mox.bottom += rootWindow.parent.clientStart.y;
750 surface = display.GetSurface(x, y, mox);
753 surface.width = clientSize.w;
754 surface.height = clientSize.h;
760 // Setup a bitmap for Redrawing on full Window
761 Surface RedrawFull(Box box)
763 Surface surface = null;
771 if((!guiApp.fullScreenMode || guiApp.desktop.active) && display && box.right >= box.left && box.bottom >= box.top)
773 int x = absPosition.x;
774 int y = absPosition.y;
775 if(rootWindow.nativeDecorations)
777 x -= rootWindow.clientStart.x;
778 y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
780 if(!guiApp.fullScreenMode || is3D)
782 x -= rootWindow.absPosition.x;
783 y -= rootWindow.absPosition.y;
786 x += rootWindow.parent.clientStart.x;
787 y += rootWindow.parent.clientStart.y;
789 mox.left += rootWindow.parent.clientStart.x;
790 mox.top += rootWindow.parent.clientStart.y;
791 mox.right += rootWindow.parent.clientStart.x;
792 mox.bottom += rootWindow.parent.clientStart.y;
797 surface = display.GetSurface(x, y, mox);
800 surface.width = size.w;
801 surface.height = size.h;
807 void FigureCaption(char * caption)
811 strcpy(caption, this.caption);
812 if(style.isDocument || fileName)
814 if(caption[0]) strcat(caption, " - ");
816 strcat(caption, fileName);
820 sprintf(title, "Untitled %d", documentID);
821 strcat(caption, title);
824 strcat(caption, " *");
826 if(activeClient && menuBar &&
827 activeClient.state == maximized)
829 if(activeClient.caption)
831 if(caption[0]) strcat(caption, " - ");
832 strcat(caption, activeClient.caption);
834 if(activeClient.style.isDocument || activeClient.fileName)
836 if(caption[0]) strcat(caption, " - ");
837 strcat(caption, "[");
838 if(activeClient.fileName)
839 strcat(caption, activeClient.fileName);
843 sprintf(title, "Untitled %d", activeClient.documentID);
844 strcat(caption, title);
846 if(activeClient.modifiedDocument)
847 strcat(caption, " *");
848 strcat(caption, "]");
853 // Code for returning dirty from ScrollDisplay:
855 for(d = 0; d<scrollExtent.count; d++)
857 Box * box = &scrollExtent.boxes[d];
863 Min(box.right, box.left-scroll.x),box.bottom
865 dirtyArea.UnionBox(update);
871 Max(box.left, box.right-scroll.x), box.top,
872 box.right, box.bottom
874 dirtyArea.UnionBox(update);
882 box.right, Min(box.bottom, box.top-scroll.y),
884 dirtyArea.UnionBox(update);
890 box.left, Max(box.top, box.bottom-scroll.y),
891 box.right, box.bottom
893 dirtyArea.UnionBox(update);
898 void UpdateDecorations(void)
900 // TODO: *** TEMPORARY HACK ***
907 Update({ -clientStart.x, -clientStart.y, -clientStart.x + size.w-1, 0 });
909 Update({ -clientStart.x, clientSize.h, -clientStart.x + size.w-1, -clientStart.y + size.h-1 });
911 Update({ -clientStart.x,0, -1, clientSize.h-1 });
913 Update({ clientSize.w, 0, -clientStart.x + size.w-1, clientSize.h-1 });
916 // Returns w & h for Position
917 void ComputeAnchors(Anchor anchor, SizeAnchor sizeAnchor, int *ox, int *oy, int *ow, int *oh)
919 Window parent = this.parent ? this.parent : guiApp.desktop;
920 int vpw = parent ? parent.clientSize.w : 0;
921 int vph = parent ? parent.clientSize.h : 0;
922 int pw = parent ? parent.clientSize.w : 0;
923 int ph = parent ? parent.clientSize.h : 0;
924 int w = sizeAnchor.size.w, h = sizeAnchor.size.h;
925 int x = anchor.left.distance, y = anchor.top.distance;
927 MinMaxValue ew = 0, eh = 0;
929 float cascadeW, cascadeH;
931 int tilingW, tilingH, tilingSplit, tilingLastH;
932 int addX = 0, addY = 0;
934 if(parent && rootWindow == this && guiApp && guiApp.interfaceDriver)
936 Window masterWindow = this;
937 Box box { addX, addY, addX + vpw - 1, addY + vph - 1 };
940 if(master == guiApp.desktop)
941 masterWindow = guiApp.desktop.activeChild;
943 masterWindow = master.rootWindow;
944 if(!masterWindow) masterWindow = this;
946 guiApp.interfaceDriver.GetScreenArea(masterWindow, box);
947 if((anchor.left.type == offset && anchor.right.type == offset) || anchor.left.type == none)
950 pw = vpw = box.right - box.left + 1;
952 if((anchor.top.type == offset && anchor.bottom.type == offset) || anchor.top.type == none)
955 ph = vph = box.bottom - box.top + 1;
971 vpw = pw = parent.size.w;
972 vph = ph = parent.size.h;
974 else if(!style.fixed /*|| style.isDocument*/)
976 if(!style.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
977 if(!style.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
979 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
982 Desktop3D_FixSize(&pw, &ph);
983 Desktop3D_FixSize(&vpw, &vph);
986 if(pw < skinMinSize.w) pw = skinMinSize.w;
987 if(ph < skinMinSize.h) ph = skinMinSize.h;
988 if(vpw < skinMinSize.w) vpw = skinMinSize.w;
989 if(vph < skinMinSize.h) vph = skinMinSize.h;
991 // TODO: Must fix what we're snapping
996 SNAPUP(x, textCellW);
998 else if(anchor.right.type)
1000 SNAPDOWN(x, textCellW);
1005 SNAPUP(y, textCellH);
1007 else if(anchor.bottom.type)
1009 SNAPDOWN(y, textCellH);
1013 // This is required to get proper initial decoration size using native decorations on Windows
1014 if(nativeDecorations && guiApp && guiApp.interfaceDriver && !visible)
1015 guiApp.interfaceDriver.PositionRootWindow(this, x, y, Max(1, size.w), Max(1, size.h), true, true);
1016 GetDecorationsSize(&ew, &eh);
1018 if(anchor.left.type >= cascade && (state == normal /*|| state == Hidden*/))
1020 if(parent.sbv && !parent.sbv.style.hidden)
1021 pw += guiApp.currentSkin.VerticalSBW();
1022 if(parent.sbh && !parent.sbh.style.hidden)
1023 ph += guiApp.currentSkin.HorizontalSBH();
1025 if(anchor.left.type == cascade)
1027 w = (int)(pw * 0.80);
1028 h = (int)(ph * 0.80);
1030 else if(anchor.left.type >= vTiled)
1035 numTiling = parent.numPositions - parent.numIcons;
1036 if(parent.numIcons) ph -= guiApp.textMode ? 16 : 24;
1037 if(anchor.left.type == vTiled)
1039 tilingH = (int)sqrt(numTiling);
1040 tilingW = numTiling / tilingH;
1044 tilingW = (int)sqrt(numTiling);
1045 tilingH = numTiling / tilingW;
1048 leftOver = numTiling - tilingH * tilingW;
1051 tilingSplit = (tilingW - leftOver) * tilingH;
1052 tilingLastH = tilingH+1;
1055 tilingSplit = numTiling;
1057 if(positionID >= tilingSplit)
1059 x = pw * (tilingSplit / tilingH + (positionID - tilingSplit) / tilingLastH)/tilingW;
1060 y = ph * ((positionID - tilingSplit) % tilingLastH) / tilingLastH;
1061 x2 = pw * (tilingSplit/tilingH + (positionID - tilingSplit) / tilingLastH + 1)/tilingW;
1062 y2 = ph * (((positionID - tilingSplit) % tilingLastH) + 1) / tilingLastH;
1066 x = pw * (positionID / tilingH) / tilingW;
1067 y = ph * (positionID % tilingH) / tilingH;
1068 x2 = pw * (positionID / tilingH + 1) / tilingW;
1069 y2 = ph * ((positionID % tilingH) + 1) / tilingH;
1073 SNAPDOWN(x, textCellW);
1074 SNAPDOWN(y, textCellH);
1075 SNAPDOWN(x2, textCellW);
1076 SNAPDOWN(y2, textCellH);
1084 if(sizeAnchor.isClientW) w += ew;
1085 if(sizeAnchor.isClientH) h += eh;
1087 if(anchor.left.type == offset)
1088 x = anchor.left.distance;
1089 else if(anchor.left.type == relative)
1090 x = (anchor.left.percent < 0) ? ((int)(vpw * anchor.left.percent - 0.5)) : (int)(vpw * anchor.left.percent + 0.5);
1091 else if(anchor.right.type == relative)
1092 // ex = (anchor.right.percent < 0) ? ((int)(vpw * anchor.right.percent + 0)) : ((int)(vpw * anchor.right.percent + 0));
1093 ex = (anchor.right.percent < 0) ? ((int)(vpw * (1.0-anchor.right.percent) + 0)) : ((int)(vpw * (1.0-anchor.right.percent) + 0));
1094 else if(anchor.right.type == offset)
1095 ex = vpw - anchor.right.distance;
1097 if(anchor.top.type == offset)
1098 y = anchor.top.distance;
1099 else if(anchor.top.type == relative)
1100 y = (anchor.top.percent < 0) ? ((int)(vph * anchor.top.percent - 0.5)) : ((int)(vph * anchor.top.percent + 0.5));
1101 else if(anchor.bottom.type == relative)
1102 //ey = (anchor.bottom.percent < 0) ? ((int)(vph * anchor.bottom.percent + 0)) : ((int)(vph * anchor.bottom.percent + 0));
1103 ey = (anchor.bottom.percent < 0) ? ((int)(vph * (1.0-anchor.bottom.percent) + 0)) : ((int)(vph * (1.0-anchor.bottom.percent) + 0));
1104 else if(anchor.bottom.type == offset)
1105 ey = vph - anchor.bottom.distance;
1107 if(anchor.left.type && anchor.right.type)
1109 switch(anchor.right.type)
1112 ex = pw * (1.0f-anchor.right.percent);
1113 w = Max((int)(ex + 0.5) - x, 0);
1116 ex = vpw - anchor.right.distance;
1117 w = Max((int)(ex + 0.5) - x, 0);
1121 if(anchor.top.type && anchor.bottom.type)
1123 switch(anchor.bottom.type)
1126 ey = ph * (1.0f-anchor.bottom.percent);
1127 h = Max((int)(ey + 0.5) - y, 0);
1130 ey = vph - anchor.bottom.distance;
1131 h = Max((int)(ey + 0.5) - y, 0);
1140 if(state == normal /*|| state == Hidden*/)
1142 bool addSbV = false, addSbH = false;
1144 if(sizeAnchor.isClientW || (anchor.left.type && anchor.right.type)) w = Max(w, 1); else w = Max(w, 0);
1145 if(sizeAnchor.isClientH || (anchor.top.type && anchor.bottom.type)) h = Max(h, 1); else h = Max(h, 0);
1147 w = Max(w, minSize.w);
1148 h = Max(h, minSize.h);
1149 w = Min(w, maxSize.w);
1150 h = Min(h, maxSize.h);
1152 if((sizeAnchor.isClientW || !w || (anchor.left.type && anchor.right.type)) && reqScrollArea.h > h /*&& w*/ && sbv)
1154 if(w) w -= guiApp.currentSkin.VerticalSBW();
1157 if((sizeAnchor.isClientH || !h || (anchor.top.type && anchor.bottom.type)) && reqScrollArea.w > w /*&& h*/ && sbh)
1159 if(h) h -= guiApp.currentSkin.HorizontalSBH();
1163 if(!OnResizing(&w, &h))
1169 if((addSbV)) // || reqScrollArea.h > h) && sbv)
1170 w += guiApp.currentSkin.VerticalSBW();
1171 if((addSbH)) // || reqScrollArea.w > w) && sbh)
1172 h += guiApp.currentSkin.HorizontalSBH();
1174 w = Max(w, skinMinSize.w);
1175 h = Max(h, skinMinSize.h);
1188 SNAPDOWN(w, textCellW);
1189 SNAPDOWN(h, textCellH);
1192 if(anchor.left.type == cascade && (state == normal /*|| state == Hidden*/))
1194 if(parent.numIcons) ph -= guiApp.textMode ? 16 : 24;
1197 (pw - w) / CASCADE_SPACE,
1198 (ph - h) / CASCADE_SPACE);
1204 cascW = (pw - w) / (numCascade-1);
1205 cascH = (ph - h) / (numCascade-1);
1206 SNAPDOWN(cascW, textCellW);
1207 SNAPDOWN(cascH, textCellH);
1208 cascadeW = (float)cascW;
1209 cascadeH = (float)cascH;
1213 numCascade = Max(numCascade, 2);
1214 cascadeW = (float)(pw - w) / (numCascade-1);
1215 cascadeH = (float)(ph - h) / (numCascade-1);
1218 x = (int)((positionID % numCascade) * cascadeW);
1219 y = (int)((positionID % numCascade) * cascadeH);
1221 else if(anchor.left.type < vTiled)
1223 if(!anchor.left.type || anchor.horz.type == middleRelative)
1225 if(!anchor.right.type)
1227 if(anchor.horz.type == middleRelative)
1228 x = (int)(vpw * (0.5 + anchor.horz.percent) - w / 2);
1230 x = vpw / 2 + anchor.horz.distance - w / 2;
1236 // case A_EDGE: x = x - w; break;
1238 if(!anchor.top.type || anchor.vert.type == middleRelative)
1240 if(!anchor.bottom.type)
1242 if(anchor.vert.type == middleRelative)
1243 y = (int)(vph * (0.5 + anchor.vert.percent) - h / 2);
1245 y = vph / 2 + anchor.vert.distance - h / 2;
1251 // case A_EDGE: y = y - h; break;
1254 if((state == normal /*|| state == Hidden*/) && !OnMoving(&x, &y, w, h))
1262 SNAPDOWN(x, textCellW);
1263 SNAPDOWN(y, textCellH);
1275 if(anchored && style.fixed && style.isActiveClient)
1280 void UpdateCaret(bool forceUpdate, bool erase)
1282 static Window lastWindow = null;
1283 static int caretX, caretY, caretSize;
1285 if(guiApp && guiApp.caretOwner == this)
1287 int x = caretPos.x - scroll.x;
1288 int y = caretPos.y - scroll.y;
1290 if((erase || this.caretSize) &&
1291 x >= clientArea.left && x <= clientArea.right &&
1292 y >= clientArea.top && y <= clientArea.bottom)
1296 guiApp.interfaceDriver.SetCaret(
1297 x + absPosition.x + clientStart.x,
1298 y + absPosition.y + clientStart.y, this.caretSize);
1299 guiApp.caretEnabled = true;
1301 if(erase || lastWindow != this || caretX != x || caretY != y || caretSize != this.caretSize || forceUpdate)
1305 if(lastWindow != this)
1307 updateBox.left = x + 1;
1309 updateBox.right = x + 2;
1310 updateBox.bottom = y + this.caretSize - 1;
1314 updateBox.left = Min(x + 1, caretX + 1);
1315 updateBox.top = Min(y, caretY);
1316 updateBox.right = Max(x + 2, caretX + 2);
1317 updateBox.bottom = Max(y + this.caretSize - 1, caretY + caretSize - 1);
1320 guiApp.caretOwner.Update(updateBox);
1327 caretSize = this.caretSize;
1333 guiApp.interfaceDriver.SetCaret(0,0,0);
1334 guiApp.caretEnabled = false;
1340 void SetPosition(int x, int y, int w, int h, bool modifyArea, bool modifyThisArea, bool modifyClientArea)
1345 scrolledPos.x = position.x = x;
1346 scrolledPos.y = position.y = y;
1348 clientSize.w = size.w = w;
1349 clientSize.h = size.h = h;
1351 if(parent && !style.nonClient)
1353 //if(!style.fixed || style.isDocument)
1355 if(!style.dontScrollHorz) scrolledPos.x -= parent.scroll.x;
1356 if(!style.dontScrollVert) scrolledPos.y -= parent.scroll.y;
1360 clientStart.x = clientStart.y = 0;
1362 SetWindowArea(&clientStart.x, &clientStart.y, &size.w, &size.h, &clientSize.w, &clientSize.h);
1364 //if(!activeClient || activeClient.state != maximized)
1365 if(!noAutoScrollArea)
1367 // Check if scroll area must be modified
1368 if(guiApp && !guiApp.modeSwitching && (sbv || sbh))
1370 bool foundChild = false;
1372 int cw = clientSize.w;// + ((!sbv || sbv.range > 1) ? guiApp.currentSkin.VerticalSBW() : 0);
1373 int ch = clientSize.h;// + ((!sbh || sbh.rangw > 1) ? guiApp.currentSkin.HorizontalSBH() : 0);
1374 for(child = children.first; child; child = child.next)
1376 if(child.modifyVirtArea && !child.style.hidden && child.created && /*!child.anchored &&*/
1377 !child.style.dontScrollHorz && !child.style.dontScrollVert && !child.style.nonClient)
1379 if(child.stateAnchor.right.type == none && child.stateAnchor.left.type == offset)
1380 w = Max(w, child.position.x + child.size.w);
1381 else if(child.stateAnchor.right.type == none && child.stateAnchor.left.type == none)
1382 w = Max(w, Max(child.position.x, 0) + child.size.w);
1383 if(child.stateAnchor.bottom.type == none && child.stateAnchor.top.type == offset)
1384 h = Max(h, child.position.y + child.size.h);
1385 else if(child.stateAnchor.bottom.type == none && child.stateAnchor.top.type == none)
1386 h = Max(h, Max(child.position.y, 0) + child.size.h);
1391 if(foundChild && (w > cw || h > ch))
1393 //if((w > reqScrollArea.w) || (h > reqScrollArea.w))
1395 int stepX = sbStep.x, stepY = sbStep.y;
1396 // Needed to make snapped down position match the skin's check of client area
1397 // against realvirtual
1400 SNAPDOWN(stepX, textCellW);
1401 SNAPDOWN(stepY, textCellH);
1402 stepX = Max(stepX, textCellW);
1403 stepY = Max(stepY, textCellH);
1405 if(scrollFlags.snapX)
1407 if(scrollFlags.snapY)
1410 reqScrollArea.w = w;
1411 reqScrollArea.h = h;
1414 else if(reqScrollArea.w || reqScrollArea.h)
1416 reqScrollArea.w = 0;
1417 reqScrollArea.h = 0;
1418 SetScrollPosition(0,0);
1423 // Automatic MDI Client Scrolling Area Adjustment
1424 if(parent && !parent.noAutoScrollArea)
1426 if(modifyArea && modifyVirtArea /*&& !anchored*/ && (parent.sbv || parent.sbh) &&
1427 !style.dontScrollHorz && !style.dontScrollVert && !style.nonClient)
1429 Window parent = this.parent;
1430 int w = parent.reqScrollArea.w;
1431 int h = parent.reqScrollArea.h;
1433 if(stateAnchor.right.type == none && stateAnchor.left.type == offset)
1434 w = Max(w, position.x + size.w);
1435 else if(stateAnchor.right.type == none && stateAnchor.left.type == none)
1436 w = Max(w, Max(position.x, 0) + size.w);
1437 if(stateAnchor.bottom.type == none && stateAnchor.top.type == offset)
1438 h = Max(h, position.y + size.h);
1439 else if(stateAnchor.bottom.type == none && stateAnchor.top.type == none)
1440 h = Max(h, Max(position.y, 0) + size.h);
1442 if((w > parent.clientSize.w && w > parent.reqScrollArea.w) ||
1443 (h > parent.clientSize.h && h > parent.reqScrollArea.h))
1445 /*bool resize = false;
1446 int stepX = parent.sbStep.x, stepY = parent.sbStep.y;
1447 // Needed to make snapped down position match the skin's check of client area
1448 // against realvirtual
1451 SNAPDOWN(stepX, textCellW);
1452 SNAPDOWN(stepY, textCellH);
1453 stepX = Max(stepX, textCellW);
1454 stepY = Max(stepY, textCellH);
1456 if(parent.scrollFlags.snapX)
1458 if(parent.scrollFlags.snapY)
1460 if(parent.reqScrollArea.w != w || parent.reqScrollArea.h != h)
1462 parent.reqScrollArea.w = w;
1463 parent.reqScrollArea.h = h;*/
1465 // parent.UpdateScrollBars(true, true);
1466 parent.Position(parent.position.x, parent.position.y, parent.size.w, parent.size.h,
1467 false, true, true, true, false, false);
1472 GetRidOfVirtualArea();
1476 UpdateScrollBars(modifyThisArea, false);
1477 else if(guiApp.currentSkin)
1480 &clientStart.x, &clientStart.y, &size.w, &size.h, &clientSize.w, &clientSize.h);
1482 if(sbv && (scrollFlags.dontHide || sbv.range > 1))
1483 clientSize.w -= guiApp.currentSkin.VerticalSBW();
1484 if(sbh && (scrollFlags.dontHide || sbh.range > 1))
1485 clientSize.h -= guiApp.currentSkin.HorizontalSBH();
1488 scrollArea.w = Max(clientSize.w, reqScrollArea.w);
1489 scrollArea.h = Max(clientSize.h, reqScrollArea.h);
1491 absPosition = scrolledPos;
1492 if(guiApp && guiApp.driver != null && guiApp.interfaceDriver)
1493 guiApp.interfaceDriver.OffsetWindow(this, &absPosition.x, &absPosition.y);
1495 if(this != guiApp.desktop && parent)
1497 absPosition.x += parent.absPosition.x;
1498 absPosition.y += parent.absPosition.y;
1499 if(!style.nonClient && this != guiApp.desktop)
1501 absPosition.x += parent.clientStart.x;
1502 absPosition.y += parent.clientStart.y;
1506 box = Box { 0, 0, size.w - 1, size.h - 1 };
1511 // Clip against parent's client area
1512 box.ClipOffset(against, scrolledPos.x, scrolledPos.y);
1514 // Compute client area in this window coordinate system
1515 clientArea.left = 0;
1517 clientArea.right = clientSize.w - 1;
1518 clientArea.bottom = clientSize.h - 1;
1520 // Clip against parent's client area
1522 clientArea.ClipOffset(against, scrolledPos.x + clientStart.x, scrolledPos.y + clientStart.y);
1526 //absPosition.x -= parent.clientStart.x;
1527 //absPosition.y -= parent.clientStart.y;
1530 // Adjust all children
1531 for(child = children.first; child; child = child.next)
1532 child.SetPosition(child.position.x, child.position.y, child.size.w, child.size.h, false, true, true);
1534 UpdateCaret(false, false);
1537 void GetRidOfVirtualArea(void)
1539 if(parent && !parent.destroyed && style.fixed &&
1540 !style.dontScrollHorz && !style.dontScrollVert && !style.nonClient &&
1541 parent.reqScrollArea.w && parent.reqScrollArea.h)
1543 if(!parent.noAutoScrollArea)
1547 for(child = children.first; child; child = child.next)
1549 if(child.modifyVirtArea && !child.style.dontScrollHorz && !child.style.dontScrollVert && !child.style.nonClient)
1551 if(child.position.x + child.size.w > parent.clientSize.w + ((!parent.sbv || parent.sbv.style.hidden) ? 0 : guiApp.currentSkin.VerticalSBW()) ||
1552 child.position.y + child.size.h > parent.clientSize.h + ((!parent.sbh || parent.sbh.style.hidden) ? 0 : guiApp.currentSkin.HorizontalSBH()))
1561 Window parent = this.parent;
1563 parent.position.x, parent.position.y, parent.size.w, parent.size.h,
1564 false, true, true, true, false, false);
1566 parent.SetScrollArea(0,0,true);
1567 parent.SetScrollPosition(0,0);
1573 public void ExternalPosition(int x, int y, int w, int h)
1575 Position(x, y, w, h, false, true, true, true, false, false);
1578 // (w, h): Full window size
1579 bool Position(int x, int y, int w, int h, bool force, bool processAnchors, bool modifyArea, bool updateScrollBars, bool thisOnly, bool changeRootWindow)
1581 bool result = false;
1582 int oldCW = clientSize.w, oldCH = clientSize.h;
1583 bool clientResized, windowResized, windowMoved;
1585 bool realResized = size.w != w || size.h != h;
1587 // TOCHECK: This wasn't in ecere.dll
1588 //if(!parent) return true;
1589 if(destroyed) return false;
1591 windowMoved = position.x != x || position.y != y || force;
1593 // windowResized = realResized || force;
1594 windowResized = size.w != w || size.h != h || force;
1596 if(rootWindow != this && display && !display.flags.flipping && scrolledPos.x != MININT)
1602 scrolledPos.x - parent.clientStart.x + this.box.left, scrolledPos.y - parent.clientStart.y + this.box.top,
1603 scrolledPos.x - parent.clientStart.x + this.box.right,
1604 scrolledPos.y - parent.clientStart.y + this.box.bottom
1610 Box box { scrolledPos.x + this.box.left, scrolledPos.y + this.box.top, scrolledPos.x + this.box.right, scrolledPos.y + this.box.bottom};
1615 SetPosition(x, y, w, h, true, modifyArea, updateScrollBars);
1617 clientResized = oldCW != clientSize.w || oldCH != clientSize.h || force;
1619 if(display && rootWindow != this)
1622 if(guiApp && guiApp.windowMoving)
1624 if(guiApp.windowMoving.style.nonClient)
1625 guiApp.windowMoving.parent.SetMouseRangeToWindow();
1627 guiApp.windowMoving.parent.SetMouseRangeToClient();
1637 // Buttons bitmap resources crash if we do this while switching mode
1638 if(!guiApp || !guiApp.modeSwitching)
1641 // Process Anchored Children
1645 for(child = children.first; child; child = child.next)
1648 ((child.stateAnchor.left.type != offset ||
1649 child.stateAnchor.top.type != offset ||
1650 child.stateAnchor.right.type != none ||
1651 child.stateAnchor.bottom.type != none) ||
1652 child.state == maximized || child.state == minimized))
1654 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor,
1656 // child.Position(x, y, w, h, false, true, true, true, false);
1657 // This must be true cuz otherwise we're gonna miss everything since we SetPosition recursively already
1658 child.Position(x, y, w, h, true, true, true, true, false, true /*false*/);
1664 // Is this gonna cause other problems? Commented out for the FileDialog end bevel bug
1665 //if(updateScrollBars)
1667 OnResize(clientSize.w, clientSize.h);
1669 if((clientResized || windowMoved) && created)
1670 OnPosition(position.x, position.y, clientSize.w, clientSize.h);
1672 if(guiApp.interimWindow && guiApp.interimWindow.master.rootWindow == this)
1674 Window master = guiApp.interimWindow.master;
1675 master.OnPosition(master.position.x, master.position.y, master.clientSize.w, master.clientSize.h);
1678 if(rootWindow == this && !is3D)
1682 x -= guiApp.desktop.absPosition.x;
1683 y -= guiApp.desktop.absPosition.y;
1685 //guiApp.Log("Position %s\n", caption);
1686 if(windowResized || windowMoved)
1687 if(display && !display.flags.memBackBuffer && changeRootWindow)
1688 guiApp.interfaceDriver.PositionRootWindow(this, x, y, w, h, windowMoved, windowResized); //realResized);
1690 if(!guiApp.fullScreenMode && this != guiApp.desktop && (windowResized || windowMoved))
1691 for(child = parent.children.first; child && child != this; child = child.next)
1692 if(child.rootWindow)
1693 guiApp.interfaceDriver.UpdateRootWindow(child.rootWindow);
1697 if(windowMoved || windowResized)
1699 display.Lock(true /*false*/);
1702 display.Position(absPosition.x, absPosition.y);
1703 //display.Position(absPosition.x + clientStart.x, absPosition.y + clientStart.y);
1706 // result = realResized ? display.Resize(size.w, size.h) : true;
1707 if(nativeDecorations)
1709 int w = clientSize.w, h = clientSize.h;
1710 if(hasMenuBar) h += skinMenuHeight;
1711 if(hasStatusBar) h += statusBarHeight;
1712 if(sbv && sbv.visible) w += sbv.size.w;
1713 if(sbh && sbh.visible) h += sbh.size.h;
1714 result = manageDisplay ? display.Resize(w, h) : true;
1717 result = manageDisplay ? display.Resize(size.w, size.h) : true;
1721 else if(clientResized)
1723 // --- Major Slow Down / Fix OpenGL Resizing Main Window Lag
1726 if(!guiApp.fullScreenMode && !guiApp.modeSwitching && this == rootWindow)
1730 if(windowMoved || windowResized)
1735 if(guiApp.driver && changeRootWindow)
1737 if(windowResized || windowMoved)
1738 if(!display || display.flags.memBackBuffer)
1739 guiApp.interfaceDriver.PositionRootWindow(this,
1740 x, y, w, h, windowMoved, windowResized);
1741 guiApp.interfaceDriver.UpdateRootWindow(this);
1743 for(child = children.first; child; child = child.next)
1745 if(child.is3D && child.created)
1747 // Copy Display Content
1748 child.display.displaySystem = display.displaySystem;
1749 child.display.window = display.window;
1750 child.display.current = display.current;
1751 child.display.width = display.width;
1752 child.display.height = display.height;
1753 child.display.driverData = display.driverData;
1754 child.display.mutex = null;
1765 void UpdateScrollBars(bool flag, bool fullThing)
1768 bool resizeH = false, resizeV = false;
1769 bool scrolled = false;
1770 rvw = (activeChild && activeChild.state == maximized) ? 0 : reqScrollArea.w;
1771 rvh = (activeChild && activeChild.state == maximized) ? 0 : reqScrollArea.h;
1773 if(destroyed) return;
1774 if(guiApp.currentSkin)
1776 MinMaxValue cw = 0, ch = 0;
1777 bool sbvVisible, sbhVisible;
1779 int positionH, positionV;
1781 // First get client area with no respect to scroll bars
1786 &clientStart.x, &clientStart.y, &size.w, &size.h, &cw, &ch);
1788 if(scrollFlags.dontHide)
1791 cw -= guiApp.currentSkin.VerticalSBW();
1793 ch -= guiApp.currentSkin.HorizontalSBH();
1795 // Update the scrollbar visibility
1801 sbh.disabled = rangeH <= 1;
1802 if(sbh.style.hidden)
1812 sbv.disabled = rangeV <= 1;
1813 if(sbv.style.hidden)
1821 // Then start off with horizontal scrollbar range
1824 positionH = sbh.thumbPosition;
1829 ch -= guiApp.currentSkin.HorizontalSBH();
1832 // Do the same for vertical scrollbar
1835 positionV = sbv.thumbPosition;
1841 cw -= guiApp.currentSkin.VerticalSBW();
1842 // Maybe we need to set the range on the horizontal scrollbar again
1847 sbh.Action(setRange, positionH, 0);
1848 if(rangeH <= 1 && sbh.range > 1)
1850 ch -= guiApp.currentSkin.HorizontalSBH();
1854 sbv.Action(setRange, positionV, 0);
1861 // Update the scrollbar visibility
1862 if(!scrollFlags.dontHide)
1864 if(sbh && ((rangeH <= 1 && !sbh.style.hidden) || (rangeH > 1 && sbh.style.hidden)))
1868 if(sbv && ((rangeV <= 1 && !sbv.style.hidden) || (rangeV > 1 && sbv.style.hidden)))
1875 if(guiApp.currentSkin)
1882 sbhVisible = sbh.style.hidden ? true : false;
1884 sbvVisible = sbv.style.hidden ? true : false;
1886 // Do our resize here
1887 if(flag && (resizeH || resizeV) && fullThing)
1889 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, false);
1894 OnResize(clientSize.w, clientSize.h);
1900 sbh.visible = sbhVisible;
1902 sbv.visible = sbvVisible;
1904 scrollArea.w = Max(clientSize.w, reqScrollArea.w);
1905 scrollArea.h = Max(clientSize.h, reqScrollArea.h);
1908 sbh.pageStep = clientSize.w;
1910 sbv.pageStep = clientSize.h;
1912 // Notify doesn't handle setRange anymore... process it here
1915 int positionH = sbh.thumbPosition;
1916 if(scroll.x != positionH)
1918 OnHScroll(setRange, positionH, 0);
1922 SNAPDOWN(positionH, textCellW);
1923 scroll.x = positionH;
1929 int seen = clientSize.w, total = reqScrollArea.w;
1932 if(scrollFlags.snapX)
1933 SNAPDOWN(seen, sbStep.x);
1935 if(!total) total = seen;
1936 range = total - seen + 1;
1938 range = Max(range, 1);
1940 if(x >= range) x = range - 1;
1942 if(scrollFlags.snapX)
1943 SNAPUP(x, sbStep.x);
1947 OnHScroll(setRange, x, 0);
1952 SNAPDOWN(x, textCellW);
1958 int positionV = sbv.thumbPosition;
1959 if(scroll.y != positionV)
1961 OnVScroll(setRange, positionV, 0);
1965 SNAPDOWN(positionV, textCellH);
1966 scroll.y = positionV;
1972 int seen = clientSize.h, total = reqScrollArea.h;
1975 if(scrollFlags.snapY)
1976 SNAPDOWN(seen, sbStep.y);
1978 if(!total) total = seen;
1979 range = total - seen + 1;
1980 range = Max(range, 1);
1982 if(y >= range) y = range - 1;
1984 if(scrollFlags.snapY)
1985 SNAPUP(y, sbStep.y);
1989 OnVScroll(setRange, y, 0);
1994 SNAPDOWN(y, textCellH);
2000 if(scrolled || (resizeH || resizeV)) // This ensures children anchored to bottom/right gets repositioned correctly
2003 for(child = children.first; child; child = child.next)
2005 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2008 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
2009 child.Position(x, y, w, h, false, true, false, true, false, false);
2016 // Process Scrollbars
2018 if(sbh) // && !sbh.style.hidden
2020 sbh.Move(clientStart.x, clientStart.y + clientSize.h, clientSize.w,0);
2021 // Need to set the range again (should improve...) since the scrollbars didn't have
2022 // the right size when UpdateScrollArea set the range on it
2025 sbh.seen = clientSize.w;
2029 if(sbv) // && !sbv.state.hidden
2031 sbv.Move(clientStart.x + clientSize.w, clientStart.y, 0, clientSize.h);
2032 // Need to set the range again (should improve...) since the scrollbars didn't have
2033 // the right size when UpdateScrollArea set the range on it
2036 sbv.seen = clientSize.h;
2041 // TESTING THIS LOWER
2042 if(scrolled || (resizeH || resizeV)) // This ensures children anchored to bottom/right gets repositioned correctly
2045 for(child = children.first; child; child = child.next)
2047 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2050 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
2051 child.Position(x, y, w, h, false, true, false, true, false, false);
2057 bool MaximizeButtonClicked(Button button, int x, int y, Modifiers mods)
2059 SetState(maximized, false, mods);
2063 bool RestoreButtonClicked(Button button, int x, int y, Modifiers mods)
2065 SetState(normal, false, mods);
2069 bool MinimizeButtonClicked(Button button, int x, int y, Modifiers mods)
2071 SetState(minimized, false, mods);
2072 parent.CycleChildren(false, true, false, true);
2076 void ScrollBarNotification(ScrollBar control, ScrollBarAction action, int position, Key keyFlags)
2079 // Scroll bar notifications
2080 if(action != setRange)
2082 bool changed = false;
2086 if(scroll.x != position)
2088 OnHScroll(action, position, keyFlags);
2093 SNAPDOWN(position, textCellW);
2095 scroll.x = position;
2099 if(scroll.y != position)
2101 OnVScroll(action, position, keyFlags);
2106 SNAPDOWN(position, textCellH);
2108 scroll.y = position;
2112 bool childMove = false;
2113 for(child = children.first; child; child = child.next)
2115 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2118 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
2119 child.Position(x, y, w, h, false, true, false, true, false, false);
2123 // Testing this patch out to solve MDI workspace redraw bugs
2124 // We were already supposed to be updating parent's affected area in Position() but it doesn't seem to be working
2125 // Scroll offsets to blame?
2129 UpdateCaret(false, false);
2133 // Testing this patch out to solve MDI workspace redraw bugs
2134 for(child = children.first; child; child = child.next)
2136 if(!child.style.nonClient && child.state != maximized && (!child.style.dontScrollHorz || !child.style.dontScrollVert))
2145 void CreateSystemChildren(void)
2147 Window parent = this;
2148 bool scrollBarChanged = false;
2149 bool hasClose = false, hasMaxMin = false;
2150 Point scroll = this.scroll;
2152 if(state == maximized && this.parent.menuBar)
2154 if(this.parent.activeClient == this)
2155 parent = this.parent.menuBar;
2162 if(style.hasClose) hasClose = true;
2163 if(style.hasMaximize || style.hasMinimize)
2170 if(sysButtons[2] && (!hasClose || sysButtons[2].parent != parent))
2172 sysButtons[2].Destroy(0);
2173 sysButtons[2] = null;
2175 if(sysButtons[1] && (!hasMaxMin || sysButtons[1].parent != parent))
2177 sysButtons[1].Destroy(0);
2178 sysButtons[1] = null;
2180 if(sysButtons[0] && (!hasMaxMin || sysButtons[0].parent != parent))
2182 sysButtons[0].Destroy(0);
2183 sysButtons[0] = null;
2186 if(hasClose && parent)
2193 parent, master = this,
2194 inactive = true, nonClient = true, visible = false;
2196 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2202 if(this.parent == guiApp.desktop)
2203 sysButtons[2].hotKey = altF4;
2204 else if(style.isActiveClient)
2205 sysButtons[2].hotKey = ctrlF4;
2206 sysButtons[2].Create();
2209 sysButtons[2].symbol = 'X';
2210 sysButtons[2].disabled = !style.hasClose;
2213 if(hasMaxMin && parent)
2217 bool (* method)(Window window, Button button, int x, int y, Modifiers mods);
2218 if(state == maximized)
2221 method = RestoreButtonClicked;
2227 method = MaximizeButtonClicked;
2235 parent, master = this,
2236 hotKey = altEnter, inactive = true, nonClient = true, visible = false
2238 sysButtons[1].Create();
2240 sysButtons[1].NotifyClicked = method;
2242 sysButtons[1].symbol = symbol;
2243 sysButtons[1].disabled = !style.hasMaximize;
2246 if(hasMaxMin && parent)
2250 bool (* method)(Window window, Button button, int x, int y, Modifiers mods);
2251 if (state == minimized)
2254 method = RestoreButtonClicked;
2260 method = MinimizeButtonClicked;
2268 parent, master = this,
2269 hotKey = altM, inactive = true, nonClient = true, visible = false
2271 sysButtons[0].Create();
2273 sysButtons[0].NotifyClicked = method;
2275 sysButtons[0].symbol = symbol;
2276 sysButtons[0].disabled = !style.hasMinimize;
2279 // Create the scrollbars
2280 if(style.hasHorzScroll && !sbh)
2286 direction = horizontal,
2290 snap = scrollFlags.snapX,
2291 NotifyScrolling = ScrollBarNotification
2294 scrollBarChanged = true;
2296 else if(sbh && !style.hasHorzScroll)
2302 if(style.hasVertScroll && !sbv)
2308 direction = vertical,
2312 snap = scrollFlags.snapY,
2313 NotifyScrolling = ScrollBarNotification
2316 scrollBarChanged = true;
2318 else if(sbv && !style.hasVertScroll)
2323 if(scrollBarChanged)
2325 SetScrollLineStep(sbStep.x, sbStep.y);
2326 UpdateScrollBars(true, true);
2330 if(scrollBarChanged)
2332 if(sbh) sbh.thumbPosition = scroll.x;
2333 if(sbv) sbv.thumbPosition = scroll.y;
2337 void UpdateCaption(void)
2339 if(rootWindow == this)
2342 FigureCaption(caption);
2343 guiApp.interfaceDriver.SetRootWindowCaption(this, caption);
2345 UpdateDecorations();
2348 if(parent.rootWindow == parent && parent.activeClient == this) // Added this last check
2351 parent.FigureCaption(caption);
2352 guiApp.interfaceDriver.SetRootWindowCaption(parent, caption);
2354 parent.UpdateDecorations();
2358 void UpdateActiveDocument(Window previous)
2360 Window activeClient = this.activeClient;
2361 Window activeChild = this.activeChild;
2368 activeClient.CreateSystemChildren();
2370 previous.CreateSystemChildren();
2381 if(activeClient && activeClient.menu && activeClient.state != minimized)
2385 //activeClient.menu.Clean(activeClient);
2386 menu.Merge(activeClient.menu, true, activeClient);
2390 if(activeChild && activeChild != activeClient && activeChild.menu && activeChild.state != minimized)
2393 menu.Merge(activeChild.menu, true, activeChild);
2396 // Build window list
2399 Menu windowMenu = menu.FindMenu("Window");
2404 for(id = 0, cycle = activeClient.cycle; cycle && id<10;)
2407 Window document = cycle.data;
2408 if(!document.style.nonClient && document.style.isActiveClient && document.visible)
2410 char name[2048], caption[2048];
2411 document.FigureCaption(caption);
2412 sprintf(name, "%d %s", id+1, caption);
2413 windowMenu.AddDynamic(MenuItem
2415 copyText = true, text = name, hotKey = Key { k1 + id }, id = id++,
2416 NotifySelect = MenuWindowSelectWindow
2420 if(activeClient.cycle == cycle) break;
2425 if((!previous && activeClient) || !activeClient)
2431 item = menu.FindItem(MenuWindowCloseAll, 0);
2432 if(item) item.disabled = false;
2433 item = menu.FindItem(MenuWindowNext, 0);
2434 if(item) item.disabled = false;
2435 item = menu.FindItem(MenuWindowPrevious, 0);
2436 if(item) item.disabled = false;
2437 item = menu.FindItem(MenuWindowCascade, 0);
2438 if(item) item.disabled = false;
2439 item = menu.FindItem(MenuWindowTileHorz, 0);
2440 if(item) item.disabled = false;
2441 item = menu.FindItem(MenuWindowTileVert, 0);
2442 if(item) item.disabled = false;
2443 item = menu.FindItem(MenuWindowArrangeIcons, 0);
2444 if(item) item.disabled = false;
2445 item = menu.FindItem(MenuWindowWindows, 0);
2446 if(item) item.disabled = false;
2449 item = menu.FindItem(MenuFileClose, 0);
2450 if(item) item.disabled = !activeClient || !activeClient.style.hasClose;
2451 item = menu.FindItem(MenuFileSaveAll, 0);
2452 if(item) item.disabled = numDocuments < 1;
2454 // This is called again for a child window change, with same active client
2455 OnActivateClient(activeClient, previous);
2458 void _ShowDecorations(Box box, bool post)
2460 if(rootWindow == this && nativeDecorations) return;
2461 if(visible && this != guiApp.desktop)
2463 Surface surface = RedrawFull(box);
2467 FigureCaption(caption);
2470 ShowDecorations(captionFont.font,
2473 active, //parent.activeClient == this
2474 guiApp.windowMoving == this);
2476 PreShowDecorations(captionFont.font,
2479 active, //parent.activeClient == this
2480 guiApp.windowMoving == this);
2487 void UpdateExtent(Box refresh)
2489 Surface surface = null;
2491 if(!manageDisplay) { OnRedraw(null);return; }
2492 _ShowDecorations(refresh, false);
2494 surface = Redraw(refresh);
2495 // Opaque background: just fill before EW_REDRAW (clear?)
2498 surface.SetBackground(background);
2499 surface.SetForeground(foreground);
2500 surface.DrawingChar(' ');
2501 if(this == rootWindow)
2503 if(style.drawBehind || background.a)
2504 surface.Clear(colorBuffer);
2506 else if(background.a)
2510 background.color = { (byte)GetRandom(0,255), (byte)GetRandom(0,255), (byte)GetRandom(0,255) };
2511 surface.SetForeground((background.color.r > 128 || background.color.g > 128) ? black : white);
2514 if(display.flags.alpha && background.a < 255 && background)
2516 surface.Area(0,0,clientSize.w, clientSize.h);
2517 /*if(style.clearDepthBuffer)
2518 surface.Clear(depthBuffer);*/
2520 else if(/*style.clearDepthBuffer || */background.a)
2522 // surface.Clear((style.clearDepthBuffer ? depthBuffer : 0) | (background.a ? colorBuffer : 0));
2523 surface.Clear(colorBuffer);
2528 surface.TextFont(usedFont.font);
2529 surface.TextOpacity(false);
2533 // Draw the caret ...
2534 if(!disabled && this == guiApp.caretOwner && guiApp.caretEnabled /*&& !guiApp.interimWindow*/ && !guiApp.currentSkin.textMode)
2536 // surface.SetBackground(0xFFFFFF - background.color);
2537 surface.SetBackground(~background.color);
2539 caretPos.x - scroll.x + 1, caretPos.y - scroll.y,
2540 caretPos.x - scroll.x + 2, caretPos.y - scroll.y + caretSize - 1);
2546 void DrawOverChildren(Box refresh)
2548 Surface surface = Redraw(refresh);
2552 surface.DrawingChar(' ');
2553 surface.SetBackground(background);
2554 surface.SetForeground(foreground);
2556 surface.TextFont(usedFont.font);
2557 surface.TextOpacity(false);
2559 OnDrawOverChildren(surface);
2564 _ShowDecorations(refresh, true);
2567 void ComputeClipExtents(void)
2570 Extent clipExtent { /*first = -1, last = -1, free = -1*/ };
2572 clipExtent.Copy(this.clipExtent);
2574 for(child = children.last; child; child = child.prev)
2576 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2578 bool opaque = child.IsOpaque(); // TODO: acess background directly
2579 int dx = child.absPosition.x - absPosition.x, dy = child.absPosition.y - absPosition.y;
2581 child.clipExtent.Copy(clipExtent);
2582 child.clipExtent.Offset(-dx, -dy);
2583 child.clipExtent.IntersectBox(child.box);
2585 child.ComputeClipExtents();
2587 if(opaque && !child.style.nonClient)
2589 // Adjust the box for the parent:
2590 Box box { child.box.left + dx, child.box.top + dy, child.box.right + dx, child.box.bottom + dy };
2591 clipExtent.ExcludeBox(box, rootWindow.tempExtents[0]);
2596 // ??? Only do this for overlapped window or if parent has with clip children flag
2598 // Do this if window has clip children flag on (default false?)
2599 // this.clipExtent = clipExtent;
2601 clipExtent.Free(null);
2604 void ComputeRenderAreaNonOpaque(Extent dirtyExtent, Extent overDirtyExtent, Extent backBufferUpdate)
2606 bool opaque = IsOpaque();
2608 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2609 if(rootWindow.nativeDecorations)
2611 offsetX -= rootWindow.clientStart.x;
2612 offsetY -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
2616 for(child = children.last; child; child = child.prev)
2618 ColorAlpha background = *(ColorAlpha *)&child.background;
2619 bool opaque = child.IsOpaque();
2620 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2624 // Adjust renderArea to the root window level
2625 Extent * renderArea = &rootWindow.tempExtents[1];
2627 int offsetX = child.absPosition.x - rootWindow.absPosition.x, offsetY = child.absPosition.y - rootWindow.absPosition.y;
2628 if(child.rootWindow.nativeDecorations)
2630 offsetX -= child.rootWindow.clientStart.x;
2631 offsetY -= child.rootWindow.clientStart.y - (child.rootWindow.hasMenuBar ? skinMenuHeight : 0);
2635 Extent childRenderArea;
2637 if(backBufferUpdate != null)
2639 childRenderArea.Copy(backBufferUpdate);
2640 childRenderArea.Offset(-offsetX, -offsetY);
2643 childRenderArea.Copy(child.dirtyArea);
2645 // Add extent forced by transparency to the dirty area, adjusting dirty extent to the window
2646 renderArea.Copy(dirtyExtent);
2647 renderArea.Offset(-offsetX, -offsetY);
2648 childRenderArea.Union(renderArea);
2651 // Intersect with the clip extent
2652 childRenderArea.Intersection(child.clipExtent);
2655 renderArea->Copy(child.dirtyArea /*childRenderArea*/);
2656 renderArea->Offset(offsetX, offsetY);
2657 dirtyExtent.Union(renderArea, rootWindow.tempExtents[0]);
2658 // overDirtyExtent.Union(renderArea);
2659 renderArea->Empty();
2660 // childRenderArea.Free();
2662 //child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2667 for(child = children.last; child; child = child.prev)
2669 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2671 child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2676 void ComputeRenderArea(Extent dirtyExtent, Extent overDirtyExtent, Extent backBufferUpdate)
2678 bool opaque = IsOpaque();
2679 Extent * dirtyExtentWindow = &rootWindow.tempExtents[1];
2681 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2682 if(rootWindow.nativeDecorations)
2684 offsetX -= rootWindow.clientStart.x;
2685 offsetY -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
2689 for(child = children.last; child; child = child.prev)
2691 //child.ComputeRenderAreaNonOpaque(dirtyExtent, overDirtyExtent, backBufferUpdate);
2693 ColorAlpha background = *(ColorAlpha *)&child.background;
2694 bool opaque = child.IsOpaque();
2695 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2699 int offsetX = child.absPosition.x - rootWindow.absPosition.x, offsetY = child.absPosition.y - rootWindow.absPosition.y;
2700 // Adjust renderArea to the root window level
2702 renderArea.Copy(child.dirtyArea);
2703 renderArea.Offset(offsetX, offsetY);
2704 dirtyExtent.Union(renderArea);
2705 overDirtyExtent.Union(renderArea);
2711 for(child = children.last; child; child = child.prev)
2713 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow)
2715 child.ComputeRenderArea(dirtyExtent, overDirtyExtent, backBufferUpdate);
2719 if(backBufferUpdate != null)
2721 renderArea.Copy(backBufferUpdate);
2722 renderArea.Offset(-offsetX, -offsetY);
2724 overRenderArea.Copy(backBufferUpdate);
2725 overRenderArea.Offset(-offsetX, -offsetY);
2731 renderArea.Copy(dirtyArea);
2733 overRenderArea.Copy(dirtyArea);
2736 // Add extent forced by transparency to the dirty area, adjusting dirty extent to the window
2737 dirtyExtentWindow->Copy(dirtyExtent);
2738 dirtyExtentWindow->Offset(-offsetX, -offsetY);
2739 renderArea.Union(dirtyExtentWindow, rootWindow.tempExtents[0]);
2740 dirtyExtentWindow->Empty();
2742 // Intersect with the clip extent
2743 renderArea.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2746 if(renderArea.count > 10)
2749 printf("\nToo many extents (%d):\n", renderArea.count);
2751 //extent.UnionBox({ 112, 6, 304, 7 }, rootWindow.tempExtents[0]);
2752 //extent.UnionBox({ 112, 8, 304, 17 }, rootWindow.tempExtents[0]);
2757 for(c = 0; c<10; c++)
2760 FASTLIST_LOOP(renderArea, extentBox)
2762 extent.UnionBox(extentBox.box, rootWindow.tempExtents[0]);
2764 renderArea.Copy(extent);
2766 FASTLIST_LOOP(renderArea, extentBox)
2769 printf("(%d, %d) - (%d, %d)\n",
2770 extentBox.box.left, extentBox.box.top,
2771 extentBox.box.right, extentBox.box.bottom);
2775 printf("\nNow %d\n", renderArea.count);
2781 // WHY WAS THIS COMMENTED ??
2783 // Add extent forced by DrawOverChildren to the dirty area, adjusting dirty extent to the window
2784 dirtyExtentWindow->Copy(overDirtyExtent);
2785 dirtyExtentWindow->Offset(-offsetX, -offsetY);
2786 overRenderArea.Union(dirtyExtentWindow, rootWindow.tempExtents[0]);
2787 dirtyExtentWindow->Empty();
2789 // Intersect with the clip extent
2790 overRenderArea.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2796 if(scrollExtent.count)
2798 // Subtract render extent from scrolling extent
2799 scrollExtent.Exclusion(renderArea, rootWindow.tempExtents[0]);
2801 if(backBufferUpdate == null)
2803 Extent * dirty = &rootWindow.tempExtents[3];
2806 // Intersect scrolling extent with clip extent
2807 scrollExtent.Intersection(clipExtent, rootWindow.tempExtents[0], rootWindow.tempExtents[1], rootWindow.tempExtents[2]);
2809 // offset this scroll to be at the root window level
2810 scrollExtent.Offset(offsetX, offsetY);
2811 // Add area that was scrolled to the dirty extents of the back buffer
2812 rootWindow.dirtyBack.Union(scrollExtent, rootWindow.tempExtents[0]);
2816 // Will need scrolledArea.x & scrolledArea.y to support multiple scrolls
2817 for(scrollBox = (BoxItem)scrollExtent.first; scrollBox; scrollBox = (BoxItem)scrollBox.next)
2818 display.Scroll(scrollBox.box, scrolledArea.x, scrolledArea.y, dirty);
2823 scrollExtent.Empty();
2825 // Add the exposed extent to the window render area
2826 dirty->Offset(-offsetX, -offsetY);
2827 renderArea.Union(dirty, rootWindow.tempExtents[0]);
2832 // Subtract the window's box from the transparency forced extent
2833 dirtyExtent.ExcludeBox({box.left + offsetX, box.top + offsetY, box.right + offsetX, box.bottom + offsetY }, rootWindow.tempExtents[0]);
2839 renderArea.Copy(this.renderArea);
2840 renderArea.Offset(offsetX, offsetY);
2841 dirtyExtent.Union(renderArea);
2847 Extent renderArea { };
2849 renderArea.Copy(overRenderArea);
2850 renderArea.Offset(offsetX, offsetY);
2851 overDirtyExtent.Union(renderArea, rootWindow.tempExtents[0]);
2856 if(backBufferUpdate != null)
2858 // Remove render area from dirty area
2859 dirtyArea.Exclusion(renderArea, rootWindow.tempExtents[0]);
2861 dirtyArea.Exclusion(overRenderArea, rootWindow.tempExtents[0]);
2868 // Remove the window render area from the dirty extents of the back buffer
2869 rootWindow.dirtyBack.Exclusion(renderArea);
2873 void Render(Extent updateExtent)
2877 Window rootWindow = this.rootWindow;
2878 int offsetX = absPosition.x - rootWindow.absPosition.x, offsetY = absPosition.y - rootWindow.absPosition.y;
2879 if(rootWindow.nativeDecorations)
2881 offsetX -= rootWindow.clientStart.x;
2882 offsetY -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
2885 if(rootWindow.fullRender)
2894 background = Color { (byte)GetRandom(0,255), (byte)GetRandom(0,255), (byte)GetRandom(0,255) };
2895 foreground = (background.color.r > 128 || background.color.g > 128) ? black : white;
2900 /*if(renderArea.count)
2901 printf("\n\nRendering %s (%x):\n------------------------------------------\n", _class.name, this);*/
2904 for(extentBox = (BoxItem)renderArea.first; extentBox; extentBox = (BoxItem)extentBox.next)
2906 Box box = extentBox.box;
2909 /*printf("(%d, %d) - (%d, %d)\n",
2910 extentBox.box.left, extentBox.box.top,
2911 extentBox.box.right, extentBox.box.bottom);*/
2916 box.left += offsetX;
2918 box.right += offsetX;
2919 box.bottom += offsetY;
2921 if(updateExtent != null)
2922 updateExtent.UnionBox(box, rootWindow.tempExtents[0]);
2926 for(child = children.first; child; child = child.next)
2927 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow && !child.nonClient)
2928 child.Render(updateExtent);
2930 if(rootWindow.fullRender)
2931 DrawOverChildren(box);
2934 // TO DO: There's an issue about draw over children...
2935 // TO DO: Don't wanna go through this if method isn't used
2936 for(extentBox = (BoxItem)overRenderArea.first; extentBox; extentBox = (BoxItem)extentBox.next)
2937 //FASTLIST_LOOP(/*renderArea */overRenderArea, extentBox)
2939 Box box = extentBox.box;
2941 DrawOverChildren(box);
2943 box.left += offsetX;
2945 box.right += offsetX;
2946 box.bottom += offsetY;
2948 if(updateExtent != null)
2949 updateExtent.UnionBox(box, rootWindow.tempExtents[0]);
2952 for(child = children.first; child; child = child.next)
2953 if(!child.style.hidden && child.created && !child.is3D && child.rootWindow && child.nonClient)
2954 child.Render(updateExtent);
2957 overRenderArea.Empty();
2960 public void UpdateDisplay(void)
2962 if(!manageDisplay) { OnRedraw(null);return; }
2963 if(rootWindow && this != rootWindow)
2964 rootWindow.UpdateDisplay();
2967 Extent dirtyExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that needs to be forced due to transparency
2968 Extent overExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that forced for DrawOverChildren
2971 dirtyExtent.Clear();
2974 clipExtent.AddBox(box);
2976 display.StartUpdate();
2978 if(!rootWindow.fullRender)
2980 ComputeClipExtents();
2981 ComputeRenderAreaNonOpaque(dirtyExtent, overExtent, null);
2982 ComputeRenderArea(dirtyExtent, overExtent, null);
2985 clipExtent.Free(null);
2987 dirtyExtent.Free(null);
2988 overExtent.Free(null);
2990 if(display.flags.flipping)
2993 display.Update(null);
2997 Extent updateExtent { /*first = -1, last = -1, free = -1*/ }; // Extent that needs to be updated
2998 updateExtent.Clear();
3000 Render(updateExtent);
3002 updateExtent.UnionBox(this.box, tempExtents[0]);
3005 //printf("\n\nUpdate:\n------------------------------------------\n");
3008 //FASTLIST_LOOP(updateExtent, extentBox)
3009 for(extentBox = (BoxItem)updateExtent.first; extentBox; extentBox = (BoxItem)extentBox.next)
3012 /*printf("Updating (%d, %d) - (%d, %d)\n",
3013 extentBox.box.left, extentBox.box.top,
3014 extentBox.box.right, extentBox.box.bottom);*/
3017 display.Update(extentBox.box);
3020 updateExtent.Free(null);
3023 display.EndUpdate();
3031 void UpdateBackDisplay(Box box)
3037 Extent intersection { /*first = -1, last = -1, free = -1*/ };
3039 //printf("UpdateBackDisplay going through!\n");
3040 display.StartUpdate();
3044 intersection.Copy(dirtyBack);
3045 intersection.IntersectBox(box);
3047 dirtyExtent.Clear();
3050 clipExtent.AddBox(box);
3052 if(!rootWindow.fullRender)
3054 ComputeClipExtents();
3055 ComputeRenderArea(dirtyExtent, overExtent, intersection);
3058 clipExtent.Free(null);
3060 intersection.Free(null);
3061 dirtyExtent.Free(null);
3062 overExtent.Free(null);
3067 if(display.flags.flipping)
3068 display.Update(null);
3071 rootWindow.display.Update(box);
3074 display.EndUpdate();
3078 dirtyBack.ExcludeBox(box, rootWindow.tempExtents[0]);
3079 if(dirtyBack.count > MAX_DIRTY_BACK)
3081 BoxItem extentBox, next;
3082 BoxItem first = (BoxItem)ACCESS_ITEM(dirtyBack, dirtyBack.first);
3083 for(extentBox = (BoxItem)dirtyBack.first; extentBox; extentBox = next)
3085 next = (BoxItem)extentBox.next;
3086 if(extentBox != first)
3088 if(extentBox.box.left < first.box.left)
3089 first.box.left = extentBox.box.left;
3090 if(extentBox.box.top < first.box.top)
3091 first.box.top = extentBox.box.top;
3092 if(extentBox.box.right > first.box.right)
3093 first.box.right = extentBox.box.right;
3094 if(extentBox.box.bottom > first.box.bottom)
3095 first.box.bottom = extentBox.box.bottom;
3096 dirtyBack.Delete(extentBox);
3105 // --- Window positioning ---
3106 // --- Window identification ---
3108 // Returns window at position "Position"
3109 Window GetAtPosition(int x, int y, bool clickThru, bool acceptDisabled, Window last)
3111 Window child, result = null;
3113 box.left += absPosition.x;
3114 box.right += absPosition.x;
3115 box.top += absPosition.y;
3116 box.bottom += absPosition.y;
3118 if(!destroyed && visible && (acceptDisabled || !disabled))
3120 int lx = x - absPosition.x;
3121 int ly = y - absPosition.y;
3122 if(IsInside(lx, ly))
3123 // if(box.IsPointInside(Point{x, y}))
3125 if(!clickThru || !style.clickThrough) result = (this == last) ? null : this;
3126 // If the window is disabled, stop looking in children (for acceptDisabled mode)
3129 for(child = (last && last.parent == this) ? last.previous : children.last; child; child = child.prev)
3131 if(child != statusBar && child.rootWindow == rootWindow)
3133 Window childResult = child.GetAtPosition(x, y, clickThru, acceptDisabled, last);
3140 for(child = (last && last.parent == this) ? last.previous : children.last; child; child = child.prev)
3142 if(child != statusBar && child.rootWindow == rootWindow)
3144 Window childResult = child.GetAtPosition(x, y, false, acceptDisabled, last);
3156 Window FindModal(void)
3158 Window modalWindow = this, check;
3159 Window check2 = null;
3160 for(check = this; check.master; check = check.master)
3162 if(check.master.modalSlave && check.master.modalSlave.created && check != check.master.modalSlave)
3164 modalWindow = check.master.modalSlave;
3165 check = modalWindow;
3167 // TESTING THIS FOR DROPBOX...
3168 if(!rootWindow || !rootWindow.style.interim)
3170 for(check2 = check; check2.activeChild; check2 = check2.activeChild)
3172 if(check2.modalSlave && check2.modalSlave.created)
3174 modalWindow = check2.modalSlave;
3182 if(modalWindow == this)
3184 for(check = this; check.activeChild; check = check.activeChild)
3186 if(check.modalSlave)
3188 modalWindow = check.modalSlave;
3194 for(; modalWindow.modalSlave && modalWindow.modalSlave.created; modalWindow = modalWindow.modalSlave);
3195 return (modalWindow == this || this == guiApp.interimWindow || IsDescendantOf(modalWindow)) ? null : modalWindow;
3198 void StopMoving(void)
3200 if(this == guiApp.windowMoving)
3202 guiApp.windowMoving = null;
3203 UpdateDecorations();
3204 SetMouseRange(null);
3207 if(rootWindow.active)
3208 guiApp.interfaceDriver.StopMoving(rootWindow);
3211 guiApp.resizeX = guiApp.resizeY = guiApp.resizeEndX = guiApp.resizeEndY = false;
3212 guiApp.windowIsResizing = false;
3216 void SelectMouseCursor(void)
3221 Window cursorWindow = null;
3222 bool rx, ry, rex, rey;
3224 guiApp.desktop.GetMousePosition(&x, &y);
3225 mouseWindow = rootWindow ? rootWindow.GetAtPosition(x,y, true, false, null) : null;
3227 if((guiApp.windowMoving && !guiApp.windowIsResizing) || guiApp.windowScrolling)
3228 guiApp.SetCurrentCursor(guiApp.systemCursors[moving]);
3229 else if(mouseWindow)
3231 modalWindow = mouseWindow.FindModal();
3232 x -= mouseWindow.absPosition.x;
3233 y -= mouseWindow.absPosition.y;
3234 if(guiApp.windowIsResizing)
3236 rex = guiApp.resizeEndX;
3237 rey = guiApp.resizeEndY;
3238 rx = guiApp.resizeX;
3239 ry = guiApp.resizeY;
3240 if((rex && rey) || (rx && ry))
3241 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNWSE]);
3242 else if((rex && ry) || (rx && rey))
3243 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNESW]);
3244 else if((ry || rey) && (!rx && !rex))
3245 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNS]);
3246 else if((rx || rex) && (!ry && !rey))
3247 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeWE]);
3249 else if(!modalWindow && !guiApp.windowCaptured &&
3250 mouseWindow.IsMouseResizing(x, y, mouseWindow.size.w, mouseWindow.size.h,
3251 &rx, &ry, &rex, &rey))
3253 if((rex && rey) || (rx && ry))
3254 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNWSE]);
3255 else if((rex && ry) || (rx && rey))
3256 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNESW]);
3257 else if((ry || rey) && (!rx && !rex))
3258 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeNS]);
3259 else if((rx || rex) && (!ry && !rey))
3260 guiApp.SetCurrentCursor(guiApp.systemCursors[sizeWE]);
3262 else if(!guiApp.windowCaptured && !modalWindow && !guiApp.interimWindow)
3264 if(!mouseWindow.clientArea.IsPointInside({x - mouseWindow.clientStart.x, y - mouseWindow.clientStart.y}))
3265 cursorWindow = mouseWindow.parent;
3267 cursorWindow = mouseWindow;
3269 else if(!guiApp.interimWindow)
3270 cursorWindow = guiApp.windowCaptured;
3273 for(; !cursorWindow.cursor && !cursorWindow.style.nonClient; cursorWindow = cursorWindow.parent);
3274 guiApp.SetCurrentCursor(cursorWindow.cursor ? cursorWindow.cursor : guiApp.systemCursors[arrow]);
3276 else if(modalWindow)
3278 guiApp.SetCurrentCursor(guiApp.systemCursors[arrow]);
3280 else if(guiApp.interimWindow)
3282 if(guiApp.interimWindow.cursor)
3283 guiApp.SetCurrentCursor(guiApp.interimWindow.cursor);
3285 guiApp.SetCurrentCursor(mouseWindow.cursor ? mouseWindow.cursor : guiApp.systemCursors[arrow]);
3290 // --- State based input ---
3291 bool AcquireInputEx(bool state)
3296 guiApp.interfaceDriver.GetMousePosition(&guiApp.acquiredMouseX, &guiApp.acquiredMouseY);
3297 guiApp.interfaceDriver.SetMousePosition(clientSize.w/2 + absPosition.x, clientSize.h/2 + absPosition.y);
3299 result = guiApp.interfaceDriver.AcquireInput(rootWindow, state);
3301 guiApp.acquiredWindow = state ? this : null;
3304 SetMouseRangeToClient();
3305 guiApp.interfaceDriver.SetMouseCursor((SystemCursor)-1);
3310 SelectMouseCursor();
3312 if(!state) guiApp.interfaceDriver.SetMousePosition(guiApp.acquiredMouseX, guiApp.acquiredMouseY);
3316 // --- Window activation ---
3317 bool PropagateActive(bool active, Window previous, bool * goOnWithActivation, bool direct)
3320 if(!parent || !parent.style.inactive)
3322 Window parent = this.parent;
3325 if(rootWindow == this)
3326 Log(active ? "active\n" : "inactive\n");
3329 // Testing this here...
3330 if(!parent || parent == guiApp.desktop || parent.active)
3332 this.active = active;
3335 // TESTING THIS HERE
3336 UpdateDecorations();
3337 if(result = OnActivate(active, previous, goOnWithActivation, direct) && *goOnWithActivation && master)
3338 result = NotifyActivate(master, this, active, previous);
3341 this.active = !active;
3346 if(!parent || parent == guiApp.desktop || parent.active)
3348 this.active = active;
3350 AcquireInputEx(active);
3355 if(guiApp.caretOwner)
3359 guiApp.caretOwner.caretPos.x - guiApp.caretOwner.scroll.x + 1,
3360 guiApp.caretOwner.caretPos.y - guiApp.caretOwner.scroll.y + 1,
3361 guiApp.caretOwner.caretPos.x - guiApp.caretOwner.scroll.x + 2,
3362 guiApp.caretOwner.caretPos.y - guiApp.caretOwner.scroll.y + guiApp.caretOwner.caretSize - 1
3364 guiApp.caretOwner.Update(extent);
3367 if(visible || !guiApp.caretOwner)
3368 guiApp.caretOwner = this;
3369 UpdateCaret(false, false);
3375 this.active = false;
3377 AcquireInputEx(active);
3379 if(!active && guiApp.caretOwner == this)
3381 UpdateCaret(false, true);
3382 guiApp.caretOwner = null;
3383 guiApp.interfaceDriver.SetCaret(0,0,0);
3384 guiApp.caretEnabled = false;
3389 if(!active && parent && parent.activeChild && parent.activeChild != this)
3390 if(!parent.activeChild.PropagateActive(false, previous, goOnWithActivation, true) || !*goOnWithActivation)
3396 if(!active && menuBar)
3399 menuBar.OnActivate(false, null, &goOn, true);
3400 menuBar.NotifyActivate(menuBar.master, menuBar, false, null);
3404 if(!activeChild.PropagateActive(active, previous, goOnWithActivation, false) || !*goOnWithActivation)
3413 void ConsequentialMouseMove(bool kbMoving)
3417 if(kbMoving || !guiApp.windowMoving)
3421 if(rootWindow == guiApp.desktop || rootWindow.parent == guiApp.desktop)
3423 guiApp.interfaceDriver.GetMousePosition(&x, &y);
3425 if(guiApp.windowMoving || rootWindow.GetAtPosition(x, y, true, false, null))
3426 rootWindow.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &mods, true, false);
3432 bool IsDescendantOf(Window ancestor)
3435 for(window = this; window && window != ancestor; window = window.parent);
3436 return window == ancestor;
3439 bool IsSlaveOf(Window master)
3442 for(window = this; window && window != master; window = window.master);
3443 return window == master;
3446 bool ActivateEx(bool active, bool activateParent, bool moveInactive, bool activateRoot, Window external, Window externalSwap)
3450 if(this && !destroyed /*&& state != Hidden*/)
3452 Window swap = externalSwap;
3460 if(activateParent &&
3461 (parent.activeChild != this ||
3462 (guiApp.interimWindow && !IsDescendantOf(guiApp.interimWindow))) &&
3463 active && _isModal &&
3464 parent != master && master)
3465 master.ActivateEx(true, true, false, activateRoot, external, externalSwap);
3471 bool real = parent.activeChild != this;
3473 // TEST THIS: New activateParent check here!!! CAUSED MENUS NOT GOING AWAY
3474 if(/*activateParent && */guiApp.interimWindow &&
3475 !IsDescendantOf(guiApp.interimWindow) &&
3476 !IsSlaveOf(guiApp.interimWindow))
3478 Window interimWindow = guiApp.interimWindow;
3479 while(interimWindow && interimWindow != this)
3481 Window master = interimWindow.master;
3483 guiApp.interimWindow = null;
3484 if(guiApp.caretOwner)
3485 guiApp.caretOwner.UpdateCaret(false, false);
3487 incref interimWindow;
3488 if(!interimWindow.PropagateActive(false, this, &goOn, true))
3493 delete interimWindow;
3494 interimWindow = (master && master.style.interim) ? master : null;
3499 guiApp.interimWindow = this;
3500 /*guiApp.interfaceDriver.SetCaret(0,0,0);
3501 guiApp.caretEnabled = false;*/
3502 UpdateCaret(false, true);
3507 bool acquireInput = false;
3509 parent.activeChild &&
3510 parent.activeChild.state == maximized &&
3511 parent != guiApp.desktop;
3513 if(!style.inactive) // (!style.isRemote || parent.active || parent.style.hidden))
3518 swap = parent.activeChild;
3519 if(swap && swap.destroyed) swap = null;
3520 if(swap && swap != this)
3523 if(!swap.PropagateActive(false, this, &goOn, true))
3524 swap = parent.activeChild;
3535 if(!parent || parent.activeChild != this || style.interim)
3538 result = PropagateActive(true, swap, &goOn, true);
3539 if(!result && !goOn)
3544 acquireInput = true;
3548 if(style.hasMaximize && parent != guiApp.desktop)
3551 SetState(maximized, false, 0);
3552 else if(state != maximized)
3555 for(child = parent.children.first; child; child = child.next)
3557 if(this != child && child.state == maximized)
3558 child.SetState(normal, false, 0);
3565 if(!style.inactive && !style.interim /*&& (!style.isRemote || parent.active || parent.style.hidden)*/)
3567 Window previous = parent.activeClient;
3568 parent.activeChild = this;
3569 if(!style.nonClient /*&& style.isActiveClient*/)
3571 if(style.isActiveClient && !style.hidden)
3572 parent.activeClient = this;
3573 parent.UpdateActiveDocument(previous);
3578 //if(!style.isRemote)
3580 if(rootWindow != this)
3582 if(activateParent && parent && !parent.active /*parent != parent.parent.activeChild*/)
3583 parent.ActivateEx(true, true, moveInactive, activateRoot, external, externalSwap);
3585 else if(!guiApp.fullScreenMode)
3587 Window modalRoot = FindModal();
3588 if(!modalRoot) modalRoot = this;
3589 if(!modalRoot.isForegroundWindow)
3591 modalRoot.isForegroundWindow = true;
3592 // To check : Why is parent null?
3593 if(activateRoot && modalRoot.parent && !modalRoot.parent.display && external != modalRoot)
3595 guiApp.interfaceDriver.ActivateRootWindow(modalRoot);
3597 modalRoot.isForegroundWindow = false;
3602 if(result && real && (!style.inactive || moveInactive) && parent)
3604 Window last = parent.children.last;
3606 if(!style.stayOnTop)
3607 for(; last && last.style.stayOnTop; last = last.prev);
3609 parent.children.Move(this, last);
3611 // Definitely don't want that: why not?
3615 parent.childrenOrder.Move(order, parent.childrenOrder.last);
3621 if(!parent || style.interim || (parent.activeChild == this && !style.inactive))
3628 parent.activeChild = null;
3629 if(!style.nonClient /*&& style.isActiveClient*/)
3631 Window previous = parent.activeClient;
3632 if(style.isActiveClient)
3633 parent.activeClient = null;
3634 parent.UpdateActiveDocument(previous);
3638 if(this == guiApp.interimWindow)
3640 guiApp.interimWindow = null;
3641 if(guiApp.caretOwner)
3642 guiApp.caretOwner.UpdateCaret(false, false);
3644 if(!PropagateActive(false, externalSwap, &goOn, true) || !goOn)
3651 if(!active || !swap)
3652 UpdateDecorations();
3654 swap.UpdateDecorations();
3656 if(active && rootWindow != this)
3657 ConsequentialMouseMove(false);
3664 // --- Input Messages ---
3665 void ::UpdateMouseMove(int mouseX, int mouseY, bool consequential)
3667 static bool reEntrancy = false;
3668 if(reEntrancy) return;
3672 guiApp.cursorUpdate = true;
3673 if(guiApp.windowScrolling && !consequential)
3675 guiApp.windowScrolling.SetScrollPosition(
3676 (guiApp.windowScrolling.sbh) ?
3677 (guiApp.windowScrollingBefore.x - mouseX + guiApp.windowScrollingStart.x) : 0,
3678 (guiApp.windowScrolling.sbv) ?
3679 (guiApp.windowScrollingBefore.y - mouseY + guiApp.windowScrollingStart.y) : 0);
3681 if(guiApp.windowMoving)
3683 if(mouseX != guiApp.movingLast.x || mouseY != guiApp.movingLast.y)
3685 Window window = guiApp.windowMoving;
3687 int w = window.size.w;
3688 int h = window.size.h;
3693 rx = mouseX - guiApp.windowMovingStart.x;
3694 ry = mouseY - guiApp.windowMovingStart.y;
3697 window.GetDecorationsSize(&ew, &eh);
3699 if(guiApp.windowIsResizing)
3701 x = window.scrolledPos.x;
3702 y = window.scrolledPos.y;
3706 aw = Max(guiApp.windowResizingBefore.w - rx,window.skinMinSize.w);
3707 rx = guiApp.windowResizingBefore.w - aw;
3708 rx = Min(guiApp.windowMovingBefore.x + rx, window.parent.clientSize.w-1) - guiApp.windowMovingBefore.x;
3709 w = guiApp.windowResizingBefore.w - rx;
3713 ah = Max(guiApp.windowResizingBefore.h - ry,window.skinMinSize.h);
3714 ry = guiApp.windowResizingBefore.h - ah;
3715 ry = Min(guiApp.windowMovingBefore.y + ry, window.parent.clientSize.h-1) - guiApp.windowMovingBefore.y;
3716 ry = Max(ry, -guiApp.windowMovingBefore.y);
3717 h = guiApp.windowResizingBefore.h - ry;
3719 if(guiApp.resizeEndX)
3721 w = guiApp.windowResizingBefore.w + rx;
3724 if(guiApp.resizeEndY) h = guiApp.windowResizingBefore.h + ry;
3732 w = Max(w, window.minSize.w);
3733 h = Max(h, window.minSize.h);
3734 w = Min(w, window.maxSize.w);
3735 h = Min(h, window.maxSize.h);
3737 if(!window.OnResizing(&w, &h))
3739 w = window.clientSize.w;
3740 h = window.clientSize.h;
3743 w = Max(w, window.skinMinSize.w);
3744 h = Max(h, window.skinMinSize.h);
3751 SNAPDOWN(w, textCellW);
3752 SNAPDOWN(h, textCellH);
3757 aw = Max(w,window.skinMinSize.w);
3758 rx = guiApp.windowResizingBefore.w - aw;
3759 rx = Min(guiApp.windowMovingBefore.x + rx, window.parent.clientSize.w-1) - guiApp.windowMovingBefore.x;
3760 w = guiApp.windowResizingBefore.w - rx;
3764 ah = Max(h,window.skinMinSize.h);
3765 ry = guiApp.windowResizingBefore.h - ah;
3766 ry = Min(guiApp.windowMovingBefore.y + ry, window.parent.clientSize.h-1) - guiApp.windowMovingBefore.y;
3767 ry = Max(ry, -guiApp.windowMovingBefore.y);
3768 h = guiApp.windowResizingBefore.h - ry;
3773 if(!guiApp.windowIsResizing || guiApp.resizeX)
3774 x = guiApp.windowMovingBefore.x + rx;
3775 if(!guiApp.windowIsResizing || guiApp.resizeY)
3776 y = guiApp.windowMovingBefore.y + ry;
3778 if(!guiApp.windowIsResizing)
3781 if(window.parent == guiApp.desktop && guiApp.virtualScreen.w)
3783 x = Min(x, (guiApp.virtualScreen.w + guiApp.virtualScreenPos.x) -1);
3784 y = Min(y, (guiApp.virtualScreen.h + guiApp.virtualScreenPos.y) -1);
3785 x = Max(x,-(w-1) + guiApp.virtualScreenPos.x);
3786 y = Max(y,-(h-1) + guiApp.virtualScreenPos.y);
3790 x = Min(x, (window.parent.reqScrollArea.w ? window.parent.reqScrollArea.w : window.parent.clientSize.w) -1);
3791 y = Min(y, (window.parent.reqScrollArea.h ? window.parent.reqScrollArea.h : window.parent.clientSize.h) -1);
3797 if(!guiApp.windowIsResizing || (guiApp.resizeX || guiApp.resizeY))
3799 if(!window.OnMoving(&x, &y, w, h))
3801 x = window.scrolledPos.x;
3802 y = window.scrolledPos.y;
3808 SNAPDOWN(x, textCellW);
3809 SNAPDOWN(y, textCellH);
3812 if(!window.style.nonClient)
3814 if(!window.style.fixed /*|| window.style.isDocument*/)
3816 if(!window.style.dontScrollHorz)
3817 x += window.parent.scroll.x;
3818 if(!window.style.dontScrollVert)
3819 y += window.parent.scroll.y;
3823 // Break the anchors for moveable/resizable windows
3824 // Will probably cause problem with IDE windows... Will probably need a way to specify if anchors should break
3825 if(window.style.fixed)
3827 if(window.state == normal)
3829 window.normalAnchor = Anchor { left = x, top = y };
3830 window.normalSizeAnchor = SizeAnchor { { w, h } };
3831 window.anchored = false;
3835 window.stateAnchor = Anchor { left = x, top = y };
3836 window.stateSizeAnchor = SizeAnchor { { w, h } };
3838 window.Position(x, y, w, h, false, true, guiApp.windowIsResizing, guiApp.windowIsResizing, false, true);
3839 // TOCHECK: Investigate why the following only redraws the scrollbars
3840 //window.Position(x, y, w, h, false, true, true, true, false, true);
3842 guiApp.movingLast.x = mouseX;
3843 guiApp.movingLast.y = mouseY;
3849 public bool MouseMessage(uint method, int x, int y, Modifiers * mods, bool consequential, bool activate)
3852 bool wasMoving = guiApp.windowMoving ? true : false;
3853 bool wasScrolling = guiApp.windowScrolling ? true : false;
3855 while(result && w != this)
3857 Window msgWindow = GetAtPosition(x,y, false, true, w);
3858 Window trueWindow = GetAtPosition(x,y, false, false, w);
3859 bool windowDragged = false;
3864 window = (w && !w.disabled) ? w : null;
3866 if(trueWindow) incref trueWindow;
3868 if(consequential) mods->isSideEffect = true;
3870 UpdateMouseMove(x, y, consequential);
3872 if(guiApp.windowCaptured && (guiApp.windowCaptured.rootWindow == this))
3874 if(!guiApp.windowCaptured.isEnabled)
3875 guiApp.windowCaptured.ReleaseCapture();
3877 window = guiApp.windowCaptured;
3880 if(trueWindow && activate &&
3881 (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown ||
3882 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown ||
3883 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown ||
3884 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick))
3886 if(mods->alt && !mods->ctrl && !mods->shift)
3888 Window moved = trueWindow;
3889 for(moved = trueWindow; moved; moved = moved.parent)
3890 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown || ((moved.style.fixed || moved.moveable) && moved.state != maximized))
3895 windowDragged = true;
3897 // Cancel the ALT menu toggling...
3898 window.rootWindow.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown, 0, 0);
3903 if(window && activate &&
3904 (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown ||
3905 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown ||
3906 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown ||
3907 method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick))
3909 Window modalWindow = window.FindModal();
3911 /*if(mods->alt && !mods->shift && !mods->ctrl)
3913 Window moved = window;
3914 for(moved = window; moved; moved = moved.parent)
3915 if(method == OnRightButtonDown || ((moved.style.fixed || moved.moveable) && moved.state != maximized))
3920 windowDragged = true;
3922 // Cancel the ALT menu toggling...
3923 window.rootWindow.KeyMessage(OnKeyDown, 0, 0);
3929 Window activateWindow = modalWindow ? modalWindow : window;
3930 if(activateWindow && !activateWindow.isRemote)
3932 bool doActivation = true;
3933 //bool needToDoActivation = false;
3934 Window check = activateWindow;
3936 for(check = activateWindow; check && check != guiApp.desktop; check = check.parent)
3938 if(!check.style.inactive)
3940 //needToDoActivation = true;
3942 doActivation = false;
3947 if(!needToDoActivation)
3948 doActivation = false;
3951 if((doActivation && (activateWindow.parent != guiApp.desktop || guiApp.fullScreen)) ||
3952 (guiApp.interimWindow && !window.IsDescendantOf(guiApp.interimWindow)))
3954 // Let the OnLeftButtonDown do the activating instead
3955 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick)
3963 incref activateWindow;
3964 if(!activateWindow.ActivateEx(true, true, false, true, null, null))
3966 delete activateWindow;
3970 if(activateWindow._refCount == 1)
3972 delete activateWindow;
3976 delete activateWindow;
3978 mods->isActivate = true;
3982 if(!modalWindow && window && !window.destroyed)
3984 if(!guiApp.windowCaptured || windowDragged)
3986 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown)
3988 bool moving = ((window.state != maximized &&
3989 window.IsMouseMoving(
3990 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h)))
3991 || (guiApp.windowMoving && !guiApp.windowIsResizing);
3993 if(!moving && window.IsMouseResizing(
3994 x - window.absPosition.x,
3995 y - window.absPosition.y,
3996 window.size.w, window.size.h,
3997 &guiApp.resizeX, &guiApp.resizeY, &guiApp.resizeEndX, &guiApp.resizeEndY))
3999 guiApp.windowIsResizing = true;
4000 guiApp.windowResizingBefore.w = window.size.w;
4001 guiApp.windowResizingBefore.h = window.size.h;
4003 if(guiApp.windowIsResizing || windowDragged || moving)
4006 guiApp.windowMoving = window;
4007 guiApp.windowMovingStart.x = guiApp.movingLast.x = x;
4008 guiApp.windowMovingStart.y = guiApp.movingLast.y = y;
4009 guiApp.windowMovingBefore.x = window.position.x;//s;
4010 guiApp.windowMovingBefore.y = window.position.y;//s;
4011 if(guiApp.windowMoving == guiApp.windowMoving.rootWindow)
4012 guiApp.interfaceDriver.StartMoving(guiApp.windowMoving.rootWindow, 0,0,false);
4015 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown)
4017 if(window.style.fixed &&
4019 window.IsMouseMoving(
4020 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h)))
4022 window.ShowSysMenu(x, y);
4026 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown)
4028 if(window.sbv || window.sbh)
4031 guiApp.windowScrolling = window;
4032 guiApp.windowScrollingStart.x = x;
4033 guiApp.windowScrollingStart.y = y;
4034 guiApp.windowScrollingBefore.x = window.scroll.x;
4035 guiApp.windowScrollingBefore.y = window.scroll.y;
4038 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick)
4040 if(window.style.hasMaximize &&
4041 window.IsMouseMoving(
4042 x - window.absPosition.x, y - window.absPosition.y, window.size.w, window.size.h))
4045 (window.state == maximized) ? normal : maximized, false, *mods);
4053 if(guiApp.windowMoving)
4055 if(guiApp.windowMoving.parent)
4057 if(guiApp.windowMoving.style.nonClient)
4058 guiApp.windowMoving.parent.SetMouseRangeToWindow();
4060 guiApp.windowMoving.parent.SetMouseRangeToClient();
4064 window.UpdateDecorations();
4067 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp)
4069 // Log("\n*** LEFT BUTTON UP ***\n");
4070 if(guiApp.windowMoving)
4071 guiApp.windowMoving.StopMoving();
4073 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp)
4075 if(guiApp.windowScrolling)
4077 Window windowScrolling = guiApp.windowScrolling;
4078 guiApp.windowScrolling = null;
4079 windowScrolling.ReleaseCapture();
4083 if(!result || (window && window.destroyed)) window = null;
4085 if(window && window.FindModal())
4088 if(trueWindow && trueWindow.FindModal())
4096 msgWindow = GetAtPosition(x,y, true, false);
4098 msgWindow.SelectMouseCursor();
4101 if(guiApp.windowCaptured || trueWindow)
4103 Window prevWindow = guiApp.prevWindow;
4104 if(guiApp.prevWindow && trueWindow != guiApp.prevWindow)
4106 guiApp.prevWindow.mouseInside = false;
4107 guiApp.prevWindow = null;
4109 // Eventually fix this not to include captured?
4110 if(!prevWindow.OnMouseLeave(*mods))
4113 if(result && trueWindow && !trueWindow.destroyed/* && trueWindow == window*/)
4115 Box box = trueWindow.box;
4116 box.left += trueWindow.absPosition.x;
4117 box.right += trueWindow.absPosition.x;
4118 box.top += trueWindow.absPosition.y;
4119 box.bottom += trueWindow.absPosition.y;
4121 if(box.IsPointInside({x, y}) && trueWindow != /*guiApp.*/prevWindow /*!trueWindow.mouseInside*/)
4123 int overX = x - (trueWindow.absPosition.x + trueWindow.clientStart.x);
4124 int overY = y - (trueWindow.absPosition.y + trueWindow.clientStart.y);
4126 overX = Max(Min(overX, 32767),-32768);
4127 overY = Max(Min(overY, 32767),-32768);
4129 trueWindow.mouseInside = true;
4130 if(!trueWindow.OnMouseOver(overX, overY, *mods))
4134 if(trueWindow && trueWindow._refCount > 1 && !trueWindow.destroyed)
4135 guiApp.prevWindow = trueWindow;
4137 guiApp.prevWindow = null;
4139 SelectMouseCursor();
4141 if(window && !guiApp.windowMoving && !wasMoving && !wasScrolling)
4143 int clientX = x - (window.absPosition.x + window.clientStart.x);
4144 int clientY = y - (window.absPosition.y + window.clientStart.y);
4146 bool (* MouseMethod)(Window instance, int x, int y, Modifiers mods);
4148 clientX = Max(Min(clientX, 32767),-32768);
4149 clientY = Max(Min(clientY, 32767),-32768);
4151 MouseMethod = (void *)window._vTbl[method];
4153 if(MouseMethod /*&& !consequential*/ && !window.disabled)
4156 if(!MouseMethod(window, clientX, clientY, *mods))
4163 if(result && w && w.clickThrough && w.parent)
4168 if(!result || !w || !w.clickThrough)
4175 // --- Mouse cursor management ---
4177 bool KeyMessage(uint method, Key key, unichar character)
4182 if(guiApp.interimWindow)
4183 this = guiApp.interimWindow;
4186 if((SmartKey)key != alt && (SmartKey)key != Key::control && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown && parent && this != parent.menuBar)
4190 if(!style.inactive || rootWindow != this)
4192 bool (*KeyMethod)(Window window, Key key, unichar ch) = (void *)_vTbl[method];
4193 Window modalWindow = FindModal();
4194 Window interimMaster = master ? master.rootWindow : null;
4198 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4199 status = OnSysKeyDown(key, character);
4200 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit)
4201 status = OnSysKeyHit(key, character);
4202 else if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4203 status = OnSysKeyUp(key, character);
4210 // Process Key Message for Internal UI Keyboard actions
4211 if(status && !destroyed && menuBar && state != minimized)
4214 if((SmartKey)key != alt)
4215 menuBar.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown, 0, 0);
4218 SmartKey sk = (SmartKey) key;
4219 if((character && !key.alt && !key.ctrl) || sk == left || sk == right || sk == up || sk == down || sk == home || sk == end || sk == escape || sk == alt)
4221 status = menuBar.KeyMessage(method, key, character);
4226 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4227 menuBar.OnKeyHit(escape, 0);
4229 if(!menuBar.focus && guiApp.caretOwner)
4230 guiApp.caretOwner.UpdateCaret(true, false);
4233 if(!destroyed && status)
4235 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4239 case left: case up: case right: case down:
4240 if(guiApp.windowMoving == this)
4243 int w = guiApp.windowMoving.size.w;
4244 int h = guiApp.windowMoving.size.h;
4245 int x = guiApp.windowMoving.scrolledPos.x;
4246 int y = guiApp.windowMoving.scrolledPos.y;
4250 if(key == down || key == up)
4251 step = Max(step, textCellH);
4253 step = Max(step, textCellW);
4256 if(guiApp.windowIsResizing)
4260 case left: w-=step; break;
4261 case right: w+=step; break;
4262 case up: h-=step; break;
4263 case down: h+=step; break;
4270 case left: x-=step; break;
4271 case right: x+=step; break;
4272 case up: y-=step; break;
4273 case down: y+=step; break;
4277 if(guiApp.resizeX) x += w - guiApp.windowMoving.size.w;
4278 if(guiApp.resizeY) y += h - guiApp.windowMoving.size.h;
4280 if(!guiApp.windowIsResizing || guiApp.resizeX)
4281 x = (x - guiApp.windowMovingBefore.x) + guiApp.windowMovingStart.x;
4283 x = (w - guiApp.windowResizingBefore.w) + guiApp.windowMovingStart.x;
4285 if(!guiApp.windowIsResizing || guiApp.resizeY)
4286 y = (y - guiApp.windowMovingBefore.y) + guiApp.windowMovingStart.y;
4288 y = (h - guiApp.windowResizingBefore.h) + guiApp.windowMovingStart.y;
4290 guiApp.interfaceDriver.SetMousePosition(x, y);
4291 ConsequentialMouseMove(true);
4299 if(guiApp.windowMoving && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4301 guiApp.windowMoving.StopMoving();
4302 ConsequentialMouseMove(false);
4310 ShowSysMenu(absPosition.x, absPosition.y);
4318 if(!destroyed && status && state != minimized)
4320 // Process all the way down the children
4321 if(activeChild && !activeChild.disabled)
4323 status = activeChild.KeyMessage(method, key, character);
4325 if(status && activeClient && activeChild != activeClient && !activeClient.disabled && (key.alt || key.ctrl) &&
4326 key.code != left && key.code != right && key.code != up && key.code != down)
4328 status = activeClient.KeyMessage(method, key, character);
4332 if(!destroyed && status && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4334 if((SmartKey)key == enter && !key.alt && !key.ctrl && defaultControl && !defaultControl.disabled && state != minimized)
4335 // && defaultControl != activeChild)
4337 delete previousActive;
4338 previousActive = activeChild;
4339 if(previousActive) incref previousActive;
4341 ConsequentialMouseMove(false);
4342 if((defaultControl.active ||
4343 defaultControl.ActivateEx(true, true, false, true, null, null)) && !defaultControl.disabled)
4344 defaultControl.KeyMessage(method, defaultKey, character);
4350 if(!destroyed && status && (!modalWindow || this == guiApp.desktop))
4352 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4359 ShowSysMenu(absPosition.x, absPosition.y);
4366 if(this != guiApp.desktop)
4368 if(!guiApp.windowMoving && !guiApp.windowCaptured)
4370 if(state != maximized && (key.shift ? style.sizeable : style.fixed))
4372 MenuMoveOrSize(key.shift, true);
4376 else if(guiApp.windowMoving)
4378 guiApp.windowMoving.StopMoving();
4379 ConsequentialMouseMove(false);
4387 if(!destroyed && status && state != minimized)
4389 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4393 case tab: case shiftTab:
4395 Window cycleParent = this;
4396 if(this == guiApp.interimWindow && !master.style.interim && !cycleParent.style.tabCycle)
4397 cycleParent = master.parent;
4399 if(!guiApp.windowCaptured && cycleParent.style.tabCycle)
4401 if(cycleParent.CycleChildren(!key.shift, false, false, true))
4403 Window child = cycleParent.activeChild;
4405 // Scroll the window to include the active control
4407 if(cycleParent.sbh && !child.style.dontScrollHorz)
4409 if(child.scrolledPos.x < 0)
4410 cycleParent.sbh.Action(Position,
4411 cycleParent.scroll.x + child.scrolledPos.x, 0);
4412 else if(child.scrolledPos.x + child.size.w > cycleParent.clientSize.w)
4413 cycleParent.sbh.Action(Position,
4414 cycleParent.scroll.x + child.scrolledPos.x + child.size.w - cycleParent.clientSize.w, 0);
4416 if(cycleParent.sbv && !child.style.dontScrollVert)
4418 if(child.scrolledPos.y < 0)
4419 cycleParent.sbv.Action(Position,
4420 cycleParent.scroll.y + child.scrolledPos.y, 0);
4421 else if(child.scrolledPos.y + child.size.w > window.clientSize.h)
4422 cycleParent.sbv.Action(Position,
4423 cycleParent.scroll.y + child.scrolledPos.y+child.size.h - cycleParent.clientSize.h, 0);
4426 cycleParent.ConsequentialMouseMove(false);
4432 case f6: case shiftF6:
4433 if(!guiApp.windowMoving /*!guiApp.windowCaptured*/)
4435 // NOT NEEDED... guiApp.windowMoving.ReleaseCapture();
4436 if(parent == guiApp.desktop)
4437 if(guiApp.desktop.CycleChildren(key.shift, true, false, true))
4442 if(style.tabCycle ||
4443 CycleChildren(key.shift, true, false, true))
4451 // mIRC Style Window Shortcuts
4452 case alt1: case alt2: case alt3: case alt4: case alt5:
4453 case alt6: case alt7: case alt8: case alt9: case alt0:
4458 for(document = children.first; document; document = document.next)
4460 if(document.style.isDocument && document.documentID - 1 == key.code - k1)
4462 if(document == activeChild)
4464 if(document.state == minimized)
4465 document.SetState(normal, false, key);
4468 document.SetState(minimized, false, key);
4469 CycleChildren(false, true, false);
4474 if(activeChild.state == maximized && document.style.hasMaximize)
4475 document.SetState(maximized, false, key);
4476 else if(document.state == minimized)
4477 document.SetState(normal, false, key);
4478 document.Activate();
4493 if(!destroyed && status)
4495 if(state == minimized)
4500 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4502 if((SmartKey)key == enter && !key.alt && !key.ctrl && defaultControl && previousActive)
4504 if(defaultControl.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp, key, character))
4505 previousActive.ActivateEx(true, false, false, true, null, null);
4506 delete previousActive;
4512 if(!destroyed && status)
4514 status = ProcessHotKeys(method, key, character);
4516 if(!destroyed && status && !modalWindow && state != minimized)
4519 status = KeyMethod(this, key, character);
4520 if(!destroyed && status && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown)
4521 status = OnKeyHit(key, character);
4522 if(!destroyed && status && (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown || method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit))
4524 bool result = false;
4527 case ctrlUp: case ctrlDown:
4528 if(sbv && !guiApp.windowScrolling)
4529 result = sbv.Action((key == ctrlUp) ? up : down, 0, key);
4531 case wheelUp: case wheelDown:
4532 if(sbv && !guiApp.windowScrolling)
4534 result = sbv.Action((key == wheelUp) ? wheelUp : wheelDown, 0, key);
4535 // Do we want to do a consequential move regardless of result in this case?
4536 ConsequentialMouseMove(false);
4539 case ctrlPageUp: case ctrlPageDown:
4540 if(sbh && !guiApp.windowScrolling)
4541 result = sbh.Action((key == ctrlPageUp) ? up : down, 0, key);
4546 ConsequentialMouseMove(false);
4551 if(status && !destroyed && menuBar && state != minimized)
4552 status = menuBar.KeyMessage(method, key, character);
4554 if(style.interim && /*destroyed && */status && interimMaster)
4556 // Testing this... for Ctrl-O to open dialog when autocompletion listbox is popped...
4557 status = interimMaster.KeyMessage(method, key, character);
4564 bool ProcessHotKeys(uint method, Key key, unichar character)
4569 for(hotKey = hotKeys.first; hotKey; hotKey = hotKey.next)
4570 if((hotKey.key == key || (method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp && hotKey.key.code == key.code)) &&
4571 !hotKey.window.disabled && (hotKey.window.style.nonClient || state != minimized))
4573 Window hotKeyWindow = hotKey.window;
4574 Window parent = hotKeyWindow.parent;
4575 Window prevActiveWindow = activeChild;
4577 // Don't process non-visible buttons, but make an exception for the Alt-F4 with Native Decorations turned on
4578 if(hotKeyWindow.style.hidden && (!hotKeyWindow.style.nonClient || !parent || !parent.nativeDecorations || (hotKeyWindow != parent.sysButtons[2] && hotKeyWindow != parent.sysButtons[1] )))
4581 if(prevActiveWindow) incref prevActiveWindow;
4582 incref hotKeyWindow;
4583 if(method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown && !hotKeyWindow.style.nonClient)
4584 if(!hotKeyWindow.ActivateEx(true, true, false, true, null, null))
4587 delete hotKeyWindow;
4588 delete prevActiveWindow;
4592 if(hotKeyWindow.style.nonClient && method == __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit)
4593 method = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown;
4594 if(!hotKeyWindow.KeyMessage(method, Key::hotKey, character))
4596 // ********* WORKING ON THIS ***********
4597 if(prevActiveWindow && !guiApp.interimWindow)
4598 prevActiveWindow.ActivateEx(true, false, false, false, null, null);
4601 else if(hotKeyWindow.style.inactive)
4602 status = hotKeyWindow.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp, Key::hotKey, character);
4604 delete prevActiveWindow;
4605 delete hotKeyWindow;
4606 // For Key Ups, don't set status to false... (e.g.: Releasing Enter vs AltEnter hot key)
4607 if(method != __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp)
4611 if(status && tabCycle)
4614 for(child = children.first; child; child = child.next)
4616 if(child.tabCycle && !child.ProcessHotKeys(method, key, character))
4627 // --- Windows and graphics initialization / termination ---
4628 bool SetupRoot(void)
4632 // Setup relationship with outside world (bb root || !bb)
4633 if((!guiApp.fullScreenMode && parent == guiApp.desktop) || this == guiApp.desktop ||
4634 (_displayDriver && dispDriver != parent.dispDriver))
4638 tempExtents = new0 Extent[4];
4643 /*if(guiApp.fullScreenMode)
4644 rootWindow = guiApp.desktop;
4646 //rootWindow = parent.created ? parent.rootWindow : null;
4647 rootWindow = parent.rootWindow;
4650 against = &parent.box;
4652 against = &parent.clientArea;
4655 for(child = children.first; child; child = child.next)
4658 return (rootWindow && (rootWindow == this || rootWindow.created)) ? true : false;
4661 bool Setup(bool positionChildren)
4663 bool result = false;
4666 if((!guiApp.fullScreenMode && parent == guiApp.desktop) || (guiApp.fullScreenMode && (this == guiApp.desktop || (_displayDriver && dispDriver != parent.dispDriver))))
4668 subclass(DisplayDriver) dDriver = (dispDriver && !formDesigner) ? dispDriver : GetDisplayDriver(guiApp.defaultDisplayDriver);
4669 DisplaySystem displaySystem = dDriver ? dDriver.displaySystem : null;
4671 windowHandle = dDriver.printer ? null : guiApp.interfaceDriver.CreateRootWindow(this);
4673 // This was here, is it really needed?
4674 //guiApp.interfaceDriver.ActivateRootWindow(this);
4678 displaySystem = DisplaySystem {};
4679 if(!displaySystem.Create(dDriver.name, guiApp.fullScreenMode ? windowHandle : windowHandle /*null*/, guiApp.fullScreenMode))
4681 delete displaySystem;
4686 display = Display { alphaBlend = alphaBlend, useSharedMemory = useSharedMemory, windowDriverData = windowData };
4687 if(display.Create(displaySystem, windowHandle))
4694 guiApp.interfaceDriver.SetIcon(this, icon);
4696 else if(this != guiApp.desktop)
4698 display = rootWindow ? rootWindow.display : null;
4704 if(guiApp.acquiredWindow && rootWindow == guiApp.acquiredWindow.rootWindow)
4705 guiApp.interfaceDriver.AcquireInput(guiApp.acquiredWindow.rootWindow, true);
4707 for(child = children.first; child; child = child.next)
4709 if(child.created && !child.Setup(false))
4715 bool SetupDisplay(void)
4717 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
4718 if(is3D) return Window3D_SetupDisplay(this); else
4725 class_data void ** pureVTbl;
4727 bool LoadGraphics(bool creation, bool resetAnchors)
4729 bool result = false;
4730 bool success = false;
4732 WindowState stateBackup = state;
4735 if(!rootWindow.created)
4739 if(((subclass(Window))_class).pureVTbl)
4741 if(_vTbl == _class._vTbl)
4743 _vTbl = ((subclass(Window))_class).pureVTbl;
4748 for(m = 0; m < _class.vTblSize; m++)
4750 if(_vTbl[m] == _class._vTbl[m])
4751 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
4755 if(guiApp.currentSkin && ((subclass(Window))_class).pureVTbl)
4757 if(_vTbl == ((subclass(Window))_class).pureVTbl)
4759 _vTbl = _class._vTbl;
4764 for(m = 0; m < _class.vTblSize; m++)
4766 if(_vTbl[m] == ((subclass(Window))_class).pureVTbl[m])
4767 _vTbl[m] = _class._vTbl[m];
4772 if(guiApp.fullScreenMode || this != guiApp.desktop)
4774 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
4780 display.Lock(false);
4781 if(rootWindow == this)
4783 // Set Color Palette
4784 display.SetPalette(palette, true);
4788 if(guiApp.fullScreenMode && this == guiApp.desktop)
4793 for(c=0; c<SystemCursor::enumSize; c++)
4794 if(!guiApp.systemCursors[c].bitmap)
4796 guiApp.systemCursors[c].bitmapName = guiApp.currentSkin.CursorsBitmaps(c,
4797 &guiApp.systemCursors[c].hotSpotX,&guiApp.systemCursors[c].hotSpotY, &guiApp.systemCursors[c].paletteShades);
4798 if(guiApp.systemCursors[c].bitmapName)
4800 guiApp.systemCursors[c].bitmap = eBitmap_LoadT(guiApp.systemCursors[c].bitmapName, null,
4801 guiApp.systemCursors[c].paletteShades ? null : guiApp.desktop.display.displaySystem);
4802 if(guiApp.systemCursors[c].bitmap)
4803 guiApp.systemCursors[c].bitmap.paletteShades = guiApp.systemCursors[c].paletteShades;
4808 for(cursor = guiApp.customCursors.first; cursor; cursor = cursor.next)
4810 cursor.bitmap = eBitmap_LoadT(cursor.bitmapName, null,
4811 cursor.paletteShades ? null : guiApp.desktop.display.displaySystem);
4813 cursor.bitmap.paletteShades = cursor.paletteShades;
4817 guiApp.cursorUpdate = true;
4820 ConsequentialMouseMove(false);
4826 // Load Window Graphic Resources
4829 if(usedFont == setFont || usedFont == window.systemFont)
4830 RemoveResource(usedFont);
4833 RemoveResource(setFont); // TESTING setFont instead of usedFont);
4836 RemoveResource(systemFont);
4839 RemoveResource(captionFont);
4841 for(ptr = resources.first; ptr; ptr = ptr.next)
4843 ptr.loaded = display.displaySystem.LoadResource(ptr.resource);
4846 AddResource(setFont);
4848 AddResource(systemFont);
4850 usedFont = setFont ? setFont : ((parent && parent.parent) ? parent.usedFont : systemFont);
4857 //if(master && master.font)
4858 if(parent && parent.font)
4862 faceName = parent.font.faceName,
4863 size = parent.font.size,
4864 bold = parent.font.bold,
4865 italic = parent.font.italic,
4866 underline = parent.font.underline
4868 //font = parent.font;
4869 watch(parent) { font { } };
4872 font = guiApp.currentSkin.SystemFont();
4879 captionFont = guiApp.currentSkin.CaptionFont();
4880 AddResource(captionFont);
4882 if(OnLoadGraphics())
4888 //SetScrollLineStep(sbStep.x, sbStep.y);
4890 if(this != guiApp.desktop)
4894 normalAnchor = anchor;
4895 normalSizeAnchor = sizeAnchor;
4898 // Break the anchors for moveable/resizable windows
4900 if(style.fixed && style.isDocument)
4902 ComputeAnchors(ax, ay, aw, ah, &x, &y, &w, &h);
4914 stateAnchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
4915 stateSizeAnchor = SizeAnchor {};
4920 int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH;
4925 left = (iconID % maxIcons) * MINIMIZED_WIDTH,
4926 bottom = (iconID / maxIcons) * (guiApp.textMode ? 16 : 24)
4929 stateSizeAnchor = SizeAnchor { size.w = MINIMIZED_WIDTH };
4933 stateAnchor = normalAnchor;
4934 stateSizeAnchor = normalSizeAnchor;
4937 position = Point { };
4938 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
4949 if(Position(x, y, w, h, true, false, true, true, true, true))
4951 if((this != guiApp.desktop || guiApp.fullScreenMode) && rootWindow == this)
4954 guiApp.interfaceDriver.SetRootWindowState(this, normal, true);
4971 success = result = true;
4974 if(!creation && result)
4976 // Load menu bar first because sys buttons are on it...
4979 if(!menuBar.LoadGraphics(false, resetAnchors))
4985 for(child = children.first; child; child = child.next)
4987 if(child.created && child != menuBar && !child.LoadGraphics(false, resetAnchors))
4994 CreateSystemChildren();
4998 if(this == guiApp.desktop && !guiApp.fullScreenMode)
5001 guiApp.interfaceDriver.ActivateRootWindow(activeChild);
5006 //guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, caption);
5007 guiApp.LogErrorCode(IERR_GRAPHICS_LOADING_FAILED, class.name);
5010 // Do this here to avoid problems on Windows
5011 if(stateBackup == maximized)
5012 property::state = maximized;
5016 void UnloadGraphics(bool destroyWindows)
5020 // Free children's graphics
5021 for(child = children.first; child; child = child.next)
5022 child.UnloadGraphics(destroyWindows);
5025 display.Lock(false);
5028 if(guiApp.fullScreenMode && this == guiApp.desktop)
5033 for(c=0; c<SystemCursor::enumSize; c++)
5034 if(guiApp.systemCursors[c].bitmap)
5035 delete guiApp.systemCursors[c].bitmap;
5037 for(cursor = guiApp.customCursors.first; cursor; cursor = cursor.next)
5038 delete cursor.bitmap;
5040 guiApp.cursorBackground.Free();
5043 if(display && display.displaySystem)
5047 for(ptr = resources.first; ptr; ptr = ptr.next)
5051 display.displaySystem.UnloadResource(ptr.resource, ptr.loaded);
5056 // Free window graphics
5059 // Free skin graphics
5060 if(rootWindow == this)
5062 DisplaySystem displaySystem = display.displaySystem;
5065 display.driverData = null;
5066 display.displaySystem = null;
5070 if(displaySystem && !displaySystem.numDisplays && !is3D)
5071 delete displaySystem;
5080 if(guiApp.acquiredWindow && this == guiApp.acquiredWindow.rootWindow)
5081 guiApp.interfaceDriver.AcquireInput(guiApp.acquiredWindow.rootWindow, false);
5083 if(this == guiApp.desktop || parent == guiApp.desktop)
5085 if((guiApp.fullScreenMode || this != guiApp.desktop) && rootWindow == this && windowHandle && destroyWindows)
5086 guiApp.interfaceDriver.DestroyRootWindow(this);
5090 // --- Window Hiding ---
5092 void SetVisibility(bool state)
5094 bool visible = (style.hidden || !created) ? false : state;
5095 if(visible != this.visible)
5099 this.visible = visible;
5100 for(child = children.first; child; child = child.next)
5101 child.SetVisibility(visible);
5103 ConsequentialMouseMove(false);
5107 // --- Windows and graphics initialization / termination ---
5109 bool DisplayModeChanged(void)
5111 bool result = false;
5112 if(!guiApp.fullScreenMode && !guiApp.modeSwitching/* && guiApp.desktop.active*/)
5114 guiApp.modeSwitching = true;
5115 UnloadGraphics(false);
5117 if(LoadGraphics(false, false))
5119 guiApp.modeSwitching = false;
5124 // --- Window updates system ---
5126 void UpdateDirty(Box updateBox)
5128 if(!manageDisplay) { OnRedraw(null);return; }
5131 if(display && (!guiApp.fullScreenMode || guiApp.desktop.active) && !guiApp.modeSwitching)
5134 if(display.flags.flipping)
5137 rootWindow.UpdateDisplay();
5140 UpdateBackDisplay(updateBox);
5142 if(guiApp.fullScreenMode)
5144 guiApp.cursorUpdate = true;
5145 guiApp.PreserveAndDrawCursor();
5147 if(guiApp.fullScreenMode)
5148 guiApp.RestoreCursorBackground();
5154 // This function is strictly called as a result of system window activation
5155 bool ExternalActivate(bool active, bool activateRoot, Window window, Window swap)
5158 Window interimMaster = null;
5159 Window interimWindow = guiApp.interimWindow;
5160 if(interimWindow && interimWindow.master)
5161 interimMaster = interimWindow.master.rootWindow;
5163 if(active && state == minimized) // && (!window.nativeDecorations || window.rootWindow != window)
5164 // SetState(normal, false, 0);
5165 SetState(lastState, false, 0);
5167 if(interimMaster && swap == interimMaster && interimMaster.IsSlaveOf(window))
5171 /* WTH is this doing here?
5172 while(swap && swap.activeChild)
5174 swap = swap.activeChild;
5177 // TESTING THIS BEFORE...
5178 if(interimWindow && this == interimMaster)
5182 // Window interimSwap = this;
5183 Window menuBar = this.menuBar;
5184 if(menuBar && interimWindow.master == menuBar)
5187 while(interimSwap && interimSwap.activeChild)
5188 interimSwap = interimSwap.activeChild;
5190 result = interimWindow.ActivateEx(false, false, false, activateRoot, null,
5191 (menuBar && interimWindow.master == menuBar) ? menuBar : interimSwap);
5193 result = /*interimWindow.*/ActivateEx(false, false, false, activateRoot, null, menuBar);
5194 //result = ActivateEx(true, true, false, activateRoot, window, null);
5199 // Testing & FindModal() here: broke reactivating when a modal dialog is up (didn't root activate dialog)
5200 result = ActivateEx(active, active, false, activateRoot /*&& FindModal()*/, window, swap);
5202 if(interimWindow == this && interimMaster && !active)
5204 while(interimMaster && interimMaster.interim && interimMaster.master)
5206 // printf("Going up one master %s\n", interimMaster._class.name);
5207 interimMaster = interimMaster.master.rootWindow;
5209 // printf("Unactivating interim master %s (%x)\n", interimMaster._class.name, interimMaster);
5210 interimMaster.ActivateEx(active, active, false, activateRoot, window, swap);
5216 bool DestroyEx(int returnCode)
5219 Timer timer, nextTimer;
5221 OldLink prevOrder = null;
5222 Window client = null;
5224 if(parent) stopwatching(parent, font);
5226 // if(window.modalSlave) return false;
5227 if(destroyed || !created)
5234 OldLink slave = master.slaves.FindLink(this);
5235 master.slaves.Delete(slave);
5238 // TOFIX IMMEDIATELY: COMMENTED THIS OUT... causes problem second time creating file dialog
5244 this.returnCode = (DialogResult)returnCode;
5246 AcquireInput(false);
5251 master.hotKeys.Delete(hotKey);
5255 if(guiApp.prevWindow == this)
5257 guiApp.prevWindow = null;
5260 if(guiApp.caretOwner == this)
5262 guiApp.interfaceDriver.SetCaret(0,0,0);
5263 UpdateCaret(false, true);
5264 guiApp.caretEnabled = false;
5269 parent.childrenCycle.Remove(cycle);
5273 OldLink tmpPrev = order.prev;
5274 if(tmpPrev && !(((Window)tmpPrev.data).style.hidden) && !(((Window)tmpPrev.data).destroyed) && (((Window)tmpPrev.data).created))
5275 prevOrder = tmpPrev;
5278 client = tmpPrev ? tmpPrev.data : null;
5279 if(client == this) { client = null; break; }
5280 if(client && (client.style.hidden || client.destroyed || !client.created))
5281 tmpPrev = client.order.prev;
5285 prevOrder = tmpPrev;
5290 // If this window can be an active client, make sure the next window we activate can also be one
5291 if(!style.nonClient && style.isActiveClient)
5293 tmpPrev = prevOrder;
5296 client = tmpPrev ? tmpPrev.data : null;
5297 if(client == this) { client = null; break; }
5298 if(client && (client.style.nonClient || !client.style.isActiveClient || client.style.hidden || client.destroyed || !client.created))
5299 tmpPrev = client.order.prev;
5303 prevOrder = tmpPrev;
5307 if(client && client.style.hidden) client = null;
5309 // parent.childrenOrder.Remove(order);
5312 if(parent && style.isActiveClient && visible)
5314 if(state == minimized) parent.numIcons--;
5315 parent.numPositions--;
5318 // TESTING THIS HERE!
5322 // If no display, don't bother deactivating stuff (causes unneeded problems when trying
5323 // to create a window inside a rootwindow that's being destroyed)
5324 // DISABLED THIS BECAUSE OF CREATING WINDOW IN DESKTOP IN WINDOWED MODE
5326 if(master && !master.destroyed /*&&
5327 rootWindow && rootWindow.display && !rootWindow.destroyed*/)
5329 if(master.defaultControl == this)
5330 master.defaultControl = null;
5332 if(parent && !parent.destroyed /*&&
5333 rootWindow && rootWindow.display && !rootWindow.destroyed*/)
5335 if((parent.activeChild == this /*|| parent.activeClient == this */|| guiApp.interimWindow == this))
5337 if(order && prevOrder && prevOrder.data != this && active)
5339 //((Window)prevOrder.data).ActivateEx(true, false, false, false /*true*/, null);
5341 ((Window)prevOrder.data).ActivateEx(true, false, false, (rootWindow == this) ? true : false, null, null);
5342 if(parent.activeClient == this)
5344 parent.activeClient = null;
5345 parent.UpdateActiveDocument(null);
5350 if(guiApp.interimWindow == this)
5353 PropagateActive(false, null, &goOn, true);
5357 //if(window.parent.activeChild == window)
5358 parent.activeChild = null;
5359 if(!style.nonClient /*&& style.isActiveClient*/)
5361 Window previous = parent.activeClient;
5362 if(style.isActiveClient)
5363 parent.activeClient = null;
5364 parent.UpdateActiveDocument(previous);
5369 else if(parent.activeClient == this)
5371 parent.activeClient = client;
5372 parent.UpdateActiveDocument(this);
5376 if(guiApp.interimWindow == this)
5378 guiApp.interimWindow = null;
5379 if(guiApp.caretOwner)
5381 Window desktop = guiApp.desktop;
5382 if(desktop.activeChild && desktop.activeChild.menuBar && !desktop.activeChild.menuBar.focus)
5383 guiApp.caretOwner.UpdateCaret(false, false);
5388 if(_isModal && master && master.modalSlave == this)
5389 master.modalSlave = null;
5393 if(!guiApp.caretOwner && parent.caretSize)
5395 guiApp.caretOwner = parent;
5396 parent.UpdateCaret(false, false);
5397 parent.Update(null);
5400 // Why was this commented out?
5401 GetRidOfVirtualArea();
5407 dirtyArea.Free(null);
5408 dirtyBack.Free(null);
5409 scrollExtent.Free(null);
5411 /* ATTEMPTING TO MOVE THAT ABOVE
5420 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5421 for(;(child = window.children.first);)
5423 for(; child && (child.destroyed || !child.created); child = child.next);
5432 UnloadGraphics(true);
5435 delete previousActive;
5438 // statusBar = null;
5441 if(master && !master.destroyed)
5443 //master.NotifyDestroyed(this, this.returnCode);
5444 NotifyDestroyed(master, this, this.returnCode);
5447 for(timer = guiApp.windowTimers.first; timer; timer = nextTimer)
5449 nextTimer = timer.next;
5450 if(timer.window == this)
5452 // WHY WERE WE SETTING THIS TO NULL? NO MORE WINDOW WHEN RECREATING...
5453 // timer.window = null;
5459 if(this == guiApp.windowMoving)
5462 if(guiApp.windowCaptured == this)
5464 //guiApp.windowCaptured = null;
5466 if(rootWindow != this && rootWindow)
5467 rootWindow.ConsequentialMouseMove(false);
5475 //for(child = children.first; next = child ? child.next : null, child; child = next)
5476 for(;(child = children.first); )
5478 for(; child && (child.destroyed || !child.created); child = child.next);
5488 /* // MOVED THIS UP...
5491 //for(child = window.children.first; next = child ? child.next : null, child; child = next)
5492 for(;(child = window.children.first); )
5494 for(; child && (child.destroyed || !child.created); child = child.next);
5503 while((slave = slaves.first))
5505 for(; slave && (((Window)slave.data).destroyed || !((Window)slave.data).created); slave = slave.next);
5507 ((Window)slave.data).DestroyEx(0);
5512 if(guiApp.caretOwner == this)
5513 guiApp.caretOwner = null;
5515 sysButtons[0] = null;
5516 sysButtons[1] = null;
5517 sysButtons[2] = null;
5520 if(rootWindow != this)
5522 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
5525 box.left -= parent.clientStart.x;
5526 box.top -= parent.clientStart.y;
5527 box.right -= parent.clientStart.x;
5528 box.bottom -= parent.clientStart.y;
5530 if(parent) parent.Update(box);
5535 OldLink slave = master.slaves.FindVoid(this);
5536 master.slaves.Delete(slave);
5542 parent.children.Remove(this);
5547 //autoCreate = false;
5550 // SHOULD THIS BE HERE? FIXED CRASH WITH GOTO DIALOG
5551 if(((subclass(Window))_class).pureVTbl)
5553 if(_vTbl == _class._vTbl)
5555 _vTbl = ((subclass(Window))_class).pureVTbl;
5560 for(m = 0; m < _class.vTblSize; m++)
5562 if(_vTbl[m] == _class._vTbl[m])
5563 _vTbl[m] = ((subclass(Window))_class).pureVTbl[m];
5572 void SetStateEx(WindowState newState, bool activate)
5575 WindowState prevState = state;
5579 if(prevState != newState)
5580 lastState = prevState;
5582 if(rootWindow != this || !nativeDecorations)
5584 if(style.isActiveClient && !style.hidden && prevState == minimized)
5587 // This block used to be at the end of the function... moved it for flicker problem in X
5588 // ------------------------------------------------------
5592 stateAnchor = normalAnchor;
5593 stateSizeAnchor = normalSizeAnchor;
5596 stateAnchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
5597 stateSizeAnchor = SizeAnchor {};
5601 int maxIcons = parent.clientSize.w / MINIMIZED_WIDTH;
5604 byte * idBuffer = new0 byte[size];
5606 for(child = parent.children.first; child; child = child.next)
5608 if(child != this && child.state == minimized)
5610 if(child.iconID > size - 2)
5612 idBuffer = renew0 idBuffer byte[size*2];
5613 memset(idBuffer + size, 0, size);
5616 idBuffer[child.iconID] = (byte)bool::true;
5619 for(c = 0; c<size; c++)
5624 if(style.isActiveClient && !style.hidden)
5627 stateAnchor = Anchor { left = (iconID % maxIcons) * MINIMIZED_WIDTH, bottom = (iconID / maxIcons) * (guiApp.textMode ? 16 : 24) };
5628 stateSizeAnchor = SizeAnchor { size.w = MINIMIZED_WIDTH };
5632 // TOCHECK: Why was this here?
5633 //position.x = (tx > 0) ? tx & 0xFFFFF : tx;
5634 //position.y = (ty > 0) ? ty & 0xFFFFF : ty;
5635 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5637 Position(x, y, w, h, true, true, true, true, false, true);
5639 if(!style.inactive && !style.interim && this == parent.activeClient)
5640 parent.UpdateActiveDocument(null);
5643 CreateSystemChildren();
5644 // ------------------------------------------------------
5647 int GetPositionID(Window forChild)
5651 byte * idBuffer = new0 byte[size];
5654 for(child = children.first; child; child = child.next)
5656 if(child.style.isActiveClient && !child.style.hidden && child != forChild)
5658 if(child.positionID > size - 2)
5660 idBuffer = renew0 idBuffer byte[size*2];
5661 memset(idBuffer + size, 0, size);
5664 idBuffer[child.positionID] = (byte)bool::true;
5667 for(c = 0; c<size; c++)
5674 // --- Window related graphics ---
5676 void SetPalette(ColorAlpha * newPalette, bool colorMatch)
5678 palette = newPalette;
5679 if(rootWindow.display)
5680 rootWindow.display.SetPalette(palette, colorMatch);
5683 public bool AcquireInput(bool acquired)
5686 if(acquiredInput != acquired)
5688 if(active || (!visible && creationActivation == activate))
5689 result = AcquireInputEx(acquired);
5694 acquiredInput = acquired ? result : !result;
5699 void ListChildren(ListBox listBox)
5703 for(child = children.first; child; child = child.next)
5705 if(child.cycle && !child.style.nonClient && child.style.isActiveClient && child.visible)
5707 DataRow row = listBox.AddRow();
5708 row.tag = (int)child;
5709 child.FigureCaption(caption);
5710 row.SetData(null, caption);
5715 void UpdateVisual(Box extent)
5717 if(guiApp.driver != null)
5719 if(guiApp.fullScreenMode && guiApp.desktop.display)
5721 guiApp.desktop.mutex.Wait();
5722 guiApp.desktop.display.Lock(true);
5725 if(guiApp.desktop.active)
5727 if(guiApp.desktop.dirty || guiApp.cursorUpdate)
5729 if(guiApp.desktop.display.flags.flipping)
5730 guiApp.desktop.Update(null);
5731 guiApp.desktop.UpdateDisplay();
5732 guiApp.cursorUpdate = true;
5734 if(guiApp.cursorUpdate || guiApp.desktop.dirty)
5736 guiApp.PreserveAndDrawCursor();
5737 // guiApp.desktop.display.ShowScreen();
5738 guiApp.cursorUpdate = false;
5739 guiApp.desktop.dirty = false;
5740 guiApp.RestoreCursorBackground();
5744 guiApp.desktop.display.Unlock();
5745 guiApp.desktop.mutex.Release();
5749 Window rootWindow = this.rootWindow;
5750 rootWindow.mutex.Wait();
5755 guiApp.SignalEvent();
5758 guiApp.waitMutex.Wait();
5759 guiApp.interfaceDriver.Lock(rootWindow);
5760 if(!rootWindow.style.hidden && rootWindow.dirty)
5762 if(rootWindow.display)
5764 rootWindow.UpdateDisplay();
5765 //rootWindow.display.ShowScreen(null);
5767 rootWindow.dirty = false;
5769 guiApp.interfaceDriver.Unlock(rootWindow);
5770 guiApp.waitMutex.Release();
5773 rootWindow.mutex.Release();
5778 void UnlockDisplay(void)
5780 guiApp.interfaceDriver.Unlock(rootWindow);
5783 void LockDisplay(void)
5785 guiApp.interfaceDriver.Lock(rootWindow);
5788 Surface GetSurface(Box box)
5790 return Redraw((box == null) ? this.box : box);
5793 void SetMousePosition(int x, int y)
5795 guiApp.interfaceDriver.SetMousePosition(x + absPosition.x + clientStart.x, y + absPosition.y + clientStart.y);
5799 void IntegrationActivate(bool active)
5801 if(!guiApp.modeSwitching && !guiApp.fullScreenMode)
5803 isForegroundWindow = true;
5804 ActivateEx(active, active, false, false, null, null);
5805 isForegroundWindow = false;
5810 Window QueryCapture(void)
5812 return guiApp.windowCaptured;
5815 int GetDocumentID(void)
5819 byte * idBuffer = new0 byte[size];
5822 for(child = children.first; child; child = child.next)
5824 if(child.style.isDocument)
5826 if(child.documentID-1 > size - 2)
5828 idBuffer = renew0 idBuffer byte[size*2];
5829 memset(idBuffer + size, 0, size);
5832 idBuffer[child.documentID-1] = 1;
5835 for(c = 0; c<size; c++)
5843 void SetInitSize(Size size)
5846 sizeAnchor.size = size;
5847 normalSizeAnchor = sizeAnchor;
5849 // Break the anchors for moveable/resizable windows
5850 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
5852 stateAnchor = normalAnchor;
5853 stateSizeAnchor = normalSizeAnchor;
5855 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
5856 Position(x,y, w, h, true, true, true, true, false, true);
5860 void MenuMoveOrSize(bool resize, bool setCursorPosition)
5862 if(this != guiApp.desktop && state != maximized && (resize ? (state != minimized && style.sizable) : (style.fixed || moveable)))
5864 guiApp.windowIsResizing = resize;
5865 guiApp.windowMoving = this;
5866 guiApp.windowMovingStart = guiApp.movingLast = absPosition;
5867 if(guiApp.windowIsResizing)
5869 guiApp.windowMovingStart.x += size.w - 1;
5870 guiApp.windowMovingStart.y += size.h - 1;
5872 guiApp.windowMovingBefore = scrolledPos;
5873 guiApp.windowResizingBefore = size;
5874 guiApp.windowMoving.UpdateDecorations();
5875 if(guiApp.windowIsResizing)
5876 guiApp.resizeEndX = guiApp.resizeEndY = true;
5878 if(setCursorPosition)
5879 guiApp.interfaceDriver.SetMousePosition(guiApp.windowMovingStart.x, guiApp.windowMovingStart.y);
5883 guiApp.interfaceDriver.GetMousePosition(&x, &y);
5884 guiApp.windowMovingStart.x += x - absPosition.x;
5885 guiApp.windowMovingStart.y += y - absPosition.y;
5888 if(guiApp.windowMoving)
5890 if(guiApp.windowMoving.style.nonClient)
5891 guiApp.windowMoving.parent.SetMouseRangeToWindow();
5893 guiApp.windowMoving.parent.SetMouseRangeToClient();
5898 if(this == rootWindow)
5899 guiApp.interfaceDriver.StartMoving(rootWindow, guiApp.windowMovingStart.x, guiApp.windowMovingStart.y, true);
5907 bool result = false;
5911 else if(guiApp && guiApp.driver != null)
5913 void * systemParent = null;
5914 OldLink slaveHolder;
5916 bool visible = !style.hidden;
5920 systemParent = parent;
5921 parent = guiApp.desktop;
5923 last = parent ? parent.children.last : null;
5925 if((parent && parent != guiApp.desktop && !parent.created) ||
5926 (master && master != guiApp.desktop && !master.created))
5930 property::parent = guiApp.desktop;
5931 if(!master) master = parent;
5933 if(_isModal && master.modalSlave)
5934 property::master = master.modalSlave;
5938 parent.children.Remove(this);
5941 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
5942 if(slaveHolder.data == this)
5944 master.slaves.Delete(slaveHolder);
5949 if(parent == guiApp.desktop && !mutex)
5952 if(style.isDocument)
5955 parent.numDocuments--;
5956 documentID = parent.GetDocumentID();
5959 if(!style.stayOnTop)
5960 for(; last && last.style.stayOnTop; last = last.prev);
5962 parent.children.Insert((last == this) ? null : last, this);
5963 //parent.children.Add(this);
5966 dispDriver = parent.dispDriver;
5969 master.modalSlave = this;
5971 box = Box { MAXINT, MAXINT, MININT, MININT }; //-MAXINT, -MAXINT };
5976 master.slaves.Add(slaveHolder = OldLink { data = this });
5981 master.hotKeys.Add(hotKey = HotKeySlot { key = setHotKey, window = this });
5983 if(style.isDefault && !master.defaultControl)
5984 master.defaultControl = this;
5986 stateAnchor = normalAnchor = anchor;
5987 stateSizeAnchor = normalSizeAnchor = sizeAnchor;
5989 // TOCHECK: Why is this here?
5990 //position.x = (ax > 0) ? ax & 0xFFFFF : ax;
5991 //position.y = (ay > 0) ? ay & 0xFFFFF : ay;
5993 this.visible = false;
5994 style.hidden = true;
5997 // autoCreate = true;
6005 if(parent == guiApp.desktop)
6006 Log("LoadGraphics %s\n", caption);
6008 if(LoadGraphics(true, false))
6016 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
6023 if(style.hasMenuBar /*&& menu*/)
6029 menu = menu, isMenuBar = true, anchor = Anchor { top = 23, left = 1, right = 1 },
6030 interim = false, inactive = true, nonClient = true, size.h = 24
6038 // Create the system buttons
6039 CreateSystemChildren();
6041 UpdateActiveDocument(null);
6043 if(style.isDocument)
6047 MenuItem item = menu.FindItem(MenuFileSave, 0);
6048 if(item) item.disabled = !modifiedDocument && fileName;
6053 if(parent == guiApp.desktop)
6054 Log("Preemptive SetState %s\n", caption);
6057 // Preemptive Set State to ensure proper anchoring
6058 SetStateEx(state, false);
6060 style.hidden = true;
6066 for(child = children.first; child; child = next)
6069 if(!child.created && (child.autoCreate || child.wasCreated))
6076 for(link = slaves.first; link; link = next)
6078 Window slave = link.data;
6080 if(!slave.created && (slave.autoCreate || slave.wasCreated))
6089 if(parent == guiApp.desktop)
6090 Log("Real SetState %s\n", caption);
6093 if(isActiveClient && visible)
6095 parent.numPositions--;
6096 if(state == minimized) parent.numIcons--;
6099 // Real set state & activate for proper display & activation
6100 property::visible = visible;
6101 // SetState(state & 0x00000003, true, 0);
6106 /*if(rootWindow == this)
6107 guiApp.interfaceDriver.ActivateRootWindow(this);
6109 if(creationActivation == activate)
6110 ActivateEx(true, false, true, true, null, null);
6111 else if(creationActivation == flash)
6116 rootWindow.ConsequentialMouseMove(false);
6127 guiApp.LogErrorCode(IERR_WINDOW_CREATION_FAILED, caption);
6133 // Testing this here... Otherwise a failed LoadGraphics stalls the application
6135 //style.hidden = true; // !visible;
6136 style.hidden = !visible;
6137 if(master.modalSlave == this)
6138 master.modalSlave = null;
6145 void WriteCaption(Surface surface, int x, int y)
6148 Interface::WriteKeyedTextDisabled(surface, x,y, caption, hotKey ? hotKey.key : 0, !isEnabled);
6151 void Update(Box region)
6157 rootWindow = this.rootWindow;
6159 // rootWindow.mutex.Wait();
6160 if(!destroyed && visible && display)
6165 // Testing this to avoid repetitve full update to take time...
6166 if(dirtyArea.count == 1)
6168 BoxItem item = (BoxItem)ACCESS_ITEM(dirtyArea, dirtyArea.first);
6169 if(item.box.left <= box.left &&
6170 item.box.top <= box.top &&
6171 item.box.right >= box.right &&
6172 item.box.bottom >= box.bottom)
6174 rootWindow.dirty = true;
6179 if(display.flags.flipping && !rootWindow.dirty)
6181 if(this == rootWindow)
6185 rootWindow.Update(null);
6190 rootWindow.dirty = true;
6195 realBox.left += clientStart.x;
6196 realBox.top += clientStart.y;
6197 realBox.right += clientStart.x;
6198 realBox.bottom += clientStart.y;
6204 if(realBox.right >= realBox.left &&
6205 realBox.bottom >= realBox.top)
6207 // if(!rootWindow.fullRender)
6208 dirtyArea.UnionBox(realBox, rootWindow.tempExtents[0]);
6210 for(child = children.first; child; child = child.next)
6215 box.left -= child.absPosition.x - absPosition.x;
6216 box.top -= child.absPosition.y - absPosition.y;
6217 box.right -= child.absPosition.x - absPosition.x;
6218 box.bottom -= child.absPosition.y - absPosition.y;
6219 if(box.right >= child.box.left && box.left <= child.box.right &&
6220 box.bottom >= child.box.top && box.top <= child.box.bottom)
6222 box.left -= child.clientStart.x;
6223 box.top -= child.clientStart.y;
6224 box.right -= child.clientStart.x;
6225 box.bottom -= child.clientStart.y;
6231 realBox.left += absPosition.x - rootWindow.absPosition.x;
6232 realBox.top += absPosition.y - rootWindow.absPosition.y;
6233 realBox.right += absPosition.x - rootWindow.absPosition.x;
6234 realBox.bottom += absPosition.y - rootWindow.absPosition.y;
6235 rootWindow.dirtyBack.UnionBox(realBox, rootWindow.tempExtents[0]);
6238 else if(this == guiApp.desktop)
6241 for(window = children.first; window; window = window.next)
6247 Box childBox = region;
6249 childBox.left -= window.absPosition.x - guiApp.desktop.absPosition.x;
6250 childBox.top -= window.absPosition.y - guiApp.desktop.absPosition.y;
6251 childBox.right -= window.absPosition.x - guiApp.desktop.absPosition.x;
6252 childBox.bottom -= window.absPosition.y - guiApp.desktop.absPosition.y;
6254 window.Update(childBox);
6257 window.Update(null);
6262 // rootWindow.mutex.Release();
6269 if(guiApp.windowCaptured != this)
6271 if(guiApp.windowCaptured)
6275 //Logf("Captured %s (%s)\n", caption, class.name);
6276 guiApp.interfaceDriver.SetMouseCapture(rootWindow);
6277 guiApp.windowCaptured = this;
6283 bool Destroy(int code)
6288 if(!CloseConfirmation(false)) return false;
6292 // TOCHECK: Should autoCreate be set to false here?
6295 // Is this needed here? DestroyEx should decref already...
6304 void Move(int x, int y, int w, int h)
6306 normalAnchor = Anchor { left = x, top = y };
6307 normalSizeAnchor = SizeAnchor { size = { w, h } };
6309 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
6311 if(destroyed) return;
6313 stateAnchor = normalAnchor;
6314 stateSizeAnchor = normalSizeAnchor;
6316 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
6317 Position(x,y, w, h, true, true, true, true, false, true);
6321 DialogResult Modal(void)
6327 // FIXES MEMORY LEAK IF Create() FAILED
6333 void SetScrollArea(int width, int height, bool snapToStep)
6335 bool resize = false;
6338 int stepX = sbStep.x, stepY = sbStep.y;
6339 // Needed to make snapped down position match the skin's check of client area
6340 // against realvirtual
6343 SNAPDOWN(stepX, textCellW);
6344 SNAPDOWN(stepY, textCellH);
6345 stepX = Max(stepX, textCellW);
6346 stepY = Max(stepY, textCellH);
6348 if(scrollFlags.snapX)
6349 SNAPUP(width, stepX);
6350 if(scrollFlags.snapY)
6351 SNAPUP(height, stepY);
6354 reqScrollArea.w = width;
6355 reqScrollArea.h = height;
6356 noAutoScrollArea = (width > 0 || height > 0);
6358 UpdateScrollBars(true, true);
6361 void SetScrollPosition(int x, int y)
6364 sbh.Action(setPosition, x, 0);
6368 int seen = clientSize.w, total = reqScrollArea.w;
6370 if(scrollFlags.snapX)
6371 SNAPDOWN(seen, sbStep.x);
6373 if(!total) total = seen;
6374 range = total - seen + 1;
6375 range = Max(range, 1);
6377 if(x >= range) x = range - 1;
6379 if(scrollFlags.snapX)
6380 SNAPUP(x, sbStep.x);
6383 OnHScroll(setPosition, x, 0);
6387 SNAPDOWN(x, textCellW);
6393 sbv.Action(setPosition, y, 0);
6397 int seen = clientSize.h, total = reqScrollArea.h;
6400 if(scrollFlags.snapY)
6401 SNAPDOWN(seen, sbStep.y);
6403 if(!total) total = seen;
6404 range = total - seen + 1;
6405 range = Max(range, 1);
6407 if(y >= range) y = range - 1;
6409 if(scrollFlags.snapY)
6410 SNAPUP(y, sbStep.y);
6413 OnVScroll(setPosition, y, 0);
6416 SNAPDOWN(y, textCellH);
6421 UpdateCaret(false, false);
6424 void SetScrollLineStep(int stepX, int stepY)
6430 SNAPDOWN(stepX, textCellW);
6431 SNAPDOWN(stepY, textCellH);
6432 stepX = Max(stepX, textCellW);
6433 stepY = Max(stepY, textCellH);
6436 sbh.lineStep = stepX;
6438 sbv.lineStep = stepY;
6441 void SetState(WindowState newState, bool activate, Modifiers mods)
6445 if(state == newState || OnStateChange(newState, mods))
6447 WindowState prevState = state;
6451 // This used to be at the end of the brackets... moved for X, testing...
6452 // This has the effect of activating the window through the system...
6453 if(rootWindow == this)
6454 guiApp.interfaceDriver.SetRootWindowState(this, newState, !style.hidden);
6456 SetStateEx(newState, activate);
6458 if(rootWindow == this && !rootWindow.nativeDecorations)
6460 int x = position.x, y = position.y;
6463 x -= guiApp.desktop.absPosition.x;
6464 y -= guiApp.desktop.absPosition.y;
6466 guiApp.interfaceDriver.PositionRootWindow(this, x, y, size.w, size.h, true, true);
6470 //state = prevState;
6472 if(state != maximized && style.hasMaximize)
6475 for(child = parent.children.first; child; child = child.next)
6477 if(child != this && child.state == maximized)
6478 child.SetStateEx(normal, false);
6482 if(!style.nonClient && (sbv || sbh) && this != parent.sbv && this != parent.sbh)
6483 parent.UpdateScrollBars(true, true);
6486 // Do we really need this stuff here?
6487 // Shouldn't the Activate stuff take care of it?
6488 if(parent.rootWindow == parent && style)
6491 parent.FigureCaption(caption);
6492 guiApp.interfaceDriver.SetRootWindowCaption(parent, caption);
6493 parent.UpdateDecorations();
6497 rootWindow.ConsequentialMouseMove(false);
6504 BitmapResource GetIcon(SkinBitmap iconID)
6506 return guiApp.currentSkin.GetBitmap(iconID);
6509 void SetMouseRange(Box range)
6511 if(range || guiApp.fullScreenMode)
6516 clip.left = range.left + absPosition.x + clientStart.x;
6517 clip.top = range.top + absPosition.y + clientStart.y;
6518 clip.right = range.right + absPosition.x + clientStart.x;
6519 clip.bottom = range.bottom + absPosition.y + clientStart.y;
6523 clip.left = guiApp.desktop.box.left;
6524 clip.top = guiApp.desktop.box.top;
6525 clip.right = guiApp.desktop.box.right;
6526 clip.bottom = guiApp.desktop.box.bottom;
6528 guiApp.interfaceDriver.SetMouseRange(rootWindow, clip);
6531 guiApp.interfaceDriver.SetMouseRange(rootWindow, null);
6534 void SetMouseRangeToClient(void)
6536 if(guiApp.fullScreenMode || this != guiApp.desktop)
6538 Box box {0, 0, clientSize.w - 1, clientSize.h - 1 };
6539 box.Clip(clientArea);
6543 SetMouseRange(null);
6546 void SetMouseRangeToWindow(void)
6548 Box box { -clientStart.x, -clientStart.y, size.w-1, size.h-1 };
6549 if(this == guiApp.desktop)
6550 SetMouseRangeToClient();
6555 // x, y: Desktop Coordinates
6556 void ShowSysMenu(int x, int y)
6559 PopupMenu windowMenu { master = this, interim = true, position = { x + 1 - guiApp.desktop.position.x, y + 1 - guiApp.desktop.position.y }, menu = menu };
6562 menu, "Restore", r, NotifySelect = MenuWindowRestore,
6563 disabled = (!style.hasMaximize && !style.hasMinimize) || state == normal, bitmap = guiApp.currentSkin.GetBitmap(restore)
6567 menu, "Move", m, NotifySelect = MenuWindowMove,
6568 disabled = !style.fixed || state == maximized
6572 menu, "Size", s, NotifySelect = MenuWindowSize,
6573 disabled = !style.sizable || state != normal
6577 menu, "Minimize", n, NotifySelect = MenuWindowMinimize,
6578 disabled = !style.hasMinimize || state == minimized, bitmap = guiApp.currentSkin.GetBitmap(minimize)
6582 menu, "Maximize", KeyCode::x, NotifySelect = MenuWindowMaximize,
6583 disabled = !style.hasMaximize || state == maximized, bitmap = guiApp.currentSkin.GetBitmap(maximize)
6587 menu, "Stay On Top", t, NotifySelect = MenuWindowStayOnTop,
6588 disabled = !style.fixed, checkable = true, checked = style.stayOnTop
6590 MenuDivider { menu };
6593 menu, "Close", c, (parent == guiApp.desktop) ? altF4 : ( style.isActiveClient ? ctrlF4 : 0), NotifySelect = MenuWindowClose,
6594 bold = true, disabled = !style.hasClose, bitmap = guiApp.currentSkin.GetBitmap(close)
6596 windowMenu.Create();
6601 ActivateEx(true, true, true, true, null, null);
6604 void MakeActive(void)
6606 ActivateEx(true, false, true, false, null, null);
6609 void SoftActivate(void)
6611 if(guiApp.desktop.active)
6617 void Deactivate(void)
6619 ActivateEx(false, true, true, true, null, null);
6624 guiApp.interfaceDriver.FlashRootWindow(rootWindow);
6627 bool CycleChildren(bool backward, bool clientOnly, bool tabCycleOnly, bool cycleParents)
6629 bool result = false;
6630 if(activeChild && activeChild.cycle)
6632 Window modalWindow, child = activeChild;
6633 if(!clientOnly /*&& parent.tabCycle*/)
6635 Window next = child;
6638 if(next.cycle == (backward ? childrenCycle.first : childrenCycle.last))
6642 if(parent && parent.CycleChildren(backward, false, true, true))
6650 next = next.cycle.prev.data;
6652 next = next.cycle.next.data;
6653 if(!next.disabled && !next.inactive /*isRemote*/ && next.created && !next.nonClient && (!clientOnly || next.style.isActiveClient) && !next.style.hidden && next.FindModal() != activeChild)
6658 if(!clientOnly && child.cycle == (backward ? childrenCycle.first : childrenCycle.last) &&
6659 parent.tabCycle && parent.CycleChildren(backward, false, false))
6663 if(tabCycleOnly && !tabCycle) return false;
6670 child = child.cycle.prev.data;
6672 child = child.cycle.next.data;
6673 if(child == child.parent.activeChild)
6675 else if(!child.disabled && child.created && (!clientOnly || child.style.isActiveClient) && !child.style.hidden && child.FindModal() != activeChild)
6678 modalWindow = child.FindModal();
6681 // Scroll the window to include the active control
6682 if(sbh && !child.style.dontScrollHorz)
6684 if(child.scrolledPos.x < 0)
6685 sbh.Action(setPosition, scroll.x + child.scrolledPos.x, 0);
6686 else if(child.scrolledPos.x + child.size.w > clientSize.w)
6687 sbh.Action(setPosition, scroll.x + child.scrolledPos.x + child.size.w - clientSize.w, 0);
6689 if(sbv && !child.style.dontScrollVert)
6691 if(child.scrolledPos.y < 0)
6692 sbv.Action(setPosition, scroll.y + child.scrolledPos.y, 0);
6693 else if(child.scrolledPos.y + child.size.h > clientSize.h)
6694 sbv.Action(setPosition, scroll.y + child.scrolledPos.y + child.size.h - clientSize.h, 0);
6698 child = modalWindow ? modalWindow : child;
6699 child.ActivateEx(true, true, true, true, null, null);
6700 if(child.tabCycle && child.childrenCycle.first)
6701 child = ((OldLink)(backward ? child.childrenCycle.first : child.childrenCycle.last)).data;
6709 ConsequentialMouseMove(false);
6713 void AddResource(Resource resource)
6717 ResPtr ptr { resource = resource };
6721 // Load Graphics here if window is created already
6722 if(/*created && */display)
6724 display.Lock(false);
6725 ptr.loaded = display.displaySystem.LoadResource(resource);
6729 // Temporary hack to load font right away for listbox in dropbox ...
6730 else if(master && master.display)
6732 master.display.Lock(false);
6733 master.display.displaySystem.LoadResource(resource);
6734 master.display.Unlock();
6740 void RemoveResource(Resource resource)
6745 for(ptr = resources.first; ptr; ptr = ptr.next)
6747 if(ptr.resource == resource)
6753 // Unload Graphics here if window is created already
6754 if(/*created && */display)
6758 display.Lock(false);
6759 display.displaySystem.UnloadResource(resource, ptr.loaded);
6765 resources.Delete(ptr);
6770 void SetCaret(int x, int y, int size)
6777 if(active && !style.interim)
6779 if(visible || !guiApp.caretOwner)
6780 guiApp.caretOwner = size ? this : null;
6782 UpdateCaret(false, false);
6785 guiApp.interfaceDriver.SetCaret(0,0,0);
6786 UpdateCaret(false, true);
6787 guiApp.caretEnabled = false;
6790 else if(style.inactive && active)
6792 guiApp.interfaceDriver.SetCaret(0,0,0);
6793 UpdateCaret(false, true);
6794 guiApp.caretEnabled = false;
6799 void Scroll(int x, int y)
6801 bool opaque = !style.drawBehind || background.a;
6802 if(opaque && display && display.flags.scrolling)
6804 Box box = clientArea;
6805 box.left += clientStart.x;
6806 box.top += clientStart.y;
6807 box.right += clientStart.x;
6808 box.bottom += clientStart.y;
6810 //scrollExtent.Free(null);
6811 scrollExtent.AddBox(box);
6812 scrolledArea.x += x;
6813 scrolledArea.y += y;
6815 //scrollExtent.Free();
6816 //scrollExtent.AddBox(clientArea);
6817 //scrollExtent.Offset(clientStart.x, clientStart.y);
6818 //scrolledArea.x = x;
6819 //scrolledArea.y = y;
6825 rootWindow.dirty = true;
6828 void ReleaseCapture()
6830 if(guiApp && guiApp.windowCaptured && guiApp.windowCaptured == this)
6832 Window oldCaptured = guiApp.windowCaptured;
6833 guiApp.windowCaptured = null;
6834 guiApp.prevWindow = null;
6837 //guiApp.Log("Released Capture\n");
6839 guiApp.interfaceDriver.SetMouseCapture(null);
6841 //oldCaptured.OnMouseCaptureLost();
6844 oldCaptured.ConsequentialMouseMove(false);
6849 void SetText(char * format, ...)
6856 char caption[MAX_F_STRING];
6858 va_start(args, format);
6859 vsprintf(caption, format, args);
6862 this.caption = new char[strlen(caption)+1];
6864 strcpy(this.caption, caption);
6873 bool Grab(Bitmap bitmap, Box box, bool decorations)
6875 bool result = false;
6876 if(display || this == guiApp.desktop)
6878 Box clip = {MININT, MININT, MAXINT, MAXINT};
6884 clip.Clip(clientArea);
6886 clip.Clip(this.box);
6888 if(rootWindow != this)
6890 clip.left += absPosition.y;
6891 clip.top += absPosition.y;
6892 clip.right += absPosition.x;
6893 clip.bottom += absPosition.y;
6896 clip.left += decorations ? 0 : clientStart.x;
6897 clip.top += decorations ? 0 : clientStart.y;
6898 clip.right += decorations ? 0 : clientStart.x;
6899 clip.bottom += decorations ? 0 : clientStart.y;
6901 if(display && display.flags.flipping)
6903 rootWindow.Update(null);
6904 rootWindow.UpdateDisplay();
6911 result = window.display.displaySystem.driver.GrabScreen(null, bitmap, clip.left, clip.top,
6912 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6916 result = display.Grab(bitmap, clip.left, clip.top,
6917 clip.right - clip.left + 1, clip.bottom - clip.top + 1);
6919 if(bitmap.pixelFormat != pixelFormat888 && bitmap.pixelFormat != pixelFormat8)
6921 if(!bitmap.Convert(null, pixelFormat888, null))
6928 void GetMousePosition(int * x, int * y)
6930 int mouseX = 0, mouseY = 0;
6931 if(!guiApp.acquiredWindow && (guiApp.desktop.active || !guiApp.fullScreenMode))
6934 guiApp.interfaceDriver.GetMousePosition(&mouseX, &mouseY);
6935 if(this != guiApp.desktop)
6937 mouseX -= absPosition.x + clientStart.x;
6938 mouseY -= absPosition.y + clientStart.y;
6945 DialogResult DoModal()
6947 DialogResult returnCode = 0;
6948 int terminated = terminateX;
6951 while(!destroyed && guiApp.driver != null)
6953 if(terminateX != terminated)
6955 terminated = terminateX;
6956 guiApp.desktop.Destroy(0);
6957 if(guiApp.desktop.created)
6960 //printf("Resetting terminate X to 0\n");
6966 guiApp.UpdateDisplay();
6967 if(!guiApp.ProcessInput(false))
6970 returnCode = this.returnCode;
6983 return !destroyed && guiApp.driver != null && terminateX < 2;
6986 DialogResult DoModalEnd()
6988 DialogResult returnCode = this.returnCode;
6993 // --- Window manipulation ---
6994 /*bool GetDisabled()
6996 bool disabled = this.disabled;
6998 for(window = this; (window = window.master); )
7009 // --- Mouse Manipulation ---
7010 void GetNCMousePosition(int * x, int * y)
7012 GetMousePosition(x, y);
7013 if(x) *x += clientStart.x;
7014 if(y) *y += clientStart.y;
7017 // --- Carets manipulation ---
7018 void GetCaretPosition(Point caretPos)
7020 caretPos = this.caretPos;
7023 int GetCaretSize(void)
7028 bool ButtonCloseDialog(Button button, int x, int y, Modifiers mods)
7034 bool CloseConfirmation(bool parentClosing)
7047 if(!OnClose(parentClosing))
7050 // If you want to skip this, simply set modifiedDocument to false in OnClose
7051 if(result && (/*fileName || */style.isDocument) && modifiedDocument)
7053 DialogResult dialogRes;
7056 sprintf(message, "Save changes to %s?", fileName);
7058 sprintf(message, "Save changes to Untitled %d?", documentID);
7060 dialogRes = MessageBox { master = master, type = yesNoCancel, text = parent.caption, contents = message }.Modal();
7062 if(dialogRes == yes)
7064 // TOFIX: Precomp error if brackets are taken out
7065 result = (DialogResult)MenuFileSave(null, 0) != cancel;
7067 else if(dialogRes == cancel)
7073 for(slave = slaves.first; slave; slave = slave.next)
7074 if(!((Window)slave.data).CloseConfirmation(true))
7076 // ((Window)slave.data).CloseConfirmation(true);
7084 for(child = children.first; child; child = child.next)
7085 if(child.master != this && !child.CloseConfirmation(true))
7095 // Static methods... move them somewhere else?
7096 void ::RestoreCaret()
7098 if(guiApp.caretOwner)
7099 guiApp.caretOwner.UpdateCaret(false, false);
7102 void ::FreeMouseRange()
7104 guiApp.interfaceDriver.SetMouseRange(null, null);
7108 bool MenuFileClose(MenuItem selection, Modifiers mods)
7110 Window document = activeChild;
7112 document.Destroy(0);
7116 bool MenuFileExit(MenuItem selection, Modifiers mods)
7122 bool MenuFileSave(MenuItem selection, Modifiers mods)
7126 fileMonitor.fileName = null;
7129 if(OnSaveFile(fileName))
7131 //if(OnFileModified != Window::OnFileModified)
7134 fileMonitor.fileName = fileName;
7140 MessageBox dialog { master = master, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7141 DialogResult answer = dialog.Modal();
7143 if(answer != yes) return (bool)answer;
7146 return MenuFileSaveAs(selection, mods);
7149 bool MenuFileSaveAs(MenuItem selection, Modifiers mods)
7151 DialogResult result = (DialogResult)bool::true;
7152 FileDialog fileDialog = saveDialog;
7155 fileDialog = FileDialog {};
7160 fileDialog.filePath = fileName;
7163 char filePath[MAX_FILENAME];
7164 sprintf(filePath, "Untitled %d", documentID);
7165 fileDialog.filePath = filePath;
7167 fileMonitor.fileName = null;
7169 fileDialog.type = save;
7170 fileDialog.text = "Save As";
7174 fileDialog.master = master.parent ? master : this;
7175 if(fileDialog.Modal() == ok)
7177 char * filePath = fileDialog.filePath;
7179 if(OnSaveFile(filePath))
7182 property::fileName = filePath;
7183 NotifySaved(master, this, filePath);
7188 MessageBox dialog { master = master.parent ? master : this, type = yesNoCancel, text = "Error writing file", contents = "Save as a different file?" };
7189 DialogResult answer = dialog.Modal();
7204 //if(OnFileModified != Window::OnFileModified && fileName)
7207 fileMonitor.fileName = fileName;
7211 return (bool)result; // Actually returning result from Yes/NoCancel message box
7214 bool MenuFileSaveAll(MenuItem selection, Modifiers mods)
7216 Window document = activeChild;
7218 for(document = children.first; document; document = next)
7220 next = document.next;
7221 if(document.style.isDocument || document.fileName)
7222 document.MenuFileSave(selection, mods);
7227 bool MenuWindowArrangeIcons(MenuItem selection, Modifiers mods)
7231 for(document = children.first; document; document = document.next)
7232 //if(document.style.isDocument && document.state == minimized)
7233 if(document.style.isActiveClient && document.state == minimized)
7234 document.SetState(minimized, false, mods);
7238 bool MenuWindowCascade(MenuItem selection, Modifiers mods)
7240 Window document = activeChild;
7243 Window firstDocument = null;
7245 OldLink cycle = document.cycle.prev;
7250 if(child.style.isActiveClient && !child.style.hidden)
7254 firstDocument = child;
7255 if(child.state == minimized)
7256 child.SetState(minimized, false, mods);
7259 child.positionID = id++;
7260 child.SetState(normal, false, mods);
7261 child.anchor.left.type = cascade;
7264 child.normalSizeAnchor = *&child.sizeAnchor;
7265 child.normalAnchor = child.anchor;
7267 // Break the anchors for moveable/resizable windows
7268 if(child.style.fixed)
7270 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7272 (*&child.normalAnchor).left = x;
7273 (*&child.normalAnchor).top = y;
7274 (*&child.normalAnchor).right.type = none;
7275 (*&child.normalAnchor).bottom.type = none;
7277 child.normalSizeAnchor.isClientW = false;
7278 child.normalSizeAnchor.isClientH = false;
7279 child.normalSizeAnchor.size.w = w;
7280 child.normalSizeAnchor.size.h = h;
7281 child.anchored = false;
7284 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7286 child.stateAnchor = child.normalAnchor;
7287 child.stateSizeAnchor = child.normalSizeAnchor;
7289 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7290 child.Position(x, y, w, h, true, true, true, true, false, false);
7295 last = children.last;
7296 if(!child.style.stayOnTop)
7297 for(; last && last.style.stayOnTop; last = last.prev);
7298 children.Move(child, last);
7299 childrenOrder.Move(child.order, childrenOrder.last);
7301 if(cycle == document.cycle) break;
7305 firstDocument.Activate();
7310 bool MenuWindowClose(MenuItem selection, Modifiers mods)
7317 // Close all closes all active clients, not all documents
7318 bool MenuWindowCloseAll(MenuItem selection, Modifiers mods)
7320 Window next, document;
7322 for(document = children.first; document; document = next)
7324 for(next = document.next; next && !(next.style.isActiveClient; next = next.next);
7325 if(document.style.isActiveClient)
7326 if(!document.Destroy(0) && !document.style.hidden)
7332 bool MenuWindowMaximize(MenuItem selection, Modifiers mods)
7334 if(style.hasMaximize && state != maximized)
7335 SetState(maximized, 0, 0);
7339 bool MenuWindowMinimize(MenuItem selection, Modifiers mods)
7341 if(style.hasMinimize && state != minimized)
7343 SetState(minimized, 0, 0);
7344 parent.CycleChildren(false, true, false, true);
7349 bool MenuWindowMove(MenuItem selection, Modifiers mods)
7351 MenuMoveOrSize(false, selection ? true : false);
7355 bool MenuWindowNext(MenuItem selection, Modifiers mods)
7357 CycleChildren(false, true, false, true);
7361 bool MenuWindowPrevious(MenuItem selection, Modifiers mods)
7363 CycleChildren(true, true, false, true);
7367 bool MenuWindowSize(MenuItem selection, Modifiers mods)
7369 MenuMoveOrSize(true, true);
7373 bool MenuWindowRestore(MenuItem selection, Modifiers mods)
7376 SetState(normal, 0, 0);
7380 bool MenuWindowSelectWindow(MenuItem selection, Modifiers mods)
7383 int id = selection.id;
7384 OldLink cycle = activeClient.cycle;
7386 //for(c = 0, cycle = activeChild.cycle; c<id; cycle = cycle.next, c++);
7389 Window sibling = cycle.data;
7390 if(sibling.style.isActiveClient)
7398 document = cycle.data;
7399 document.Activate();
7401 //if(activeChild.state == maximized)
7402 // document.SetState(maximized, false, mods);
7403 //else if(document.state == minimized)
7404 // document.SetState(normal, false, mods);
7408 bool MenuWindowStayOnTop(MenuItem selection, Modifiers mods)
7410 stayOnTop = !style.stayOnTop;
7414 bool MenuWindowTileHorz(MenuItem selection, Modifiers mods)
7416 Window document = activeChild;
7419 Window firstDocument = null;
7420 OldLink cycle = document.cycle;
7424 Window child = cycle.data;
7425 if(child.style.isActiveClient && !child.style.hidden)
7427 if(!firstDocument) firstDocument = child;
7428 if(child.state == minimized)
7429 child.SetState(minimized, false, mods);
7432 child.positionID = id++;
7433 child.SetState(normal, false, mods);
7434 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7436 child.anchor.left.type = hTiled;
7439 child.normalSizeAnchor = *&child.sizeAnchor;
7440 child.normalAnchor = child.anchor;
7442 // Break the anchors for moveable/resizable windows
7443 if(child.style.fixed)
7445 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7447 (*&child.normalAnchor).left = x;
7448 (*&child.normalAnchor).top = y;
7449 (*&child.normalAnchor).right.type = none;
7450 (*&child.normalAnchor).bottom.type = none;
7451 child.normalSizeAnchor.isClientW = false;
7452 child.normalSizeAnchor.isClientH = false;
7453 child.normalSizeAnchor.size.w = w;
7454 child.normalSizeAnchor.size.h = h;
7455 child.anchored = false;
7458 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7460 child.stateAnchor = child.normalAnchor;
7461 child.stateSizeAnchor = child.normalSizeAnchor;
7463 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7464 child.Position(x,y, w, h, true, true, true, true, false, true);
7469 if((cycle = cycle.next) == document.cycle) break;
7472 firstDocument.Activate();
7477 bool MenuWindowTileVert(MenuItem selection, Modifiers mods)
7479 Window document = activeChild;
7482 Window firstDocument = null;
7484 OldLink cycle = document.cycle;
7489 //if(child.style.isDocument)
7490 if(child.style.isActiveClient && !child.style.hidden)
7492 if(!firstDocument) firstDocument = child;
7493 if(child.state == minimized)
7494 child.SetState(minimized, false, mods);
7497 child.positionID = id++;
7498 child.SetState(normal, false, mods);
7499 child.ActivateEx(true, false, false, false, null, null); // To move active clients on top of other windows
7501 child.anchor.left.type = vTiled;
7504 child.normalSizeAnchor = *&child.sizeAnchor;
7505 child.normalAnchor = child.anchor;
7507 // Break the anchors for moveable/resizable windows
7508 if(child.style.fixed)
7510 child.ComputeAnchors(child.anchor, *&child.sizeAnchor, &x, &y, &w, &h);
7512 (*&child.normalAnchor).left = x;
7513 (*&child.normalAnchor).top = y;
7514 (*&child.normalAnchor).right.type = none;
7515 (*&child.normalAnchor).bottom.type = none;
7516 child.normalSizeAnchor.isClientW = false;
7517 child.normalSizeAnchor.isClientH = false;
7518 child.normalSizeAnchor.size.w = w;
7519 child.normalSizeAnchor.size.h = h;
7520 child.anchored = false;
7523 if(child.state == normal /*|| child.state == Hidden */) // Hidden is new here ...
7525 child.stateAnchor = child.normalAnchor;
7526 child.stateSizeAnchor = child.normalSizeAnchor;
7528 child.ComputeAnchors(child.stateAnchor, child.stateSizeAnchor, &x, &y, &w, &h);
7529 child.Position(x,y, w, h, true, true, true, true, false, true);
7534 if((cycle = cycle.next) == document.cycle) break;
7537 firstDocument.Activate();
7542 bool MenuWindowWindows(MenuItem selection, Modifiers mods)
7544 WindowList dialog { master = this };
7545 Window document = (Window)dialog.Modal();
7548 if(activeChild.state == maximized)
7549 document.SetState(maximized, false, mods);
7550 else if(document.state == minimized)
7551 document.SetState(normal, false, mods);
7552 document.Activate();
7558 virtual bool OnCreate(void);
7559 virtual void OnDestroy(void);
7560 virtual void OnDestroyed(void);
7561 virtual bool OnClose(bool parentClosing);
7562 virtual bool OnStateChange(WindowState state, Modifiers mods);
7563 virtual bool OnPostCreate(void);
7564 virtual bool OnMoving(int *x, int *y, int w, int h);
7565 virtual bool OnResizing(int *width, int *height);
7566 virtual void OnResize(int width, int height);
7567 virtual void OnPosition(int x, int y, int width, int height);
7568 virtual bool OnLoadGraphics(void);
7569 virtual void OnApplyGraphics(void);
7570 virtual void OnUnloadGraphics(void);
7571 virtual void OnRedraw(Surface surface);
7572 virtual bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct);
7573 virtual void OnActivateClient(Window client, Window previous);
7574 virtual bool OnKeyDown(Key key, unichar ch);
7575 virtual bool OnKeyUp(Key key, unichar ch);
7576 virtual bool OnKeyHit(Key key, unichar ch);
7577 virtual bool OnSysKeyDown(Key key, unichar ch);
7578 virtual bool OnSysKeyUp(Key key, unichar ch);
7579 virtual bool OnSysKeyHit(Key key, unichar ch);
7580 virtual bool OnMouseOver(int x, int y, Modifiers mods);
7581 virtual bool OnMouseLeave(Modifiers mods);
7582 virtual bool OnMouseMove(int x, int y, Modifiers mods);
7583 virtual bool OnLeftButtonDown(int x, int y, Modifiers mods);
7584 virtual bool OnLeftButtonUp(int x, int y, Modifiers mods);
7585 virtual bool OnLeftDoubleClick(int x, int y, Modifiers mods);
7586 virtual bool OnRightButtonDown(int x, int y, Modifiers mods);
7587 virtual bool OnRightButtonUp(int x, int y, Modifiers mods);
7588 virtual bool OnRightDoubleClick(int x, int y, Modifiers mods);
7589 virtual bool OnMiddleButtonDown(int x, int y, Modifiers mods);
7590 virtual bool OnMiddleButtonUp(int x, int y, Modifiers mods);
7591 virtual bool OnMiddleDoubleClick(int x, int y, Modifiers mods);
7592 virtual void OnMouseCaptureLost(void);
7593 virtual void OnHScroll(ScrollBarAction action, int position, Key key);
7594 virtual void OnVScroll(ScrollBarAction action, int position, Key key);
7595 virtual void OnDrawOverChildren(Surface surface);
7596 virtual bool OnFileModified(FileChange fileChange, char * param);
7597 virtual bool OnSaveFile(char * fileName);
7599 // Skins Virtual Functions
7600 virtual void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h);
7601 virtual void SetWindowMinimum(MinMaxValue * mw, MinMaxValue * mh);
7602 virtual void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
7607 virtual void ShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7608 virtual void PreShowDecorations(Font captionFont, Surface surface, char * name, bool active, bool moving);
7609 virtual bool IsMouseMoving(int x, int y, int w, int h);
7610 virtual bool IsMouseResizing(int x, int y, int w, int h, bool *resizeX, bool *resizeY, bool *resizeEndX, bool *resizeEndY);
7611 virtual void UpdateNonClient();
7612 virtual void SetBox(Box box);
7613 virtual bool IsInside(int x, int y)
7615 return box.IsPointInside({x, y});
7617 virtual bool IsOpaque()
7619 return (!style.drawBehind || background.a == 255);
7623 virtual bool Window::NotifyActivate(Window window, bool active, Window previous);
7624 virtual void Window::NotifyDestroyed(Window window, DialogResult result);
7625 virtual void Window::NotifySaved(Window window, char * filePath);
7630 property Window parent
7632 property_category "Layout"
7635 if(value || guiApp.desktop)
7638 Window oldParent = parent;
7639 Anchor anchor = this.anchor;
7641 if(value && value.IsDescendantOf(this)) return;
7642 if(value && value == this)
7644 if(!value) value = guiApp.desktop;
7646 if(value == oldParent) return;
7648 if(!master || (master == this.parent && master == guiApp.desktop))
7649 property::master = value;
7653 parent.children.Remove(this);
7657 box.left - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7658 box.top - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y,
7659 box.right - absPosition.x + parent.absPosition.x + style.nonClient * parent.clientStart.x,
7660 box.bottom - absPosition.y + parent.absPosition.y + style.nonClient * parent.clientStart.y
7664 last = value.children.last;
7666 if(style.isDocument)
7669 parent.numDocuments--;
7670 documentID = value.GetDocumentID();
7673 if(style.isActiveClient && !style.hidden)
7675 if(parent && parent != guiApp.desktop && !(style.hidden))
7677 if(state == minimized) parent.numIcons--;
7678 parent.numPositions--;
7682 if(!style.stayOnTop)
7683 for(; last && last.style.stayOnTop; last = last.prev);
7685 value.children.Insert(last, this);
7687 // *** NEW HERE: ***
7689 parent.childrenCycle.Delete(cycle);
7691 parent.childrenOrder.Delete(order);
7699 int x = position.x, y = position.y, w = size.w, h = size.h;
7703 x += parent.absPosition.x - value.absPosition.x + parent.clientStart.x - value.clientStart.x;
7704 y += parent.absPosition.y - value.absPosition.y + parent.clientStart.y - value.clientStart.y;
7706 vpw = value.clientSize.w;
7707 vph = value.clientSize.h;
7713 else if(style.fixed)
7715 if(!style.dontScrollHorz && value.scrollArea.w) vpw = value.scrollArea.w;
7716 if(!style.dontScrollVert && value.scrollArea.h) vph = value.scrollArea.h;
7719 anchor = this.anchor;
7721 if(anchor.left.type == offset) anchor.left.distance = x;
7722 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
7723 if(anchor.top.type == offset) anchor.top.distance = y;
7724 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
7725 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
7726 //else if(anchor.right.type == relative) anchor.right.percent = 1.0-(float) (vpw - (x + w)) / vpw;
7727 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
7728 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
7729 //else if(anchor.bottom.type == relative) anchor.bottom.percent = 1.0-(float) (vph - (y + h)) / vph;
7730 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
7732 if(!anchor.left.type && !anchor.right.type)
7734 anchor.horz.distance = (x + w / 2) - (vpw / 2);
7735 //anchor.horz.type = anchor.horz.distance ? AnchorValueOffset : 0;
7737 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
7738 if(!anchor.top.type && !anchor.bottom.type)
7740 anchor.vert.distance = (y + h / 2) - (vph / 2);
7741 //anchor.vert.type = anchor.vert.distance ? AnchorValueOffset : 0;
7743 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
7751 parent.childrenCycle.Insert(
7752 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
7753 cycle = OldLink { data = this });
7754 parent.childrenOrder.Insert(
7755 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
7756 order = OldLink { data = this });
7759 if(!style.hidden && style.isActiveClient)
7761 positionID = parent.GetPositionID(this);
7762 parent.numPositions++;
7763 if(state == minimized) parent.numIcons--;
7766 // *** FONT INHERITANCE ***
7767 if(!setFont && oldParent)
7768 stopwatching(oldParent, font);
7772 RemoveResource(systemFont);
7775 // TESTING WITH WATCHERS:
7776 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7777 // usedFont = setFont ? setFont : (systemFont);
7781 if(guiApp.currentSkin)
7783 systemFont = guiApp.currentSkin.SystemFont();
7786 usedFont = systemFont;
7787 AddResource(systemFont);
7795 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
7804 if(value.rootWindow && value.rootWindow.display && rootWindow)
7806 bool reloadGraphics = (oldParent.rootWindow == oldParent && value.rootWindow) || (!value.rootWindow && rootWindow == this) ||
7807 (value.rootWindow.display && value.rootWindow.display.displaySystem != rootWindow.display.displaySystem);
7810 UnloadGraphics(false);
7813 LoadGraphics(false, false);
7816 if(value.rootWindow != rootWindow)
7817 DisplayModeChanged();
7821 scrolledPos.x = MININT; // Prevent parent update
7822 property::anchor = anchor;
7826 if(guiApp.currentSkin)
7827 guiApp.currentSkin.SetWindowMinimum(this, &skinMinSize.w, &skinMinSize.h);
7829 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7830 Position(x, y, w, h, true, true, true, true, false, true);
7835 // else parent = value;
7838 get { return parent; }
7841 property Window master
7843 property_category "Behavior"
7846 //if(this == value) return;
7847 if(value && value.IsSlaveOf(this)) return;
7853 OldLink slaveHolder;
7854 for(slaveHolder = master.slaves.first; slaveHolder; slaveHolder = slaveHolder.next)
7855 if(slaveHolder.data == this)
7857 master.slaves.Delete(slaveHolder);
7864 value.slaves.Add(OldLink { data = this });
7869 master.hotKeys.Remove(hotKey);
7870 value.hotKeys.Add(hotKey);
7873 if(master && master.defaultControl == this)
7874 master.defaultControl = null;
7876 if(style.isDefault && !value.defaultControl)
7877 value.defaultControl = this;
7883 get { return master ? master : parent; }
7886 property char * text
7888 property_category "Appearance"
7895 caption = new char[strlen(value)+1];
7897 strcpy(caption, value);
7902 get { return caption; }
7907 property_category "Behavior"
7916 master.hotKeys.Add(hotKey = HotKeySlot { });
7920 hotKey.window = this;
7925 master.hotKeys.Delete(hotKey);
7930 get { return hotKey ? hotKey.key : 0; }
7933 property Color background
7935 property_category "Appearance"
7938 background.color = value;
7943 if(this == rootWindow)
7944 guiApp.interfaceDriver.SetRootWindowColor(this);
7947 get { return background.color; }
7950 property Percentage opacity
7952 property_category "Appearance"
7955 background.a = (byte)Min(Max((int)(value * 255), 0), 255);
7956 drawBehind = background.a ? false : true;
7958 get { return background.a / 255.0f; }
7961 property Color foreground
7963 property_category "Appearance"
7971 get { return foreground; }
7974 property BorderStyle borderStyle
7976 property_category "Appearance"
7979 if(!((BorderBits)value).fixed)
7981 style.hasClose = false;
7982 style.hasMaximize = false;
7983 style.hasMinimize = false;
7985 style.borderBits = value;
7989 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
7991 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
7992 Position(x, y, w, h, true, true, true, true, false, true);
7993 CreateSystemChildren();
7996 get { return (BorderStyle)style.borderBits; }
7999 property Size minClientSize
8001 property_category "Layout"
8002 set { minSize = value; }
8003 get { value = minSize; }
8006 property Size maxClientSize
8008 property_category "Layout"
8009 set { maxSize = value; }
8010 get { value = maxSize; }
8013 property bool hasMaximize
8015 property_category "Window Style"
8018 style.hasMaximize = value;
8019 if(value) { style.fixed = true; style.contour = true; }
8023 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
8025 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8026 Position(x, y, w, h, true, true, true, true, false, true);
8028 CreateSystemChildren();
8031 get { return style.hasMaximize; }
8034 property bool hasMinimize
8036 property_category "Window Style"
8039 style.hasMinimize = value;
8040 if(value) { style.fixed = true; style.contour = true; }
8044 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
8046 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8047 Position(x, y, w, h, true, true, true, true, false, true);
8049 CreateSystemChildren();
8052 get { return style.hasMinimize; }
8055 property bool hasClose
8057 property_category "Window Style"
8060 style.hasClose = value;
8061 if(value) { style.fixed = true; style.contour = true; }
8065 SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
8066 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8067 Position(x, y, w, h, true, true, true, true, false, true);
8068 CreateSystemChildren();
8071 get { return style.hasClose; }
8074 property bool nonClient
8076 property_category "Layout"
8079 style.nonClient = value;
8081 style.stayOnTop = true;
8083 get { return style.nonClient; }
8086 property bool inactive
8088 property_category "Behavior"
8093 // *** NEW HERE: ***
8097 parent.childrenCycle.Delete(cycle);
8099 parent.childrenOrder.Delete(order);
8106 active = false; // true;
8107 if(parent.activeChild == this)
8108 parent.activeChild = null;
8109 if(parent.activeClient == this)
8110 parent.activeClient = null;
8119 parent.childrenCycle.Insert(
8120 (parent.activeChild && parent.activeChild.cycle) ? parent.activeChild.cycle.prev : null,
8121 cycle = OldLink { data = this });
8123 parent.childrenOrder.Insert(
8124 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8125 order = OldLink { data = this });
8128 style.inactive = value;
8130 get { return style.inactive; }
8133 property bool clickThrough
8135 property_category "Behavior"
8136 set { style.clickThrough = value; }
8137 get { return style.clickThrough; }
8140 property bool isRemote
8142 property_category "Behavior"
8143 set { style.isRemote = value; }
8144 get { return style.isRemote; }
8147 property bool noCycle
8149 property_category "Behavior"
8150 set { style.noCycle = value; }
8151 get { return style.noCycle; }
8154 property bool isModal
8156 property_category "Behavior"
8157 set { style.modal = value; }
8158 get { return style.modal; }
8161 property bool interim
8163 property_category "Behavior"
8164 set { style.interim = value; }
8165 get { return style.interim; }
8168 property bool tabCycle
8170 property_category "Behavior"
8171 set { style.tabCycle = value; }
8172 get { return style.tabCycle; }
8175 property bool isDefault
8177 property_category "Behavior"
8185 /*for(sibling = parent.children.first; sibling; sibling = sibling.next)
8186 if(sibling != this && sibling.style.isDefault)
8187 sibling.style.isDefault = false;*/
8188 if(master.defaultControl)
8189 master.defaultControl.style.isDefault = false;
8190 master.defaultControl = this;
8192 else if(master.defaultControl == this)
8193 master.defaultControl = null;
8197 style.isDefault = value;
8199 Position(position.x, position.y, size.w, size.h, true, true, true,true,true, true);
8201 get { return style.isDefault; }
8204 property bool drawBehind
8206 property_category "Window Style"
8207 set { style.drawBehind = value; }
8208 get { return style.drawBehind; }
8211 property bool hasMenuBar
8213 property_category "Window Style"
8223 if(created && !menuBar)
8230 anchor = Anchor { top = 23, left = 1, right = 1 },
8232 inactive = true, nonClient = true
8237 else if(created && menuBar)
8242 style.hasMenuBar = value;
8244 get { return style.hasMenuBar; }
8247 property bool hasStatusBar
8249 property_category "Window Style"
8256 statusBar = StatusBar { this };
8264 style.hasStatusBar = value;
8266 get { return style.hasStatusBar; }
8268 property bool stayOnTop
8270 property_category "Window Style"
8275 if(created && !style.stayOnTop)
8277 if(rootWindow == this)
8278 guiApp.interfaceDriver.OrderRootWindow(this, true);
8279 else if(parent.children.last != this)
8281 parent.children.Move(this, parent.children.last);
8285 style.stayOnTop = true;
8289 if(created && style.stayOnTop)
8291 if(rootWindow == this)
8292 guiApp.interfaceDriver.OrderRootWindow(this, false);
8299 for(order = (this.order == parent.childrenOrder.first) ? null : this.order.prev;
8300 order && ((Window)order.data).style.stayOnTop;
8301 order = (order == parent.childrenOrder.first) ? null : order.prev);
8302 last = order ? order.data : null;
8306 for(last = parent.children.last;
8307 last && last.style.stayOnTop;
8311 parent.children.Move(this, last);
8315 style.stayOnTop = false;
8318 get { return style.stayOnTop; }
8323 property_category "Window Style"
8333 if(menuBar && !value)
8340 if(!menuBar && style.hasMenuBar && value)
8344 this, menu = value, isMenuBar = true,
8345 anchor = Anchor { left = 1, top = 23, right = 1 }, size.h = 24,
8346 inactive = true, nonClient = true
8350 UpdateActiveDocument(null);
8353 get { return menu; }
8356 property FontResource font
8358 property_category "Appearance"
8360 isset { return setFont ? true : false; }
8365 if(value && !setFont) { stopwatching(parent, font); }
8366 else if(!value && setFont)
8372 usedFont = setFont ? setFont : (parent.parent ? parent.usedFont : systemFont);
8381 RemoveResource(setFont);
8386 RemoveResource(systemFont);
8393 AddResource(setFont);
8396 usedFont = setFont ? setFont : ((parent && parent.parent) ? parent.usedFont : systemFont);
8399 systemFont = guiApp.currentSkin.SystemFont();
8401 usedFont = systemFont;
8402 AddResource(systemFont);
8410 get { return usedFont; }
8413 property SizeAnchor sizeAnchor
8415 property_category "Layout"
8418 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8419 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8420 sizeAnchor.isClientW != sizeAnchor.isClientH;
8427 normalSizeAnchor = sizeAnchor;
8429 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8431 stateAnchor = normalAnchor;
8432 stateSizeAnchor = normalSizeAnchor;
8434 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8435 Position(x,y, w, h, true, true, true, true, false, true);
8442 { sizeAnchor.isClientW ? clientSize.w : size.w, sizeAnchor.isClientH ? clientSize.h : size.h },
8443 sizeAnchor.isClientW,
8444 sizeAnchor.isClientH
8451 property_category "Layout"
8454 Anchor thisAnchor = anchor;
8455 SizeAnchor thisSizeAnchor = sizeAnchor;
8456 bool leftRight = (anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none);
8457 bool topBottom = (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none);
8458 bool isClient = !sizeAnchor.isClientW && !sizeAnchor.isClientH;
8459 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8460 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8461 !sizeAnchor.isClientW && !sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8467 sizeAnchor.isClientW = false;
8468 sizeAnchor.isClientH = false;
8469 sizeAnchor.size = value;
8471 normalSizeAnchor = sizeAnchor;
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);
8482 get { value = size; }
8485 property Size clientSize
8487 property_category "Layout"
8490 return ((anchor.left.type == none || anchor.left.type == middleRelative || anchor.right.type == none) ||
8491 (anchor.top.type == none || anchor.top.type == middleRelative || anchor.bottom.type == none)) &&
8492 sizeAnchor.isClientW && sizeAnchor.isClientH && sizeAnchor.size.w && sizeAnchor.size.h;
8497 sizeAnchor.isClientW = true;
8498 sizeAnchor.isClientH = true;
8499 sizeAnchor.size = value;
8501 normalSizeAnchor = sizeAnchor;
8503 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8505 stateAnchor = normalAnchor;
8506 stateSizeAnchor = normalSizeAnchor;
8508 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8509 Position(x,y, w, h, true, true, true, true, false, true);
8512 get { value = clientSize; }
8515 property Size initSize { get { value = sizeAnchor.size; } };
8517 property Anchor anchor
8519 property_category "Layout"
8520 isset { return (anchor.left.type != offset || anchor.top.type != offset || anchor.right.type || anchor.bottom.type); }
8526 if(anchor.left.type && anchor.right.type && (!value.left.type || !value.right.type))
8528 normalSizeAnchor.isClientW = sizeAnchor.isClientW = false;
8529 normalSizeAnchor.size.w = sizeAnchor.size.w = size.w;
8531 if(anchor.top.type && anchor.bottom.type && (!value.top.type || !value.bottom.type))
8533 normalSizeAnchor.isClientH = sizeAnchor.isClientH = false;
8534 normalSizeAnchor.size.h = sizeAnchor.size.h = size.h;
8538 if(anchor.right.type && (anchor.horz.type == middleRelative || !anchor.left.type))
8540 anchor.left.distance = 0;
8541 anchor.horz.type = 0;
8543 if(anchor.bottom.type && (anchor.vert.type == middleRelative || !anchor.top.type))
8545 anchor.top.distance = 0;
8546 anchor.vert.type = 0;
8555 normalAnchor = anchor;
8557 // Break the anchors for moveable/resizable windows
8558 /*if(style.fixed ) //&& value.left.type == cascade)
8560 ComputeAnchors(anchor, sizeAnchor, &x, &y, &w, &h);
8562 this.anchor = normalAnchor = Anchor { left = x, top = y };
8563 normalSizeAnchor = SizeAnchor { { w, h } };
8566 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8568 stateAnchor = normalAnchor;
8569 stateSizeAnchor = normalSizeAnchor;
8571 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8572 Position(x, y, w, h, true, true, true, true, false, true);
8581 get { value = this ? anchor : Anchor { }; }
8584 property Point position
8586 property_category "Layout"
8589 if(value == null) return;
8591 anchor.left = value.x;
8592 anchor.top = value.y;
8593 anchor.right.type = none;
8594 anchor.bottom.type = none;
8599 normalAnchor = anchor;
8601 // Break the anchors for moveable/resizable windows
8605 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8607 normalAnchor.left = x;
8608 normalAnchor.top = y;
8609 normalAnchor.right.type = none;
8610 normalAnchor.bottom.type = none;
8611 normalSizeAnchor.size.width = w;
8612 normalSizeAnchor.size.height = h;
8616 if(state == normal /*|| state == Hidden */) // Hidden is new here ...
8618 stateAnchor = normalAnchor;
8619 stateSizeAnchor = normalSizeAnchor;
8621 ComputeAnchors(stateAnchor, stateSizeAnchor, &x, &y, &w, &h);
8622 Position(x,y, w, h, true, true, true, true, false, true);
8626 get { value = position; }
8629 property bool disabled
8631 property_category "Behavior"
8634 if(this && disabled != value)
8641 get { return (bool)disabled; }
8644 property bool isEnabled
8649 for(parent = this; parent; parent = parent.parent)
8656 property WindowState state
8658 property_category "Behavior"
8659 set { SetState(value, false, 0); }
8660 get { return this ? state : 0; }
8663 property bool visible
8665 property_category "Behavior"
8668 if(this && !value && !style.hidden && parent)
8670 bool wasActiveChild = parent.activeChild == this;
8671 Window client = null;
8673 style.hidden = true;
8674 if(style.isActiveClient)
8676 parent.numPositions--;
8677 if(state == minimized) parent.numIcons--;
8682 OldLink prevOrder = null;
8684 if(rootWindow == this)
8685 guiApp.interfaceDriver.SetRootWindowState(this, state, false);
8688 Box box { scrolledPos.x, scrolledPos.y, scrolledPos.x + size.w - 1, scrolledPos.y + size.h - 1 };
8691 box.left -= parent.clientStart.x;
8692 box.top -= parent.clientStart.y;
8693 box.right -= parent.clientStart.x;
8694 box.bottom -= parent.clientStart.y;
8698 if(_isModal && master && master.modalSlave == this)
8699 master.modalSlave = null;
8703 OldLink tmpPrev = order.prev;
8704 client = tmpPrev ? tmpPrev.data : null;
8705 if(client && !client.style.hidden && !client.destroyed && client.created)
8706 prevOrder = tmpPrev;
8709 client = tmpPrev ? tmpPrev.data : null;
8710 if(client == this) { client = null; break; }
8711 if(client && ((client.style.hidden) || client.destroyed || !client.created))
8713 tmpPrev = client.order.prev;
8718 prevOrder = tmpPrev;
8723 // If this window can be an active client, make sure the next window we activate can also be one
8724 if(!style.nonClient && style.isActiveClient)
8726 tmpPrev = prevOrder;
8729 client = tmpPrev ? tmpPrev.data : null;
8730 if(client == this) { client = null; break; }
8731 if(client && (client.style.nonClient || !client.style.isActiveClient || client.style.hidden || client.destroyed || !client.created))
8733 tmpPrev = client.order.prev;
8738 prevOrder = tmpPrev;
8742 if(client && client.style.hidden) client = null;
8746 if((wasActiveChild /*parent.activeChild == this*/ || guiApp.interimWindow == this) && true /*activate*/)
8748 if(order && prevOrder && prevOrder.data != this)
8749 ((Window)prevOrder.data).ActivateEx(true, false, false, true, null, null);
8751 ActivateEx(false, false, false, true, null, null);
8753 // TESTING THIS HERE FOR HIDING ACTIVE CLIENT
8754 if(parent.activeClient == this)
8756 parent.activeClient = null;
8757 parent.UpdateActiveDocument(null);
8760 else if(parent.activeClient == this)
8762 parent.activeClient = client;
8763 parent.UpdateActiveDocument(this);
8766 // *** Not doing this anymore ***
8769 parent.childrenCycle.Delete(cycle);
8771 parent.childrenOrder.Delete(order);
8776 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8781 else if(this && value && style.hidden)
8783 style.hidden = false;
8786 SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8787 if(rootWindow == this)
8788 guiApp.interfaceDriver.SetRootWindowState(this, state, true);
8790 if(_isModal && master)
8791 master.modalSlave = this;
8793 if(style.isActiveClient)
8795 positionID = parent.GetPositionID(this);
8796 parent.numPositions++;
8797 if(state == minimized) parent.numIcons++;
8800 // *** NOT DOING THIS ANYMORE ***
8802 if(!(style.inactive))
8804 if(!(style.noCycle))
8806 cycle = parent.childrenCycle.AddAfter(
8807 (parent.activeChild && parent.activeChild.cycle) ?
8808 parent.activeChild.cycle.prev : null, sizeof(OldLink));
8811 order = parent.childrenOrder.AddAfter(
8812 (parent.activeChild && parent.activeChild.order) ? parent.activeChild.order.prev : parent.childrenOrder.last,
8819 if(true || !parent.activeChild)
8820 ActivateEx(true, false, true, true, null, null);
8822 if(creationActivation == activate)
8823 ActivateEx(true, false, true, true, null, null);
8824 else if(creationActivation == flash && !object)
8827 //SetVisibility(!parent.style.hidden && (style.hidden ? false : true));
8831 ConsequentialMouseMove(false);
8837 style.hidden = !value;
8840 get { return (style.hidden || !setVisible) ? false : true; }
8843 property bool isDocument
8845 property_category "Document"
8846 set { style.isDocument = value; }
8847 get { return style.isDocument; }
8850 property bool mergeMenus
8852 property_category "Window Style"
8853 set { mergeMenus = value; }
8854 get { return (bool)mergeMenus; }
8857 property bool hasHorzScroll
8859 property_category "Window Style"
8864 if(!style.hasHorzScroll && created)
8866 CreateSystemChildren();
8867 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8870 else if(style.hasHorzScroll)
8874 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8876 style.hasHorzScroll = value;
8879 get { return style.hasHorzScroll; }
8882 property bool hasVertScroll
8884 property_category "Window Style"
8889 if(!style.hasVertScroll && created)
8891 style.hasVertScroll = true;
8892 CreateSystemChildren();
8893 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8896 else if(style.hasVertScroll)
8900 Position(position.x, position.y, size.w, size.h, false, true, false, false, false, true);
8902 style.hasVertScroll = value;
8904 get { return style.hasVertScroll; }
8907 property bool dontHideScroll
8909 property_category "Behavior"
8912 scrollFlags.dontHide = value;
8915 //UpdateScrollBars(true, true);
8916 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8920 // UpdateScrollBars(true, true);
8921 Position(position.x, position.y, size.w, size.h, false, true, true, true, true, true);
8924 get { return scrollFlags.dontHide; }
8927 property bool dontScrollVert
8929 property_category "Behavior"
8930 set { style.dontScrollVert = value; }
8931 get { return style.dontScrollVert; }
8933 property bool dontScrollHorz
8935 property_category "Behavior"
8936 set { style.dontScrollHorz = value; }
8937 get { return style.dontScrollHorz; }
8940 property bool snapVertScroll
8942 property_category "Behavior"
8945 scrollFlags.snapY = value;
8946 if(sbv) sbv.snap = value;
8948 get { return scrollFlags.snapY; }
8950 property bool snapHorzScroll
8952 property_category "Behavior"
8955 scrollFlags.snapX = value;
8956 if(sbh) sbh.snap = value;
8958 get { return scrollFlags.snapX; }
8961 property Point scroll
8963 property_category "Behavior"
8967 // TESTING THIS IMPLEMENTATION:
8968 SetScrollPosition(value.x, value.y);
8970 get { value = scroll; }
8973 property bool modifyVirtualArea
8975 property_category "Behavior"
8976 set { modifyVirtArea = value; }
8977 get { return (bool)modifyVirtArea; }
8980 property char * fileName
8982 property_category "Document"
8985 if(menu && ((!fileName && value) || (fileName && !value)))
8987 MenuItem item = menu.FindItem(MenuFileSave, 0);
8988 if(item) item.disabled = !modifiedDocument && value;
8993 if(value && value[0])
8994 fileName = CopyString(value);
8996 if(parent && this == parent.activeClient)
8997 parent.UpdateActiveDocument(null);
9001 // if(style.isDocument)
9003 fileMonitor.fileName = value;
9005 get { return fileName; }
9010 property_category "Data"
9015 property bool modifiedDocument
9017 property_category "Document"
9020 if(style.isDocument || fileName)
9024 MenuItem item = menu.FindItem(MenuFileSave, 0);
9025 if(item) item.disabled = !value && fileName;
9029 if(modifiedDocument != value)
9031 modifiedDocument = value;
9032 if(style.isDocument || fileName)
9036 get { return (bool)modifiedDocument; }
9039 property bool showInTaskBar
9041 property_category "Window Style"
9042 set { style.showInTaskBar = value; }
9043 get { return (style.showInTaskBar; }
9045 property FileDialog saveDialog { set { saveDialog = value; } };
9046 property bool isActiveClient
9048 property_category "Behavior"
9049 set { style.isActiveClient = value; }
9050 get { return style.isActiveClient; }
9053 property Cursor cursor
9055 property_category "Appearance"
9059 SelectMouseCursor();
9061 get { return cursor; }
9064 //#if !defined(ECERE_VANILLA)
9065 property char * name
9067 property_category "Design"
9070 return (this && object) ? object.name : null;
9075 activeDesigner.RenameObject(object, value);
9079 property char * displayDriver
9081 property_category "Behavior"
9084 dispDriver = GetDisplayDriver(value);
9085 //DisplayModeChanged();
9089 return dispDriver ? dispDriver.name : null;
9093 // RUNTIME PROPERTIES
9094 property bool autoCreate { set { autoCreate = value; } get { return (bool)autoCreate; } };
9095 property Size scrollArea
9097 property_category "Behavior"
9101 SetScrollArea(value.w, value.h, false);
9103 SetScrollArea(0,0, true);
9105 get { value = scrollArea; }
9108 return scrollArea.w > clientSize.w || scrollArea.h > clientSize.h;
9113 property_category "Layout"
9114 set { if(this) is3D = value; }
9115 get { return (bool)is3D; }
9118 // Runtime Only Properties (No Set, can display the displayable ones depending on the type?)
9120 // Will be merged with font later
9121 property Font fontObject { get { return usedFont ? usedFont.font : null; } };
9122 property Point clientStart { get { value = clientStart; } };
9123 property Point absPosition { get { value = absPosition; } };
9124 property Anchor normalAnchor { get {value = normalAnchor; } };
9125 // property Size normalSizeAnchor { get { value = normalSizeAnchor; } };
9126 property bool active { get { return (bool)active; } };
9127 property bool created { get { return (bool)created; } };
9128 property bool destroyed { get { return (bool)destroyed; } };
9129 property Window firstSlave { get { return slaves.first ? ((OldLink)slaves.first).data : null; } };
9130 property Window firstChild { get { return children.first; } };
9131 property Window lastChild { get { return children.last; } };
9132 property Window activeClient { get { return activeClient; } };
9133 property Window activeChild { get { return activeChild; } };
9134 property Display display { get { return display ? display : ((parent && parent.rootWindow) ? parent.rootWindow.display : null); } };
9135 property DisplaySystem displaySystem { get { return display ? display.displaySystem : null; } };
9136 property ScrollBar horzScroll { get { return sbh; } };
9137 property ScrollBar vertScroll { get { return sbv; } };
9138 property StatusBar statusBar { get { return statusBar; } };
9139 property Window rootWindow { get { return rootWindow; } };
9140 property bool closing { get { return (bool)closing; } set { closing = value; } };
9141 property int documentID { get { return documentID; } };
9142 property Window previous { get { return prev; } }
9143 property Window next { get { return next; } }
9144 property Window nextSlave { get { OldLink link = master ? master.slaves.FindLink(this) : null; return (link && link.next) ? link.next.data : null; } }
9145 property PopupMenu menuBar { get { return menuBar; } }
9146 property ScrollBar sbv { get { return sbv; } }
9147 property ScrollBar sbh { get { return sbh; } }
9148 property bool fullRender { set { fullRender = value; } get { return (bool)fullRender; } }
9149 property void * systemHandle { get { return windowHandle; } }
9150 property Button minimizeButton { get { return sysButtons[0]; } };
9151 property Button maximizeButton { get { return sysButtons[1]; } };
9152 property Button closeButton { get { return sysButtons[2]; } };
9153 property BitmapResource icon
9155 get { return icon; }
9159 if(icon) incref icon;
9161 guiApp.interfaceDriver.SetIcon(this, value);
9164 property bool moveable { get { return (bool)moveable; } set { moveable = value; } };
9165 property bool alphaBlend { get { return (bool)alphaBlend; } set { alphaBlend = value; } };
9166 property bool useSharedMemory { get { return (bool)useSharedMemory; } set { useSharedMemory = value; } };
9167 property CreationActivationOption creationActivation { get { return creationActivation; } set { creationActivation = value; } };
9168 property bool nativeDecorations { get { return (bool)nativeDecorations && (formDesigner || rootWindow == this); } set { nativeDecorations = value; } };
9169 property bool manageDisplay { get { return (bool)manageDisplay; } set { manageDisplay = value; } };
9175 WindowBits style; // Window Style
9176 char * caption; // Name / Caption
9177 Window parent; // Parent window
9178 OldList children; // List of children in Z order
9179 Window activeChild; // Child window having focus
9180 Window activeClient;
9181 Window previousActive; // Child active prior to activating the default child
9182 Window master; // Window owning and receiving notifications concerning this window
9183 OldList slaves; // List of windows belonging to this window
9184 Display display; // Display this window is drawn into
9186 Point position; // Position in parent window client area
9187 Point absPosition; // Absolute position
9188 Point clientStart; // Client area position from (0,0) in this window
9190 Size clientSize; // Client area size
9191 Size scrollArea; // Virtual Scroll area size
9192 Size reqScrollArea; // Requested virtual area size
9193 Point scroll; // Virtual area scrolling position
9194 public ScrollBar sbh, sbv; // Scrollbar window handles
9195 Cursor cursor; // Mouse cursor used for this window
9198 StatusBar statusBar;
9199 Button sysButtons[3];
9201 Box clientArea; // Client Area box clipped to parent
9203 HotKeySlot hotKey; // HotKey for this window
9207 ScrollFlags scrollFlags;// Window Scrollbar Flags
9208 int id; // Control ID
9210 ColorAlpha background; // Background color used to draw the window area
9212 subclass(DisplayDriver) dispDriver; // Display driver name for this window
9213 OldList childrenCycle; // Cycling order
9214 OldLink cycle; // Element of parent's cycling order
9215 OldList childrenOrder; // Circular Z-Order
9216 OldLink order; // Element of parent's circular Z-Order
9217 Window modalSlave; // Slave window blocking this window's interaction
9219 Window rootWindow; // Topmost system managed window
9220 void * windowHandle; // System window handle
9222 DialogResult returnCode;// Return code for modal windows
9224 Point sbStep; // Scrollbar line scrolling steps
9227 SizeAnchor stateSizeAnchor;
9229 Anchor normalAnchor;
9230 SizeAnchor normalSizeAnchor;
9232 Size skinMinSize; // Minimal window size based on style
9233 Point scrolledPos; // Scrolled position
9234 Box box; // Window box clipped to parent
9235 Box * against; // What to clip the box to
9237 Extent dirtyArea { /*first = -1, last = -1, free = -1*/ }; // Area marked for update by Update
9238 Extent renderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered
9239 Extent overRenderArea { /*first = -1, last = -1, free = -1*/ }; // Temporary extent: Area that is going to be rendered over children
9240 Extent clipExtent { /*first = -1, last = -1, free = -1*/ }; // Temporary extent against which to clip render area
9241 Extent scrollExtent { /*first = -1, last = -1, free = -1*/ }; // Area to scroll
9242 Point scrolledArea; // Distance to scroll area by
9243 Extent dirtyBack { /*first = -1, last = -1, free = -1*/ }; // Only used by root window
9245 OldList hotKeys; // List of the hotkeys of all children
9246 Window defaultControl; // Default child control
9250 ColorAlpha * palette; // Color palette used for this window
9252 int caretSize; // Size of caret, non zero if a caret is present
9253 Point caretPos; // Caret position
9255 void * systemParent; // Parent System Window for embedded windows
9262 WindowState lastState;
9264 FileMonitor fileMonitor
9266 this, FileChange { modified = true };
9268 bool OnFileNotify(FileChange action, char * param)
9271 fileMonitor.StopMonitoring();
9272 if(OnFileModified(action, param))
9273 fileMonitor.StartMonitoring();
9278 FontResource setFont, systemFont;
9279 FontResource usedFont;
9280 FontResource captionFont;
9282 FileDialog saveDialog;
9284 SizeAnchor sizeAnchor;
9286 // FormDesigner data
9289 Extent * tempExtents; //[4];
9290 BitmapResource icon;
9292 CreationActivationOption creationActivation;
9295 bool active:1; // true if window and ancestors are active
9296 bool acquiredInput:1; // true if the window is processing state based input
9297 bool modifiedDocument:1;
9298 bool disabled:1; // true if window cannot interact
9299 bool isForegroundWindow:1;// true while a root window is being activated
9300 bool visible:1; // Visibility flag
9301 bool destroyed:1; // true if window is being destroyed
9302 bool anchored:1; // true if this window is repositioned when the parent resizes
9303 bool dirty:1; // Flag set to true if any descendant must be redrawn
9309 bool modifyVirtArea:1;
9310 bool noAutoScrollArea:1;
9313 bool setVisible:1; // FOR FORM DESIGNER
9319 bool useSharedMemory:1;
9322 bool nativeDecorations:1;
9323 bool manageDisplay:1;
9324 bool formDesigner:1; // True if we this is running in the form editor
9327 // Checks used internally for them not to take effect in FormDesigner
9328 property bool _isModal { get { return !formDesigner ? style.modal : false; } }
9329 property subclass(DisplayDriver) _displayDriver { get { return !formDesigner ? dispDriver : null; } }
9331 WindowController controller;
9332 public property WindowController controller { get { return controller; } set { delete controller; controller = value; if(controller) incref controller; } }
9335 public class CommonControl : Window
9337 // creationActivation = doNothing;
9340 public class Percentage : float
9342 char * OnGetString(char * string, float * fieldData, bool * needClass)
9346 sprintf(string, "%.2f", this);
9347 c = strlen(string)-1;
9350 if(string[c] != '0')
9351 last = Max(last, c);
9352 if(string[c] == '.')
9365 public void ApplySkin(Class c, char * name, void ** vTbl)
9367 char className[1024];
9372 subclass(Window) wc = (subclass(Window))c;
9373 subclass(Window) base = (subclass(Window))c.base;
9375 sprintf(className, "%sSkin_%s", name, c.name);
9376 wc.pureVTbl = c._vTbl;
9377 c._vTbl = new void *[c.vTblSize];
9378 memcpy(c._vTbl, wc.pureVTbl, c.vTblSize * sizeof(void *));
9379 sc = eSystem_FindClass(c.module.application, className);
9383 for(m = 0; m < c.base.vTblSize; m++)
9385 if(c._vTbl[m] == base.pureVTbl[m])
9386 c._vTbl[m] = vTbl[m];
9391 for(m = 0; m < c.vTblSize; m++)
9393 if(sc._vTbl[m] != wc.pureVTbl[m])
9394 c._vTbl[m] = sc._vTbl[m];
9398 for(d = c.derivatives.first; d; d = d.next)
9400 ApplySkin(d.data, name, c._vTbl);
9404 public void UnapplySkin(Class c)
9406 char className[1024];
9408 subclass(Window) wc = (subclass(Window))c;
9409 subclass(Window) base = (subclass(Window))c.base;
9412 if(wc.pureVTbl && c._vTbl != wc.pureVTbl)
9415 c._vTbl = wc.pureVTbl;
9419 for(d = c.derivatives.first; d; d = d.next)
9421 UnapplySkin(d.data);
9425 void CheckFontIntegrity(Window window)
9430 if(window.usedFont && window.usedFont.font == 0xecececec)
9432 FontResource uf = window.usedFont;
9433 char * className = window._class.name;
9434 char * text = window.text;
9437 for(c = window.firstChild; c; c = c.next)
9438 CheckFontIntegrity(c);
9442 public class ControllableWindow : Window
9444 /*WindowController controller;
9445 public property WindowController controller { get { return controller; } set { delete controller; controller = value; incref controller; } }
9446 ~ControllableWindow() { delete controller; }*/
9449 class WindowControllerInterface : ControllableWindow
9451 bool OnKeyDown(Key key, unichar ch)
9453 bool result = ((int(*)())(void *)controller.OnKeyDown)((void *)controller.controlled, (void *)controller, key, ch);
9455 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyDown](controller.window, key, ch);
9459 bool OnKeyUp(Key key, unichar ch)
9461 bool result = ((int(*)())(void *)controller.OnKeyUp)((void *)controller.controlled, (void *)controller, key, ch);
9463 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyUp](controller.window, key, ch);
9467 bool OnKeyHit(Key key, unichar ch)
9469 bool result = ((int(*)())(void *)controller.OnKeyHit)((void *)controller.controlled, (void *)controller, key, ch);
9471 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit](controller.window, key, ch);
9475 bool OnMouseMove(int x, int y, Modifiers mods)
9477 bool result = ((int(*)())(void *)controller.OnMouseMove)((void *)controller.controlled, (void *)controller, x, y, mods);
9479 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove](controller.window, x, y, mods);
9483 bool OnLeftButtonDown(int x, int y, Modifiers mods)
9485 bool result = ((int(*)())(void *)controller.OnLeftButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9487 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown](controller.window, x, y, mods);
9491 bool OnLeftButtonUp(int x, int y, Modifiers mods)
9493 bool result = ((int(*)())(void *)controller.OnLeftButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9495 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp](controller.window, x, y, mods);
9499 bool OnLeftDoubleClick(int x, int y, Modifiers mods)
9501 bool result = ((int(*)())(void *)controller.OnLeftDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9503 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick](controller.window, x, y, mods);
9507 bool OnRightButtonDown(int x, int y, Modifiers mods)
9509 bool result = ((int(*)())(void *)controller.OnRightButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9511 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonDown](controller.window, x, y, mods);
9515 bool OnRightButtonUp(int x, int y, Modifiers mods)
9517 bool result = ((int(*)())(void *)controller.OnRightButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9519 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp](controller.window, x, y, mods);
9523 bool OnRightDoubleClick(int x, int y, Modifiers mods)
9525 bool result = ((int(*)())(void *)controller.OnRightDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9527 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightDoubleClick](controller.window, x, y, mods);
9531 bool OnMiddleButtonDown(int x, int y, Modifiers mods)
9533 bool result = ((int(*)())(void *)controller.OnMiddleButtonDown)((void *)controller.controlled, (void *)controller, x, y, mods);
9535 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonDown](controller.window, x, y, mods);
9539 bool OnMiddleButtonUp(int x, int y, Modifiers mods)
9541 bool result = ((int(*)())(void *)controller.OnMiddleButtonUp)((void *)controller.controlled, (void *)controller, x, y, mods);
9543 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp](controller.window, x, y, mods);
9547 bool OnMiddleDoubleClick(int x, int y, Modifiers mods)
9549 bool result = ((int(*)())(void *)controller.OnMiddleDoubleClick)((void *)controller.controlled, (void *)controller, x, y, mods);
9551 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleDoubleClick](controller.window, x, y, mods);
9555 void OnResize(int width, int height)
9557 ((int(*)())(void *)controller.OnResize)((void *)controller.controlled, (void *)controller, width, height);
9558 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnResize](controller.window, width, height);
9561 void OnRedraw(Surface surface)
9563 ((int(*)())(void *)controller.OnRedraw)((void *)controller.controlled, (void *)controller, surface);
9564 controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRedraw](controller.window, surface);
9569 bool result = ((int(*)())(void *)controller.OnCreate)((void *)controller.controlled, (void *)controller);
9571 result = controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnCreate](controller.window);
9576 public class WindowController<class V>
9579 property Window window
9583 uint size = class(Window).vTblSize;
9586 windowVTbl = new void *[size];
9587 memcpy(windowVTbl, value._vTbl, size * sizeof(void *));
9588 if(value._vTbl == value._class._vTbl)
9590 value._vTbl = new void *[value._class.vTblSize];
9591 memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *));
9595 for(c = 0; c < size; c++)
9597 void * function = class(WindowControllerInterface)._vTbl[c];
9598 if(function != DefaultFunction)
9599 value._vTbl[c] = function;
9601 value._vTbl[c] = windowVTbl[c];
9606 memcpy(value._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *));
9609 get { return window; }
9611 property V controlled
9613 set { controlled = value; }
9614 get { return controlled; }
9616 virtual bool V::OnKeyDown(WindowController controller, Key key, unichar ch);
9617 virtual bool V::OnKeyUp(WindowController controller, Key key, unichar ch);
9618 virtual bool V::OnKeyHit(WindowController controller, Key key, unichar ch);
9619 virtual bool V::OnMouseMove(WindowController controller, int x, int y, Modifiers mods);
9620 virtual bool V::OnLeftButtonDown(WindowController controller, int x, int y, Modifiers mods);
9621 virtual bool V::OnLeftButtonUp(WindowController controller, int x, int y, Modifiers mods);
9622 virtual bool V::OnLeftDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9623 virtual bool V::OnRightButtonDown(WindowController controller, int x, int y, Modifiers mods);
9624 virtual bool V::OnRightButtonUp(WindowController controller, int x, int y, Modifiers mods);
9625 virtual bool V::OnRightDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9626 virtual bool V::OnMiddleButtonDown(WindowController controller, int x, int y, Modifiers mods);
9627 virtual bool V::OnMiddleButtonUp(WindowController controller, int x, int y, Modifiers mods);
9628 virtual bool V::OnMiddleDoubleClick(WindowController controller, int x, int y, Modifiers mods);
9629 virtual void V::OnResize(WindowController controller, int width, int height);
9630 virtual void V::OnRedraw(WindowController controller, Surface surface);
9631 virtual bool V::OnCreate(WindowController controller);
9634 int (** windowVTbl)();