]> git.saurik.com Git - wxWidgets.git/blame - src/generic/sashwin.cpp
don't assert if MsgWaitForMultipleObjects() returns WAIT_OBJECT_0 but there are no...
[wxWidgets.git] / src / generic / sashwin.cpp
CommitLineData
a6d70308 1/////////////////////////////////////////////////////////////////////////////
ed4b0fdc 2// Name: src/generic/sashwin.cpp
a6d70308
JS
3// Purpose: wxSashWindow implementation. A sash window has an optional
4// sash on each edge, allowing it to be dragged. An event
5// is generated when the sash is released.
6// Author: Julian Smart
7// Modified by:
8// Created: 01/02/97
9// RCS-ID: $Id$
10// Copyright: (c) Julian Smart
65571936 11// Licence: wxWindows licence
a6d70308
JS
12/////////////////////////////////////////////////////////////////////////////
13
a6d70308
JS
14// For compilers that support precompilation, includes "wx.h".
15#include "wx/wxprec.h"
16
17#ifdef __BORLANDC__
ed4b0fdc 18 #pragma hdrstop
a6d70308
JS
19#endif
20
1e6feb95
VZ
21#if wxUSE_SASH
22
11dbb4bf
WS
23#include "wx/sashwin.h"
24
a6d70308 25#ifndef WX_PRECOMP
04dbb646
VZ
26 #include "wx/dialog.h"
27 #include "wx/frame.h"
28 #include "wx/settings.h"
ed4b0fdc 29 #include "wx/dcclient.h"
11dbb4bf 30 #include "wx/dcscreen.h"
18680f86 31 #include "wx/math.h"
a6d70308
JS
32#endif
33
a6d70308
JS
34#include <stdlib.h>
35
f9b1708c 36#include "wx/laywin.h"
a6d70308 37
32956769
JS
38DEFINE_EVENT_TYPE(wxEVT_SASH_DRAGGED)
39
a6d70308
JS
40IMPLEMENT_DYNAMIC_CLASS(wxSashWindow, wxWindow)
41IMPLEMENT_DYNAMIC_CLASS(wxSashEvent, wxCommandEvent)
42
43BEGIN_EVENT_TABLE(wxSashWindow, wxWindow)
44 EVT_PAINT(wxSashWindow::OnPaint)
45 EVT_SIZE(wxSashWindow::OnSize)
46 EVT_MOUSE_EVENTS(wxSashWindow::OnMouseEvent)
64407854 47#if defined( __WXMSW__ ) || defined( __WXMAC__)
2b5f62a0 48 EVT_SET_CURSOR(wxSashWindow::OnSetCursor)
ed4b0fdc 49#endif // __WXMSW__ || __WXMAC__
2b5f62a0 50
a6d70308 51END_EVENT_TABLE()
a6d70308 52
f6bcfd97
BP
53bool wxSashWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
54 const wxSize& size, long style, const wxString& name)
a6d70308 55{
f6bcfd97
BP
56 return wxWindow::Create(parent, id, pos, size, style, name);
57}
a6d70308 58
f6bcfd97
BP
59wxSashWindow::~wxSashWindow()
60{
61 delete m_sashCursorWE;
62 delete m_sashCursorNS;
a6d70308
JS
63}
64
f6bcfd97 65void wxSashWindow::Init()
a6d70308
JS
66{
67 m_draggingEdge = wxSASH_NONE;
68 m_dragMode = wxSASH_DRAG_NONE;
69 m_oldX = 0;
70 m_oldY = 0;
71 m_firstX = 0;
72 m_firstY = 0;
73 m_borderSize = 3;
74 m_extraBorderSize = 0;
75 m_minimumPaneSizeX = 0;
76 m_minimumPaneSizeY = 0;
f66b7050
MR
77 m_maximumPaneSizeX = 10000;
78 m_maximumPaneSizeY = 10000;
a6d70308
JS
79 m_sashCursorWE = new wxCursor(wxCURSOR_SIZEWE);
80 m_sashCursorNS = new wxCursor(wxCURSOR_SIZENS);
ca65c044 81 m_mouseCaptured = false;
2b5f62a0 82 m_currentCursor = NULL;
a6d70308
JS
83
84 // Eventually, we'll respond to colour change messages
85 InitColours();
86}
87
a6d70308
JS
88void wxSashWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
89{
90 wxPaintDC dc(this);
91
ee4c6942 92 DrawBorders(dc);
a6d70308
JS
93 DrawSashes(dc);
94}
95
96void wxSashWindow::OnMouseEvent(wxMouseEvent& event)
97{
8d7eaf91 98 wxCoord x = 0, y = 0;
cfeb83fd 99 event.GetPosition(&x, &y);
a6d70308
JS
100
101 wxSashEdgePosition sashHit = SashHitTest(x, y);
102
a1b82138
VZ
103 if (event.LeftDown())
104 {
9f334bea 105 CaptureMouse();
ca65c044 106 m_mouseCaptured = true;
9f334bea 107
a6d70308
JS
108 if ( sashHit != wxSASH_NONE )
109 {
a1b82138 110 // Required for X to specify that
b412f9be
JS
111 // that we wish to draw on top of all windows
112 // - and we optimise by specifying the area
113 // for creating the overlap window.
114 // Find the first frame or dialog and use this to specify
115 // the area to draw on.
116 wxWindow* parent = this;
117
118 while (parent && !parent->IsKindOf(CLASSINFO(wxDialog)) &&
119 !parent->IsKindOf(CLASSINFO(wxFrame)))
120 parent = parent->GetParent();
121
122 wxScreenDC::StartDrawingOnTop(parent);
a6d70308
JS
123
124 // We don't say we're dragging yet; we leave that
125 // decision for the Dragging() branch, to ensure
126 // the user has dragged a little bit.
127 m_dragMode = wxSASH_DRAG_LEFT_DOWN;
128 m_draggingEdge = sashHit;
129 m_firstX = x;
130 m_firstY = y;
9f334bea
JS
131
132 if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) )
133 {
2b5f62a0
VZ
134 if (m_currentCursor != m_sashCursorWE)
135 {
136 SetCursor(*m_sashCursorWE);
137 }
138 m_currentCursor = m_sashCursorWE;
9f334bea
JS
139 }
140 else
141 {
2b5f62a0
VZ
142 if (m_currentCursor != m_sashCursorNS)
143 {
144 SetCursor(*m_sashCursorNS);
145 }
146 m_currentCursor = m_sashCursorNS;
9f334bea 147 }
a6d70308 148 }
a1b82138 149 }
a6d70308
JS
150 else if ( event.LeftUp() && m_dragMode == wxSASH_DRAG_LEFT_DOWN )
151 {
152 // Wasn't a proper drag
40fab78b
JS
153 if (m_mouseCaptured)
154 ReleaseMouse();
ca65c044 155 m_mouseCaptured = false;
40fab78b 156
a6d70308
JS
157 wxScreenDC::EndDrawingOnTop();
158 m_dragMode = wxSASH_DRAG_NONE;
159 m_draggingEdge = wxSASH_NONE;
a6d70308 160 }
a1b82138
VZ
161 else if (event.LeftUp() && m_dragMode == wxSASH_DRAG_DRAGGING)
162 {
a6d70308
JS
163 // We can stop dragging now and see what we've got.
164 m_dragMode = wxSASH_DRAG_NONE;
40fab78b
JS
165 if (m_mouseCaptured)
166 ReleaseMouse();
ca65c044 167 m_mouseCaptured = false;
40fab78b 168
a6d70308
JS
169 // Erase old tracker
170 DrawSashTracker(m_draggingEdge, m_oldX, m_oldY);
171
172 // End drawing on top (frees the window used for drawing
173 // over the screen)
174 wxScreenDC::EndDrawingOnTop();
175
176 int w, h;
a1b82138 177 GetSize(&w, &h);
a6d70308 178 int xp, yp;
a1b82138 179 GetPosition(&xp, &yp);
a6d70308
JS
180
181 wxSashEdgePosition edge = m_draggingEdge;
182 m_draggingEdge = wxSASH_NONE;
183
184 wxRect dragRect;
185 wxSashDragStatus status = wxSASH_STATUS_OK;
a1b82138
VZ
186
187 // the new height and width of the window - if -1, it didn't change
422d0ff0
WS
188 int newHeight = wxDefaultCoord,
189 newWidth = wxDefaultCoord;
a1b82138
VZ
190
191 // NB: x and y may be negative and they're relative to the sash window
192 // upper left corner, while xp and yp are expressed in the parent
193 // window system of coordinates, so adjust them! After this
194 // adjustment, all coordinates are relative to the parent window.
195 y += yp;
196 x += xp;
197
a6d70308
JS
198 switch (edge)
199 {
200 case wxSASH_TOP:
a1b82138
VZ
201 if ( y > yp + h )
202 {
203 // top sash shouldn't get below the bottom one
a6d70308 204 status = wxSASH_STATUS_OUT_OF_RANGE;
a1b82138
VZ
205 }
206 else
207 {
208 newHeight = h - (y - yp);
209 }
a6d70308 210 break;
a1b82138 211
a6d70308 212 case wxSASH_BOTTOM:
a1b82138
VZ
213 if ( y < yp )
214 {
215 // bottom sash shouldn't get above the top one
a6d70308 216 status = wxSASH_STATUS_OUT_OF_RANGE;
a1b82138
VZ
217 }
218 else
219 {
220 newHeight = y - yp;
221 }
a6d70308 222 break;
a1b82138 223
a6d70308 224 case wxSASH_LEFT:
a1b82138
VZ
225 if ( x > xp + w )
226 {
227 // left sash shouldn't get beyond the right one
a6d70308 228 status = wxSASH_STATUS_OUT_OF_RANGE;
a1b82138
VZ
229 }
230 else
231 {
232 newWidth = w - (x - xp);
233 }
a6d70308 234 break;
a1b82138 235
a6d70308 236 case wxSASH_RIGHT:
a1b82138
VZ
237 if ( x < xp )
238 {
239 // and the right sash, finally, shouldn't be beyond the
240 // left one
a6d70308 241 status = wxSASH_STATUS_OUT_OF_RANGE;
a1b82138
VZ
242 }
243 else
244 {
245 newWidth = x - xp;
246 }
a6d70308 247 break;
a1b82138
VZ
248
249 case wxSASH_NONE:
250 // can this happen at all?
251 break;
252 }
253
422d0ff0 254 if ( newHeight == wxDefaultCoord )
a1b82138
VZ
255 {
256 // didn't change
257 newHeight = h;
258 }
259 else
260 {
261 // make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range
262 newHeight = wxMax(newHeight, m_minimumPaneSizeY);
263 newHeight = wxMin(newHeight, m_maximumPaneSizeY);
a6d70308
JS
264 }
265
422d0ff0 266 if ( newWidth == wxDefaultCoord )
a1b82138
VZ
267 {
268 // didn't change
269 newWidth = w;
270 }
271 else
272 {
273 // make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range
274 newWidth = wxMax(newWidth, m_minimumPaneSizeX);
275 newWidth = wxMin(newWidth, m_maximumPaneSizeX);
276 }
277
278 dragRect = wxRect(x, y, newWidth, newHeight);
279
4e115ed2
VZ
280 wxSashEvent eventSash(GetId(), edge);
281 eventSash.SetEventObject(this);
282 eventSash.SetDragStatus(status);
283 eventSash.SetDragRect(dragRect);
284 GetEventHandler()->ProcessEvent(eventSash);
a1b82138 285 }
9f334bea
JS
286 else if ( event.LeftUp() )
287 {
40fab78b
JS
288 if (m_mouseCaptured)
289 ReleaseMouse();
ca65c044 290 m_mouseCaptured = false;
9f334bea 291 }
52bbf260 292 else if ((event.Moving() || event.Leaving()) && !event.Dragging())
a1b82138 293 {
a6d70308
JS
294 // Just change the cursor if required
295 if ( sashHit != wxSASH_NONE )
296 {
a1b82138
VZ
297 if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) )
298 {
2b5f62a0
VZ
299 if (m_currentCursor != m_sashCursorWE)
300 {
301 SetCursor(*m_sashCursorWE);
302 }
303 m_currentCursor = m_sashCursorWE;
a1b82138
VZ
304 }
305 else
306 {
2b5f62a0
VZ
307 if (m_currentCursor != m_sashCursorNS)
308 {
309 SetCursor(*m_sashCursorNS);
310 }
311 m_currentCursor = m_sashCursorNS;
a1b82138
VZ
312 }
313 }
c0bcc480
JS
314 else
315 {
8a9c2246 316 SetCursor(wxNullCursor);
2b5f62a0 317 m_currentCursor = NULL;
c0bcc480 318 }
a1b82138
VZ
319 }
320 else if ( event.Dragging() &&
321 ((m_dragMode == wxSASH_DRAG_DRAGGING) ||
322 (m_dragMode == wxSASH_DRAG_LEFT_DOWN)) )
323 {
324 if ( (m_draggingEdge == wxSASH_LEFT) || (m_draggingEdge == wxSASH_RIGHT) )
325 {
2b5f62a0
VZ
326 if (m_currentCursor != m_sashCursorWE)
327 {
328 SetCursor(*m_sashCursorWE);
329 }
330 m_currentCursor = m_sashCursorWE;
a1b82138
VZ
331 }
332 else
333 {
2b5f62a0
VZ
334 if (m_currentCursor != m_sashCursorNS)
335 {
336 SetCursor(*m_sashCursorNS);
337 }
338 m_currentCursor = m_sashCursorNS;
a6d70308 339 }
a6d70308
JS
340
341 if (m_dragMode == wxSASH_DRAG_LEFT_DOWN)
342 {
343 m_dragMode = wxSASH_DRAG_DRAGGING;
344 DrawSashTracker(m_draggingEdge, x, y);
345 }
346 else
347 {
a1b82138
VZ
348 if ( m_dragMode == wxSASH_DRAG_DRAGGING )
349 {
350 // Erase old tracker
351 DrawSashTracker(m_draggingEdge, m_oldX, m_oldY);
a6d70308 352
a1b82138
VZ
353 // Draw new one
354 DrawSashTracker(m_draggingEdge, x, y);
355 }
a6d70308
JS
356 }
357 m_oldX = x;
358 m_oldY = y;
a1b82138 359 }
a6d70308
JS
360 else if ( event.LeftDClick() )
361 {
362 // Nothing
363 }
364 else
365 {
366 }
367}
368
369void wxSashWindow::OnSize(wxSizeEvent& WXUNUSED(event))
370{
371 SizeWindows();
372}
373
341287bf 374wxSashEdgePosition wxSashWindow::SashHitTest(int x, int y, int WXUNUSED(tolerance))
a6d70308
JS
375{
376 int cx, cy;
377 GetClientSize(& cx, & cy);
378
379 int i;
380 for (i = 0; i < 4; i++)
381 {
382 wxSashEdge& edge = m_sashes[i];
383 wxSashEdgePosition position = (wxSashEdgePosition) i ;
384
385 if (edge.m_show)
386 {
387 switch (position)
388 {
389 case wxSASH_TOP:
390 {
391 if (y >= 0 && y <= GetEdgeMargin(position))
392 return wxSASH_TOP;
393 break;
394 }
395 case wxSASH_RIGHT:
396 {
397 if ((x >= cx - GetEdgeMargin(position)) && (x <= cx))
398 return wxSASH_RIGHT;
399 break;
400 }
401 case wxSASH_BOTTOM:
402 {
403 if ((y >= cy - GetEdgeMargin(position)) && (y <= cy))
404 return wxSASH_BOTTOM;
405 break;
406 }
407 case wxSASH_LEFT:
408 {
82540ef2 409 if ((x <= GetEdgeMargin(position)) && (x >= 0))
a6d70308
JS
410 return wxSASH_LEFT;
411 break;
412 }
341287bf
JS
413 case wxSASH_NONE:
414 {
415 break;
416 }
a6d70308
JS
417 }
418 }
419 }
420 return wxSASH_NONE;
421}
422
423// Draw 3D effect borders
424void wxSashWindow::DrawBorders(wxDC& dc)
425{
426 int w, h;
427 GetClientSize(&w, &h);
428
04ee05f9
PC
429 wxPen mediumShadowPen(m_mediumShadowColour, 1, wxPENSTYLE_SOLID);
430 wxPen darkShadowPen(m_darkShadowColour, 1, wxPENSTYLE_SOLID);
431 wxPen lightShadowPen(m_lightShadowColour, 1, wxPENSTYLE_SOLID);
432 wxPen hilightPen(m_hilightColour, 1, wxPENSTYLE_SOLID);
a6d70308 433
f6bcfd97 434 if ( GetWindowStyleFlag() & wxSW_3DBORDER )
a6d70308
JS
435 {
436 dc.SetPen(mediumShadowPen);
437 dc.DrawLine(0, 0, w-1, 0);
438 dc.DrawLine(0, 0, 0, h - 1);
439
440 dc.SetPen(darkShadowPen);
441 dc.DrawLine(1, 1, w-2, 1);
442 dc.DrawLine(1, 1, 1, h-2);
443
444 dc.SetPen(hilightPen);
445 dc.DrawLine(0, h-1, w-1, h-1);
446 dc.DrawLine(w-1, 0, w-1, h); // Surely the maximum y pos. should be h - 1.
447 /// Anyway, h is required for MSW.
448
449 dc.SetPen(lightShadowPen);
450 dc.DrawLine(w-2, 1, w-2, h-2); // Right hand side
451 dc.DrawLine(1, h-2, w-1, h-2); // Bottom
452 }
448af9a4 453 else if ( GetWindowStyleFlag() & wxSW_BORDER )
a6d70308
JS
454 {
455 dc.SetBrush(*wxTRANSPARENT_BRUSH);
456 dc.SetPen(*wxBLACK_PEN);
457 dc.DrawRectangle(0, 0, w-1, h-1);
458 }
459
460 dc.SetPen(wxNullPen);
461 dc.SetBrush(wxNullBrush);
462}
463
464void wxSashWindow::DrawSashes(wxDC& dc)
465{
466 int i;
467 for (i = 0; i < 4; i++)
468 if (m_sashes[i].m_show)
469 DrawSash((wxSashEdgePosition) i, dc);
470}
471
472// Draw the sash
473void wxSashWindow::DrawSash(wxSashEdgePosition edge, wxDC& dc)
474{
475 int w, h;
476 GetClientSize(&w, &h);
477
04ee05f9
PC
478 wxPen facePen(m_faceColour, 1, wxPENSTYLE_SOLID);
479 wxBrush faceBrush(m_faceColour, wxBRUSHSTYLE_SOLID);
480 wxPen mediumShadowPen(m_mediumShadowColour, 1, wxPENSTYLE_SOLID);
481 wxPen darkShadowPen(m_darkShadowColour, 1, wxPENSTYLE_SOLID);
482 wxPen lightShadowPen(m_lightShadowColour, 1, wxPENSTYLE_SOLID);
483 wxPen hilightPen(m_hilightColour, 1, wxPENSTYLE_SOLID);
42841dfc
WS
484 wxColour blackClr(0, 0, 0);
485 wxColour whiteClr(255, 255, 255);
04ee05f9
PC
486 wxPen blackPen(blackClr, 1, wxPENSTYLE_SOLID);
487 wxPen whitePen(whiteClr, 1, wxPENSTYLE_SOLID);
a6d70308
JS
488
489 if ( edge == wxSASH_LEFT || edge == wxSASH_RIGHT )
490 {
999836aa 491 int sashPosition = (edge == wxSASH_LEFT) ? 0 : ( w - GetEdgeMargin(edge) );
a6d70308
JS
492
493 dc.SetPen(facePen);
494 dc.SetBrush(faceBrush);
495 dc.DrawRectangle(sashPosition, 0, GetEdgeMargin(edge), h);
496
f6bcfd97 497 if (GetWindowStyleFlag() & wxSW_3DSASH)
a6d70308
JS
498 {
499 if (edge == wxSASH_LEFT)
500 {
d0b223a1 501 // Draw a dark grey line on the left to indicate that the
a6d70308 502 // sash is raised
d0b223a1 503 dc.SetPen(mediumShadowPen);
a6d70308
JS
504 dc.DrawLine(GetEdgeMargin(edge), 0, GetEdgeMargin(edge), h);
505 }
506 else
507 {
f6bcfd97 508 // Draw a highlight line on the right to indicate that the
a6d70308 509 // sash is raised
f6bcfd97 510 dc.SetPen(hilightPen);
a6d70308
JS
511 dc.DrawLine(w - GetEdgeMargin(edge), 0, w - GetEdgeMargin(edge), h);
512 }
513 }
514 }
515 else // top or bottom
516 {
999836aa 517 int sashPosition = (edge == wxSASH_TOP) ? 0 : ( h - GetEdgeMargin(edge) );
a6d70308
JS
518
519 dc.SetPen(facePen);
520 dc.SetBrush(faceBrush);
521 dc.DrawRectangle(0, sashPosition, w, GetEdgeMargin(edge));
522
f6bcfd97 523 if (GetWindowStyleFlag() & wxSW_3DSASH)
a6d70308
JS
524 {
525 if (edge == wxSASH_BOTTOM)
526 {
f6bcfd97 527 // Draw a highlight line on the bottom to indicate that the
a6d70308 528 // sash is raised
f6bcfd97 529 dc.SetPen(hilightPen);
058939fc 530 dc.DrawLine(0, h - GetEdgeMargin(edge), w, h - GetEdgeMargin(edge));
a6d70308
JS
531 }
532 else
533 {
d0b223a1 534 // Draw a drak grey line on the top to indicate that the
a6d70308 535 // sash is raised
d0b223a1 536 dc.SetPen(mediumShadowPen);
c0bcc480 537 dc.DrawLine(1, GetEdgeMargin(edge), w-1, GetEdgeMargin(edge));
a6d70308
JS
538 }
539 }
540 }
541
542 dc.SetPen(wxNullPen);
543 dc.SetBrush(wxNullBrush);
544}
545
546// Draw the sash tracker (for whilst moving the sash)
547void wxSashWindow::DrawSashTracker(wxSashEdgePosition edge, int x, int y)
548{
549 int w, h;
550 GetClientSize(&w, &h);
551
552 wxScreenDC screenDC;
553 int x1, y1;
554 int x2, y2;
555
556 if ( edge == wxSASH_LEFT || edge == wxSASH_RIGHT )
557 {
558 x1 = x; y1 = 2;
559 x2 = x; y2 = h-2;
560
561 if ( (edge == wxSASH_LEFT) && (x1 > w) )
562 {
563 x1 = w; x2 = w;
564 }
565 else if ( (edge == wxSASH_RIGHT) && (x1 < 0) )
566 {
567 x1 = 0; x2 = 0;
568 }
569 }
570 else
571 {
572 x1 = 2; y1 = y;
573 x2 = w-2; y2 = y;
574
575 if ( (edge == wxSASH_TOP) && (y1 > h) )
576 {
577 y1 = h;
578 y2 = h;
579 }
580 else if ( (edge == wxSASH_BOTTOM) && (y1 < 0) )
581 {
582 y1 = 0;
583 y2 = 0;
584 }
585 }
586
587 ClientToScreen(&x1, &y1);
588 ClientToScreen(&x2, &y2);
589
04ee05f9 590 wxPen sashTrackerPen(*wxBLACK, 2, wxPENSTYLE_SOLID);
a6d70308 591
3c679789 592 screenDC.SetLogicalFunction(wxINVERT);
a6d70308
JS
593 screenDC.SetPen(sashTrackerPen);
594 screenDC.SetBrush(*wxTRANSPARENT_BRUSH);
595
596 screenDC.DrawLine(x1, y1, x2, y2);
597
598 screenDC.SetLogicalFunction(wxCOPY);
599
600 screenDC.SetPen(wxNullPen);
601 screenDC.SetBrush(wxNullBrush);
602}
603
604// Position and size subwindows.
605// Note that the border size applies to each subwindow, not
606// including the edges next to the sash.
607void wxSashWindow::SizeWindows()
608{
609 int cw, ch;
610 GetClientSize(&cw, &ch);
611
b1d4dd7a 612 if (GetChildren().GetCount() == 1)
a6d70308 613 {
b1d4dd7a 614 wxWindow* child = GetChildren().GetFirst()->GetData();
a6d70308
JS
615
616 int x = 0;
617 int y = 0;
618 int width = cw;
619 int height = ch;
620
621 // Top
622 if (m_sashes[0].m_show)
623 {
624 y = m_borderSize;
625 height -= m_borderSize;
626 }
627 y += m_extraBorderSize;
628
629 // Left
630 if (m_sashes[3].m_show)
631 {
632 x = m_borderSize;
633 width -= m_borderSize;
634 }
635 x += m_extraBorderSize;
636
637 // Right
638 if (m_sashes[1].m_show)
639 {
640 width -= m_borderSize;
641 }
642 width -= 2*m_extraBorderSize;
643
644 // Bottom
645 if (m_sashes[2].m_show)
646 {
647 height -= m_borderSize;
648 }
649 height -= 2*m_extraBorderSize;
650
651 child->SetSize(x, y, width, height);
652 }
b1d4dd7a 653 else if (GetChildren().GetCount() > 1)
f9b1708c
JS
654 {
655 // Perhaps multiple children are themselves sash windows.
656 // TODO: this doesn't really work because the subwindows sizes/positions
657 // must be set to leave a gap for the parent's sash (hit-test and decorations).
658 // Perhaps we can allow for this within LayoutWindow, testing whether the parent
659 // is a sash window, and if so, allowing some space for the edges.
660 wxLayoutAlgorithm layout;
661 layout.LayoutWindow(this);
662 }
a6d70308
JS
663
664 wxClientDC dc(this);
665 DrawBorders(dc);
666 DrawSashes(dc);
667}
668
669// Initialize colours
670void wxSashWindow::InitColours()
671{
672 // Shadow colours
a756f210
VS
673 m_faceColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
674 m_mediumShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW);
675 m_darkShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW);
676 m_lightShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
677 m_hilightColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT);
a6d70308
JS
678}
679
680void wxSashWindow::SetSashVisible(wxSashEdgePosition edge, bool sash)
681{
682 m_sashes[edge].m_show = sash;
683 if (sash)
684 m_sashes[edge].m_margin = m_borderSize;
685 else
686 m_sashes[edge].m_margin = 0;
687}
688
64407854 689#if defined( __WXMSW__ ) || defined( __WXMAC__)
2b5f62a0
VZ
690
691// this is currently called (and needed) under MSW only...
692void wxSashWindow::OnSetCursor(wxSetCursorEvent& event)
693{
694 // if we don't do it, the resizing cursor might be set for child window:
695 // and like this we explicitly say that our cursor should not be used for
696 // children windows which overlap us
697
698 if ( SashHitTest(event.GetX(), event.GetY()) != wxSASH_NONE)
699 {
700 // default processing is ok
701 event.Skip();
702 }
703 //else: do nothing, in particular, don't call Skip()
704}
705
ed4b0fdc 706#endif // __WXMSW__ || __WXMAC__
2b5f62a0 707
75be3f5e 708#endif // wxUSE_SASH