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