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