]> git.saurik.com Git - wxWidgets.git/blob - src/generic/splitter.cpp
wxListBox::FindString(): it's not an error if the string is not found, so
[wxWidgets.git] / src / generic / splitter.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: splitter.cpp
3 // Purpose: wxSplitterWindow implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "splitter.h"
14 // #pragma interface
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #include <math.h>
29 #include <stdlib.h>
30
31 #include "wx/string.h"
32 #include "wx/splitter.h"
33 #include "wx/dcscreen.h"
34
35 #if !USE_SHARED_LIBRARY
36 IMPLEMENT_DYNAMIC_CLASS(wxSplitterWindow, wxWindow)
37
38 BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
39 EVT_PAINT(wxSplitterWindow::OnPaint)
40 EVT_SIZE(wxSplitterWindow::OnSize)
41 EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent)
42 END_EVENT_TABLE()
43 #endif
44
45 wxSplitterWindow::wxSplitterWindow(void)
46 {
47 m_splitMode = wxSPLIT_VERTICAL;
48 m_windowOne = (wxWindow *) NULL;
49 m_windowTwo = (wxWindow *) NULL;
50 m_dragMode = wxSPLIT_DRAG_NONE;
51 m_oldX = 0;
52 m_oldY = 0;
53 m_firstX = 0;
54 m_firstY = 0;
55 m_sashSize = 7;
56 m_borderSize = 2;
57 m_sashPosition = 0;
58 m_sashCursorWE = (wxCursor *) NULL;
59 m_sashCursorNS = (wxCursor *) NULL;
60 m_sashTrackerPen = (wxPen *) NULL;
61 m_lightShadowPen = (wxPen *) NULL;
62 m_mediumShadowPen = (wxPen *) NULL;
63 m_darkShadowPen = (wxPen *) NULL;
64 m_faceBrush = (wxBrush *) NULL;
65 m_facePen = (wxPen *) NULL;
66 m_hilightPen = (wxPen *) NULL;
67 m_minimumPaneSize = 0;
68 }
69
70 wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos,
71 const wxSize& size, long style, const wxString& name)
72 :wxWindow(parent, id, pos, size, style, name)
73 {
74 m_splitMode = wxSPLIT_VERTICAL;
75 m_windowOne = (wxWindow *) NULL;
76 m_windowTwo = (wxWindow *) NULL;
77 m_dragMode = wxSPLIT_DRAG_NONE;
78 m_oldX = 0;
79 m_oldY = 0;
80 m_firstX = 0;
81 m_firstY = 0;
82 m_sashSize = 7;
83 m_borderSize = 2;
84 m_sashPosition = 0;
85 m_minimumPaneSize = 0;
86 m_sashCursorWE = new wxCursor(wxCURSOR_SIZEWE);
87 m_sashCursorNS = new wxCursor(wxCURSOR_SIZENS);
88 m_sashTrackerPen = new wxPen(*wxBLACK, 2, wxSOLID);
89 m_lightShadowPen = (wxPen *) NULL;
90 m_mediumShadowPen = (wxPen *) NULL;
91 m_darkShadowPen = (wxPen *) NULL;
92 m_faceBrush = (wxBrush *) NULL;
93 m_facePen = (wxPen *) NULL;
94 m_hilightPen = (wxPen *) NULL;
95
96 if ( style & wxSP_3D )
97 {
98 m_borderSize = 2;
99 m_sashSize = 7;
100 }
101 else if ( style & wxSP_BORDER )
102 {
103 m_borderSize = 1;
104 m_sashSize = 3;
105 }
106 else
107 {
108 m_borderSize = 0;
109 m_sashSize = 3;
110 }
111
112 // Eventually, we'll respond to colour change messages
113 InitColours();
114
115 // For debugging purposes, to see the background.
116 // SetBackground(wxBLUE_BRUSH);
117 }
118
119 wxSplitterWindow::~wxSplitterWindow(void)
120 {
121 delete m_sashCursorWE;
122 delete m_sashCursorNS;
123 delete m_sashTrackerPen;
124 delete m_lightShadowPen;
125 delete m_darkShadowPen;
126 delete m_mediumShadowPen;
127 delete m_hilightPen;
128 delete m_facePen;
129 delete m_faceBrush;
130 }
131
132 void wxSplitterWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
133 {
134 wxPaintDC dc(this);
135
136 if ( m_borderSize > 0 )
137 DrawBorders(dc);
138 DrawSash(dc);
139 }
140
141 void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
142 {
143 long x, y;
144 event.Position(&x, &y);
145
146 if (event.LeftDown())
147 {
148 if ( SashHitTest(x, y) )
149 {
150 CaptureMouse();
151
152 // Required for X to specify that
153 // that we wish to draw on top of all windows
154 // - and we optimise by specifying the area
155 // for creating the overlap window.
156 wxScreenDC::StartDrawingOnTop(this);
157
158 // We don't say we're dragging yet; we leave that
159 // decision for the Dragging() branch, to ensure
160 // the user has dragged a little bit.
161 m_dragMode = wxSPLIT_DRAG_LEFT_DOWN;
162 m_firstX = x;
163 m_firstY = y;
164 }
165 }
166 else if ( event.LeftUp() && m_dragMode == wxSPLIT_DRAG_LEFT_DOWN )
167 {
168 // Wasn't a proper drag
169 ReleaseMouse();
170 wxScreenDC::EndDrawingOnTop();
171 m_dragMode = wxSPLIT_DRAG_NONE;
172
173 SetCursor(*wxSTANDARD_CURSOR);
174 }
175 else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING)
176 {
177 // We can stop dragging now and see what we've got.
178 m_dragMode = wxSPLIT_DRAG_NONE;
179 ReleaseMouse();
180 // Erase old tracker
181 DrawSashTracker(m_oldX, m_oldY);
182
183 // End drawing on top (frees the window used for drawing
184 // over the screen)
185 wxScreenDC::EndDrawingOnTop();
186
187 int w, h;
188 GetClientSize(&w, &h);
189 if ( m_splitMode == wxSPLIT_VERTICAL )
190 {
191 // First check if we should veto this resize because
192 // the pane size is too small
193 if ( wxMax(x, 0) < m_minimumPaneSize || wxMax((w - x), 0) < m_minimumPaneSize)
194 return;
195
196 if ( x <= 4 )
197 {
198 // We remove the first window from the view
199 wxWindow *removedWindow = m_windowOne;
200 m_windowOne = m_windowTwo;
201 m_windowTwo = (wxWindow *) NULL;
202
203 OnUnsplit(removedWindow);
204 m_sashPosition = 0;
205 }
206 else if ( x >= (w - 4) )
207 {
208 // We remove the second window from the view
209 wxWindow *removedWindow = m_windowTwo;
210 m_windowTwo = (wxWindow *) NULL;
211 OnUnsplit(removedWindow);
212 m_sashPosition = 0;
213 }
214 else
215 {
216 m_sashPosition = x;
217 }
218 }
219 else
220 {
221 // First check if we should veto this resize because
222 // the pane size is too small
223 if ( wxMax(y, 0) < m_minimumPaneSize || wxMax((h - y), 0) < m_minimumPaneSize)
224 return;
225
226 if ( y <= 4 )
227 {
228 // We remove the first window from the view
229 wxWindow *removedWindow = m_windowOne;
230 m_windowOne = m_windowTwo;
231 m_windowTwo = (wxWindow *) NULL;
232
233 OnUnsplit(removedWindow);
234 m_sashPosition = 0;
235 }
236 else if ( y >= (h - 4) )
237 {
238 // We remove the second window from the view
239 wxWindow *removedWindow = m_windowTwo;
240 m_windowTwo = (wxWindow *) NULL;
241 OnUnsplit(removedWindow);
242 m_sashPosition = 0;
243 }
244 else
245 {
246 m_sashPosition = y;
247 }
248 }
249 SizeWindows();
250 }
251 else if (event.Moving() && !event.Dragging())
252 {
253 // Just change the cursor if required
254 if ( SashHitTest(x, y) )
255 {
256 if ( m_splitMode == wxSPLIT_VERTICAL )
257 {
258 SetCursor(*m_sashCursorWE);
259 }
260 else
261 {
262 SetCursor(*m_sashCursorNS);
263 }
264 }
265 else
266 {
267 SetCursor(*wxSTANDARD_CURSOR);
268 }
269 }
270 else if ( (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) ||
271 (event.Dragging() && SashHitTest(x, y, 4)) )
272 {
273 if ( m_splitMode == wxSPLIT_VERTICAL )
274 {
275 SetCursor(*m_sashCursorWE);
276 }
277 else
278 {
279 SetCursor(*m_sashCursorNS);
280 }
281
282 // Detect that this is really a drag: we've moved more than 1 pixel either way
283 if ((m_dragMode == wxSPLIT_DRAG_LEFT_DOWN) &&
284 // (abs((int)x - m_firstX) > 1 || abs((int)y - m_firstY) > 1) )
285 (abs((int)x - m_firstX) > 0 || abs((int)y - m_firstY) > 1) )
286 {
287 m_dragMode = wxSPLIT_DRAG_DRAGGING;
288 DrawSashTracker(x, y);
289 }
290 else
291 {
292 if ( m_dragMode == wxSPLIT_DRAG_DRAGGING )
293 {
294 // Erase old tracker
295 DrawSashTracker(m_oldX, m_oldY);
296
297 // Draw new one
298 DrawSashTracker(x, y);
299 }
300 }
301 m_oldX = x;
302 m_oldY = y;
303 }
304 else if ( event.LeftDClick() )
305 {
306 OnDoubleClickSash(x, y);
307 }
308 else
309 {
310 }
311 }
312
313 void wxSplitterWindow::OnSize(wxSizeEvent& WXUNUSED(event))
314 {
315 int cw, ch;
316 GetClientSize( &cw, &ch );
317 if ( m_windowTwo )
318 {
319 if ( m_splitMode == wxSPLIT_VERTICAL )
320 {
321 if ( m_sashPosition >= (cw - 5) )
322 m_sashPosition = wxMax(10, cw - 40);
323 }
324 if ( m_splitMode == wxSPLIT_HORIZONTAL )
325 {
326 if ( m_sashPosition >= (ch - 5) )
327 m_sashPosition = wxMax(10, ch - 40);
328 }
329 }
330 SizeWindows();
331 }
332
333 bool wxSplitterWindow::SashHitTest(int x, int y, int tolerance)
334 {
335 if ( m_windowTwo == NULL || m_sashPosition == 0)
336 return FALSE; // No sash
337
338 if ( m_splitMode == wxSPLIT_VERTICAL )
339 {
340 if ( (x >= m_sashPosition - tolerance) && (x <= m_sashPosition + m_sashSize + tolerance) )
341 return TRUE;
342 else
343 return FALSE;
344 }
345 else
346 {
347 if ( (y >= (m_sashPosition- tolerance)) && (y <= (m_sashPosition + m_sashSize + tolerance)) )
348 return TRUE;
349 else
350 return FALSE;
351 }
352
353 return FALSE;
354 }
355
356 // Draw 3D effect borders
357 void wxSplitterWindow::DrawBorders(wxDC& dc)
358 {
359 int w, h;
360 GetClientSize(&w, &h);
361
362 if ( GetWindowStyleFlag() & wxSP_3D )
363 {
364 dc.SetPen(*m_mediumShadowPen);
365 dc.DrawLine(0, 0, w-1, 0);
366 dc.DrawLine(0, 0, 0, h - 1);
367
368 dc.SetPen(*m_darkShadowPen);
369 dc.DrawLine(1, 1, w-2, 1);
370 dc.DrawLine(1, 1, 1, h-2);
371
372 dc.SetPen(*m_hilightPen);
373 dc.DrawLine(0, h-1, w-1, h-1);
374 dc.DrawLine(w-1, 0, w-1, h); // Surely the maximum y pos. should be h - 1.
375 /// Anyway, h is required for MSW.
376
377 dc.SetPen(*m_lightShadowPen);
378 dc.DrawLine(w-2, 1, w-2, h-2); // Right hand side
379 dc.DrawLine(1, h-2, w-1, h-2); // Bottom
380 }
381 else if ( GetWindowStyleFlag() & wxSP_BORDER )
382 {
383 dc.SetBrush(*wxTRANSPARENT_BRUSH);
384 dc.SetPen(*wxBLACK_PEN);
385 dc.DrawRectangle(0, 0, w-1, h-1);
386 }
387
388 dc.SetPen(wxNullPen);
389 dc.SetBrush(wxNullBrush);
390 }
391
392 // Draw the sash
393 void wxSplitterWindow::DrawSash(wxDC& dc)
394 {
395 if ( m_sashPosition == 0 || !m_windowTwo)
396 return;
397
398 int w, h;
399 GetClientSize(&w, &h);
400
401 if ( GetWindowStyleFlag() & wxSP_3D )
402 {
403 if ( m_splitMode == wxSPLIT_VERTICAL )
404 {
405 dc.SetPen(*m_facePen);
406 dc.SetBrush(*m_faceBrush);
407 dc.DrawRectangle(m_sashPosition + 2, 0, m_sashSize - 4, h);
408
409 dc.SetBrush(*wxTRANSPARENT_BRUSH);
410
411 dc.SetPen(*m_lightShadowPen);
412 dc.DrawLine(m_sashPosition, 1, m_sashPosition, h-2);
413
414 dc.SetPen(*m_hilightPen);
415 dc.DrawLine(m_sashPosition+1, 0, m_sashPosition+1, h);
416
417 dc.SetPen(*m_mediumShadowPen);
418 dc.DrawLine(m_sashPosition+m_sashSize-2, 1, m_sashPosition+m_sashSize-2, h-1);
419
420 dc.SetPen(*m_darkShadowPen);
421 dc.DrawLine(m_sashPosition+m_sashSize-1, 2, m_sashPosition+m_sashSize-1, h-2);
422 }
423 else
424 {
425 dc.SetPen(*m_facePen);
426 dc.SetBrush(*m_faceBrush);
427 dc.DrawRectangle(0, m_sashPosition + 2, w, m_sashSize - 4);
428
429 dc.SetBrush(*wxTRANSPARENT_BRUSH);
430
431 dc.SetPen(*m_lightShadowPen);
432 dc.DrawLine(1, m_sashPosition, w-2, m_sashPosition);
433
434 dc.SetPen(*m_hilightPen);
435 dc.DrawLine(0, m_sashPosition+1, w, m_sashPosition+1);
436
437 dc.SetPen(*m_mediumShadowPen);
438 dc.DrawLine(1, m_sashPosition+m_sashSize-2, w-1, m_sashPosition+m_sashSize-2);
439
440 dc.SetPen(*m_darkShadowPen);
441 dc.DrawLine(2, m_sashPosition+m_sashSize-1, w-2, m_sashPosition+m_sashSize-1);
442 }
443 }
444 else
445 {
446 if ( m_splitMode == wxSPLIT_VERTICAL )
447 {
448 dc.SetPen(*wxBLACK_PEN);
449 dc.SetBrush(*wxBLACK_BRUSH);
450 int h1 = h-1;
451 if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER )
452 h1 += 1; // Not sure why this is necessary...
453 dc.DrawRectangle(m_sashPosition, 0, m_sashSize, h1);
454 }
455 else
456 {
457 dc.SetPen(*wxBLACK_PEN);
458 dc.SetBrush(*wxBLACK_BRUSH);
459 int w1 = w-1;
460 if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER )
461 w1 ++;
462
463 dc.DrawRectangle(0, m_sashPosition, w1, m_sashSize);
464 }
465
466 }
467
468 dc.SetPen(wxNullPen);
469 dc.SetBrush(wxNullBrush);
470 }
471
472 // Draw the sash tracker (for whilst moving the sash)
473 void wxSplitterWindow::DrawSashTracker(int x, int y)
474 {
475 int w, h;
476 GetClientSize(&w, &h);
477
478 wxScreenDC screenDC;
479 int x1, y1;
480 int x2, y2;
481
482 if ( m_splitMode == wxSPLIT_VERTICAL )
483 {
484 x1 = x; y1 = 2;
485 x2 = x; y2 = h-2;
486
487 if ( x1 > w )
488 {
489 x1 = w; x2 = w;
490 }
491 else if ( x1 < 0 )
492 {
493 x1 = 0; x2 = 0;
494 }
495 }
496 else
497 {
498 x1 = 2; y1 = y;
499 x2 = w-2; y2 = y;
500
501 if ( y1 > h )
502 {
503 y1 = h;
504 y2 = h;
505 }
506 else if ( y1 < 0 )
507 {
508 y1 = 0;
509 y2 = 0;
510 }
511 }
512
513 ClientToScreen(&x1, &y1);
514 ClientToScreen(&x2, &y2);
515
516 screenDC.SetLogicalFunction(wxXOR);
517 screenDC.SetPen(*m_sashTrackerPen);
518 screenDC.SetBrush(*wxTRANSPARENT_BRUSH);
519
520 screenDC.DrawLine(x1, y1, x2, y2);
521
522 screenDC.SetLogicalFunction(wxCOPY);
523
524 screenDC.SetPen(wxNullPen);
525 screenDC.SetBrush(wxNullBrush);
526 }
527
528 // Position and size subwindows.
529 // Note that the border size applies to each subwindow, not
530 // including the edges next to the sash.
531 void wxSplitterWindow::SizeWindows(void)
532 {
533 int w, h;
534 GetClientSize(&w, &h);
535
536 if ( m_windowOne && !m_windowTwo )
537 {
538 m_windowOne->SetSize(m_borderSize, m_borderSize, w - 2*m_borderSize, h - 2*m_borderSize);
539 }
540 else if ( m_windowOne && m_windowTwo )
541 {
542 if (m_splitMode == wxSPLIT_VERTICAL)
543 {
544 int x1 = m_borderSize;
545 int y1 = m_borderSize;
546 int w1 = m_sashPosition - m_borderSize;
547 int h1 = h - 2*m_borderSize;
548
549 int x2 = m_sashPosition + m_sashSize;
550 int y2 = m_borderSize;
551 int w2 = w - 2*m_borderSize - m_sashSize - w1;
552 int h2 = h - 2*m_borderSize;
553
554 m_windowOne->SetSize(x1, y1,
555 w1, h1);
556 m_windowTwo->SetSize(x2, y2,
557 w2, h2);
558 }
559 else
560 {
561 m_windowOne->SetSize(m_borderSize, m_borderSize,
562 w - 2*m_borderSize, m_sashPosition - m_borderSize);
563 m_windowTwo->SetSize(m_borderSize, m_sashPosition + m_sashSize,
564 w - 2*m_borderSize, h - 2*m_borderSize - m_sashSize - (m_sashPosition - m_borderSize));
565 }
566 }
567 wxClientDC dc(this);
568 DrawBorders(dc);
569 DrawSash(dc);
570 }
571
572 // Set pane for unsplit window
573 void wxSplitterWindow::Initialize(wxWindow *window)
574 {
575 m_windowOne = window;
576 m_windowTwo = (wxWindow *) NULL;
577 m_sashPosition = 0;
578 }
579
580 // Associates the given window with window 2, drawing the appropriate sash
581 // and changing the split mode.
582 // Does nothing and returns FALSE if the window is already split.
583 bool wxSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, int sashPosition)
584 {
585 if ( IsSplit() )
586 return FALSE;
587
588 m_splitMode = wxSPLIT_VERTICAL;
589 m_windowOne = window1;
590 m_windowTwo = window2;
591 if ( sashPosition == -1 )
592 m_sashPosition = 100;
593 else
594 m_sashPosition = sashPosition;
595
596 SizeWindows();
597
598 return TRUE;
599 }
600
601 bool wxSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, int sashPosition)
602 {
603 if ( IsSplit() )
604 return FALSE;
605
606 m_splitMode = wxSPLIT_HORIZONTAL;
607 m_windowOne = window1;
608 m_windowTwo = window2;
609 if ( sashPosition == -1 )
610 m_sashPosition = 100;
611 else
612 m_sashPosition = sashPosition;
613
614 SizeWindows();
615
616 return TRUE;
617 }
618
619
620 // Remove the specified (or second) window from the view
621 // Doesn't actually delete the window.
622 bool wxSplitterWindow::Unsplit(wxWindow *toRemove)
623 {
624 if ( ! IsSplit() )
625 return FALSE;
626
627 if ( toRemove == NULL || toRemove == m_windowTwo)
628 {
629 wxWindow *win = m_windowTwo ;
630 m_windowTwo = (wxWindow *) NULL;
631 m_sashPosition = 0;
632 OnUnsplit(win);
633 SizeWindows();
634 }
635 else if ( toRemove == m_windowOne )
636 {
637 wxWindow *win = m_windowOne ;
638 m_windowOne = m_windowTwo;
639 m_windowTwo = (wxWindow *) NULL;
640 m_sashPosition = 0;
641 OnUnsplit(win);
642 SizeWindows();
643 }
644 else
645 return FALSE;
646
647 return TRUE;
648 }
649
650 void wxSplitterWindow::SetSashPosition(int position, bool redraw)
651 {
652 m_sashPosition = position;
653
654 if ( redraw )
655 {
656 SizeWindows();
657 }
658 }
659
660 // Called when the sash is double-clicked.
661 // The default behaviour is to remove the sash if the
662 // minimum pane size is zero.
663 void wxSplitterWindow::OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y) )
664 {
665 if ( GetMinimumPaneSize() == 0 )
666 {
667 Unsplit();
668 }
669 }
670
671 // Initialize colours
672 void wxSplitterWindow::InitColours(void)
673 {
674 if ( m_facePen )
675 delete m_facePen;
676 if ( m_faceBrush )
677 delete m_faceBrush;
678 if ( m_mediumShadowPen )
679 delete m_mediumShadowPen;
680 if ( m_darkShadowPen )
681 delete m_darkShadowPen;
682 if ( m_lightShadowPen )
683 delete m_lightShadowPen;
684 if ( m_hilightPen )
685 delete m_hilightPen;
686
687 // Shadow colours
688 #if defined(__WIN95__)
689 // COLORREF ref = ::GetSysColor(COLOR_3DFACE); // Normally light grey
690 wxColour faceColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
691 m_facePen = new wxPen(faceColour, 1, wxSOLID);
692 m_faceBrush = new wxBrush(faceColour, wxSOLID);
693
694 // ref = ::GetSysColor(COLOR_3DSHADOW); // Normally dark grey
695 wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
696 m_mediumShadowPen = new wxPen(mediumShadowColour, 1, wxSOLID);
697
698 // ref = ::GetSysColor(COLOR_3DDKSHADOW); // Normally black
699 wxColour darkShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW));
700 m_darkShadowPen = new wxPen(darkShadowColour, 1, wxSOLID);
701
702 // ref = ::GetSysColor(COLOR_3DLIGHT); // Normally light grey
703 wxColour lightShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT));
704 m_lightShadowPen = new wxPen(lightShadowColour, 1, wxSOLID);
705
706 // ref = ::GetSysColor(COLOR_3DHILIGHT); // Normally white
707 wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
708 m_hilightPen = new wxPen(hilightColour, 1, wxSOLID);
709 #else
710 m_facePen = new wxPen("LIGHT GREY", 1, wxSOLID);
711 m_faceBrush = new wxBrush("LIGHT GREY", wxSOLID);
712 m_mediumShadowPen = new wxPen("GREY", 1, wxSOLID);
713 m_darkShadowPen = new wxPen("BLACK", 1, wxSOLID);
714 m_lightShadowPen = new wxPen("LIGHT GREY", 1, wxSOLID);
715 m_hilightPen = new wxPen("WHITE", 1, wxSOLID);
716 #endif
717 }
718