OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
docking.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1995, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of docking window classes
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9
10#include <owl/docking.h>
11#include <owl/controlb.h>
12#include <owl/tooltip.h>
13#include <owl/uihelper.h> // for TUIBorder edge painting
14#include <owl/uimetric.h>
15#include <owl/template.h>
16
17#if defined(BI_MULTI_THREAD_RTL)
18#include <owl/thread.h>
19#endif
20
21#if defined(__TRACE) || defined(__WARN)
22# include <owl/profile.h>
23#endif
24
25#include <vector>
26#include <algorithm>
27
28using namespace std;
29
30namespace owl {
31
32//
33// Fillin missing defines for some configurations
34//
35#if !defined(WM_SIZING)
36# define WM_SIZING 0x0214
37#endif
38#if !defined(DS_SETFOREGROUND)
39# define DS_SETFOREGROUND 0x200L // not in win3.1
40#endif
41
42//
43// Diagnostic group for docking
44//
47
48
50
51//----------------------------------------------------------------------------
52
53//
54/// This constructor creates a dockable gadget window and sets the appropriate
55/// styles for the window.
56//
59 TFont* font,
60 TModule* module)
61:
62 TGadgetWindow(parent, direction, font, module),
63 TDockable(),
64 Cursor(nullptr)
65{
66#if 0
67 Attr.Style |= WS_BORDER; // Add in border for boundries between dockables
68#else
69 Attr.Style &= ~WS_BORDER; // Normally no borders
70#endif
71 Attr.Style |= WS_CLIPSIBLINGS;
72
73 // Always shrink wrapped when dockable since slip fills out docking area
74 //
75 SetShrinkWrap(true, true);
76}
77
78//
79//
80//
85
86
92
93//
94//
95//
101
102
103/// Inserts/deletes FlatBar Grip.
104void
106{
109 if(dir == Rectangular){
110 delete Cursor;
111 Cursor = 0;
112 }
113 else if(!GadgetWithId(IDG_FLATHANDLE)){
115 if(gadget)
117
118 // set cursor
119 if(dir == Horizontal)
120 Cursor = new TCursor(0, IDC_SIZEWE);
121 else
122 Cursor = new TCursor(0, IDC_SIZENS);
123
125 }
126 else{
127 if(GetDirection() != dir){
128 delete Cursor;
129 if(dir == Horizontal)
130 Cursor = new TCursor(0, IDC_SIZEWE);
131 else
132 Cursor = new TCursor(0, IDC_SIZENS);
133 }
135 }
136 }
137 // if exist GridGadget
139 // set cursor
140 if(dir == Horizontal)
141 Cursor = new TCursor(0, IDC_SIZEWE);
142 else
143 Cursor = new TCursor(0, IDC_SIZENS);
144
146 }
147}
148
149//
150//
151//
152bool
154{
162 boundsRect.right = boundsRect.left+8;
164 }
165 else{
166 boundsRect.bottom = boundsRect.top+7;
168 }
169 if(boundsRect.Contains(point)){
171 return true;
172 }
173 }
175}
176
177//
178/// Finds out how big this dockable would be in a given location, and with a given
179/// optional size hint.
180//
181TSize
183{
185
186 // Save current settings to restore when done, since this is a info-request
187 // only function
188 //
190 int oldWidth = RowWidth;
191
192 // If rectangular, calcuate adjust size for surrounding parent frame window
193 //
194 TSize delta(0,0);
195 if (dir == Rectangular) {
196 // If we currently are in a floating slip, use that window to calc frame delta
197 //
198 TWindow* parent = GetParentO();
199 if (oldDir == Rectangular && parent && parent->GetHandle()) {
200 delta = parent->GetWindowRect().Size() - parent->GetClientRect().Size();
201 // In Win95, the bottom margin and the bottom sizing border are the
202 // same color and not separated by a hard border, so we 'kern' them
203 // together to match the size of the top margin.
204 //
206 int topM, leftM, bottomM, rightM;
208 delta.cy -= std::min(yt, bottomM);
209 }
210 // No floating parent yet. Calculate the delta based on assumed frame
211 // styles. (This rect is only used to size the drag frame anyway.)
212 //
213 else {
214 TRect winRect(0, 0, 0, 0);
218 delta = winRect.Size();
219 }
220 }
221
222 TSize sz(0, 0);
223 Direction = dir;
224
225 // Seek a vertical size if just a non-zero cy is given
226 //
227 if (dim && dim->cx == 0 && dim->cy != 0) {
228
229 int seekCy = dim->cy - delta.cy; // This is the height to shoot for
230
233
234 // Seek the row whose height is less than seekCy
235 ///CH: I really would like to have a better, non-iterative algorithm for
236 ///CH: this, but for now this works.
237 //
238 if (testSz.cy < seekCy) {
239 // Seek a taller row by successivly shrinking the width
240 //
241 while (1) {
242 int prevW = RowWidth;
243 sz = testSz;
244 RowWidth -= 5;
245 if (RowWidth <= 0) { // Limit reached. Give up
246 RowWidth = testSz.cx;
247 sz = testSz;
248 break;
249 }
251 if (seekCy < testSz.cy) { // Shrunk too far: use previous size
252 RowWidth = prevW;
253 break;
254 }
255 }
256 }
257 else if (testSz.cy > seekCy) {
258 // Seek a shorter row by successivly growing the width
259 //
260 while (1) {
261 int prevW = RowWidth;
262 sz = testSz;
263 RowWidth += 5;
264 if (RowWidth > 1000) { // CHNOTE: Limit reached. Give up
265 RowWidth = testSz.cx;
266 sz = testSz;
267 break;
268 }
270 if (seekCy > testSz.cy) {
271 RowWidth = prevW;
272 break;
273 }
274 }
275 }
276 else // seekCy == testSz.cy
277 sz = testSz;
278 }
279 // Change to a given horizontal size, or just the natural size for the
280 // direction
281 //
282 else {
283 if (dim) // Change the row width here because we are changing size.
284 RowWidth = dim->cx - delta.cx;
286 }
287
288 Direction = oldDir;
289 RowWidth = oldWidth;
290 sz += delta;
291
292 return sz;
293}
294
295//
296/// Gets this dockable's screen rectangle.
297//
298void
303
304//
305/// Returns a gadget window tile direction code, given a docking absolute location
306/// code.
307//
310{
311 switch(loc) {
312 case alTop:
313 case alBottom:
314 return Horizontal;
315 case alLeft:
316 case alRight:
317 return Vertical;
318 case alNone:
319 default:
320 return Rectangular;
321 }
322}
323
324//
325/// Causes this dockable to lay itself out vertically, horizontally, or
326/// rectangularly.
327//
328void
330{
332 if (GetDirection() != dir || dim) {
333 if (dim)
334 SetRectangularDimensions(dim->cx, dim->cy); // Sets RowWidth mostly
335
336 // Set the layout direction, which ends up invoking LayoutSession &
337 // SetWindowPos
338 //
340 }
341}
342
343//
344/// Returns true if the mouse click point is in a spot that should move this
345/// dockable around.
346//
347bool
349{
351 if (g)
352 // !CQ should also allow non-clickables to drag, like text!
353#if 1
354 return !g->IsVisible(); // Allow hidden gadgets to begin a drag; separators are hidden
355#else
356 return !g->GetEnabled(); // Allow disabled gadgets to begin a drag
357#endif
358
359 return true;
360}
361
362//
363/// Returns the TWindow part of this dockable object. In this case, it is just this
364/// window.
365//
366TWindow*
368{
369 return this;
370}
371
372//
373/// If the gadget window changes size when laying out a dockable gadget window, this
374/// function tells the dock about it so the dock can resize too.
375//
376void
378{
379 TSize sz;
380 GetDesiredSize(sz); // Find out how big we'd like to be
381
382 Attr.W = sz.cx; // This will allow LayoutSession to work as if
383 Attr.H = sz.cy; // we were the right size.
384
386
387 // If we are in a slip that has been created properly, then tell it to adjust
388 // to our new layout
389 //
390 if (GetParentO()) {
392 if (slip) {
393 // If this is a null-sized gadget window, hide our floating frame.
394 //
395 bool hideSlip = Attr.W == 0 || Attr.H == 0;
397
398 // Make sure the slip will adjust to our new size
399 //
401 if (!stc)
403 SetWindowPos(nullptr, 0, 0, Attr.W, Attr.H, SWP_NOACTIVATE | SWP_NOMOVE);
404 if (!stc)
406 }
407 // If we aren't in a slip (because we haven't been inserted yet) resize
408 // anyway.
409 //
410 else {
411 SetWindowPos(nullptr, 0, 0, Attr.W, Attr.H, SWP_NOACTIVATE | SWP_NOMOVE);
412 }
413 }
414}
415
416//
417/// Returns the harbor containing the dockable object.
418//
419THarbor*
421{
422 // If parent is a slip, return its harbor.
423 // If parent is the harbor (because the dockable is hidden), return the harbor.
424 //
425 if (!Parent)
426 return nullptr;
428 if (slip)
429 return slip->GetHarbor();
431 return harbor;
432}
433
434//
435/// Forwards event to slip to allow movement of gadget within the slip.
436//
437void
439{
440 TPoint pt = point;
442
443 // Forward the message to the parent, this is for the docking areas. To
444 // allow moving of the controlbars within the docking areas.
445 // !CQ Use OWL parent??? Or old hwnd parent?
446 //
447 TWindow* w = GetParentO();
448
449 // Check that we're parented to the right window. In OLE server situation,
450 // the toolbar could have been reparented to another HWND [i.e. container's
451 // window]
452 //
453 if (w && ::GetParent(*this) != w->GetHandle())
454 return;
455
456 // Forward to parent [which is a slip]
457 //
458 if (w && w->GetHandle()) {
459 TPoint p = MapWindowPoints(*w, point); // Transform to parent's coordinate system.
460 w->HandleMessage(WM_LBUTTONDOWN, modKeys, MkParam2(int16(p.x), int16(p.y)));
461 }
462
463 // At this point, our window may be in drag mode [i.e. being docked or
464 // undocked]. This means that the harbor has invoked 'SetCapture' which in
465 // turn implies that we won't see subsequent WM_MOUSEMOVE/WM_LBUTTONDOWN
466 // messages. This will leave the tooltip the impression [strong impression
467 // if I may add] that the mouse button never came up. The net side-effect
468 // will be that the tooltip will not activate until it sees an LBUTTONUP
469 // message. So to avoid this side-effect we fake an LBUTTONUP message here.
470 //
472 if (harbor && GetCapture() == *harbor)
473 {
475 if (tooltip && tooltip->IsWindow())
476 {
477 MSG msg;
478 msg.hwnd = *this;
479 msg.message = WM_LBUTTONUP;
480 msg.wParam = modKeys;
481 msg.lParam = MkUint32(int16(pt.x), int16(pt.y));
482 tooltip->RelayEvent(msg);
483 }
484 }
485}
486//----------------------------------------------------------------------------
487
491
492//
493/// Constructs a dockable control bar.
494//
497 TFont* font,
498 TModule* module)
499:
500 TDockableGadgetWindow(parent, direction, font, module)
501{
503 WantTooltip = true;
504
506}
507
508//
509//
510//
511void
513{
514 // !CQ Conrad's IDEOWL uses 6*Border,3*border & vice versa
515 if (GetDirection() == Horizontal) {
516 Margins.Left = Margins.Right = TUIMetric::CxSizeFrame + TUIMetric::CxFixedFrame;
517 Margins.Top = Margins.Bottom = TUIMetric::CySizeFrame;
518 }
519 else if(Direction == Vertical){
520 Margins.Left = Margins.Right = TUIMetric::CxSizeFrame;
521 Margins.Top = Margins.Bottom = TUIMetric::CySizeFrame + TUIMetric::CyFixedFrame;
522 }
523 else{
524 Margins.Left = Margins.Right = TUIMetric::CxSizeFrame;
525 Margins.Top = Margins.Bottom = TUIMetric::CySizeFrame;
526 }
527}
528
529//
530//
531//
532void
538
539
544 EV_WM_SIZING, // Win 4.0 message only.
550
551//
552/// Constructs a floating slip and sets the appropriate style for the window.
553//
555 int x, int y,
557 bool shrinkToClient,
558 int captionHeight,
559 bool popupPalette,
560 TModule* module)
561:
562 TFloatingFrame(parent, clientWnd->GetCaption(), nullptr/*clientWnd*/, shrinkToClient,
564
565{
566 SetDragFrame(false);
567
569 Attr.Style &= ~(WS_VISIBLE); // Create initially hidden, show later
570 Attr.Style |= WS_CLIPCHILDREN; // Dont womp on children
571 Attr.Style |= WS_BORDER | WS_THICKFRAME; // Sizeable frame to allow reshaping
572
573 // Let tiny caption recalc margin & border dimensions using new styles. Tiny
574 // caption will adjust these some more as needed.
575 //
576 EnableTinyCaption(TFloatingFrame::DefaultCaptionHeight, true);
577
578 // Calculate a real initial position, & an estimated size. May resize later
579 // when client has reshaped.
580 //
581 TRect winRect(x, y, x+clientWnd->GetWindowAttr().W, y+clientWnd->GetWindowAttr().H);
582 AdjustWindowRectEx(winRect, Attr.Style, false, Attr.ExStyle);
583
584#if 1
585 Attr.X = x; // Places this frame at given screen x,y
586 Attr.Y = y;
587#else
588 Attr.X = winRect.left; // Places client rect at given screen x,y
589 Attr.Y = winRect.top;
590#endif
591 Attr.W = winRect.Width();
592 Attr.H = winRect.Height();
593}
594
595//
596/// Handles lbutton down bubbled up from the client to begin a dockable drag
597/// operation.
598//
599void
601{
602 if (hitTest == HTCAPTION) {
603 // Call the dockable dragging setup function in Harbor, passing this
604 // window as the dragged dockable and as the docking slip too
605 //
606 if (Harbor && Harbor->DockDraggingBegin(*this, point, alNone, this))
607 return;
608 }
610}
611
612//
613/// Handles lbutton down bubbled up from the client to begin a dockable drag
614/// operation.
615//
616void
618{
619 // Is the mouseDown in a area where we can move the docked window?
620 //
623
624 TPoint childPt = MapWindowPoints(*cw, point); // Transform to client window's coordinate system.
625
626 if (d && d->ShouldBeginDrag(childPt)) {
628 if (Harbor && Harbor->DockDraggingBegin(*this, p, alNone, this))
629 return; // Successfully started
630 }
632}
633
634//
635/// When closing the floating slip, removes any dockable first so that it is not
636/// destroyed. Dockables are owned by the harbor, not the slip, and must not be
637/// destroyed when the slip is destroyed.
638//
639void
641{
643 if (dd)
644 Harbor->Remove(*dd); // Will cause a close in DockableRemoved()
645 else
647}
648
649//
650/// Handles the Windows 4.0 message for the best resize user feedback.
651//
652bool
654{
655
656 // Look for size changes & make them track the dockable
657 //
659 if (w) {
661 if (dockable) {
662 TSize trackSize(rect.Size());
663 switch (side) {
664 case WMSZ_BOTTOM:
665 case WMSZ_TOP:
666 trackSize.cx = 0;
667 break;
668 case WMSZ_LEFT:
669 case WMSZ_RIGHT:
670 trackSize.cy = 0;
671 break;
672 }
673 TSize dsz = dockable->ComputeSize(alNone, &trackSize);
674
675 // Center the fixed axis
676 //
677 switch (side) {
678 case WMSZ_BOTTOM:
679 case WMSZ_TOP:
680 rect.left = rect.left + (rect.Width() - dsz.cx)/2;
681 break;
682 case WMSZ_LEFT:
683 case WMSZ_RIGHT:
684 rect.top = rect.top + (rect.Height() - dsz.cy)/2;
685 break;
686 }
687
688 // Change the window size, keeping it pinned on the opposite corner
689 //
690 switch (side) {
691 case WMSZ_TOP:
692 case WMSZ_TOPRIGHT:
693 rect.top = rect.bottom - dsz.cy;
694 rect.right = rect.left + dsz.cx;
695 break;
696 case WMSZ_TOPLEFT:
697 rect.left = rect.right - dsz.cx;
698 rect.top = rect.bottom - dsz.cy;
699 break;
700 case WMSZ_BOTTOMLEFT:
701 case WMSZ_LEFT:
702 rect.left = rect.right - dsz.cx;
703 rect.bottom = rect.top + dsz.cy;
704 break;
705 case WMSZ_BOTTOM:
706 case WMSZ_BOTTOMRIGHT:
707 case WMSZ_RIGHT:
708 rect.right = rect.left + dsz.cx;
709 rect.bottom = rect.top + dsz.cy;
710 break;
711 }
712 }
713 }
714
715 return true;
716}
717
718//
719/// Handles WM_WINDOWPOSCHANGING to make sure that the frame is properly constrained
720/// by the dimensions of the dockable client.
721//
722bool
724{
726
727 // Look for size changes & make them track the dockable
728 //
729 if (!(windowPos.flags&SWP_NOSIZE)) {
731 if (w) {
733 if (dockable) {
734// !CQ Shouldn't we adjust .cx by our frame thickness to get client width?
735// !CQ Maybe keep Delta around for these client<->frame size calculations...
736/// TRect cr(0,0,0,0);
737/// AdjustWindowRectEx(cr, Attr.Style, false, Attr.ExStyle);
738 TSize ts(windowPos.cx, 0);
739 TSize dsz = dockable->ComputeSize(alNone, &ts);
740
741 // Center the non-sizing axis
742 //
743 if (!(windowPos.flags&SWP_NOMOVE)) {
744/// if (sizing horizontally)
745 windowPos.y = windowPos.y + (windowPos.cy - dsz.cy)/2;
746/// else
747/// windowPos.x = windowPos.x + (windowpos.cx - dsz.cx)/2;
748 }
749 windowPos.cx = dsz.cx;
750 windowPos.cy = dsz.cy;
751 }
752 }
753 }
754 windowPos.flags |= SWP_NOACTIVATE; // Not very effective, but worth a try
755 return false;
756}
757
758//
759/// Handles WM_WINDOWPOSCHANGED to make sure that the dockable client gets a chance
760/// to do final layout.
761//
762void
764{
766
767 if (!(windowPos.flags&SWP_NOSIZE)) {
769 if (w) {
771 if (dockable) {
772/// TRect cr(0,0,0,0);
773/// AdjustWindowRectEx(cr, Attr.Style, false, Attr.ExStyle);
774 TSize ts(windowPos.cx, 0);
775 TSize dsz = dockable->ComputeSize(alNone, &ts);
776
777 dockable->Layout(alNone, &dsz);
778 }
779 }
780 }
781}
782//
783/// Event handler for the .INI file changed message. The window may have resized
784/// because the user has changed the caption size.
785//
786void
788
789{
791
792 // Resize, since our sizing borders may have changed size
793 //
794 if (w) {
795 TRect newWinRect = w->GetWindowRect();
796 AdjustWindowRectEx(newWinRect, Attr.Style, false, Attr.ExStyle);
797
799
800 if (winRect.Height() != newWinRect.Height() ||
801 winRect.Width() != newWinRect.Width()) {
803 }
804 }
805}
806
807//
808// Respond to WM_GETMINMAXINFO messages to ensure that the minTrackSize
809// used by Windows is not greater than the size would be for a vertical
810// floating control bar.
811//
812void
814{
815 TSize sz(0,0);
816 ComputeSize( alLeft, &sz );
817 info.ptMinTrackSize.x = sz.cx;
818 info.ptMinTrackSize.y = sz.cy;
819}
820
821//
822/// Overriden TDockingSlip virtual. Called by mouseup handler after a dockable is
823/// dropped into this docking window.
824//
825void
827 const TPoint* /*topLeft*/,
828 TRelPosition /*position*/, TDockable* /*relDockable*/)
829
830{
831 dockable.Layout(alNone); // No specific dimensions suggested
832 SetClientWindow(dockable.GetWindow()); // Set dockable as client & resize
833
834 // Retrieve window object of dockable
835 //
836 TWindow* dockableWindow = dockable.GetWindow();
838
839 // Let window know it was docked [well, undocked]
840 //
841#ifdef UNIX
842 if (dockableWindow->IsWindow()) //?????????????????????
844 TParam2((TDockingSlip*)this));
845#else
847 TParam2((TDockingSlip*)this));
848#endif
849}
850
851//
852/// Overriden TDockingSlip virtual. Called by lbutton up handler after a drag within
853/// this docking window. This floating slip only moves itself.
854//
855void
857 TRelPosition /*position*/, TDockable* /*relDockable*/)
858{
859 if (topLeft)
860 SetWindowPos(nullptr, topLeft->x, topLeft->y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE);
861}
862
863//
864/// Overriden TDockingSlip virtual. Called by lbutton up handler after a dockable
865/// has been removed from this docking slip.
866//
867void
869{
870 // Clear client window
871 //
872 SetClientWindow(nullptr);
873
874// !BB CloseWindow has the side-effect of leaving things around - i.e.
875// !BB window object is not condemned... Can be expensive after a few
876// !BB floating slips.
877// !BB
878// !BB CloseWindow();
880}
881
882//
883/// Forward the first four TDockable virtuals to the client dockable.
884//
885TSize
887{
889 if (w) {
891 if (dockable)
892 return dockable->ComputeSize(loc, dim);
893 }
894 return TSize(0, 0);
895}
896
897//
898/// Gets this dockable's screen rect.
899//
900void
905
906//
907/// Forwards the layout message over to the dockable object.
908//
909void
911{
913 if (w) {
915 if (dockable)
916 dockable->Layout(loc, dim); // !CQ adjust dim by our frame thickness?
917 }
918 CHECK(w);
919}
920
921//
922/// A given mouse down should never begin a drag for this dockable.
923//
924bool
926{
927 return false;
928}
929
930//
931/// Returns the TWindow part of this dockable object. In this case it is actually
932/// the client window.
933//
934TWindow*
940
941//
942/// Returns the associated harbor.
943//
944THarbor*
946{
947 return Harbor;
948}
949
950//
951/// Returns the location of the object.
952//
955{
956 return alNone;
957}
958
959
969
970//
971/// Constructs an edge slip, and sets the approriate styles for the window.
972//
974:
975 TWindow(&parent, _T("EdgeSlip"), module),
976 Location(location),
977 GridType(Location == alTop || Location == alBottom ? YCoord : XCoord)
978{
979#if defined(__TRACE) || defined(__WARN)
980 // Make slip dark blue for debugging purposes in diagnostic build
981 //
982 TProfile iniFile(_T("Diagnostics"), _T(OWL_INI));
983
984 bool useDiagColor = iniFile.GetInt(_T("DiagToolbarBorders")) != 0;
985
986 if (useDiagColor)
987 SetBkgndColor(TColor(0, 0, 128));
988 else
989#endif
990
992
994}
995
996//
997// Type of decoration
998//
999struct TEachDecoration {
1000 TWindow* Window;
1001 int Top; // or Left if XCoord
1002 int Bottom; // or Right if XCoord
1003
1004 TEachDecoration(TWindow*, TGridType);
1005 TEachDecoration(int Top, int Bottom, TWindow* w);
1006
1007 bool operator <(const TEachDecoration& other) const
1008 {return Top < other.Top;}
1009};
1010
1011//
1012// Create a decoration from the grid.
1013//
1014TEachDecoration::TEachDecoration(TWindow* w, TGridType gridType)
1015:
1016 Window(w)
1017{
1018 TRect rect = w->GetWindowRect();
1019 if (gridType == YCoord) {
1020 Top = rect.top;
1021 Bottom = rect.bottom;
1022 }
1023 else {
1024 Top = rect.left;
1025 Bottom = rect.right;
1026 }
1027}
1028
1029//
1030// Create the decoration from a specific location.
1031//
1032TEachDecoration::TEachDecoration(int top, int bottom, TWindow* w)
1033:
1034 Window(w),
1035 Top(top),
1036 Bottom(bottom)
1037{
1038}
1039
1040namespace
1041{
1042
1043template <class TDecoration>
1045{
1047 for (TWindow* w = s.GetFirstChild(); w; w = (w == s.GetLastChild()) ? nullptr : w->Next())
1049 sort(v.begin(), v.end());
1050 return v;
1051}
1052
1053} // namespace
1054
1055//
1056/// Ensures that all decorations in the docking window are abutted against each
1057/// other (both horizontally and vertically); there should be no gaping holes.
1058//
1059void
1061{
1062 TWindow::SetupWindow(); // Create all children.
1063
1065
1066 // Look for any gaping holes between the dockable windows and collapse them.
1067 // Normally, this doesn't occur unless the to be created size is different
1068 // from the actual created size of a gadget. This, currently, only occurs
1069 // for TControlGadgets where the gadget is a combobox the created size
1070 // specifies the editclass area and the drop-down area, however, the window
1071 // rect (when the GetHandle() is valid) is just the editclass area.
1072 //
1073 int diff = 0;
1074 int startWindowChange = -1;
1075 int rowHeight = 0;
1076 for (size_t i = 1; i < decoList.size(); ++i) {
1077 // Are the two decorations we're going to look at on the same vertical?
1078 //
1079 if (decoList[i-1].Top != decoList[i].Top) {
1080 // No, so compute possible difference.
1081 //
1082 if (decoList[i-1].Bottom+diff != decoList[i].Top+diff) {
1083 // Remember the first window which is adjusted, we'll want to delay the
1084 // SetWindowPos until all windows from this point to the end have been
1085 // completely adjusted.
1086 //
1087 if (startWindowChange == -1)
1088 startWindowChange = static_cast<int>(i);
1089
1090 // Found a spot. Compute the offset.
1091 //
1092 diff += decoList[i-1].Top + rowHeight - decoList[i].Top;
1093 }
1094 rowHeight = decoList[i].Bottom - decoList[i].Top;
1095 }
1096 else {
1097 rowHeight = std::max(rowHeight, decoList[i].Bottom - decoList[i].Top);
1098 }
1099 if (diff) {
1100 TEachDecoration& decoItem = decoList[i];
1101 decoItem.Top += diff;
1102 decoItem.Bottom += diff;
1103 }
1104 }
1105
1106 // Re-adjust all windows which have changed location.
1107 //
1108 if (startWindowChange != -1) {
1109 for (size_t i = startWindowChange; i < decoList.size(); ++i) {
1110 TEachDecoration& decoItem = decoList[i];
1111 TRect r;
1112 decoItem.Window->GetWindowRect(r);
1113
1114 TPoint pt(r.left, r.top);
1115 if (GridType == YCoord)
1116 pt.y = decoItem.Top;
1117 else
1118 pt.x = decoItem.Top;
1119
1120 // Map from global to local coord (the parent's coordinate space).
1121 //
1122 ::MapWindowPoints(nullptr, *this, (TPoint*)&pt, 1);
1123 decoItem.Window->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1125 i++;
1126 }
1127 }
1128
1129 // Make sure that our size is updated
1130 //
1131 ReLayout(true);
1132}
1133
1134//
1135/// Changes the reciever to be the framewindow, not the docking window. The receiver
1136/// window is normally set up in Activate upon the creation of TButtonGadgetEnabler.
1137//
1138void
1140{
1141 if (GetParentO()) {
1142 // Already being processed?
1143 //
1144 if (!commandEnabler.IsReceiver(GetParentO()->GetHandle())) {
1145 // No, so forward it up to our parent
1146 //
1147 commandEnabler.SetReceiver(GetParentO()->GetHandle());
1149 }
1150 }
1151}
1152
1153//
1154/// Forward command messages to the parent.
1155//
1156/// Changes the receiver to be the framewindow, not the docking window. The receiver
1157/// window is normally set up in Activate upon the creation of TButtonGadgetEnabler.
1158//
1159TResult
1161{
1162 TRACEX(OwlCmd, 1, "TEdgeSlip::EvCommand - id(" << id << "), ctl(" <<\
1163 static_cast<void*>(hWndCtl) << "), code(" << notifyCode << ")");
1164
1165 if (notifyCode == 0 && GetParentO())
1166 return GetParentO()->EvCommand(id, hWndCtl, notifyCode);
1167
1169}
1170
1171//
1172/// Forwards the left button down message to the dockable object.
1173//
1174void
1176{
1178
1179 // Only allow immediate children of the docking window to be clicked on.
1180 //
1181 if (cw && cw->GetParentO() == this) {
1182 // Is the mouseDown in a area where we can move the docked window?
1183 //
1186 if (d && d->ShouldBeginDrag(childPt)) {
1188 if (Harbor && Harbor->DockDraggingBegin(*d, p, Location, this)) {
1189 return; // Successfully started
1190 }
1191 }
1192 }
1194}
1195
1196//
1197/// Handles WM_LBUTONDBLCLICK to tell the frame to edit a toolbar.
1198//
1199void
1204
1205//
1206/// Returns the size of the client area, leaving room for the etched separators.
1207//
1208uint
1210{
1212 if (IsIconic())
1213 return ret;
1214
1215 // Only add in space if this slip is not shrunk to nothing
1216 //
1217 if (calcSize.rgrc[0].bottom - calcSize.rgrc[0].top > 0) {
1218 if (!(Attr.Style & WS_BORDER)) {
1219 if (Location != alBottom)
1220 calcSize.rgrc[0].top += 2;
1221 if (Location != alTop)
1222 calcSize.rgrc[0].bottom -= 2;
1223 }
1224 }
1225 return 0;
1226}
1227
1228//
1229/// Erases the background and draws in etched 'borders' within the client area.
1230//
1232{
1233 // Non-3d style
1234 // !CQ Always do 3d etch here?
1235 //
1236 if (Attr.Style & WS_BORDER) {
1238 }
1239 // Use 3-d style
1240 //
1241 else {
1242 TWindowDC dc(*this);
1243
1244 // Paint etched line along the top for left, top & right slips, and along
1245 // the bottom for bottom, left & right slips to separate from the menubar,
1246 // statusbar & eachother.
1247 //
1248 int height(GetWindowRect().Height());
1249 if (Location != alBottom){
1250 TRect tr(0,0,9999,2);
1252 }
1253 if (Location != alTop){
1254 TRect tr(0,height-2,9999,height);
1256 }
1257 }
1258}
1259
1260//
1261/// Erases the background and draws in etched 'borders' within the client area.
1262//
1263bool
1265{
1266 TWindow::EvEraseBkgnd(hDC); // Let TWindow erase everything
1267
1268 // !CQ Paint etched lines for docked children?
1269
1270 return true;
1271}
1272
1273//
1274/// Makes sure that the slip size is updated when a child changes size.
1275//
1276void
1278{
1279 if (n.Event == WM_SIZE)
1280 ReLayout(false);
1281 else
1283}
1284
1285//
1286//
1287//
1288class TDecorationSpan {
1289public:
1290 int Left;
1291 int Right;
1292 int Top;
1293 int Bottom;
1294 TWindow* Window;
1295 bool Moved;
1296
1297 TDecorationSpan(TWindow* w, TGridType);
1298
1299 bool operator <(const TDecorationSpan& other) const
1300 {return Top < other.Top || (Top == other.Top && Left < other.Left);}
1301};
1302
1303//
1304// Create the decoration span from the grid.
1305//
1306TDecorationSpan::TDecorationSpan(TWindow* w, TGridType gridType)
1307 : Moved(false)
1308{
1309 TRect rect = w->GetWindowRect();
1310 ::MapWindowPoints(nullptr, w->GetParentH(), reinterpret_cast<TPoint*>(&rect), 2); // map to slip coordinates
1311
1312 Window = w;
1313 if (gridType == YCoord) {
1314 Top = rect.top;
1315 Left = rect.left;
1316 Right = rect.right;
1317 Bottom = rect.bottom;
1318 }
1319 else {
1320 Top = rect.left;
1321 Left = rect.top;
1322 Right = rect.bottom;
1323 Bottom = rect.right;
1324 }
1325}
1326
1327//
1328/// When the slip shrinks, this function adjusts dockables where needed.
1329//
1330bool
1338
1339//
1340/// Compresses or expands dockables perpendicular to the grid line.
1341//
1342void
1344{
1346
1347 // Tile dockables perpendicular to grid lines
1348 //
1349 if (!decoList.empty()) {
1350 int gridLine = decoList[0].Top;
1351 int lastTop = gridLine - 1;
1352 int delta = 0;
1353 for (size_t i = 0; i < decoList.size(); ++i) {
1354 decoList[i].Moved = false;
1355 int t = decoList[i].Top;
1356 if (t != lastTop) {
1357 delta = gridLine-t;
1358 gridLine = t;
1359 lastTop = t;
1360 }
1361 if (delta != 0) {
1362 decoList[i].Top += delta;
1363 decoList[i].Bottom += delta;
1364 decoList[i].Moved = true;
1365 }
1366 gridLine = std::max(gridLine,decoList[i].Bottom);
1367 }
1368
1369 // Move all dockables that have changed location.
1370 //
1371 for (size_t j = 0; j < decoList.size(); ++j) {
1372 TPoint pt;
1373 TDecorationSpan& decoItem = decoList[j];
1374 if (decoItem.Moved) {
1375 if (GridType == YCoord) {
1376 pt.x = decoItem.Left;
1377 pt.y = decoItem.Top;
1378 }
1379 else {
1380 pt.x = decoItem.Top;
1381 pt.y = decoItem.Left;
1382 }
1383 decoItem.Window->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1385 }
1386 }
1387 }
1388
1389 ReLayout(false);
1390}
1391
1392//
1393/// Compresses empty space along grid line if any dockables hang out past the end.
1394//
1395void
1397{
1398 // Scan each row looking for a decoration that hangs off the end.
1399 // If possible, pull that decoration in by collapsing empty space between
1400 // decorations on that row.
1401 //
1403 size_t firstOnRow = 0;
1404 size_t lastOnRow = 0;
1405 while (firstOnRow < decoList.size()) {
1406 int spaceOnRow = decoList[firstOnRow].Left;
1407 int rowTop = decoList[firstOnRow].Top;
1408 while (lastOnRow + 1 < decoList.size() && decoList[lastOnRow + 1].Top == rowTop) {
1409 spaceOnRow += decoList[lastOnRow+1].Left-(decoList[lastOnRow].Right+1);
1410 lastOnRow ++;
1411 }
1412
1413 int delta = decoList[lastOnRow].Right - width;
1414 if (delta > 0 && spaceOnRow > 0) {
1415 if (spaceOnRow > delta) {
1416 // if there is extra empty space, collapse from the right
1417 //
1418 int r = width;
1419 size_t i = lastOnRow;
1420 while (i >= firstOnRow && (decoList[i].Right+1) > r) {
1421 int dx = (decoList[i].Right+1) - r;
1422 decoList[i].Left -= dx;
1423 decoList[i].Right -= dx;
1424 decoList[i].Moved = true;
1425 r = decoList[i].Left;
1426 if (i == 0) break;
1427 i--;
1428 }
1429 }
1430 else {
1431 // if there is not extra empty space, just collapse the space
1432 //
1433 int r = 0;
1434 for (size_t i = firstOnRow; i <= lastOnRow; ++i) {
1435 if (decoList[i].Left > r) {
1436 int dx = decoList[i].Left - r;
1437 decoList[i].Left -= dx;
1438 decoList[i].Right -= dx;
1439 decoList[i].Moved = true;
1440 r = decoList[i].Right+1;
1441 }
1442 else
1443 break;
1444 }
1445 }
1446 }
1448 }
1449
1450 // Move all dockables that have changed location.
1451 //
1452 for (size_t i = 0; i < decoList.size(); ++i) {
1453 TPoint pt;
1454 TDecorationSpan& decoItem = decoList[i];
1455 if (decoItem.Moved) {
1456 if (GridType == YCoord) {
1457 pt.x = decoItem.Left;
1458 pt.y = decoItem.Top;
1459 }
1460 else {
1461 pt.x = decoItem.Top;
1462 pt.y = decoItem.Left;
1463 }
1464 decoItem.Window->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1466 }
1467 }
1468}
1469
1470//
1471/// Changes the child metrics of this docking window within its decorated frame.
1472/// Calls when the rectangle area of the docking area is different from the computed
1473/// area of the dockable windows within the docking area.
1474//
1475void
1477{
1478 // Has the docking area changed in size?
1479 //
1481
1482 bool sizeChanged;
1483 if (Location == alTop || Location == alBottom) {
1484 sizeChanged = Attr.H != area.cy;
1485 Attr.H = area.cy;
1486 }
1487 else {
1488 sizeChanged = Attr.W != area.cx;
1489 Attr.W = area.cx;
1490 }
1491
1492 // If the size has change or we need to force a layout, then do so
1493 //
1494 if (sizeChanged || forcedLayout) {
1496 CHECK(df);
1497
1498 // Set the same metrics just to dirty the layout plan & force a rebuild
1499 //
1501 df->GetChildLayoutMetrics(*this, metrics);
1502 df->SetChildLayoutMetrics(*this, metrics);
1503
1504 df->Layout();
1505 }
1506}
1507
1508//
1509/// This function overrides TDockingSlip::DockableInsert to insert a new dockable
1510/// object into this TEdgeSlip. Called by mouseup handler after a dockable object is
1511/// dropped into this slip.
1512//
1513void
1516{
1517 // Get dockable's window & hide it in case we have to toss it around a bit
1518 // Reparent the window to the edge slip
1519 //
1520 TWindow* dockableWindow = dockable.GetWindow();
1522 dockableWindow->ShowWindow(SW_HIDE);
1523 dockableWindow->SetParent(this);
1524
1525 // Let window know it was docked...
1526 //
1527#ifdef UNIX
1528 if (dockableWindow->IsWindow()) //???????????????????????
1529 dockableWindow->HandleMessage(WM_OWLWINDOWDOCKED, TParam1(GridType == YCoord ? alTop : alLeft), TParam2( (TDockingSlip*)this) );
1530#else
1531 dockableWindow->DispatchMsg(WM_OWLWINDOWDOCKED, 0, TParam1(GridType == YCoord ? alTop : alLeft),
1532 TParam2(static_cast<TDockingSlip*>(this)));
1533#endif
1534
1535 // Slam dockable over to 0,0 since Move assumes we own it already
1536 //
1537 dockableWindow->SetWindowPos(nullptr, 0, 0, 0, 0,
1539
1540 // Make sure that the dockable is oriented the right way--horizontal layout
1541 // for Y-gridded slips
1542 //
1543 dockable.Layout(GridType == YCoord ? alTop : alLeft);
1544
1545/// dockableWindow->Create(); // just in case? but only if we are?
1547 dockableWindow->ShowWindow(SW_SHOWNA);
1548}
1549
1550//
1551/// Overriden TDockingSlip virtual. Called by mouseup handler after a drag within
1552/// this docking window.
1553//
1554void
1557{
1558 TWindow* dockableWindow = dockable.GetWindow();
1560
1561 // If no dockable topleft given, calculate based on relative dockable &
1562 // location
1563 //
1564 if (topLeft) {
1565 dockPos = *topLeft;
1566 }
1567 else {
1568 // Figure out the best relative position if none given
1569 //
1570 if (position == rpNone) switch (Location) {
1571 case alNone:
1572 break;
1573 case alTop:
1574 position = rpBelow;
1575 break;
1576 case alBottom:
1577 position = rpAbove;
1578 break;
1579 case alLeft:
1581 break;
1582 case alRight:
1584 break;
1585 default: //JJH added empty default construct
1586 break;
1587 }
1588
1589 // Get the last child inserted into this docking window and use it as the
1590 // relative window if none was given
1591 //
1592 TWindow* relWindow = 0;
1593 if (relDockable)
1594 relWindow = relDockable->GetWindow();
1595 if (!relWindow)
1597
1598 // Get its rect if it exists, or the screen coord of this slip's client area
1599 //
1600 TRect relWindowRect(0,0,0,0);
1601 if (relWindow)
1602 relWindowRect = relWindow->GetWindowRect();
1603 else
1604 ::MapWindowPoints(nullptr, *this, reinterpret_cast<TPoint*>(&relWindowRect), 2);
1605
1606 TSize dockableSize = dockableWindow->GetWindowRect().Size();
1607 switch (position) {
1608 case rpNone:
1609 break;
1610 case rpAbove:
1612 break;
1613 case rpBelow:
1614 dockPos = TPoint(relWindowRect.left, relWindowRect.bottom);
1615 break;
1616 case rpLeftOf:
1618 break;
1619 case rpRightOf:
1621 break;
1622 default: //JJH added default construct
1623 break;
1624 }
1625 }
1626
1627 // Find a gridline on which to put the dockable
1628 //
1629 int dockableEdge;
1631 CHECK(!GridList.empty());
1632 int bottomEdge = GridList[0].Top;
1633 if (Location == alTop || Location == alBottom)
1635 else
1637
1638 for (size_t i = 0; i < GridList.size(); ++i) {
1639 if (dockableEdge <= (GridList[i].Top+GridList[i].Bottom)/2)
1640 break;
1641 if (GridList[i].Window != dockableWindow)
1642 bottomEdge = std::max(bottomEdge,GridList[i].Bottom);
1643 }
1644
1645 // Adjust perpendicular coord to newly found spot
1646 //
1648 if (Location == alTop || Location == alBottom) {
1649 newPos.y = bottomEdge;
1650 }
1651 else {
1652 newPos.x = bottomEdge;
1653 }
1654
1655 // Adjust from screen coords, but make sure rect topleft is > 0
1656 //
1657 ::MapWindowPoints(nullptr, *this, &newPos, 1);
1658 if (newPos.x < 0)
1659 newPos.x = 0;
1660 if (newPos.y < 0)
1661 newPos.y = 0;
1662
1663 // Position & show the dockable window
1664 //
1665 dockableWindow->SetWindowPos(nullptr, newPos.x, newPos.y, 0, 0,
1667 dockableWindow->ShowWindow(SW_SHOWNA);
1668
1669 // Adjust all windows on the grid line
1670 //
1672
1673 // Squash down dockable's previous area if needed
1674 //
1676}
1677
1678//
1679/// Overriden TDockingSlip virtual. Called by mouseup handler after a dockable has
1680/// been removed from this docking slip.
1681//
1682void
1684{
1686}
1687
1688//
1689/// All terminology in this function is referenced to the following two windows
1690/// Drag and LeftEdge. The LeftEdge window is only valid if the Drag windows's
1691/// left side is intersecting the LeftEdge window's right side.
1692/// \code
1693/// ======================
1694/// ------------------- Drag Window |
1695/// | LeftEdge Window |================
1696/// -------------------
1697/// \endcode
1698//1 The goal of this function is to anchor down the Drag window's left side.
1699/// This is accomplished by one of three ways:
1700/// - 1. Leave the Drag window where it is; if the Drag window's left side does
1701/// not intersect with any other windows (no LeftEdge window).
1702/// - 2. Slide the Drag window to the right of the LeftEdge window being
1703/// intersected. This is only done if the intersection is not beyond the
1704/// midpoint (less than 50% of the LeftEdge window) of the LeftEdge window.
1705/// - 3. Slide the Drag window to the left side position of the LeftEdge window
1706/// (the Drag window's left side is equal to the LeftEdge window's left
1707/// side). The LeftEdge window is then slid to the right side of the Drag
1708/// window; if the intersection is beyond the mid point of the left edge
1709/// window (more than 50% of the LeftEdge window).
1710//
1711TWindow*
1713{
1714 // Do we want to move the draggedWindow, if so do that.
1715 //
1716 TRect draggedRect = draggedWindow->GetWindowRect();
1717
1719 if (first) {
1720 TWindow* w = first;
1721 do {
1722 if (w != draggedWindow) {
1723 TRect currRect = w->GetWindowRect();
1724 TPoint pt;
1725
1726 if (Location == alTop || Location == alBottom) {
1727 if (draggedRect.left >= currRect.left && draggedRect.left <= currRect.right &&
1728 currRect.top == draggedRect.top) {
1729
1730 int midPt = (currRect.right - currRect.left) / 2;
1731
1732 // If the dragged window is obscuring the window underneath by more
1733 // than 50% then the dragged window will keep its position and the
1734 // underneath window must moved. Otherwise, the dragged window
1735 // will move and the window underneath will move.
1736 //
1737 if (currRect.left + midPt > draggedRect.left) {
1738 // Move the draggedWindow to the same left as the window
1739 // underneath.
1740 //
1741 pt.x = currRect.left;
1742 pt.y = draggedRect.top;
1743 ::MapWindowPoints(nullptr, *this, &pt, 1);
1744 draggedWindow->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1746
1747 // Move the current window to the right of the dragged window.
1748 //
1749 draggedRect = draggedWindow->GetWindowRect();
1750 pt.x = draggedRect.right;
1751 pt.y = currRect.top;
1752 ::MapWindowPoints(nullptr, *this, &pt, 1);
1753 w->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1755 return w;
1756 }
1757 else {
1758 // Move the dragged window to the right of the current window (w).
1759 //
1760 pt.x = currRect.right;
1761 pt.y = draggedRect.top;
1762 ::MapWindowPoints(nullptr, *this, &pt, 1);
1763 draggedWindow->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1765 return draggedWindow;
1766 }
1767 }
1768 }
1769 else {
1770 // Left and right docking area.
1771 //
1772 if (draggedRect.top >= currRect.top && draggedRect.top <= currRect.bottom &&
1773 currRect.left == draggedRect.left) {
1774
1775 int midPt = (currRect.bottom - currRect.top) / 2;
1776
1777 // If the dragged window is obscuring the window underneath by more
1778 // than 50% then the dragged window will keep its position and the
1779 // underneath window must moved. Otherwise, the dragged window will
1780 // move and the window underneath will move.
1781 //
1782 if (currRect.top+midPt > draggedRect.top) {
1783 // Move the draggedWindow to the same left as the window underneath.
1784 //
1785 pt.x = currRect.left;
1786 pt.y = draggedRect.top;
1787 ::MapWindowPoints(nullptr, *this, &pt, 1);
1788 draggedWindow->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1790
1791 // Move the current window to the right of the dragged window.
1792 //
1793 draggedRect = draggedWindow->GetWindowRect();
1794 pt.x = draggedRect.right;
1795 pt.y = currRect.top;
1796 ::MapWindowPoints(nullptr, *this, &pt, 1);
1797 w->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1799 return w;
1800 }
1801 else {
1802 // Move the dragged window to the right of the current window (w).
1803 //
1804 pt.x = currRect.right;
1805 pt.y = draggedRect.top;
1806 ::MapWindowPoints(nullptr, *this, &pt, 1);
1807 draggedWindow->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1809 return draggedWindow;
1810 }
1811 }
1812 }
1813 }
1814
1815 w = w->Next();
1816 } while (w != first);
1817 }
1818
1819 return draggedWindow;
1820}
1821
1822//
1823// Structure to manage the list of windows to slide.
1824//
1825struct TWindowItem {
1826 TWindow* DockedWindow;
1827 int LeftSide;
1828
1829 TWindowItem(TWindow* dockedW = 0, int left = 0) : DockedWindow(dockedW),
1830 LeftSide(left)
1831 {}
1832
1833 // operator to satisfy TIArrayAsVector
1834 //
1835 bool operator == (const TWindowItem& other) {
1836 return (other.DockedWindow == DockedWindow) &&
1837 (other.LeftSide == LeftSide);
1838 }
1839};
1840
1841//
1842/// Builds a list (sorted by left coordinate) of windows on the same horizontal
1843/// (top/bottom docking) or vertical (left/right docking) of windows to the right of
1844/// or below the dragged window. The function then slides all windows from the first
1845/// one intersecting the dragged window to the last one in the list.
1846//
1847void
1849{
1850
1852
1853 // Include the (upto) two windows which were anchored in MoveDraggedWindow.
1854 //
1855 TRect draggedRect = draggedWindow->GetWindowRect() | movedWindow->GetWindowRect();
1857 if (first) {
1858 TWindow* w = first;
1859 do {
1860 // If the current window is the moved window or the draggedWindow then
1861 // grab another window.
1862 //
1863 if (w != draggedWindow) {
1864 TRect currRect = w->GetWindowRect();
1865
1866 // Build a list of windows on the same horizontal or vertical after
1867 // the dragged window.
1868 // !CQ assumes top/bottom slip -- flip axis for left/right
1869 //
1870 if (currRect.top == draggedRect.top && currRect.left >= draggedRect.left) {
1871 uint i = 0;
1872
1873 while (i < windowList.Size()) {
1874 if (currRect.left <= windowList[i].LeftSide)
1875 break;
1876 i++;
1877 }
1878
1879 TWindowItem wItem(w, currRect.left); // !CQ leave to debug
1880 windowList.AddAt(wItem, i);
1881 }
1882 }
1883
1884 w = w->Next();
1885 } while (w != first);
1886 }
1887
1888
1889 // Are there windows after the dragged window to adjust?
1890 //
1891
1892 if(windowList.Size()) {
1893 uint i = 0;
1894
1895 // Find the first one, all subsequent ones (plus this one) will be slid.
1896 //
1897 while (i < windowList.Size()) {
1898 if (windowList[i].LeftSide >= draggedRect.left &&
1899 windowList[i].LeftSide < draggedRect.right)
1900 break;
1901 i++;
1902 }
1903
1904 // Slide all windows after the dragged window.
1905 //
1906
1907 if (i == 0 || i != windowList.Size()) {
1909 TPoint pt;
1910
1911 while (i < windowList.Size()) {
1912 int offset = w1->GetWindowRect().right - windowList[i].LeftSide;
1913
1914 pt.x = windowList[i].LeftSide + offset;
1915 pt.y = windowList[i].DockedWindow->GetWindowRect().top;
1916 ::MapWindowPoints(nullptr, *this, &pt, 1);
1917 windowList[i].DockedWindow->SetWindowPos(nullptr, pt.x, pt.y, 0, 0,
1919 w1 = windowList[i++].DockedWindow;
1920 }
1921 }
1922 }
1923
1924// Iterators cannot be used when modifying the underlying container
1925//
1926// TWindowItemArrayIter iter(windowList);
1927// while (iter) {
1928// TWindowItem* item = iter.Current();
1929// windowList.Detach(item);
1930// delete item;
1931// iter++;
1932// }
1933}
1934
1935#if 0
1936//
1937// Pull every child beyond a given coord in by a given delta (positive),
1938// or push out every child beyond the given coord by the given delta (negative)
1939//
1940void
1941TEdgeSlip::Collapse(int topCoord, int delta)
1942{
1944 if (first) {
1945 TWindow* w = first;
1946 do {
1947 TRect rect = w->GetWindowRect();
1948 if (Location == alTop || Location == alBottom) {
1949 if (rect.top > topCoord) {
1950 rect.Offset(0, -delta);
1951 ::MapWindowPoints(0, *this, (LPPOINT)&rect, 1);
1952 w->SetWindowPos(0, rect.left, rect.top, 0, 0,
1954 }
1955 }
1956 else {
1957 if (rect.left > topCoord) {
1958 rect.Offset(-delta, 0);
1959 ::MapWindowPoints(0, *this, (LPPOINT)&rect, 1);
1960 w->SetWindowPos(0, rect.left, rect.top, 0, 0,
1962 }
1963 }
1964 w = w->Next();
1965 } while (w != first);
1966 }
1967}
1968#endif
1969
1970//
1971/// Computes the docking area size based on the dockables inside (total height if
1972/// top/bottom docking area or total width if left/right docking area). Includes the
1973/// non-client area etched borders or real window borders. Will return misleading
1974/// Size() if dockables not 0 justified.
1975//
1976TSize
1978{
1979 TRect rect(0, 0, 0, 0);
1980
1982 if (first) {
1983 TWindow* w = first;
1984 do {
1985 // Union of all visible areas.
1986 //
1987 if (w->GetWindowAttr().Style & WS_VISIBLE)
1988 rect |= w->GetWindowRect();
1989 w = w->Next();
1990 } while (w != first);
1991 }
1992
1993 // Only add in space if this slip is not shrunk to nothing
1994 //
1995 if (rect.bottom > rect.top && rect.right > rect.left) {
1996 if (!(Attr.Style & WS_BORDER)) { // if 3d style, add space for the etchings
1997 if (Location != alBottom)
1998 rect.bottom += 2;
1999 if (Location != alTop)
2000 rect.bottom += 2;
2001 }
2002 else {
2003 AdjustWindowRectEx(rect, Attr.Style, false, Attr.ExStyle);
2004 }
2005 }
2006
2007 return rect.Size(); // !CQ or could return rect.BottomRight()
2008}
2009
2010//
2011/// Returns the perpendicular size of the grid line with the given base coordinates.
2012/// Returns 0 if there are no dockables on the given grid line.
2013//
2014int
2016{
2018 int h = 0;
2019 if (first) {
2020 TWindow* w = first;
2021 do {
2022 if (w->GetWindowAttr().Style & WS_VISIBLE) {
2023 TRect r = w->GetWindowRect();
2024
2025 if (GridType == YCoord) {
2026 if (baseCoord == r.top) {
2027 h = std::max(h, r.Height());
2028 }
2029 }
2030 else {
2031 if (baseCoord == r.left){
2032 h = std::max(h, r.Width());
2033 }
2034 }
2035 }
2036 w = w->Next();
2037 } while (w != first);
2038 }
2039 return h;
2040}
2041
2042
2043//
2044/// Retrieves the location of the slip.
2045//
2048{
2049 return Location;
2050}
2051
2052
2058
2059//
2060/// Creates the harbor. The harbor is where the slips can go dock.
2061//
2063:
2064 TWindow(&df, _T("Harbor")),
2065 DecFrame(df)
2066{
2067 Attr.W = 0;
2068 Attr.H = 0;
2069 Attr.Style = WS_CHILD; // not visible
2070
2071 SlipTop = nullptr;
2072 SlipLeft = nullptr;
2073 SlipBottom = nullptr;
2074 SlipRight = nullptr;
2075
2076 DragDC = nullptr;
2077 DragDockable = nullptr;
2078}
2079
2080//
2081/// Destructor.
2082/// Currently does nothing.
2083//
2085{
2086}
2087
2088
2089//
2090/// Creates an edge slip at a location.
2091//
2092TEdgeSlip*
2097
2098//
2099/// Constructs a floating slip with a particular window at a location.
2100//
2106
2107//
2108/// Returns the slip at the location.
2109//
2110TEdgeSlip*
2112{
2113 switch (location) {
2114 case alNone:
2115 return nullptr;
2116 case alTop:
2117 return SlipTop;
2118 case alBottom:
2119 return SlipBottom;
2120 case alLeft:
2121 return SlipLeft;
2122 case alRight:
2123 return SlipRight;
2124 default: //JJH added empty default construct
2125 break;
2126 }
2127 return nullptr;
2128}
2129
2130//
2131/// Sets a new edge slip for a given location. Also lets the edge slip know who we
2132/// are.
2133//
2134void
2136{
2137 slip->SetHarbor(this);
2138
2139 switch (location) {
2140 case alNone:
2141 break;
2142 case alTop:
2143 SlipTop = slip;
2144 break;
2145 case alBottom:
2146 SlipBottom = slip;
2147 break;
2148 case alLeft:
2149 SlipLeft = slip;
2150 break;
2151 case alRight:
2152 SlipRight = slip;
2153 break;
2154 default: //JJH added empty default construct
2155 break;
2156 }
2157}
2158
2159//
2160/// Returns the default docking relative position for a given slip location.
2161/// \todo !CQ make a TDockingSlip virtual!
2162//
2165{
2166 switch (location) {
2167 case alNone:
2168 return rpNone;
2169 case alTop:
2170 return rpBelow;
2171 case alBottom:
2172 return rpAbove;
2173 case alLeft:
2174 return rpRightOf;
2175 case alRight:
2176 return rpLeftOf;
2177 default: //JJH added empty default construct
2178 break;
2179 }
2180 return rpNone;
2181}
2182
2183struct TDitherBrush
2185 : public TLocalObject
2186#endif
2187{
2188 TDitherBrush():Brush(THatch8x8Brush::Hatch11F1)
2189 {
2190 }
2191 ~TDitherBrush()
2192 {
2193 }
2194
2195 THatch8x8Brush Brush;
2196
2197#if defined(BI_MULTI_THREAD_RTL)
2198// TMRSWSection Lock;
2199#endif
2200};
2201
2202//
2203// Static instance of the colors
2204//
2205static TDitherBrush& GetDitherBrush()
2206{
2207#if defined(BI_MULTI_THREAD_RTL)
2209 return ditherBrush.Get();
2210#else
2211 static TDitherBrush ditherBrush;
2212 return ditherBrush;
2213#endif
2214};
2215
2216//
2217// Draw a fast window-type frame rect
2218//
2219static int fastWindowFrame(TDC& dc, const TRect& r, bool thick, uint32 rop)
2220{
2221 int thickness = thick ? TUIMetric::CxSizeFrame // a thick
2222 : TUIMetric::CxBorder; // or a thin frame
2223
2224 int x = r.left;
2225 int y = r.top;
2226 int cx = r.right - x - thickness;
2227 int cy = r.bottom - y - thickness;
2228
2229 if (thick)
2230 dc.SelectObject(GetDitherBrush().Brush);
2231 else
2232 dc.SelectStockObject(WHITE_BRUSH);
2233
2234 dc.PatBlt(x, y, thickness, cy, rop); // Left
2235 dc.PatBlt(x + thickness, y, cx, thickness, rop); // Top
2236 dc.PatBlt(x, y + cy, cx, thickness, rop); // Bottom
2237 dc.PatBlt(x + cx, y + thickness, thickness, cy, rop); // Right
2238
2239 return true;
2240}
2241
2242//
2243/// Begins a dockable window tracking session. Returns true if started
2244/// satisfactorily.
2245//
2246bool
2249{
2250 // Get dockable to drag, its frame rectangle & the mouse anchor point
2251 // Compute relative position of mouse from top/left corner of window.
2252 //
2256
2257 // Remember the docking area & original docking area too. Also remember which
2258 // docking slip to notify when drag is done.
2259 //
2262
2263 // Find out the sizes of the dockable in the three orientations:
2264 // Vertical, Horizontal & Natural
2265 //
2269
2270 // Calculate the screen relative rectangles for the four docking areas based
2271 // on the dec frame's client area.
2272 //
2273 TRect frameR = DecFrame.GetClientWindow()->GetWindowRect();
2274/// DecFrame.MapWindowPoints(0, frameR, 2);
2275
2276 if (SlipTop)
2278 else
2279 SlipTR.Set(frameR.left, frameR.top, frameR.right, frameR.top);
2280
2281 if (SlipBottom)
2283 else
2284 SlipBR.Set(frameR.left, frameR.bottom, frameR.right, frameR.bottom);
2285
2286 if (SlipLeft)
2288 else
2289 SlipLR.Set(frameR.left, frameR.top, frameR.left, frameR.bottom);
2290
2291 if (SlipRight)
2293 else
2294 SlipRR.Set(frameR.right, frameR.top, frameR.right, frameR.bottom);
2295
2296 // Capture the mouse & create a screen DC to use while dragging
2297 //
2298 SetCapture();
2299 DragDC = new TScreenDC;
2300
2301 // Update dragged window here to avoid asynchronous repaint uglies when
2302 // exposed by click. Then paint frame.
2303 //
2304 DragDockable->GetWindow()->UpdateWindow();
2305 fastWindowFrame(*DragDC, DragFrame, DragSlipLoc == alNone, PATINVERT);
2306
2307 return true;
2308}
2309
2310//
2311/// Handles MouseMove to perform dockable dragging if a drag is in progress.
2312//
2313void
2315{
2316 if (DragDockable && DragDC) {
2318
2319 // Save un-painting the frame until the end to reduce flicker
2320 //
2323
2324 // Compute the new horz, vert & natural frames to test for touching of
2325 // edge slips & to eventualy update DragRect. Make sure that horz & vert
2326 // rects surround mouse, shift as needed.
2327 //
2328 DragFrame.MoveTo(p.x - DragAnchor.x, p.y - DragAnchor.y);
2329
2331 if (!hFrame.Contains(p))
2332 hFrame.MoveTo(hFrame.left, p.y - DragHSize.cy/2);
2333
2335 if (!vFrame.Contains(p))
2336 vFrame.MoveTo(p.x - DragVSize.cx/2, vFrame.top);
2337
2339 if (!nFrame.Contains(p))
2340 nFrame.Offset(p.x - DragNSize.cx/2 - nFrame.left,
2341 p.y - DragNSize.cy/2 - nFrame.top);
2342
2343 if (hFrame.Touches(SlipTR))
2345 else if (hFrame.Touches(SlipBR))
2347 else if (vFrame.Touches(SlipLR))
2349 else if (vFrame.Touches(SlipRR))
2351 else
2353
2354 // If over a docking area and it is not the same as the last one, then
2355 // re-compute the frame rectangle
2356 //
2357 if (DragSlipLoc == alNone)
2358 DragFrame = nFrame;
2359 else if (DragSlipLoc == alTop || DragSlipLoc == alBottom)
2360 DragFrame = hFrame;
2361 else
2362 DragFrame = vFrame;
2363
2364 /// Adjust if needed to put frame around mouse? Check each rect? At least
2365 /// horz & vert?
2366 ///
2367/// if (!DragFrame.Contains(p))
2368/// DragFrame.Offset(p.x - DragFrame.left - 15, p.y - DragFrame.top - 15);
2369
2370 // Unpaint old frame, & paint new frame
2371 //
2372 fastWindowFrame(*DragDC, oldDragFrame, oldDragSlipLoc == alNone, PATINVERT);
2373 fastWindowFrame(*DragDC, DragFrame, DragSlipLoc == alNone, PATINVERT);
2374 }
2375 else
2377}
2378
2379//
2380/// Handles mouse up to drop a dockable window being dragged.
2381//
2382void
2384{
2385 if (DragDockable && DragDC) {
2386
2387 // Unpaint frame.
2388 //
2389 fastWindowFrame(*DragDC, DragFrame, DragSlipLoc == alNone, PATINVERT);
2390
2392
2395
2397 DragDockable = nullptr;
2398
2399 delete DragDC;
2400 DragDC = nullptr;
2401
2402 // We're docking into a new slip--call the Move function to do the
2403 // work.
2404 //
2405 if (DragOrgSlipLoc != DragSlipLoc) {
2406 // Get the real dockable interface for the actual dockable window--
2407 // working dockable may have been a helper.
2408 //
2410 CHECK(dd);
2412 }
2413 // Notifiy docking slip that the dragging resulted in a dockable move.
2414 //
2415 else {
2416 if (DragNotificatee)
2418 }
2419 }
2420 else
2422}
2423
2424//
2425/// Handles the left button double click and forwards the message to the dockable
2426/// window.
2427//
2428void
2430{
2431 // We get this message when a slip is in drag mode, and mouse clicks are
2432 // captured by the harbor.
2433 //
2434 if (DragDockable) {
2435 // If dragging, stop dragging and pass the message to the dragged window.
2436 //
2437 TWindow* win = DragDockable->GetWindow();
2440 }
2441 else {
2443 }
2444}
2445
2446//
2447/// Inserts a dockable into the appropriate docking area indicated by the given
2448/// location and either a point or a relative dockable and position.
2449//
2452 const TPoint* where,
2454{
2455 // Get the actual window associated with the dockable
2456 //
2457 TWindow* dw = dockable.GetWindow();
2458
2459 // Making the dockable Floating.
2460 //
2461 if (location == alNone) {
2462 // The 'where' is relative to the decframe's client. Make absolute when
2463 // the floatFrame is a popup
2464 //
2466 if (where) {
2467 floatWhere = *where;
2468 }
2469 else {
2470 // Don't know where to put the floating palette, use CW_USEDEFAULT
2471 //
2473 }
2474
2475 // Call out to the virtual to contruct a hidden floating slip
2476 //
2479 dw);
2480 // Give slip pointer to harbor
2481 //
2482 slip->SetHarbor(this);
2483
2484 // If decorated frame is already created, the create floating slip
2485 //
2486 if (DecFrame.GetHandle()) {
2487 slip->Create();
2488 slip->DockableInsert(dockable, where, rpNone, nullptr);
2489 slip->ShowWindow(SW_SHOWNA);
2490
2491 } else {
2492
2493 // Slip will be created latter (auto-creation) - make sure it's visible
2494 //
2495 slip->GetWindowAttr().Style |= WS_VISIBLE;
2496 slip->DockableInsert(dockable, where, rpNone, nullptr);
2497 }
2498
2499 // Return floating slip
2500 //
2501 return slip;
2502 }
2503 else {
2505 if (!slip) {
2506 // Make an edge slip if not one already for the given edge
2507 //
2511
2512 // If frame is created, go ahead and create slip
2513 //
2514 if (DecFrame.GetHandle())
2515 slip->Create();
2516 }
2517
2518 // Insert the dockable into the slip, based on args given
2519 //
2520 slip->DockableInsert(dockable, where, position, relDockable);
2521
2522 // Return edge slip
2523 //
2524 return slip;
2525 }
2526}
2527
2528//
2529/// Moves a dockable from one slip to another.
2530//
2531void
2534{
2535 // Get current slip, assuming it is the parent of the dockable's window
2536 //
2538 TWindow* dockableWindow = dockable.GetWindow();
2539 if (dockableWindow) {
2541 }
2542
2543 // If the location hasn't changes, just tweak the position within the slip,
2544 // otherwise insert into new & remove from old.
2545 //
2546 if (previousSlip && previousSlip->GetLocation() == location) {
2547 if (where)
2548 previousSlip->DockableMove(dockable, where);
2549 else
2550 ;// !CQ call DockableMove when it takes position & relDockable
2551 }
2552 else {
2554 dockable.GetRect(previousRect);
2555
2556 // Remove from the previous slip
2557 //
2559
2560 // Insert into the new slip
2561 //
2563 }
2564}
2565
2566//
2567/// Removes a dockable from the harbor.
2568//
2569void
2571{
2572 // Get the actual window associated with the dockable
2573 //
2574 TWindow* dockableWindow = dockable.GetWindow();
2575
2576 if (dockableWindow) {
2578 dockable.GetRect(previousRect);
2579
2580 // Find the slip containing the dockable
2581 //
2583 TDockingSlip);
2584
2585 // Remove the dockable from the slip and reparent it to the harbor
2586 //
2587 dockableWindow->ShowWindow(SW_HIDE);
2588 dockableWindow->SetParent(this);
2589
2590 // Notify original docking slip that its dockable was removed.
2591 //
2592 if (previousSlip)
2593 previousSlip->DockableRemoved(previousRect);
2594 }
2595}
2596
2597} // OWL namespace
2598
#define CHECK(condition)
Definition checks.h:239
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
Class wrapper for management of color values.
Definition color.h:245
static const TColor Sys3dFace
The symbolic system color value for the face color of 3-dimensional display elements.
Definition color.h:339
Base class for an extensible interface for auto enabling/disabling of commands (menu items,...
Definition window.h:209
TCursor, derived from TGdiBase, represents the GDI cursor object class.
Definition gdiobjec.h:730
TDecoratedFrame automatically positions its client window (you must supply a client window) so that i...
Definition decframe.h:74
TLocation
Enumeration describing the possible locations of a Gadgetwindow [Used mainly for location of Toolbar ...
Definition decframe.h:88
virtual void Insert(TWindow &decoration, TLocation location=Top)
Insert a decoration window into position at one of the four edges.
Definition decframe.cpp:899
A control bar class that is dockable.
Definition docking.h:133
TDockableControlBar(TWindow *parent=0, TTileDirection direction=Horizontal, TFont *font=0, TModule *module=0)
Constructs a dockable control bar.
Definition docking.cpp:495
void EvOwlWindowDocked(uint pos, const TDockingSlip &slip)
Definition docking.cpp:533
A version of TGadgetWindow which is dockable.
Definition docking.h:92
void Layout(TAbsLocation, TSize *=nullptr) override
Causes this dockable to lay itself out vertically, horizontally, or rectangularly.
Definition docking.cpp:329
virtual TTileDirection GetDirectionForLocation(TAbsLocation loc)
Returns the layout direction to use when placed in a slip This can be overridden to provide different...
Definition docking.cpp:309
auto GetWindow() -> TWindow *override
Returns the TWindow part of this dockable object.
Definition docking.cpp:367
void EvOwlWindowDocked(uint pos, const TDockingSlip &slip)
Inserts/deletes FlatBar Grip.
Definition docking.cpp:105
void EvLButtonDown(uint modKeys, const TPoint &point)
Forwards event to slip to allow movement of gadget within the slip.
Definition docking.cpp:438
auto ShouldBeginDrag(TPoint &) -> bool override
Returns true if the mouse click point is in a spot that should move this dockable around.
Definition docking.cpp:348
~TDockableGadgetWindow() override
Definition docking.cpp:81
virtual TGadget * GetGripGadget()
Definition docking.cpp:88
void GetRect(TRect &) override
Gets this dockable's screen rectangle.
Definition docking.cpp:299
auto ComputeSize(TAbsLocation, TSize *) -> TSize override
Finds out how big this dockable would be in a given location, and with a given optional size hint.
Definition docking.cpp:182
void LayoutSession() override
If the gadget window changes size when laying out a dockable gadget window, this function tells the d...
Definition docking.cpp:377
auto GetHarbor() -> THarbor *override
Returns the harbor containing the dockable object.
Definition docking.cpp:420
TDockableGadgetWindow(TWindow *parent=0, TTileDirection direction=Horizontal, TFont *font=0, TModule *module=0)
This constructor creates a dockable gadget window and sets the appropriate styles for the window.
Definition docking.cpp:57
bool EvSetCursor(HWND hWndCursor, uint codeHitTest, TMsgId mouseMsg)
Definition docking.cpp:153
TDockable is an abstract base class for fixed or floating docking windows that want to be dockable in...
Definition docking.h:57
virtual TWindow * GetWindow()=0
Gets dockable's window and hides it, in case we have to toss it around a bit.
virtual TSize ComputeSize(TAbsLocation loc, TSize *dim)=0
Returns the rectangle of the dockable window in the given location.
virtual void GetRect(TRect &rect)=0
Return the rectangle of the dockable window in the given location.
TDockingSlip is an abstract base class for windows which accepts and holds dockable windows.
Definition docking.h:154
virtual void DockableMove(TDockable &dockable, const TPoint *topLeft=0, TRelPosition position=rpNone, TDockable *relDockable=0)=0
THarbor * Harbor
Definition docking.h:176
TEdgeSlip is the class of windows used by THarbor as the actual docking slips along the decorated fra...
Definition docking.h:238
TWindow * MoveDraggedWindow(TWindow *draggedWindow)
All terminology in this function is referenced to the following two windows Drag and LeftEdge.
Definition docking.cpp:1712
void DockableInsert(TDockable &dockable, const TPoint *topLeft, TRelPosition position, TDockable *relDockable) override
This function overrides TDockingSlip::DockableInsert to insert a new dockable object into this TEdgeS...
Definition docking.cpp:1514
void EvParentNotify(const TParentNotify &)
Makes sure that the slip size is updated when a child changes size.
Definition docking.cpp:1277
uint EvNCCalcSize(bool calcValidRects, NCCALCSIZE_PARAMS &calcSize)
Returns the size of the client area, leaving room for the etched separators.
Definition docking.cpp:1209
TEdgeSlip(TDecoratedFrame &parent, TAbsLocation location, TModule *module=0)
Constructs an edge slip, and sets the approriate styles for the window.
Definition docking.cpp:973
void EvLButtonDown(uint modKeys, const TPoint &point)
Forwards the left button down message to the dockable object.
Definition docking.cpp:1175
bool EvWindowPosChanging(WINDOWPOS &windowPos)
When the slip shrinks, this function adjusts dockables where needed.
Definition docking.cpp:1331
void DockableRemoved(const TRect &orgRect) override
Overriden TDockingSlip virtual.
Definition docking.cpp:1683
void SetupWindow() override
Ensures that all decorations in the docking window are abutted against each other (both horizontally ...
Definition docking.cpp:1060
void CompressGridLines()
Compresses or expands dockables perpendicular to the grid line.
Definition docking.cpp:1343
void DockableMove(TDockable &dockable, const TPoint *topLeft, TRelPosition position, TDockable *relDockable) override
Overriden TDockingSlip virtual.
Definition docking.cpp:1555
auto EvCommand(uint id, THandle hWndCtl, uint notifyCode) -> TResult override
Forward command messages to the parent.
Definition docking.cpp:1160
int GridSize(int baseCoord)
Returns the perpendicular size of the grid line with the given base coordinates.
Definition docking.cpp:2015
void EvLButtonDblClk(uint modKeys, const TPoint &point)
Handles WM_LBUTONDBLCLICK to tell the frame to edit a toolbar.
Definition docking.cpp:1200
void EvCommandEnable(TCommandEnabler &commandEnabler) override
Changes the reciever to be the framewindow, not the docking window.
Definition docking.cpp:1139
void CompressParallel(int width)
Compresses empty space along grid line if any dockables hang out past the end.
Definition docking.cpp:1396
auto GetLocation() const -> TAbsLocation override
Retrieves the location of the slip.
Definition docking.cpp:2047
void EvNCPaint(HRGN)
Erases the background and draws in etched 'borders' within the client area.
Definition docking.cpp:1231
TSize ComputeDockingArea()
Computes the docking area size based on the dockables inside (total height if top/bottom docking area...
Definition docking.cpp:1977
void MoveAllOthers(TWindow *draggedWindow, TWindow *movedWindow)
Builds a list (sorted by left coordinate) of windows on the same horizontal (top/bottom docking) or v...
Definition docking.cpp:1848
void ReLayout(bool forcedLayout)
Called by Harbor when creating this docking window on a drop.
Definition docking.cpp:1476
bool EvEraseBkgnd(HDC)
Erases the background and draws in etched 'borders' within the client area.
Definition docking.cpp:1264
A gadget that is used on the far right of a status bar to provide re-sizing grip for the host window.
Definition gadget.h:375
Derived from TFrameWindow and TTinyCaption, TFloatingFrame implements a floating frame that can be po...
Definition floatfra.h:52
TFloatingSlip is a floating frame which can hold a dockable window.
Definition docking.h:187
bool EvWindowPosChanging(WINDOWPOS &windowPos)
Handles WM_WINDOWPOSCHANGING to make sure that the frame is properly constrained by the dimensions of...
Definition docking.cpp:723
auto ComputeSize(TAbsLocation, TSize *) -> TSize override
Forward the first four TDockable virtuals to the client dockable.
Definition docking.cpp:886
void EvSettingChange(uint, LPCTSTR)
Event handler for the .INI file changed message.
Definition docking.cpp:787
void EvNCLButtonDown(uint hitTest, const TPoint &point)
Handles lbutton down bubbled up from the client to begin a dockable drag operation.
Definition docking.cpp:600
auto GetHarbor() -> THarbor *override
Returns the associated harbor.
Definition docking.cpp:945
auto ShouldBeginDrag(TPoint &) -> bool override
A given mouse down should never begin a drag for this dockable.
Definition docking.cpp:925
void DockableInsert(TDockable &, const TPoint *topLeft, TRelPosition, TDockable *relDockable) override
Overriden TDockingSlip virtual.
Definition docking.cpp:826
void EvWindowPosChanged(const WINDOWPOS &windowPos)
Handles WM_WINDOWPOSCHANGED to make sure that the dockable client gets a chance to do final layout.
Definition docking.cpp:763
void GetRect(TRect &) override
Gets this dockable's screen rect.
Definition docking.cpp:901
void EvGetMinMaxInfo(MINMAXINFO &info)
Definition docking.cpp:813
void Layout(TAbsLocation, TSize *=nullptr) override
Forwards the layout message over to the dockable object.
Definition docking.cpp:910
void DockableMove(TDockable &, const TPoint *topLeft, TRelPosition, TDockable *relDockable) override
Overriden TDockingSlip virtual.
Definition docking.cpp:856
void EvClose()
When closing the floating slip, removes any dockable first so that it is not destroyed.
Definition docking.cpp:640
bool EvSizing(uint side, TRect &rect)
Handles the Windows 4.0 message for the best resize user feedback.
Definition docking.cpp:653
void DockableRemoved(const TRect &) override
Overriden TDockingSlip virtual.
Definition docking.cpp:868
void EvLButtonDown(uint hitTest, const TPoint &point)
Handles lbutton down bubbled up from the client to begin a dockable drag operation.
Definition docking.cpp:617
auto GetWindow() -> TWindow *override
Returns the TWindow part of this dockable object.
Definition docking.cpp:935
auto GetLocation() const -> TAbsLocation override
Returns the location of the object.
Definition docking.cpp:954
TFont derived from TGdiObject provides constructors for creating font objects from explicit informati...
Definition gdiobjec.h:296
virtual TWindow * GetClientWindow()
Returns a pointer to the client window.
Definition framewin.cpp:591
virtual TWindow * SetClientWindow(TWindow *clientWnd)
Sets the client window to the specified window.
Definition framewin.cpp:603
TGadget is the base class for the following derived gadget classes:
Definition gadget.h:120
TGadget * GadgetFromPoint(const TPoint &point) const
Returns the gadget that a given window-relative point is in, or 0 if none is found.
Definition gadgetli.cpp:42
TGadget * GadgetWithId(int id) const
Returns the gadget with a given ID, or 0 if none is found.
Definition gadgetli.cpp:56
TGadget * FirstGadget() const
Returns the first gadget of the list.
Definition gadgetwi.h:400
Derived from TWindow, TGadgetWindow maintains a list of tiled gadgets for a window and lets you dynam...
Definition gadgetwi.h:122
void Insert(TGadget &, TPlacement=After, TGadget *sibling=nullptr) override
Inserts a gadget before or after a sibling gadget (TPlacement).
static uint GetFlatStyle()
Returns the flat style.
Definition gadgetwi.h:459
@ FlatStandard
Flat style IE 3.0 - base style.
Definition gadgetwi.h:194
void EvLButtonDown(uint modKeys, const TPoint &point)
Responds to a left button-down mouse message by forwarding the event to the gadget (if it is enabled)...
TMargins & GetMargins()
Definition gadgetwi.h:481
virtual void GetDesiredSize(TSize &size)
Get the desired size for this gadget window by performing a trial layout of the gadgets without touch...
Definition gadgetwi.cpp:380
auto GetTooltip() const -> TTooltip *override
Returns Tooltip.
Definition gadgetwi.h:430
void SetRectangularDimensions(int width, int height, int rowMargin=-1)
Sets the maximum width for each row used for rectangular layout.
Definition gadgetwi.cpp:542
void SetShrinkWrap(bool shrinkWrapWidth, bool shrinkWrapHeight)
Sets the width and height of the data members.
Definition gadgetwi.cpp:250
virtual void SetDirection(TTileDirection direction)
Sets the horizontal or vertical orientation of the gadgets.
Definition gadgetwi.cpp:449
virtual void LayoutSession()
LayoutSession is typically called when a change occurs in the size of the margins or gadgets,...
Definition gadgetwi.cpp:357
TTileDirection
Enumeration describing how gadgets should be laid out within the gadget window.
Definition gadgetwi.h:130
@ Vertical
Arrange gadgets in a column.
Definition gadgetwi.h:132
@ Rectangular
Arrange gadgets in rows and columns (2-D grid)
Definition gadgetwi.h:133
@ Horizontal
Arrange gadgets in a row.
Definition gadgetwi.h:131
TTileDirection GetDirection() const
Returns the direction of tiling for this gadget window.
Definition gadgetwi.h:416
THarbor is the object that holds all the docking slips.
Definition docking.h:298
TDockable * DragDockable
Definition docking.h:361
void Remove(TDockable &dockable)
Remove a dockable from the harbor.
Definition docking.cpp:2570
TEdgeSlip * SlipLeft
Definition docking.h:355
TRect SlipRR
Definition docking.h:375
TRelPosition GetSlipPosition(TAbsLocation location)
Returns the default docking relative position for a given slip location.
Definition docking.cpp:2164
void EvLButtonDblClk(uint modKeys, const TPoint &point)
Handles the left button double click and forwards the message to the dockable window.
Definition docking.cpp:2429
TWindowDC * DragDC
Definition docking.h:362
TDockingSlip * Insert(TDockable &dockable, TAbsLocation location, const TPoint *where=0, TRelPosition position=rpNone, TDockable *relativeTo=0)
Dockable window insertion.
Definition docking.cpp:2451
TEdgeSlip * SlipRight
Definition docking.h:357
TSize DragNSize
Size of dockable when a natural shape.
Definition docking.h:368
TDecoratedFrame & DecFrame
Definition docking.h:350
TRect DragFrame
Definition docking.h:365
void Move(TDockable &dockable, TAbsLocation location, const TPoint *where=0, TRelPosition position=rpNone, TDockable *relativeTo=0)
Move a dockable from one slip to another, programatically.
Definition docking.cpp:2532
TRect SlipBR
Definition docking.h:373
TAbsLocation DragSlipLoc
Definition docking.h:364
TEdgeSlip * SlipBottom
Definition docking.h:356
void EvLButtonUp(uint modKeys, const TPoint &point)
Handles mouse up to drop a dockable window being dragged.
Definition docking.cpp:2383
TSize DragVSize
Size of dockable when vertical.
Definition docking.h:366
void EvMouseMove(uint modKeys, const TPoint &point)
Handles MouseMove to perform dockable dragging if a drag is in progress.
Definition docking.cpp:2314
TPoint DragAnchor
Definition docking.h:369
TSize DragHSize
Size of dockable when horizontal.
Definition docking.h:367
TRect SlipTR
Definition docking.h:372
TRect SlipLR
Definition docking.h:374
virtual TEdgeSlip * ConstructEdgeSlip(TDecoratedFrame &df, TAbsLocation location)
Creates an edge slip at a location.
Definition docking.cpp:2093
virtual TFloatingSlip * ConstructFloatingSlip(TDecoratedFrame &df, int x, int y, TWindow *dockableWindow)
Constructs a floating slip with a particular window at a location.
Definition docking.cpp:2102
TDockingSlip * DragNotificatee
Slip notified on drag operations.
Definition docking.h:370
~THarbor() override
Destructor.
Definition docking.cpp:2084
TEdgeSlip * SlipTop
Definition docking.h:354
void SetEdgeSlip(TAbsLocation location, TEdgeSlip *slip)
Sets a new edge slip for a given location.
Definition docking.cpp:2135
TAbsLocation DragOrgSlipLoc
Original slip location on mouseDown.
Definition docking.h:363
bool DockDraggingBegin(TDockable &dockable, const TPoint &pt, TAbsLocation location, TDockingSlip *dockingNotify=0)
Called by docking slips.
Definition docking.cpp:2247
TEdgeSlip * GetEdgeSlip(TAbsLocation location)
Returns the slip at the location.
Definition docking.cpp:2111
Derived from TBrush, THatch8x8Brush defines a small, 8x8, monochrome, configurable hatch brush.
Definition gdiobjec.h:250
When specifying the layout metrics for a window, four layout constraints are needed.
Definition layoutwi.h:54
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
An instance of TProfile encapsulates a setting within a system file, often referred to as a profile o...
Definition profile.h:44
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
void Set(int _left, int _top, int _right, int _bottom)
Repositions and resizes this rectangle to the given values.
Definition geometry.h:1087
const TPoint & TopLeft() const
Returns the upperleft point.
Definition geometry.h:983
TRect & MoveTo(int x, int y)
Moves the upper left corner of the rectangle to a new location and maintains the current dimension.
Definition geometry.h:1371
Derived from TWindowDC, TScreenDC is a DC class that provides direct access to the screen bitmap.
Definition dc.h:610
The tagSIZE struct is defined as.
Definition geometry.h:234
TTooltip encapsulates a tooltip window - i.e.
Definition tooltip.h:175
Assists in drawing borders of many styles.
Definition uihelper.h:270
@ EdgeEtched
Outer sunken, inner raised.
Definition uihelper.h:324
void Paint(TDC &dc) const
Paints this UIBorder object onto a given device context.
Definition uiborder.cpp:112
static const TUIMetric CyFixedFrame
Definition uimetric.h:42
static const TUIMetric CxBorder
Definition uimetric.h:39
static const TUIMetric CySizeFrame
Definition uimetric.h:67
static const TUIMetric CxFixedFrame
Definition uimetric.h:41
static const TUIMetric CxSizeFrame
Definition uimetric.h:66
Derived from TDC, TWindowDC is a device context (DC) class that provides access to the entire area ow...
Definition dc.h:588
TWindow, derived from TEventHandler and TStreamableBase, provides window-specific behavior and encaps...
Definition window.h:414
bool EvEraseBkgnd(HDC)
Handler for WM_ERASEBKGND.
Definition window.cpp:1924
static TPoint GetCursorPos()
Definition window.h:1212
static void AdjustWindowRectEx(TRect &rect, uint32 style, bool menu, uint32 exStyle)
Calculates the size of a window rectangle that has an extended style.
Definition window.h:2296
bool SetCursor(TModule *module, TResId resId)
Sets the mouse cursor for the window, loading the given resId from the given module.
Definition window.cpp:3766
HWND SetCapture()
Sets the mouse capture to the current window.
Definition window.h:2121
HWND ChildWindowFromPoint(const TPoint &point) const
Determines which of the child windows contains the point specified in TPoint.
Definition window.h:2238
void EvNCLButtonDown(uint codeHitTest, const TPoint &)
The default message handler for WM_NCLBUTTONDOWN.
Definition window.h:3883
void EvLButtonUp(uint modKeys, const TPoint &point)
The default message handler for WM_LBUTTONUP.
Definition window.h:3792
static HWND GetCapture()
Returns the handle of the window that has captured the mouse.
Definition window.h:2112
bool EvWindowPosChanging(WINDOWPOS &)
The default message handler for WM_WINDOWPOSCHANGING.
Definition window.h:4212
void SetBkgndColor(TColor color, bool shouldUpdate=true)
Sets the background color for the window.
Definition window.h:1925
TWindow * GetLastChild()
Returns a pointer to the last child window in the interface object's child list.
Definition window.h:1776
void EvClose()
The default response to a WM_CLOSE message is to call CloseWindow() and then have the window deleted ...
Definition window.cpp:2828
bool SetWindowPos(HWND hWndInsertAfter, const TRect &rect, uint flags)
Changes the size of the window pointed to by rect.
Definition window.h:2809
virtual void EvCommandEnable(TCommandEnabler &ce)
Called by WindowProc to handle WM_COMMAND_ENABLE messages, EvCommandEnable calls the CmXxxx command-h...
Definition window.cpp:1135
TWindow * GetParent() const
Retrieves the OWL object of the parent window. If none exists, returns 0.
Definition window.h:2013
TWindow * GetWindowPtr(HWND hWnd) const
Calls TApplication:GetWindowPtr on the application associated with this window.
Definition window.h:3567
TRect GetWindowRect() const
Gets the screen coordinates of the window's rectangle.
Definition window.h:2257
TPoint MapClientToScreen(const TPoint &p) const
Function-style version of ClientToScreen.
Definition window.h:838
void SetFlag(uint mask)
Sets the specified TWindow wfXxxx constant flags (for example wfAlias, wfTransfer,...
Definition window.h:1783
TWindow * GetParentO() const
Return the OWL's parent for this window.
Definition window.h:2006
static void ReleaseCapture()
Releases the mouse capture from this window.
Definition window.h:2130
void MapWindowPoints(HWND hWndTo, TPoint *pts, int count) const
Maps a set of points in one window to a relative set of points in another window.
Definition window.h:2206
bool IsIconic() const
Returns true if window is iconic or minimized.
Definition window.h:2628
void GetWindowRect(TRect &rect) const
Gets the screen coordinates of the window's rectangle and copies them into rect.
Definition window.cpp:3609
TResult HandleMessage(TMsgId, TParam1=0, TParam2=0)
Dispatches the given message using the response table.
Definition window.cpp:1392
void EvLButtonDown(uint modKeys, const TPoint &point)
Response method for an incoming WM_LBUTTONDOWN message.
Definition window.cpp:2101
void EvWindowPosChanged(const WINDOWPOS &windowPos)
The default message handler for WM_WINDOWPOSCHANGED.
Definition window.h:4205
TResult DefaultProcessing()
Handles default processing of events, which includes continued processing of menu/accelerators comman...
Definition window.cpp:852
TRect GetClientRect() const
Gets the coordinates of the window's client area (the area in a window you can use for drawing).
Definition window.h:2217
virtual TResult EvCommand(uint id, HWND hWndCtl, uint notifyCode)
WindowProc calls EvCommand to handle WM_COMMAND messages.
Definition window.cpp:999
void ClearFlag(uint mask)
Clears the specified TWindow wfXxxx constant flags (for example wfAlias, wfTransfer,...
Definition window.h:1790
void ScreenToClient(TPoint &point) const
Uses the screen coordinates specified in point to calculate the client window's coordinates and then ...
Definition window.h:2192
void EvMouseMove(uint modKeys, const TPoint &point)
The default message handler for WM_MOUSEMOVE.
Definition window.h:3841
virtual bool ShowWindow(int cmdShow)
Displays this TWindow in a given state.
Definition window.cpp:3713
TResult SendMessage(TMsgId, TParam1=0, TParam2=0) const
Sends a message (msg) to a specified window or windows.
Definition window.cpp:3288
virtual void SetupWindow()
Performs setup following creation of an associated MS-Windows window.
Definition window.cpp:2575
void EvLButtonDblClk(uint modKeys, const TPoint &point)
The default message handler for WM_LBUTTONDBLCLK.
Definition window.h:3785
bool IsFlagSet(uint mask)
Returns the state of the bit flag in Attr.Flags whose mask is supplied.
Definition window.h:1797
uint EvNCCalcSize(bool calcValidRects, NCCALCSIZE_PARAMS &)
The default message handler for WM_NCCALCSIZE.
Definition window.h:3855
bool EvSetCursor(HWND hWndCursor, uint codeHitTest, TMsgId mouseMsg)
Response method for an incoming WM_SETCURSOR message.
Definition window.cpp:2081
void GetClientRect(TRect &rect) const
Gets the coordinates of the window's client area and then copies them into the object referred to by ...
Definition window.cpp:3624
TWindow * GetFirstChild()
Returns a pointer to the first child window, which is the first window created in the interface objec...
Definition window.h:1770
HWND THandle
TWindow encapsulates an HWND.
Definition window.h:418
HWND GetHandle() const
Returns the handle of the window.
Definition window.h:2020
Definition of class TControlBar.
#define _T(x)
Definition cygwin.h:51
#define WM_OWLWINDOWDOCKED
Notify window it was [un]docked/reparented.
Definition dispatch.h:4116
#define WM_OWLSLIPDBLCLK
Notify parent of user dblclick of edge slip.
Definition dispatch.h:4115
TDockable classes: TDockableGadgetWindow & TDockableControlBar TDockingSlip classes: TFloatingSlip & ...
#define DEFINE_RESPONSE_TABLE1(cls, base)
Macro to define a response table for a class with one base.
Definition eventhan.h:492
#define IDG_FLATHANDLE
The ID for a flat bar handle.
Definition gadget.h:37
TRelPosition
General use 2-D rectangular relative position enum.
Definition docking.h:43
TGridType
Definition docking.h:227
@ rpNone
No location specified.
Definition docking.h:44
@ rpAbove
Refers to top edge of frame.
Definition docking.h:45
@ rpBelow
Refers to bottom edge of frame.
Definition docking.h:46
@ rpRightOf
Refers to left edge of frame.
Definition docking.h:47
@ rpLeftOf
Refers to right edge of frame.
Definition docking.h:48
@ XCoord
Left & right edge have X coords parallel vertically.
Definition docking.h:229
@ YCoord
Grid type corresponds with Location:
Definition docking.h:228
TAbsLocation
General use absolute 2-D rectangular location enum.
Definition geometry.h:62
@ alTop
Refers to top edge of frame.
Definition geometry.h:64
@ alRight
Refers to right edge of frame.
Definition geometry.h:67
@ alBottom
Refers to bottom edge of frame.
Definition geometry.h:65
@ alLeft
Refers to left edge of frame.
Definition geometry.h:66
@ alNone
No location specified.
Definition geometry.h:63
@ wfShrinkToClient
Shrink a frame window to its client's size.
Definition window.h:62
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
EV_WM_NCCALCSIZE
Definition docking.cpp:963
EV_WM_OWLWINDOWDOCKED
Definition docking.cpp:98
EV_WM_LBUTTONUP
Definition docking.cpp:2056
EV_WM_SETCURSOR
Definition docking.cpp:99
UINT TMsgId
Message ID type.
Definition dispatch.h:53
EV_WM_GETMINMAXINFO
Definition docking.cpp:548
EV_WM_SETTINGCHANGE
Definition docking.cpp:547
EV_WM_LBUTTONDBLCLK
Definition docking.cpp:962
EV_WM_MOUSEMOVE
Definition docking.cpp:2054
uint32 MkUint32(uint16 lo, uint16 hi)
Definition defs.h:261
unsigned long uint32
Definition number.h:34
LPARAM TParam2
Second parameter type.
Definition dispatch.h:55
signed short int16
Definition number.h:29
WPARAM TParam1
First parameter type.
Definition dispatch.h:54
TDispatch< WM_PARENTNOTIFY >::TArgs TParentNotify
Alias for convenience.
Definition dispatch.h:2894
TParam2 MkParam2(const T1 &lo, const T2 &hi)
Definition dispatch.h:65
OWL_DIAGINFO
Definition animctrl.cpp:14
EV_WM_PARENTNOTIFY
Definition docking.cpp:966
EV_WM_NCPAINT
Definition docking.cpp:964
EV_WM_WINDOWPOSCHANGING
Definition docking.cpp:545
END_RESPONSE_TABLE
Definition button.cpp:26
EV_WM_NCLBUTTONDOWN
Definition docking.cpp:541
LRESULT TResult
Result type.
Definition dispatch.h:52
EV_WM_WINDOWPOSCHANGED
Definition docking.cpp:546
unsigned int uint
Definition number.h:25
EV_WM_LBUTTONDOWN
Definition checklst.cpp:195
EV_WM_SIZING
Definition docking.cpp:544
EV_WM_ERASEBKGND
Definition docking.cpp:965
EV_WM_CLOSE
Definition commdial.cpp:23
#define OWL_INI
Definition defs.h:170
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
Definition of TProfile class.
TUnits Units
Definition gadget.h:57
Definition of container classes used and made available by OWL.
Definition of the TTooltip class and helper objects.
Definition of the UI Helper Classes: TUIHandle, TUIBorder, TUIFace, TUIPart.
Definition of TUIMetric, a UI metrics provider class.
#define WS_EX_TOOLWINDOW
Definition wsysinc.h:27
#define WS_EX_WINDOWEDGE
Definition wsysinc.h:30