1 /////////////////////////////////////////////////////////////////////////////
2 // Name: splittree.cpp
3 // Purpose: Classes to achieve a remotely-scrolled tree in a splitter
4 // window that can be scrolled by a scrolled window higher in the
5 // hierarchy
6 // Author: Julian Smart
7 // Modified by:
8 // Created: 8/7/2000
9 // RCS-ID: $Id: splittree.cpp 55007 2008-08-07 09:29:54Z JS $
10 // Copyright: (c) Julian Smart
11 // Licence: wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13
14 // ============================================================================
15 // declarations
16 // ============================================================================
17
18 // ----------------------------------------------------------------------------
19 // headers
20 // ----------------------------------------------------------------------------
21
22 // For compilers that support precompilation, includes "wx/wx.h".
23 #include "wx/wxprec.h"
24
25 #ifdef __BORLANDC__
26 #pragma hdrstop
27 #endif
28
29 // for all others, include the necessary headers (this file is usually all you
30 // need because it includes almost all "standard" wxWidgets headers)
31 #ifndef WX_PRECOMP
32 #include "wx/wx.h"
33 #endif
34
35 #ifdef __WXMSW__
36 #include <windows.h>
37 #include "wx/msw/winundef.h"
38 #endif
39
40 #include "wx/gizmos/splittree.h"
41 #include "wx/renderer.h"
42 #include <math.h>
43
44 /*
45 * wxRemotelyScrolledTreeCtrl
46 */
47
48 #if USE_GENERIC_TREECTRL
IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl,wxGenericTreeCtrl)49 IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)
50 #else
51 IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)
52 #endif
53
54 #if USE_GENERIC_TREECTRL
55 BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)
56 #else
57 BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)
58 #endif
59 EVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize)
60 EVT_PAINT(wxRemotelyScrolledTreeCtrl::OnPaint)
61 EVT_TREE_ITEM_EXPANDED(wxID_ANY, wxRemotelyScrolledTreeCtrl::OnExpand)
62 EVT_TREE_ITEM_COLLAPSED(wxID_ANY, wxRemotelyScrolledTreeCtrl::OnExpand)
63 EVT_SCROLLWIN(wxRemotelyScrolledTreeCtrl::OnScroll)
64 END_EVENT_TABLE()
65
66 wxRemotelyScrolledTreeCtrl::wxRemotelyScrolledTreeCtrl(
67 wxWindow* parent, wxWindowID id, const wxPoint& pt,
68 const wxSize& sz, long style)
69 : wxTreeCtrl(parent, id, pt, sz, style & ~wxTR_ROW_LINES)
70 {
71 m_companionWindow = NULL;
72
73 // We draw the row lines ourself so they match what's done
74 // by the companion window. That is why the flag is turned
75 // off above, so wxGenericTreeCtrl doesn't draw them in a
76 // different colour.
77 m_drawRowLines = (style & wxTR_ROW_LINES) != 0;
78 }
79
~wxRemotelyScrolledTreeCtrl()80 wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl()
81 {
82 }
83
HideVScrollbar()84 void wxRemotelyScrolledTreeCtrl::HideVScrollbar()
85 {
86 #if defined(__WXMSW__)
87 #if USE_GENERIC_TREECTRL
88 if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
89 #endif
90 {
91 ::ShowScrollBar((HWND) GetHWND(), SB_VERT, false);
92 }
93 #if USE_GENERIC_TREECTRL
94 else
95 {
96 // Implicit in overriding SetScrollbars
97 }
98 #endif
99 #endif
100 }
101
DoCalcScrolledPosition(int x,int y,int * xx,int * yy) const102 void wxRemotelyScrolledTreeCtrl::DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const
103 {
104 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
105 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
106 {
107 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
108 * yy = 0;
109 int yyy;
110 win->wxGenericTreeCtrl::DoCalcScrolledPosition(x, y, xx, & yyy);
111
112 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
113 if (scrolledWindow)
114 {
115 int xxx;
116 scrolledWindow->DoCalcScrolledPosition(x, y, & xxx, yy);
117 }
118 }
119 #endif
120 }
121
SetScrollbar(int orient,int pos,int thumbVisible,int range,bool update)122 void wxRemotelyScrolledTreeCtrl::SetScrollbar(int orient,
123 int pos,
124 int thumbVisible,
125 int range,
126 bool update)
127 {
128 #ifndef __WXMSW__
129 if (orient == wxVERTICAL)
130 range = 0;
131 #endif
132 wxWindow::SetScrollbar(orient, pos, thumbVisible, range, update);
133 }
134
135 // Number of pixels per user unit (0 or -1 for no scrollbar)
136 // Length of virtual canvas in user units
137 // Length of page in user units
SetScrollbars(int pixelsPerUnitX,int pixelsPerUnitY,int noUnitsX,int noUnitsY,int xPos,int yPos,bool noRefresh)138 void wxRemotelyScrolledTreeCtrl::SetScrollbars(
139 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
140 int pixelsPerUnitX, int pixelsPerUnitY,
141 int noUnitsX, int noUnitsY,
142 int xPos, int yPos,
143 bool noRefresh
144 #else
145 int WXUNUSED(pixelsPerUnitX), int WXUNUSED(pixelsPerUnitY),
146 int WXUNUSED(noUnitsX), int WXUNUSED(noUnitsY),
147 int WXUNUSED(xPos), int WXUNUSED(yPos),
148 bool WXUNUSED(noRefresh)
149 #endif
150 )
151 {
152 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
153 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
154 {
155 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
156 win->wxGenericTreeCtrl::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY, xPos, yPos, /* noRefresh */ true);
157
158 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
159 if (scrolledWindow)
160 {
161 scrolledWindow->SetScrollbars(0, pixelsPerUnitY, 0, noUnitsY, 0, yPos, noRefresh);
162 }
163 }
164 #endif
165 }
166
167 // In case we're using the generic tree control.
GetScrollPos(int orient) const168 int wxRemotelyScrolledTreeCtrl::GetScrollPos(
169 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
170 int orient
171 #else
172 int WXUNUSED(orient)
173 #endif
174 ) const
175 {
176
177 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
178 // this condition fixes extsitence of warning but
179 wxScrolledWindow* scrolledWindow =
180 // but GetScrolledWindow is still executed in case internally does something
181 #endif
182 GetScrolledWindow();
183
184 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
185 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
186 {
187 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
188
189 if (orient == wxHORIZONTAL)
190 return win->wxGenericTreeCtrl::GetScrollPos(orient);
191 else
192 {
193 return scrolledWindow->GetScrollPos(orient);
194 }
195 }
196 #endif
197 return 0;
198 }
199
200
201 // In case we're using the generic tree control.
202 // Get the view start
GetViewStart(int * x,int * y) const203 void wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const
204 {
205 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
206
207 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
208 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
209 {
210
211 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
212 int x1, y1, x2, y2;
213 win->wxGenericTreeCtrl::GetViewStart(& x1, & y1);
214 * x = x1; * y = y1;
215 if (!scrolledWindow)
216 return;
217
218 scrolledWindow->GetViewStart(& x2, & y2);
219 * y = y2;
220 }
221 else
222 #endif
223 {
224 // x is wrong since the horizontal scrollbar is controlled by the
225 // tree control, but we probably don't need it.
226 scrolledWindow->GetViewStart(x, y);
227 }
228 }
229
230 // In case we're using the generic tree control.
PrepareDC(wxDC & dc)231 void wxRemotelyScrolledTreeCtrl::PrepareDC(
232 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
233 wxDC& dc
234 #else
235 wxDC& WXUNUSED(dc)
236 #endif
237 )
238 {
239 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
240 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
241 {
242 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
243
244 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
245
246 int startX, startY;
247 GetViewStart(& startX, & startY);
248
249 int xppu1, yppu1, xppu2, yppu2;
250 win->wxGenericTreeCtrl::GetScrollPixelsPerUnit(& xppu1, & yppu1);
251 scrolledWindow->GetScrollPixelsPerUnit(& xppu2, & yppu2);
252
253 dc.SetDeviceOrigin( -startX * xppu1, -startY * yppu2 );
254 // dc.SetUserScale( win->GetScaleX(), win->GetScaleY() );
255 }
256 #endif
257 }
258
259 // Scroll to the given line (in scroll units where each unit is
260 // the height of an item)
ScrollToLine(int WXUNUSED (posHoriz),int posVert)261 void wxRemotelyScrolledTreeCtrl::ScrollToLine(int WXUNUSED(posHoriz), int posVert)
262 {
263 #ifdef __WXMSW__
264 #if USE_GENERIC_TREECTRL
265 if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
266 #endif // USE_GENERIC_TREECTRL
267 {
268 // JLD - 2008-07-31 - call SetScrollInfo() - Vista ignores nPos passed in WM_VSCROLL wParam
269 SCROLLINFO si = {sizeof(SCROLLINFO), SIF_POS, 0, 0, 0, posVert, 0};
270 SetScrollInfo((HWND) GetHWND(), SB_VERT, &si, FALSE);
271
272 UINT sbCode = SB_THUMBPOSITION;
273 HWND vertScrollBar = 0;
274 MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXLPARAM) vertScrollBar);
275 }
276 #if USE_GENERIC_TREECTRL
277 else
278 #endif // USE_GENERIC_TREECTRL
279 #endif // __WXMSW__
280 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
281 {
282 wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
283 win->Refresh();
284 /* Doesn't work yet because scrolling is ignored by Scroll
285 int xppu, yppu;
286 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
287 if (scrolledWindow)
288 {
289 scrolledWindow->GetScrollPixelsPerUnit(& xppu, & yppu);
290 win->Scroll(-1, posVert*yppu);
291 }
292 */
293 }
294 #endif // USE_GENERIC_TREECTRL || !defined(__WXMSW__)
295 wxUnusedVar(posVert);
296 }
297
OnSize(wxSizeEvent & event)298 void wxRemotelyScrolledTreeCtrl::OnSize(wxSizeEvent& event)
299 {
300 HideVScrollbar();
301 AdjustRemoteScrollbars();
302 event.Skip();
303 }
304
OnExpand(wxTreeEvent & event)305 void wxRemotelyScrolledTreeCtrl::OnExpand(wxTreeEvent& event)
306 {
307 AdjustRemoteScrollbars();
308 event.Skip();
309
310 // If we don't have this, we get some bits of lines still remaining
311 if (event.GetEventType() == wxEVT_COMMAND_TREE_ITEM_COLLAPSED)
312 Refresh();
313
314 // Pass on the event
315 if (m_companionWindow)
316 m_companionWindow->GetEventHandler()->ProcessEvent(event);
317 }
318
OnPaint(wxPaintEvent & event)319 void wxRemotelyScrolledTreeCtrl::OnPaint(wxPaintEvent& event)
320 {
321 wxPaintDC dc(this);
322
323 wxTreeCtrl::OnPaint(event);
324
325 if (! m_drawRowLines)
326 return;
327
328 // Reset the device origin since it may have been set
329 dc.SetDeviceOrigin(0, 0);
330
331 wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID);
332 dc.SetPen(pen);
333 dc.SetBrush(* wxTRANSPARENT_BRUSH);
334
335 wxSize clientSize = GetClientSize();
336 wxRect itemRect;
337 wxTreeItemId h, lastH;
338 for (h=GetFirstVisibleItem();
339 h.IsOk();
340 h=GetNextVisible(h))
341 {
342 if (GetBoundingRect(h, itemRect))
343 {
344 int cy = itemRect.GetTop();
345 dc.DrawLine(0, cy, clientSize.x, cy);
346 lastH = h;
347 }
348 if (! IsVisible(h))
349 break;
350 }
351 if (lastH.IsOk() && GetBoundingRect(lastH, itemRect))
352 {
353 int cy = itemRect.GetBottom();
354 dc.DrawLine(0, cy, clientSize.x, cy);
355 }
356 }
357
358
359 // Adjust the containing wxScrolledWindow's scrollbars appropriately
AdjustRemoteScrollbars()360 void wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars()
361 {
362 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
363 if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
364 {
365 // This is for the generic tree control.
366 // It calls SetScrollbars which has been overridden
367 // to adjust the parent scrolled window vertical
368 // scrollbar.
369 ((wxGenericTreeCtrl*) this)->AdjustMyScrollbars();
370 return;
371 }
372 else
373 #endif
374 {
375 // This is for the wxMSW tree control
376 wxScrolledWindow* scrolledWindow = GetScrolledWindow();
377 if (scrolledWindow)
378 {
379 wxRect itemRect;
380 if (GetBoundingRect(GetRootItem(), itemRect))
381 {
382 // Actually, the real height seems to be 1 less than reported
383 // (e.g. 16 instead of 16)
384 int itemHeight = itemRect.GetHeight() - 1;
385
386 int w, h;
387 GetClientSize(&w, &h);
388
389 wxRect rect(0, 0, 0, 0);
390 CalcTreeSize(rect);
391
392 double f = ((double) (rect.GetHeight()) / (double) itemHeight) ;
393 int treeViewHeight = (int) ceil(f);
394
395 int scrollPixelsPerLine = itemHeight;
396 int scrollPos = - (itemRect.y / itemHeight);
397
398 scrolledWindow->SetScrollbars(0, scrollPixelsPerLine, 0, treeViewHeight, 0, scrollPos);
399
400 // Ensure that when a scrollbar becomes hidden or visible,
401 // the contained window sizes are right.
402 // Problem: this is called too early (?)
403 wxSizeEvent event(scrolledWindow->GetSize(), scrolledWindow->GetId());
404 scrolledWindow->GetEventHandler()->ProcessEvent(event);
405 }
406 }
407 }
408 }
409
410
411 // Calculate the area that contains both rectangles
CombineRectangles(const wxRect & rect1,const wxRect & rect2)412 static wxRect CombineRectangles(const wxRect& rect1, const wxRect& rect2)
413 {
414 wxRect rect;
415
416 int right1 = rect1.GetRight();
417 int bottom1 = rect1.GetBottom();
418 int right2 = rect2.GetRight();
419 int bottom2 = rect2.GetBottom();
420
421 wxPoint topLeft = wxPoint(wxMin(rect1.x, rect2.x), wxMin(rect1.y, rect2.y));
422 wxPoint bottomRight = wxPoint(wxMax(right1, right2), wxMax(bottom1, bottom2));
423
424 rect.x = topLeft.x; rect.y = topLeft.y;
425 rect.SetRight(bottomRight.x);
426 rect.SetBottom(bottomRight.y);
427
428 return rect;
429 }
430
431
432 // Calculate the tree overall size so we can set the scrollbar
433 // correctly
CalcTreeSize(wxRect & rect)434 void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect)
435 {
436 CalcTreeSize(GetRootItem(), rect);
437 }
438
CalcTreeSize(const wxTreeItemId & id,wxRect & rect)439 void wxRemotelyScrolledTreeCtrl::CalcTreeSize(const wxTreeItemId& id, wxRect& rect)
440 {
441 // More efficient implementation would be to find the last item (but how?)
442 // Q: is the bounding rect relative to the top of the virtual tree workspace
443 // or the top of the window? How would we convert?
444 wxRect itemSize;
445 if (GetBoundingRect(id, itemSize))
446 {
447 rect = CombineRectangles(rect, itemSize);
448 }
449
450 wxTreeItemIdValue cookie;
451 wxTreeItemId childId = GetFirstChild(id, cookie);
452 while (childId)
453 {
454 CalcTreeSize(childId, rect);
455 childId = GetNextChild(childId, cookie);
456 }
457 }
458
459 // Find the scrolled window that contains this control
GetScrolledWindow() const460 wxScrolledWindow* wxRemotelyScrolledTreeCtrl::GetScrolledWindow() const
461 {
462 wxWindow* parent = wxWindow::GetParent();
463 while (parent)
464 {
465 if (parent->IsKindOf(CLASSINFO(wxScrolledWindow)))
466 return (wxScrolledWindow*) parent;
467 parent = parent->GetParent();
468 }
469 return NULL;
470 }
471
OnScroll(wxScrollWinEvent & event)472 void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event)
473 {
474 int orient = event.GetOrientation();
475 if (orient == wxHORIZONTAL)
476 {
477 event.Skip();
478 return;
479 }
480 wxScrolledWindow* scrollWin = GetScrolledWindow();
481 if (!scrollWin)
482 return;
483
484 int x, y;
485 scrollWin->GetViewStart(& x, & y);
486
487 ScrollToLine(-1, y);
488
489 #ifndef __WXMSW__
490 m_yScrollPosition = GetScrollPos(wxVERTICAL);
491 #endif
492 }
493
494 /*
495 * wxTreeCompanionWindow
496 *
497 * A window displaying values associated with tree control items.
498 */
499
IMPLEMENT_CLASS(wxTreeCompanionWindow,wxWindow)500 IMPLEMENT_CLASS(wxTreeCompanionWindow, wxWindow)
501
502 BEGIN_EVENT_TABLE(wxTreeCompanionWindow, wxWindow)
503 EVT_PAINT(wxTreeCompanionWindow::OnPaint)
504 EVT_SCROLLWIN(wxTreeCompanionWindow::OnScroll)
505 EVT_TREE_ITEM_EXPANDED(-1, wxTreeCompanionWindow::OnExpand)
506 EVT_TREE_ITEM_COLLAPSED(-1, wxTreeCompanionWindow::OnExpand)
507 END_EVENT_TABLE()
508
509 wxTreeCompanionWindow::wxTreeCompanionWindow(wxWindow* parent, wxWindowID id,
510 const wxPoint& pos,
511 const wxSize& sz,
512 long style):
513 wxWindow(parent, id, pos, sz, style)
514 {
515 m_treeCtrl = NULL;
516 }
517
DrawItem(wxDC & dc,wxTreeItemId id,const wxRect & rect)518 void wxTreeCompanionWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect)
519 {
520 // TEST CODE
521 #if 1
522 if (m_treeCtrl)
523 {
524 wxString text = m_treeCtrl->GetItemText(id);
525 dc.SetTextForeground(* wxBLACK);
526 dc.SetBackgroundMode(wxTRANSPARENT);
527
528 int textW, textH;
529 dc.GetTextExtent(text, & textW, & textH);
530
531 int x = 5;
532 int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2);
533
534 dc.DrawText(text, x, y);
535 }
536 #endif
537 }
538
OnPaint(wxPaintEvent & WXUNUSED (event))539 void wxTreeCompanionWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
540 {
541 wxPaintDC dc(this);
542
543 if (!m_treeCtrl)
544 return;
545
546 wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID);
547 dc.SetPen(pen);
548 dc.SetBrush(* wxTRANSPARENT_BRUSH);
549 wxFont font(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
550 dc.SetFont(font);
551
552 wxSize clientSize = GetClientSize();
553 wxRect itemRect;
554 wxTreeItemId h, lastH;
555 for (h=m_treeCtrl->GetFirstVisibleItem();
556 h.IsOk();
557 h=m_treeCtrl->GetNextVisible(h))
558 {
559 if (m_treeCtrl->GetBoundingRect(h, itemRect))
560 {
561 int cy = itemRect.GetTop();
562 wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight());
563
564 lastH = h;
565
566 // Draw the actual item
567 DrawItem(dc, h, drawItemRect);
568 dc.DrawLine(0, cy, clientSize.x, cy);
569 }
570 if (! m_treeCtrl->IsVisible(h))
571 break;
572 }
573 if (lastH.IsOk() && m_treeCtrl->GetBoundingRect(lastH, itemRect))
574 {
575 int cy = itemRect.GetBottom();
576 dc.DrawLine(0, cy, clientSize.x, cy);
577 }
578 }
579
OnScroll(wxScrollWinEvent & event)580 void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event)
581 {
582 int orient = event.GetOrientation();
583 if (orient == wxHORIZONTAL)
584 {
585 event.Skip();
586 return;
587 }
588 if (!m_treeCtrl)
589 return;
590
591 // TODO: scroll the window physically instead of just refreshing.
592 Refresh(true);
593 }
594
OnExpand(wxTreeEvent & WXUNUSED (event))595 void wxTreeCompanionWindow::OnExpand(wxTreeEvent& WXUNUSED(event))
596 {
597 // TODO: something more optimized than simply refresh the whole
598 // window when the tree is expanded/collapsed. Tricky.
599 Refresh();
600 }
601
602 /*
603 * wxThinSplitterWindow
604 */
605
IMPLEMENT_CLASS(wxThinSplitterWindow,wxSplitterWindow)606 IMPLEMENT_CLASS(wxThinSplitterWindow, wxSplitterWindow)
607
608 BEGIN_EVENT_TABLE(wxThinSplitterWindow, wxSplitterWindow)
609 EVT_SIZE(wxThinSplitterWindow::OnSize)
610 END_EVENT_TABLE()
611
612 wxThinSplitterWindow::wxThinSplitterWindow(wxWindow* parent, wxWindowID id,
613 const wxPoint& pos,
614 const wxSize& sz,
615 long style):
616 wxSplitterWindow(parent, id, pos, sz, style)
617 {
618 wxColour faceColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
619 m_facePen = new wxPen(faceColour, 1, wxSOLID);
620 m_faceBrush = new wxBrush(faceColour, wxSOLID);
621 }
622
~wxThinSplitterWindow()623 wxThinSplitterWindow::~wxThinSplitterWindow()
624 {
625 delete m_facePen;
626 delete m_faceBrush;
627 }
628
629
SizeWindows()630 void wxThinSplitterWindow::SizeWindows()
631 {
632 // The client size may have changed inbetween
633 // the sizing of the first window and the sizing of
634 // the second. So repeat SizeWindows.
635 wxSplitterWindow::SizeWindows();
636 wxSplitterWindow::SizeWindows();
637 }
638
639 // Tests for x, y over sash
SashHitTest(int x,int y,int WXUNUSED (tolerance))640 bool wxThinSplitterWindow::SashHitTest(int x, int y, int WXUNUSED(tolerance))
641 {
642 return wxSplitterWindow::SashHitTest(x, y, 4);
643 }
644
DrawSash(wxDC & dc)645 void wxThinSplitterWindow::DrawSash(wxDC& dc)
646 {
647 wxRendererNative::Get().DrawSplitterBorder
648 (
649 this,
650 dc,
651 GetClientRect()
652 );
653 if ( m_sashPosition == 0 || !m_windowTwo)
654 return;
655 if (GetWindowStyle() & wxSP_NOSASH)
656 return;
657
658 int w, h;
659 GetClientSize(&w, &h);
660
661 if ( m_splitMode == wxSPLIT_VERTICAL )
662 {
663 dc.SetPen(* m_facePen);
664 dc.SetBrush(* m_faceBrush);
665 int h1 = h-1;
666 int y1 = 0;
667 if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER )
668 h1 += 1; // Not sure why this is necessary...
669 if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER)
670 {
671 y1 = 2; h1 -= 3;
672 }
673 dc.DrawRectangle(m_sashPosition, y1, GetSashSize(), h1);
674 }
675 else
676 {
677 dc.SetPen(* m_facePen);
678 dc.SetBrush(* m_faceBrush);
679 int w1 = w-1;
680 int x1 = 0;
681 if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER )
682 w1 ++;
683 if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER)
684 {
685 x1 = 2; w1 -= 3;
686 }
687 dc.DrawRectangle(x1, m_sashPosition, w1, GetSashSize());
688 }
689
690 dc.SetPen(wxNullPen);
691 dc.SetBrush(wxNullBrush);
692 }
693
OnSize(wxSizeEvent & event)694 void wxThinSplitterWindow::OnSize(wxSizeEvent& event)
695 {
696 wxSplitterWindow::OnSize(event);
697 }
698
699 /*
700 * wxSplitterScrolledWindow
701 */
702
IMPLEMENT_CLASS(wxSplitterScrolledWindow,wxScrolledWindow)703 IMPLEMENT_CLASS(wxSplitterScrolledWindow, wxScrolledWindow)
704
705 BEGIN_EVENT_TABLE(wxSplitterScrolledWindow, wxScrolledWindow)
706 EVT_SCROLLWIN(wxSplitterScrolledWindow::OnScroll)
707 EVT_SIZE(wxSplitterScrolledWindow::OnSize)
708 END_EVENT_TABLE()
709
710 wxSplitterScrolledWindow::wxSplitterScrolledWindow(wxWindow* parent, wxWindowID id,
711 const wxPoint& pos,
712 const wxSize& sz,
713 long style):
714 wxScrolledWindow(parent, id, pos, sz, style)
715 {
716 }
717
OnSize(wxSizeEvent & WXUNUSED (event))718 void wxSplitterScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
719 {
720 wxSize sz = GetClientSize();
721 if (GetChildren().GetFirst())
722 {
723 ((wxWindow*) GetChildren().GetFirst()->GetData())->SetSize(0, 0, sz.x, sz.y);
724 }
725 }
726
OnScroll(wxScrollWinEvent & event)727 void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event)
728 {
729 // Ensure that events being propagated back up the window hierarchy
730 // don't cause an infinite loop
731 static bool inOnScroll = false;
732 if (inOnScroll)
733 {
734 event.Skip();
735 return;
736 }
737 inOnScroll = true;
738
739 int orient = event.GetOrientation();
740
741 int nScrollInc = CalcScrollInc(event);
742 if (nScrollInc == 0)
743 {
744 inOnScroll = false;
745 return;
746 }
747
748 if (orient == wxHORIZONTAL)
749 {
750 inOnScroll = false;
751 event.Skip();
752 return;
753 #if 0
754 int newPos = m_xScrollPosition + nScrollInc;
755 SetScrollPos(wxHORIZONTAL, newPos, true );
756 #endif
757 }
758 else
759 {
760 int newPos = m_yScrollPosition + nScrollInc;
761 SetScrollPos(wxVERTICAL, newPos, true );
762 }
763
764 if (orient == wxHORIZONTAL)
765 {
766 m_xScrollPosition += nScrollInc;
767 }
768 else
769 {
770 m_yScrollPosition += nScrollInc;
771 }
772
773 // Find targets in splitter window and send the event to them
774 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
775 while (node)
776 {
777 wxWindow* child = (wxWindow*) node->GetData();
778 if (child->IsKindOf(CLASSINFO(wxSplitterWindow)))
779 {
780 wxSplitterWindow* splitter = (wxSplitterWindow*) child;
781 if (splitter->GetWindow1())
782 splitter->GetWindow1()->ProcessEvent(event);
783 if (splitter->GetWindow2())
784 splitter->GetWindow2()->ProcessEvent(event);
785 break;
786 }
787 node = node->GetNext();
788 }
789
790 m_targetWindow->Update() ;
791
792 inOnScroll = false;
793 }
794