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