OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
panespli.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of Pane Splitter classes
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9
10#include <owl/contain.h>
11#include <owl/layoutwi.h>
12#include <owl/panespli.h>
13#include <owl/uihelper.h>
14#include <owl/dc.h>
15#include <owl/uimetric.h>
16#include <owl/template.h>
17
18#include <math.h>
19
20namespace owl {
21
23
24
25//
26// Defines to make typesafe downcasting simpler.
27//
28#define SPLITTER(x) TYPESAFE_DOWNCAST(x,TSplitter)
29#define LAYOUTWINDOW(x) TYPESAFE_DOWNCAST(x,TLayoutWindow)
30//#define USE_CUSTOM_CURSORS
31
32
33#if !defined(BI_COMP_GNUC)
34# pragma warn -inl
35#endif
44#if !defined(BI_COMP_GNUC)
45# pragma warn .inl
46#endif
47//------------------------------------------------------------------------------
48//------------------------------------------------------------------------------
49// TSplitter class.
50//
51
59
60//
61// Constructor for abstract base class - don't set a border.
62//
64:
66 PercentOf(percent),
67 PaneSplitter(ps)
68{
69 Attr.Style &= ~WS_BORDER;
70 Attr.Style |= WS_CLIPCHILDREN;
71}
72
73//
74// Notify TPaneSplitter object that it should begin the splitter move process.
75//
76void
78{
79 TPoint p = point;
80 MapWindowPoints(nullptr, &p, 1); // map to screen
81 PaneSplitter->StartSplitterMove(this, p);
82// TLayoutWindow::EvLButtonDown(modKeys, point);
83}
84
85//
86// Notify TPaneSplitter object that splitter has moved.
87//
88void
90{
91 TPoint p = point;
92 MapWindowPoints(nullptr, &p, 1); // map to screen
93 PaneSplitter->MouseMoved(p);
94// TLayoutWindow::EvMouseMove(modKeys, point);
95}
96
97//
98// Notify TPaneSplitter object that splitters have finished being moved.
99//
100void
102{
103 TPoint p = point;
104 MapWindowPoints(nullptr, &p, 1); // map to screen
105 PaneSplitter->EndSplitterMove(p);
106//JRSTSplitter::EvLButtonUp(uint /*modKeys*/, TPoint& /*point*/)
107//JRS{
108//JRS PaneSplitter->EndSplitterMove();
109// TLayoutWindow::EvLButtonUp(modKeys, point); // !CQ we may be deleted!
110}
111
112//
113// Notify TPaneSplitter object that it should set the appropriate cursor.
114//
115bool
117{
118 TPoint p;
119 if (hWndCursor == GetHandle() && codeHitTest == HTCLIENT) {
120 GetCursorPos(p);
121 PaneSplitter->SetSplitterMoveCursor(this, p);
122 }
123 else
125 return true;
126}
127
128//
129// Notify TPaneSplitter object that splitter needs to be repainted.
130// This allows the user to draw the splitter.
131//
132void
134{
135 TLayoutWindow::Paint(dc, true, rect);
136 PaneSplitter->DrawSplitter(dc, GetRect());
137}
138
139//
140// Resize the splitter. In certain situations the splitters that are
141// nested in this splitter don't want to resize, in which case their
142// sizes are adjusted (retained).
143//
144void
146{
147 if (sizeType != SIZE_MINIMIZED && PaneSplitter->PaneSplitterResizing)
148 AdjForResize(size);
150}
151
152//
153// Common code for T*Splitter::Setup(). Sets pane's parent to this and
154// sets their layout metrics.
155//
156void
167
168//
169// Remove a pane from this splitter.
170//
173{
174 // 'parentSplitter' represents the splitter 'this' splitter is contained in.
175 // 'retval' indicates weather their is a parent splitter, if not then 'pane'
176 // is only one.
177 // 'otherPane' is other window contained in this splitter.
178 //
181 TWindow* otherPane = Pane1() == pane ? Pane2() : Pane1();
182
185
186 pane->ShowWindow(SW_HIDE);
187 if (parentSplitter) {
188 TWindow* p1 = parentSplitter->Pane1();
189 TWindow* p2 = parentSplitter->Pane2();
190
191 parentSplitter->GetChildLayoutMetrics(*p1, lm1);
192 parentSplitter->GetChildLayoutMetrics(*p2, lm2);
193 pane->SetParent(nullptr); // remove pane.
194 otherPane->SetParent(parentSplitter); // move up one level.
195
196 if (this == p1) { // if top or left pane is being removed.
197 if (lm2.X.RelWin == this) // adjust other panes layout metrics.
198 lm2.X.RelWin = otherPane;
199 else if (lm2.Y.RelWin == this)
200 lm2.Y.RelWin = otherPane;
201 parentSplitter->SetChildLayoutMetrics(*p2, lm2);
202 parentSplitter->SetChildLayoutMetrics(*otherPane, lm1);
203 }
204 else { // other pane's layout is same as one being removed.
205 //
206 parentSplitter->SetChildLayoutMetrics(*otherPane, lm2);
207 }
208 }
209 else { // remove last pane.
212
213 PaneSplitter->GetDefLM(lmOfOtherPane);
214 otherPane->SetParent(retval);
215 pane->SetParent(nullptr);
216 retval->SetChildLayoutMetrics(*otherPane, lmOfOtherPane);
217 }
218 // Destroy pane.
219 //
221 PaneSplitter->DestroyPane(pane, dt);
222 return retval;
223}
224
225//----------------------------------------------------------------------------
226// TVSplitter class.
227//
228
229//
230// Constructor for a vertical splitter
231//
233:
234 TSplitter(parent, ps, percent)
235{
236 SetCaption(_T("VSplitter"));
237}
238
239//
240// Return TRect for the visible area (in client coordinates) of splitter.
241//
242TRect
244{
245 TRect rect;
246 TWindow* p1 = Pane1();
247
248 rect.left = p1->GetWindowAttr().X + p1->GetWindowAttr().W;
249 rect.top = p1->GetWindowAttr().Y;
250 rect.right = rect.left + PaneSplitter->GetSplitterWidth();
251 rect.bottom = p1->GetWindowAttr().Y + p1->GetWindowAttr().H;
252
253 return rect;
254}
255
256//
257// Split given pane into 2 parts: itself and a new pane.
258//
259void
261{
262 // Panes contained in this splitter.
263 //
264 TWindow* p1 = Pane1();
265 TWindow* p2 = Pane2();
267
269
270 // Create new splitter (will be a child of this splitter).
271 //
273 if (sd == psHorizontal)
274 splitter = new THSplitter(this, PaneSplitter, percent);
275 else
276 splitter = new TVSplitter(this, PaneSplitter, percent);
277
278 // Initialize new splitter by putting target and new pane into it.
279 //
280 splitter->Create();
282
283 if (p1 == targetPane) { // target pane == left pane. adjust new splitter's
284 // width and other windows left edge to be
285 // adjacent to new splitter.
286 //
287 lmOfSplitter.Width.Absolute(targetPane->GetWindowAttr().W);
288
289 lm.X.RelWin = splitter;
291 }
292 else { // set new splitter to the right of left pane.
293 //
294 lmOfSplitter.X.RightOf(p1, PaneSplitter->GetSplitterWidth());
295 }
297}
298
299//
300// Setup layout metrics and children for new splitter. Return that
301// layout metrics.
302//
305{
309
310 PaneSplitter->GetDefLM(lmOfSplitter);
312
313 // Target pane's width is 1/2 of what it was. New pane is to the right
314 // of target pane.
315 //
316 lmOfPane1.Width.Absolute(static_cast<int>(targetPane->GetWindowAttr().W * percent));
317 lmOfPane2.X.RightOf(targetPane, PaneSplitter->GetSplitterWidth());
319
320 return lmOfSplitter;
321}
322
323//
324// Create splitter indicator for this splitter.
325//
331
332//
333// Return left pane, or 0 if none exist.
334//
335TWindow*
337{
339 if (p1) {
340 TWindow* p2 = p1->Next();
341
342 return p1->GetWindowAttr().X <= p2->GetWindowAttr().X ? p1 : p2;
343 }
344 return nullptr;
345}
346
347//
348// Return right pane, or 0 if none exist.
349//
350TWindow*
352{
353 if (NumChildren() != 2)
354 return nullptr;
355
357 TWindow* p2 = p1->Next();
358
359 return p1->GetWindowAttr().X > p2->GetWindowAttr().X ? p1 : p2;
360}
361
362//
363// Called as a result of parent being resized. Adjust width of pane 1 to make
364// it appear this splitter didn't move.
365//
366void
368{
370 TWindow* pane = Pane1();
371
372 if (pane) {
374 lm.Width.Absolute(static_cast<int>(GetPercent() * sz.cx)); //JJH added static cast
376 }
377}
378
379//
380// Move splitter given distance. Accomplished by resizing pane 1.
381//
382void
384{
386 TWindow* pane = Pane1();
387
388 if (pane) {
390 lm.Width.Absolute(lm.Width.Value + dist);
392
393 // Calc new percent.
394 //
395 PercentOf = static_cast<float>(lm.Width.Value) / static_cast<float>(Attr.W);
396
397 // Update nested splitters to retain their positions.
398 //
400 if (splitter) {
401 while (1) {
402 if (splitter->SplitDirection() == SplitDirection()) {
404 splitter->GetChildLayoutMetrics(*splitter->Pane1(), lm);
405 lm.Width.Absolute(lm.Width.Value - dist);
406 splitter->SetPercent(static_cast<float>(lm.Width.Value) /
407 static_cast<float>(splitter->GetWindowAttr().W - dist));
408 splitter->SetChildLayoutMetrics(*splitter->Pane1(), lm);
409 }
410 if ((splitter = SPLITTER(splitter->Pane1())) == nullptr)
411 break;
412 }
413 }
414 }
415}
416
417//
418// Change the width of the splitter and then do a Layout() to see changes.
419//
420void
422{
424
426 lm.X.Value += w;
428 Layout();
429}
430
431//----------------------------------------------------------------------------
432// THSplitter class.
433//
434
435//
436// Constructor for a horizontal splitter
437//
439:
440 TSplitter(parent, ps, percent)
441{
442 SetCaption(_T("HSplitter"));
443}
444
445//
446// Return TRect for the visible area (in client coordinates) of splitter.
447//
448TRect
450{
451 TRect rect;
452 TWindow* p1 = Pane1();
453
454 rect.left = p1->GetWindowAttr().X;
455 rect.top = p1->GetWindowAttr().Y + p1->GetWindowAttr().H;
456 rect.right = p1->GetWindowAttr().X + p1->GetWindowAttr().W;
457 rect.bottom = rect.top + PaneSplitter->GetSplitterWidth();
458
459 return rect;
460}
461
462//
463// Split given pane into 2 parts: itself and a new pane.
464//
465void
467{
468 // Panes contained in this splitter.
469 //
470 TWindow* p1 = Pane1();
471 TWindow* p2 = Pane2();
473
475
476 // Create new splitter (will be a child of this splitter).
477 //
479 if (sd == psHorizontal)
480 splitter = new THSplitter(this, PaneSplitter, percent);
481 else
482 splitter = new TVSplitter(this, PaneSplitter, percent);
483
484 // Initialize new splitter by putting target and new pane into it.
485 //
486 splitter->Create();
488
489 if (p1 == targetPane) { // target pane == top pane. adjust new splitter's
490 // height and other windows top edge to be
491 // adjacent to new splitter.
492 //
493 lmOfSplitter.Height.Absolute(targetPane->GetWindowAttr().H);
494
495 lm.Y.RelWin = splitter;
497 }
498 else { // set new splitter to below top pane.
499 //
500 lmOfSplitter.Y.Below(p1, PaneSplitter->GetSplitterWidth());
501 }
503}
504
505//
506// Setup layout metrics and children for new splitter. Return that
507// layout metrics.
508//
511{
515
516 PaneSplitter->GetDefLM(lmOfSplitter);
518
519 // Target pane's height is 1/2 of what it was. New pane is below
520 // target pane.
521 //
522 lmOfPane1.Height.Absolute(static_cast<int>(targetPane->GetWindowAttr().H * percent)); //JJH added static cast
523 lmOfPane2.Y.Below(targetPane, PaneSplitter->GetSplitterWidth());
525
526 return lmOfSplitter;
527}
528
529//
530// Create splitter indicator for this splitter.
531//
537
538//
539// Return top pane, or 0 if none exist.
540//
541TWindow*
543{
545
546 if (p1) {
547 TWindow* p2 = p1->Next();
548
549 return p1->GetWindowAttr().Y <= p2->GetWindowAttr().Y ? p1 : p2;
550 }
551 return nullptr;
552}
553
554//
555// Return bottom pane, or 0 if none exist.
556//
557TWindow*
559{
560 if (NumChildren() != 2)
561 return nullptr;
562
564 TWindow* p2 = p1->Next();
565
566 return p1->GetWindowAttr().Y > p2->GetWindowAttr().Y ? p1 : p2;
567}
568
569//
570// Called as a result of parent being resized. Adjust height of pane 1 to make
571// it appear this splitter didn't move.
572//
573void
575{
577 TWindow* pane = Pane1();
578
579 if (pane) {
581 lm.Height.Absolute(static_cast<int>(GetPercent() * sz.cy)); //JJH added static cast
583 }
584}
585
586//
587// Move splitter given distance. Accomplished by resizing pane 1.
588//
589void
591{
593 TWindow* pane = Pane1();
594
595 if (pane) {
597 lm.Height.Absolute(lm.Height.Value + dist);
599
600 // Calc new percent.
601 //
602 PercentOf = (float)lm.Height.Value / (float)Attr.H;
603
604 // Update nested splitters to retain there relative positions.
605 //
607 if (splitter) {
608 while (1) {
609 if (splitter->SplitDirection() == SplitDirection()) {
611 splitter->GetChildLayoutMetrics(*splitter->Pane1(), lm);
612 lm.Height.Absolute(lm.Height.Value - dist);
613 splitter->SetPercent((float)lm.Height.Value /
614 (float)(splitter->GetWindowAttr().H - dist));
615 splitter->SetChildLayoutMetrics(*splitter->Pane1(), lm);
616 }
617 if ((splitter = SPLITTER(splitter->Pane1())) == nullptr)
618 break;
619 }
620 }
621 }
622}
623
624//
625// Change the width of the splitter and then do a Layout() to see changes.
626//
627void
629{
631
633 lm.Y.Value += w;
635 Layout();
636}
637
638//----------------------------------------------------------------------------
639// TSplitterIndicator class (Base class).
640//
641
642//
643// Draw splitter indicator. Use InvertRect() to create the effect.
644//
645void
647{
648 if (!Showing) {
649 Showing = true;
650 auto dc = TWindowDC{Splitter->GetHandle()};
651 const auto r = Splitter->MapScreenToClient(*this);
652 dc.InvertRect(r);
653 }
654}
655
656//----------------------------------------------------------------------------
657// TVSplitterIndicator class.
658//
659
660//
661// Connect either top or bottom side of indicator to either top or bottom side
662// of given TRect. If top of given TRect is below indicator then connect to
663// TRect's top, else if TRect is above indicator then connect to TRect's bottom.
664// Assumes that given TRect represents a horizontal indicator.
665//
666void
668{
669 if (rect.top > bottom)
670 bottom = rect.top;
671 else if (rect.top < top)
672 top = rect.bottom;
673}
674
675//
676// Move splitter indicator (do not draw it though) given dist, which
677// could be + (move right) or - (move left). If the move would put the
678// indicator out of the move area then move to edge of move area.
679//
680void
682{
685 int splitterWidth = right - left;
686
687 left = orig.left + dist;
688 right = left + splitterWidth;
689 top = orig.top;
690 bottom = orig.bottom;
691
692 //
693 // Don't allow the indicator to get closer to the edge of the moveArea
694 // than the cushion.
695 //
696 if( moveArea.Width() > static_cast<int>(Cushion) ) {
697 moveArea.left += Cushion;
698 moveArea.right -= Cushion;
699 }
700 else {
701 DistMoved = 0;
702 return;
703 }
704
705
706 if (!moveArea.Contains(*this)) {
707 // Indicator out of move area to put it adjacent to either top or bottom
708 // of move area.
709 //
710 if (left < moveArea.left) {
711 left = moveArea.left;
712 right = left + splitterWidth;
713 }
714 else {
715 right = moveArea.right;
716 left = right - splitterWidth;
717 }
718 }
719 else
720 DistMoved = dist;
721}
722
723//
724// Return distance moved (left or right) given starting and current point.
725//
726int
728{
729 return cur.x - start.x;
730}
731
732//
733// A check to see if given point could be in indicator if indicator were
734// streched. This function is used when determining if multiple splitters
735// intersect at a point (for dragging).
736//
737bool
739{
740 TRect r = *this;
741 int splitterWidth = right - left;
742
743 r.top -= splitterWidth;
744 r.bottom += splitterWidth;
745 return r.Contains(point);
746}
747
748//
749// Calculate the area in which the indicator moved. Use original splitter
750// position and current indicator position to calculate area. Used to
751// determine which panes need to be removed.
752//
753TRect
755{
756 TRect r1 = *this;
758 TRect area = r2;
759
760 if (r1.left < r2.left) {
761 area.left = r1.left;
762 area.right = r2.right;
763 }
764 else {
765 area.left = r2.left;
766 area.right = r1.right;
767 }
768 return area;
769}
770
771//----------------------------------------------------------------------------
772// THSplitterIndicator class.
773//
774
775//
776// Connect either left or right side of indicator to either left or right side
777// of given TRect. If left side of given TRect is to the right of indicator
778// then connect to TRect's left side, else if TRect is to the left of indicator
779// then connect to TRect's right side. Assumes that given TRect represents a
780// vertical indicator.
781//
782void
784{
785 if (rect.left > right)
786 right = rect.left;
787 else if (rect.left < left)
788 left = rect.right;
789}
790
791//
792// Move splitter indicator (do not draw it though) given dist, which
793// could be + (move down) or - (move up). If the move would put the
794// indicator out of the move area then move to edge of move area.
795//
796void
798{
801 int splitterWidth = bottom - top;
802
803 top = orig.top + dist;
804 bottom = top + splitterWidth;
805 left = orig.left;
806 right = orig.right;
807
808 //
809 // Don't allow the indicator to get closer to the edge of the moveArea
810 // than the cushion.
811 //
812 if( moveArea.Height() > static_cast<int>(Cushion) ) {
813 moveArea.top += Cushion;
814 moveArea.bottom -= Cushion;
815 }
816 else {
817 DistMoved = 0;
818 return;
819 }
820
821 if (!moveArea.Contains(*this)) {
822 // Indicator out of move area to put it adjacent to either top or bottom
823 // of move area.
824 //
825 if (top < moveArea.top) {
826 top = moveArea.top;
827 bottom = top + splitterWidth;
828 }
829 else {
830 bottom = moveArea.bottom;
831 top = bottom - splitterWidth;
832 }
833 }
834 else
835 DistMoved = dist;
836}
837
838//
839// Return distance moved (up or down) given starting and current point.
840//
841int
843{
844 return cur.y - start.y;
845}
846
847//
848// A check to see if given point could be in indicator if indicator were
849// streched. This function is used when determining if multiple splitters
850// intersect at a point (for dragging).
851//
852bool
854{
855 TRect r = *this;
856 int splitterWidth = bottom - top;
857
858 r.left -= splitterWidth;
859 r.right += splitterWidth;
860
861 return r.Contains(point);
862}
863
864//
865// Calculate the area in which the indicator moved. Use original splitter
866// position and current indicator position to calculate area. Used to
867// determine which panes need to be removed.
868//
869TRect
871{
872 TRect r1 = *this;
874 TRect area = r2;
875
876 if (r1.top < r2.top) {
877 area.top = r1.top;
878 area.bottom = r2.bottom;
879 }
880 else {
881 area.top = r2.top;
882 area.bottom = r1.bottom;
883 }
884 return area;
885}
886
887//----------------------------------------------------------------------------
888// TSplitterIndicatorList class.
889
890//
891// Search for indicator that was created from given splitter.
892//
895{
898 if (i->GetSplitter() == splitter)
899 return i;
900 }
901 return nullptr;
902}
903
904//----------------------------------------------------------------------------
905// TSplitterIndicatorMgr class.
906//
907
908//
909// Save indicator list for later manipulation. Record starting drag point.
910// Draw splitter indicators.
911//
912void
914 const TPoint& point)
915{
916 SplitterIndicatorList = &sil;
917 StartDragPoint = point;
918 DrawIndicators();
919}
920
921//
922// Clear indicators from screen.
923//
924void
926{
927 ClearIndicators();
928}
929
930//
931// Move all indicators. Distance moved is based on starting drag point and
932// given point.
933//
934void
936{
937 ClearIndicators();
938
939 TSplitterIndicatorListIterator iter(*SplitterIndicatorList);
940
941 if (iter){
943 while(iter) {
945 int dist = si->CalcDistMoved(StartDragPoint, point);
946 si->Move(dist);
947 if (si != main)
948 si->ConnectToRect(*main);
949 iter++;
950 }
951 }
952 DrawIndicators();
953}
954
955//
956// Draw indicators on screen.
957//
958void
959TSplitterIndicatorMgr::DrawIndicators()
960{
961 if( !SplitterIndicatorList )
962 return;
963 for(TSplitterIndicatorListIterator iter(*SplitterIndicatorList);iter;iter++)
964 ((TSplitterIndicator*)*iter)->Draw();
965}
966
967//
968// Clear all indicators from screen.
969//
970void
971TSplitterIndicatorMgr::ClearIndicators()
972{
973 if( !SplitterIndicatorList )
974 return;
975 for(TSplitterIndicatorListIterator iter(*SplitterIndicatorList);iter;iter++)
976 ((TSplitterIndicator*)*iter)->Clear();
977}
978
979//----------------------------------------------------------------------------
980// TPaneSplitter class
981//
982
983DEFINE_RESPONSE_TABLE1(TPaneSplitter, TLayoutWindow)
986
987
988//
989/// Initializes data members.
990//
993 int splitterWidth,
994 TModule* module)
995:
996 TLayoutWindow(parent, title, module),
997 Dragging(false),
998 SplitterWidth(splitterWidth),
999 SplitterCushion(0),
1000 PaneSplitterResizing(false),
1001 ShouldDelete(TShouldDelete::NoDelete)
1002{
1003 Attr.Style |= WS_CLIPCHILDREN;
1004 if (!SplitterWidth)
1005 SplitterWidth = TUIMetric::CxFixedFrame;
1006 SetCaption(_T("PaneSplitter"));
1008
1009}
1010
1011//
1012/// String-aware overload
1013//
1015 TWindow* parent,
1016 const tstring& title,
1017 int splitterWidth,
1018 TModule* module
1019 )
1020 : TLayoutWindow(parent, title, module),
1021 Dragging(false),
1022 SplitterWidth(splitterWidth),
1023 SplitterCushion(0),
1024 PaneSplitterResizing(false),
1025 ShouldDelete(TShouldDelete::NoDelete)
1026{
1027 Attr.Style |= WS_CLIPCHILDREN;
1028 if (!SplitterWidth)
1029 SplitterWidth = TUIMetric::CxFixedFrame;
1030 SetCaption(_T("PaneSplitter"));
1032}
1033
1034//
1035// Empty destructor
1036//
1042
1043//
1044/// Loads cursors and sets TSplitter's pane splitter object.
1045//
1046void
1048{
1050
1051 // Load cursors.
1052 //
1053#if defined(USE_CUSTOM_CURSORS)
1054 ResizeCursorH = LoadCursor(IDC_RESIZE_H);
1055 ResizeCursorV = LoadCursor(IDC_RESIZE_V);
1056 ResizeCursorHV = LoadCursor(IDC_RESIZE_HV);
1057#else
1058 ResizeCursorH = ::LoadCursor(nullptr, IDC_SIZENS);
1059 ResizeCursorV = ::LoadCursor(nullptr, IDC_SIZEWE);
1060 ResizeCursorHV = ::LoadCursor(nullptr, IDC_SIZEALL);
1061#endif
1062}
1063
1064//
1065/// Removes all panes (and related splitters). Destroys cursors.
1066//
1067void
1069{
1071
1072#if defined(USE_CUSTOM_CURSORS)
1073 ::DestroyCursor(ResizeCursorH);
1074 ::DestroyCursor(ResizeCursorV);
1075 ::DestroyCursor(ResizeCursorHV);
1076#endif
1077
1079}
1080
1081//
1082/// Sets data member 'PaneSplitterResizing' to indicate that contained splitters
1083/// should adjust themselves according to their percentage.
1084//
1085void
1087{
1088 PaneSplitterResizing = true;
1090 PaneSplitterResizing = false;
1091}
1092
1093//
1094/// Called by TSplitter when it needs to draw itself. The default behavior provided
1095/// in this base class is to draw a 3dface splitter.
1096//
1097void
1102
1103//
1104/// Splits given pane, 'target', with 'newPane', in either the vertical or
1105/// horizontal direction. Creates a new splitter.
1106//
1107bool
1110{
1113
1114 if (GetFirstChild() == nullptr) { // if no panes.
1116
1118 target->SetParent(this);
1119 target->Create();
1121 Layout();
1122 }
1123
1124 if (newPane) {
1125 if (!HasPane(target))
1126 return false;
1127
1130
1131 if (parentSplitter == this) { // if first split.
1132 if (splitDir == psHorizontal)
1133 splitter = new THSplitter(target->GetParentO(), this, percent);
1134 else
1135 splitter = new TVSplitter(target->GetParentO(), this, percent);
1136 splitter->Create();
1137 splitter->SetPercent(percent);
1138
1140 parentSplitter->SetChildLayoutMetrics(*splitter, lm);
1141 }
1142 else {
1143 // Ask splitter to split itself.
1144 //
1146 }
1147 parentSplitter->Layout();
1148 }
1149 return true;
1150}
1151
1152//
1153/// Removes given pane from TPaneSplitter, deleting it if requested.
1154/// This operation has the side effect of removing the splitter it was
1155/// contained in.
1156//
1157bool
1159{
1160 TLayoutWindow* layoutWin = DoRemovePane(pane, dt);
1161 if (layoutWin) {
1162 PaneSplitterResizing = true;
1163 layoutWin->Layout();
1164 PaneSplitterResizing = false;
1165 return true;
1166 }
1167 return false;
1168}
1169
1170//
1171/// Replaces 'target' pane (must exist) with 'newPane' (does not exist). 'target'
1172/// may be deleted; it depends on 'dt'.
1173//
1174bool
1177{
1178 if (!HasPane(target) || HasPane(newPane)) // 'newPane' should not exist.
1179 return false;
1180
1181 if (target->CanClose()) { // 'newPane' takes on target's layout metrics.
1184 TLayoutWindow* splitter = LAYOUTWINDOW(target->GetParentO());
1185 TWindow* pane1 = splitter->GetFirstChild();
1186 TWindow* pane2 = 0;
1187
1188 if (SPLITTER(splitter)) {
1189 pane1 = SPLITTER(splitter)->Pane1();
1190 pane2 = SPLITTER(splitter)->Pane2();
1191 }
1192 splitter->GetChildLayoutMetrics(*target, lmOfTarget);
1193
1194 if (pane1 == target && pane2) {
1195 splitter->GetChildLayoutMetrics(*pane2, lmOfOther);
1196 if (lmOfOther.X.RelWin == target)
1197 lmOfOther.X.RelWin = newPane;
1198 else
1199 lmOfOther.Y.RelWin = newPane;
1200 splitter->SetChildLayoutMetrics(*pane2, lmOfOther);
1201 }
1202 newPane->SetParent(splitter);
1203 newPane->Create();
1204 splitter->SetChildLayoutMetrics(*newPane, lmOfTarget);
1205 splitter->RemoveChildLayoutMetrics(*target);
1206 DestroyPane(target, dt);
1207 splitter->Layout();
1208 return true;
1209 }
1210 return false;
1211}
1212
1213//
1214/// Swaps given panes (must exist). Panes take on each others' layout metrics.
1215//
1216bool
1218{
1219 if (!HasPane(pane1) || !HasPane(pane2))
1220 return false;
1221
1222 TSplitter* splitter1 = SPLITTER(pane1->GetParentO());
1223 TSplitter* splitter2 = SPLITTER(pane2->GetParentO());
1224
1225 if (splitter1 != splitter2) {
1229 TWindow* paneA = splitter1->Pane1();
1230 TWindow* paneB = splitter1->Pane2();
1231
1232 splitter1->GetChildLayoutMetrics(*pane1, lmOfPane1);
1233 splitter2->GetChildLayoutMetrics(*pane2, lmOfPane2);
1234
1235 if (paneA == pane1) { // if top or left pane.
1236 splitter1->GetChildLayoutMetrics(*paneB, lmOfOther);
1237 pane1->SetParent(nullptr);
1238 if (lmOfOther.X.RelWin == pane1)
1239 lmOfOther.X.RelWin = pane2;
1240 else
1241 lmOfOther.Y.RelWin = pane2;
1242 splitter1->SetChildLayoutMetrics(*paneB, lmOfOther);
1243 }
1244
1245 paneA = splitter2->Pane1();
1246 paneB = splitter2->Pane2();
1247 if (paneA == pane2) { // if top or left pane.
1248 splitter2->GetChildLayoutMetrics(*paneB, lmOfOther);
1249 pane2->SetParent(0);
1250 if (lmOfOther.X.RelWin == pane2)
1251 lmOfOther.X.RelWin = pane1;
1252 else
1253 lmOfOther.Y.RelWin = pane1;
1254 splitter2->SetChildLayoutMetrics(*paneB, lmOfOther);
1255 }
1256 pane1->SetParent(splitter2);
1257 pane2->SetParent(splitter1);
1258 splitter1->SetChildLayoutMetrics(*pane2, lmOfPane1);
1259 splitter2->SetChildLayoutMetrics(*pane1, lmOfPane2);
1260 splitter1->Layout();
1261 splitter2->Layout();
1262 }
1263 else {
1264 TLayoutWindow* lw = LAYOUTWINDOW(pane1->GetParentO());
1267
1268 lw->GetChildLayoutMetrics(*pane1, lmOfPane1);
1269 lw->GetChildLayoutMetrics(*pane2, lmOfPane2);
1270
1271 if (lmOfPane1.X.RelWin == pane2)
1272 lmOfPane1.X.RelWin = pane1;
1273 else if (lmOfPane2.X.RelWin == pane1)
1274 lmOfPane2.X.RelWin = pane2;
1275 else if (lmOfPane1.Y.RelWin == pane2)
1276 lmOfPane1.Y.RelWin = pane1;
1277 else
1278 lmOfPane2.Y.RelWin = pane2;
1279
1280 lw->SetChildLayoutMetrics(*pane1, lmOfPane2);
1281 lw->SetChildLayoutMetrics(*pane2, lmOfPane1);
1282 lw->Layout();
1283 }
1284 return true;
1285}
1286
1287//
1288/// Iterates over each pane. If 'callback' returns 0, then iteration stops.
1289//
1290void
1292 void* p)
1293{
1294 ForEachObject(GetFirstChild(), &TPaneSplitter::DoForEachPane,
1295 (void*)callback, p); // !CQ hack cast
1296}
1297
1298//
1299/// Returns the number of panes in TPaneSplitter.
1300//
1301int
1303{
1304 int nPanes = 0;
1305
1306 ForEachObject(GetFirstChild(), &TPaneSplitter::DoPaneCount, &nPanes, nullptr);
1307 return nPanes;
1308}
1309
1310//
1311/// Removes all the panes (and their splitters). If any pane can't close, the
1312/// operation is aborted.
1313//
1314void
1316{
1318
1319 // Remove and delete (depending on 'dt') all panes.
1320 //
1321 ForEachObject(GetFirstChild(), &TPaneSplitter::GetPanes, &wList, nullptr);
1323
1324 // check to see if a pane can't close, if so abort operation.
1325 //
1326 while(wListIter){
1327 if (!(*wListIter)->CanClose())
1328 return;
1329 wListIter++;
1330 }
1331 wListIter.Restart();
1332 while (wListIter){ // remove all the panes.
1334 wListIter++;
1335 }
1336}
1337
1338//
1339/// Sets the splitter width and adjusts all splitters. Takes effect immediately.
1340//
1341int
1343{
1344 int oldWidth = SplitterWidth;
1345 int widthDiff = newWidth - SplitterWidth;
1346
1347 SplitterWidth = newWidth;
1348 ForEachObject(GetFirstChild(), &TPaneSplitter::AdjSplitterWidth, &widthDiff,
1349 nullptr);
1350 return oldWidth;
1351}
1352
1353//
1354/// Moves 'pane' a given distance. If 'pane' does not exist, or there are no
1355/// splitters, or removal of a pane has failed, then false is returned. Otherwise,
1356/// true is returned.
1357//
1358bool
1360{
1361 if (!HasPane(pane) || pane->GetParentO() == this )
1362 return false;
1363
1364 TSplitter* splitter = SPLITTER(pane->GetParentO());
1365 TSplitterIndicator* si = splitter->CreateSplitterIndicator();
1366 si->SetCushion( SplitterCushion );
1367
1370 si->Move(dist);
1371 if (RemovePanes() == 0) {
1372 MoveSplitters();
1374 return true;
1375 }
1376 return false;
1377}
1378
1379//
1380// Private Member Functions...
1381//
1382
1383//
1384// Notify indicator mgr to move the indicators.
1385//
1386void
1387TPaneSplitter::MouseMoved(const TPoint& point)
1388{
1389 if (Dragging)
1391}
1392
1393//
1394// Set capture (for mouse dragging) and notify indicator mgr that
1395// we are starting to move the indicators.
1396//
1397void
1404
1405//
1406// Release the capture and notify indicator mgr that we have stopped moving
1407// the indicators. Remove any panes that were 'covered' by the move.
1408// Finally, move the splitters.
1409//
1410void
1411TPaneSplitter::EndSplitterMove(const TPoint& /*point*/)
1412{
1413 if( !Dragging )
1414 return;
1415 Dragging = false;
1418 if (RemovePanes() == 0) {
1419 MoveSplitters();
1421 }
1422}
1423
1424//
1425// Set the appropriate cursor depending on the number of splitters
1426// that will be moved.
1427//
1428void
1429TPaneSplitter::SetSplitterMoveCursor(TSplitter* splitter, const TPoint& point)
1430{
1431 if (!Dragging)
1432 FindIntersectingSplitters(point);
1433
1435 ::SetCursor(ResizeCursorHV);
1436 else if (splitter->SplitDirection() == psHorizontal)
1437 ::SetCursor(ResizeCursorH);
1438 else
1439 ::SetCursor(ResizeCursorV);
1440}
1441
1442//
1443// Private structure for splitter and pane traversal.
1444//
1445struct TTraversalRec {
1446 TTraversalRec() : Cnt(0), Object(nullptr) {}
1447 TTraversalRec(TWindow* o) : Cnt(0), Object(o) {}
1448 TTraversalRec(const TTraversalRec& r) : Cnt(r.Cnt), Object(r.Object) {}
1449
1450 int operator == (const TTraversalRec& r) const { return Object == r.Object; }
1451 int operator < (const TTraversalRec& r) const { return Object < r.Object; }
1452 TTraversalRec& operator = (const TTraversalRec& r);
1453
1454 char Cnt;
1455 TWindow* Object;
1456};
1457
1458TTraversalRec&
1459TTraversalRec::operator = (const TTraversalRec& r)
1460{
1461 Cnt = r.Cnt; Object = r.Object;
1462 return *this;
1463}
1464
1465//
1466// Iterate over the splitters and panes, calling 'callback' on each.
1467// allows for 2 parameters to be passed. Traverses the objects in
1468// one of three order: InOrder, PreOrder and PostOrder.
1469//
1470void
1471TPaneSplitter::ForEachObject(TWindow* o, TForEachObjectCallback callback,
1472 void* p1, void* p2, TTraversalOrder order)
1473{
1474 if (!o)
1475 return;
1476
1478
1479 TTraversalRec trec;
1480 bool done = false;
1481
1482 tStack.Push(TTraversalRec(o));
1483 while (!done) {
1484 trec = tStack.Pop();
1485 //trec = tStack.Top();
1486 //delete tStack.Pop();
1487 trec.Cnt++;
1488 if ((order == psPreOrder && trec.Cnt == 1) ||
1489 (order == psInOrder && trec.Cnt == 2) ||
1490 (order == psPostOrder && trec.Cnt == 3))
1491 done = !(this->*callback)(trec.Object, p1, p2);
1492
1493 if (!done) {
1494 if (trec.Cnt != 3) {
1495 tStack.Push(TTraversalRec(trec));
1496 if (trec.Cnt == 1 && SPLITTER(trec.Object))
1497 tStack.Push(TTraversalRec(SPLITTER(trec.Object)->Pane1()));
1498 else if (trec.Cnt == 2 && SPLITTER(trec.Object) &&
1499 SPLITTER(trec.Object)->Pane2())
1500 tStack.Push(TTraversalRec(SPLITTER(trec.Object)->Pane2()));
1501 }
1502 done = tStack.Empty();
1503 }
1504 }
1505}
1506
1507//
1508// Set default TLayoutMetrics. Everything relative to parent.
1509//
1510void
1512{
1513 lm.SetMeasurementUnits(lmPixels);
1514 lm.X.SameAs(lmParent, lmLeft);
1515 lm.Y.SameAs(lmParent, lmTop);
1516 lm.Width.Set(lmRight, lmSameAs, lmParent, lmRight);
1517 lm.Height.Set(lmBottom, lmSameAs, lmParent, lmBottom);
1518}
1519
1520//
1521// Return true if this TPaneSplitter contains 'p' (pane or splitter).
1522//
1523bool
1525{
1526 TWindow* parent = p->GetParentO();
1527 while (parent) {
1528 if (parent == this)
1529 return true;
1530 parent = parent->GetParentO();
1531 }
1532 return false;
1533}
1534
1535//
1536// Do the work of removing given pane.
1537//
1539TPaneSplitter::DoRemovePane(TWindow* pane, TPaneSplitter::TDelete dt)
1540{
1541 if (!HasPane(pane) || !pane->CanClose())
1542 return nullptr;
1543
1544 TSplitter* splitter = SPLITTER(pane->GetParentO());
1545 TLayoutWindow* retval = this;
1546
1547 if (splitter) {
1548 retval = splitter->RemovePane(pane, dt);
1549 splitter->Destroy();
1550 delete splitter;
1551 }
1552 else {
1554 DestroyPane(pane, dt);
1555 }
1556 return retval;
1557}
1558
1559//
1560// Find intersecting splitters. Called when splitters will be moved.
1561//
1562void
1563TPaneSplitter::FindIntersectingSplitters(const TPoint& point)
1564{
1565 TPoint p = point;
1566
1568 ForEachObject(GetFirstChild(), &TPaneSplitter::DoFindIntersectingSplitters,
1570}
1571
1572//
1573// Remove any panes 'covered' as a result of a splitter move.
1574//
1575int
1577{
1578 TSplitterIndicatorList tempList; // don't process indicators.
1581 int nPanesNotRemoved = 0;
1582
1583 while(iter){
1584 si = iter++;
1585
1586 if(!tempList.Find(si)){ // if indicator not in list then process it.
1587 TRect area = si->CalcAreaOfSplitterMove();
1588 TBaseList<TWindow*> wList; // list of panes to remove.
1589 ForEachObject(GetFirstChild(), &TPaneSplitter::GetListOfPanesToRemove,
1590 &wList, &area);
1592 while(listIter){
1593 TWindow* pane = listIter++;
1596 SPLITTER(pane->GetParentO()))) != nullptr)
1597 tempList.PushBack(i);
1598 if (!RemovePane(pane)) {
1599 tempList.PushBack(i);
1601 break;
1602 }
1603 }
1604 }
1605 }
1606 // remove panes not to be moved from list.
1608 delete *iter1;
1610 }
1611
1612 return nPanesNotRemoved;
1613}
1614
1615//
1616// Move all splitters.
1617//
1618void
1620{
1622 TSplitterIndicator* si = iter.Current();
1623 si->GetSplitter()->Move(si->GetDistMoved());
1624 si->GetSplitter()->Layout();
1625 }
1626}
1627
1628//
1629// Destroy a pane, deleting the OWL object if requested
1630//
1631void
1632TPaneSplitter::DestroyPane(TWindow* pane, TDelete dt)
1633{
1634 pane->ShowWindow(SW_HIDE); // so user can't see.
1635 pane->SetParent(nullptr);
1636 pane->Destroy();
1637 if (DelObj(dt))
1638 delete pane;
1639}
1640
1641//
1642// ForEachObject callbacks...
1643//
1644
1645//
1646// Iterate over all panes.
1647//
1648int
1649TPaneSplitter::DoForEachPane(TWindow* o, void *p1, void*p2)
1650{
1651 if (!SPLITTER(o))
1652 return ((TForEachPaneCallback)p1)(*o, p2);
1653 return 1;
1654}
1655
1656//
1657// Find intersecting splitters. Determine which splitters to move.
1658//
1659int
1660TPaneSplitter::DoFindIntersectingSplitters(TWindow* o, void *p1, void*p2)
1661{
1663 if (splitter) {
1664 TSplitterIndicator* i = splitter->CreateSplitterIndicator();
1665 i->SetCushion( SplitterCushion );
1666 if (i->CouldContain(*(TPoint*)p2))
1667 ((TSplitterIndicatorList*)p1)->PushBack(i);
1668 else
1669 delete i;
1670 }
1671 return 1;
1672}
1673
1674//
1675// Get a list of panes that will be removed as a result of a splitter move.
1676//
1677int
1678TPaneSplitter::GetListOfPanesToRemove(TWindow* o, void *p1, void*p2)
1679{
1680 if (!SPLITTER(o)) {
1681 TRect r = o->GetWindowRect();
1682 if ((*(TRect*)p2).Contains(r))
1683 ((TBaseList<TWindow*>*)p1)->PushBack(o);
1684 }
1685 return 1;
1686}
1687
1688//
1689// Change the width of every splitter.
1690//
1691int
1692TPaneSplitter::AdjSplitterWidth(TWindow* o, void *p1, void*)
1693{
1695
1696 if (splitter)
1697 splitter->AdjSplitterWidth(*(int *)p1);
1698 return 1;
1699}
1700
1701//
1702// Calculate number of panes.
1703//
1704int
1705TPaneSplitter::DoPaneCount(TWindow* o, void *p1, void*)
1706{
1707 if (!SPLITTER(o))
1708 (*(int*)p1)++;
1709 return 1;
1710}
1711
1712//
1713// Get a list of all the panes.
1714//
1715int
1716TPaneSplitter::GetPanes(TWindow* o, void *p1, void*)
1717{
1718 if (!SPLITTER(o))
1719 ((TBaseList<TWindow*>*)p1)->PushBack(o);
1720 return 1;
1721}
1722
1723//
1724// Get a list of all splitters.
1725//
1726int
1727TPaneSplitter::GetSplitters(TWindow* o, void* p1, void*)
1728{
1729 if (SPLITTER(o))
1730 ((TBaseList<TWindow*>*)p1)->PushBack(o);
1731 return 1;
1732}
1733
1734} // OWL namespace
1735/* ========================================================================== */
1736
#define PRECONDITION(condition)
Definition checks.h:227
bool DetachItem(const T &t)
DetachItem( detach item and delete it.
Definition template.h:1989
void PushBack(const T &data)
add new item at end of list
Definition template.h:1945
static const TColor Sys3dFace
The symbolic system color value for the face color of 3-dimensional display elements.
Definition color.h:339
TDC is the root class for GDI DC wrappers.
Definition dc.h:64
bool TextRect(int x1, int y1, int x2, int y2)
Fills the given rectangle, clipping any text to the rectangle.
Definition dc.h:1878
Represents a horizontal splitter.
Definition splitter.h:123
TSplitterIndicator * CreateSplitterIndicator()
Definition panespli.cpp:533
TSplitDirection SplitDirection()
Definition splitter.h:301
TWindow * Pane1()
Definition panespli.cpp:542
TLayoutMetrics Setup(TWindow *targetPane, TWindow *newPane, float percent)
Definition panespli.cpp:510
TWindow * Pane2()
Definition panespli.cpp:558
void AdjSplitterWidth(int w)
Definition panespli.cpp:628
void AdjForResize(const TSize &sz)
Definition panespli.cpp:574
void Split(TWindow *targetPane, TWindow *newPane, TSplitDirection sd, float percent=50.0f)
Definition panespli.cpp:466
void Move(int dist)
Definition panespli.cpp:590
THSplitter(TWindow *parent, TPaneSplitter *ps, float percent=50.0f)
Definition panespli.cpp:438
Horizontal indicator.
Definition splitter.h:201
void ConnectToRect(const TRect &rect)
Definition panespli.cpp:783
bool CouldContain(const TPoint &point)
Definition panespli.cpp:853
int CalcDistMoved(const TPoint &start, const TPoint &cur)
Definition panespli.cpp:842
When specifying the layout metrics for a window, four layout constraints are needed.
Definition layoutwi.h:54
Derived from TWindow, TLayoutWindow provides functionality for defining the layout metrics for a wind...
Definition layoutwi.h:122
void EvSize(uint sizeType, const TSize &size)
Responds to a change in size by calling Layout() to resize the window.
Definition layoutwi.cpp:615
virtual void Layout()
Causes the window to resize and position its children according to the specified metrics.
Definition layoutwi.cpp:351
bool GetChildLayoutMetrics(const TWindow &child, TLayoutMetrics &metrics)
Gets the layout metrics of the child window.
Definition layoutwi.cpp:500
void SetChildLayoutMetrics(TWindow &child, const TLayoutMetrics &metrics)
Sets the metrics for the window and removes any existing ones.
Definition layoutwi.cpp:465
bool RemoveChildLayoutMetrics(const TWindow &child)
Removes child (layout) metrics for a given child (if found) and updates other children as necessary.
Definition layoutwi.cpp:529
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TPaneSplitter is a class that acts as a container for child windows (called panes) and splitters (pan...
Definition panespli.h:52
void CleanupWindow() override
Removes all panes (and related splitters). Destroys cursors.
void EvSize(uint sizeType, const TSize &size)
Sets data member 'PaneSplitterResizing' to indicate that contained splitters should adjust themselves...
bool ReplacePane(TWindow *target, TWindow *newPane, TDelete dt=TShouldDelete::DefDelete)
Replaces 'target' pane (must exist) with 'newPane' (does not exist).
friend class TVSplitter
Definition panespli.h:153
TPaneSplitter(TWindow *parent, LPCTSTR title=0, int splitterWidth=0, TModule *module=0)
Initializes data members.
Definition panespli.cpp:991
int(* TForEachPaneCallback)(TWindow &, void *)
Definition panespli.h:80
TSplitterIndicatorMgr SplitterIndicatorMgr
Definition panespli.h:103
virtual void StartSplitterMove(TSplitter *splitter, const TPoint &point)
void GetDefLM(TLayoutMetrics &lm)
virtual int RemovePanes()
int PaneCount()
Returns the number of panes in TPaneSplitter.
bool HasPane(TWindow *p)
virtual void DrawSplitter(TDC &dc, const TRect &splitter)
Called by TSplitter when it needs to draw itself.
friend class THSplitter
Definition panespli.h:152
bool RemovePane(TWindow *pane, TDelete dt=TShouldDelete::DefDelete)
Removes given pane from TPaneSplitter, deleting it if requested.
friend class TSplitter
Definition panespli.h:151
void ForEachPane(TForEachPaneCallback callback, void *p)
Iterates over each pane. If 'callback' returns 0, then iteration stops.
virtual bool SplitPane(TWindow *target, TWindow *newPane, TSplitDirection splitDir, float percent=0.50f)
Splits given pane, 'target', with 'newPane', in either the vertical or horizontal direction.
int SetSplitterWidth(int newWidth)
Sets the splitter width and adjusts all splitters. Takes effect immediately.
void SetupWindow() override
Loads cursors and sets TSplitter's pane splitter object.
TSplitterIndicatorList * SplitterIndicatorList
Definition panespli.h:101
~TPaneSplitter() override
bool SwapPanes(TWindow *pane1, TWindow *pane2)
Swaps given panes (must exist). Panes take on each others' layout metrics.
void RemoveAllPanes(TDelete dt=TShouldDelete::DefDelete)
Removes all the panes (and their splitters).
bool DelObj(TDelete dt)
Returns true if the object should be deleted.
Definition panespli.h:186
bool MoveSplitter(TWindow *pane, int dist)
Moves 'pane' a given distance.
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
The tagSIZE struct is defined as.
Definition geometry.h:234
Abstract base class for TVSplitter and THSplitter.
Definition splitter.h:44
virtual TRect GetRect()=0
float GetPercent()
Definition splitter.h:263
TRect GetScreenRect()
Similar to above except rect is in screen coordinates.
Definition splitter.h:286
virtual void AdjForResize(const TSize &sz)=0
TRect GetMoveArea()
Return the area the splitter can move in (bounding rectangle).
Definition splitter.h:278
TLayoutWindow * RemovePane(TWindow *pane, TShouldDelete::DeleteType dt=TShouldDelete::DefDelete)
Definition panespli.cpp:172
void EvLButtonUp(uint modKeys, const TPoint &point)
Definition panespli.cpp:101
bool EvSetCursor(HWND hwndCursor, uint codeHitTest, TMsgId mouseMsg)
Definition panespli.cpp:116
virtual TWindow * Pane1()=0
void EvSize(uint sizeType, const TSize &size)
Definition panespli.cpp:145
void EvLButtonDown(uint modKeys, const TPoint &point)
Definition panespli.cpp:77
void SetupEpilog(TSplitter *s, TWindow *targetPane, TWindow *newPane, TLayoutMetrics &lmOfTargetPane, TLayoutMetrics &lmOfNewPane)
Definition panespli.cpp:157
virtual TWindow * Pane2()=0
void Paint(TDC &, bool erase, TRect &) override
Definition panespli.cpp:133
TSplitter(TWindow *parent, TPaneSplitter *ps, float percent)
Definition panespli.cpp:63
void EvMouseMove(uint modKeys, const TPoint &point)
Definition panespli.cpp:89
Indicates to the user where the splitter will be moved to when dragging completes.
Definition splitter.h:149
TSplitterIndicator * FindIndicatorWithSplitter(TSplitter *splitter)
Definition panespli.cpp:894
void StartMove(TSplitterIndicatorList &sil, const TPoint &point)
Definition panespli.cpp:913
void MoveIndicators(const TPoint &point)
Definition panespli.cpp:935
static const TUIMetric CxFixedFrame
Definition uimetric.h:41
Represents a vertical splitter.
Definition splitter.h:99
void Split(TWindow *targetPane, TWindow *newPane, TSplitDirection sd, float percent=50.0f)
Definition panespli.cpp:260
void AdjSplitterWidth(int w)
Definition panespli.cpp:421
TLayoutMetrics Setup(TWindow *targetPane, TWindow *newPane, float percent)
Definition panespli.cpp:304
TSplitDirection SplitDirection()
Definition splitter.h:294
void Move(int dist)
Definition panespli.cpp:383
TSplitterIndicator * CreateSplitterIndicator()
Definition panespli.cpp:327
TVSplitter(TWindow *parent, TPaneSplitter *ps, float percent=50.0f)
Definition panespli.cpp:232
void AdjForResize(const TSize &sz)
Definition panespli.cpp:367
TWindow * Pane2()
Definition panespli.cpp:351
TWindow * Pane1()
Definition panespli.cpp:336
Vertical indicator.
Definition splitter.h:183
void ConnectToRect(const TRect &rect)
Definition panespli.cpp:667
int CalcDistMoved(const TPoint &start, const TPoint &cur)
Definition panespli.cpp:727
bool CouldContain(const TPoint &point)
Definition panespli.cpp:738
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
static TPoint GetCursorPos()
Definition window.h:1212
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
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
void SetCaption(LPCTSTR title)
Copies title to an allocated string pointed to by title.
Definition window.cpp:3410
virtual void CleanupWindow()
Always called immediately before the HWindow becomes invalid, CleanupWindow gives derived classes an ...
Definition window.cpp:2640
TPoint MapScreenToClient(const TPoint &p) const
Functional-style version of ScreenToClient.
Definition window.h:870
HCURSOR LoadCursor(TResId id) const
Definition window.h:612
virtual void SetupWindow()
Performs setup following creation of an associated MS-Windows window.
Definition window.cpp:2575
virtual void Paint(TDC &dc, bool erase, TRect &rect)
Repaints the client area (the area you can use for drawing) of a window.
Definition window.cpp:2071
uint NumChildren() const
Returns the number of child windows of the window.
Definition window.cpp:2954
bool EvSetCursor(HWND hWndCursor, uint codeHitTest, TMsgId mouseMsg)
Response method for an incoming WM_SETCURSOR message.
Definition window.cpp:2081
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 GetHandle() const
Returns the handle of the window.
Definition window.h:2020
Definition of container classes used and made available by OWL.
#define _T(x)
Definition cygwin.h:51
Definition of GDI DC encapsulation classes: TDC, TWindowDC, TScreenDC, TDesktopDC,...
#define DEFINE_RESPONSE_TABLE1(cls, base)
Macro to define a response table for a class with one base.
Definition eventhan.h:492
#define lmParent
Use to represent the parent in layout metrics.
Definition layoutco.h:31
@ lmTop
The top edge of the window.
Definition layoutco.h:38
@ lmBottom
The bottom edge of the window.
Definition layoutco.h:40
@ lmRight
The right edge of the window.
Definition layoutco.h:39
@ lmLeft
The left edge of the window.
Definition layoutco.h:37
@ lmPixels
Definition layoutco.h:58
@ lmSameAs
Definition layoutco.h:73
Definition of classes TLayoutMetrics & TLayoutWindow.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
EV_WM_LBUTTONUP
Definition docking.cpp:2056
EV_WM_SETCURSOR
Definition docking.cpp:99
UINT TMsgId
Message ID type.
Definition dispatch.h:53
TSplitDirection
Enumeration describing whether to split a window in the X or Y plane.
Definition splitter.h:30
@ psHorizontal
Horizontal split.
Definition splitter.h:31
TSplitterIndicatorList::Iterator TSplitterIndicatorListIterator
Definition splitter.h:227
EV_WM_MOUSEMOVE
Definition docking.cpp:2054
OWL_DIAGINFO
Definition animctrl.cpp:14
END_RESPONSE_TABLE
Definition button.cpp:26
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
EV_WM_LBUTTONDOWN
Definition checklst.cpp:195
EV_WM_SIZE
Definition decframe.cpp:34
#define SPLITTER(x)
Definition panespli.cpp:28
#define LAYOUTWINDOW(x)
Definition panespli.cpp:29
Definition of container classes used and made available by OWL.
Definition of the UI Helper Classes: TUIHandle, TUIBorder, TUIFace, TUIPart.
Definition of TUIMetric, a UI metrics provider class.