]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/window.cpp
fixed casting for X
[wxWidgets.git] / src / mac / carbon / window.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: windows.cpp
3// Purpose: wxWindowMac
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "window.h"
14#endif
15
16#include "wx/setup.h"
17#include "wx/menu.h"
18#include "wx/window.h"
19#include "wx/dc.h"
20#include "wx/dcclient.h"
21#include "wx/utils.h"
22#include "wx/app.h"
23#include "wx/panel.h"
24#include "wx/layout.h"
25#include "wx/dialog.h"
26#include "wx/listbox.h"
27#include "wx/scrolbar.h"
28#include "wx/statbox.h"
29#include "wx/button.h"
30#include "wx/settings.h"
31#include "wx/msgdlg.h"
32#include "wx/frame.h"
33#include "wx/notebook.h"
34#include "wx/tabctrl.h"
35#include "wx/tooltip.h"
36#include "wx/statusbr.h"
37#include "wx/menuitem.h"
38#include "wx/spinctrl.h"
39#include "wx/log.h"
40
41#if wxUSE_CARET
42 #include "wx/caret.h"
43#endif // wxUSE_CARET
44
45#define wxWINDOW_HSCROLL 5998
46#define wxWINDOW_VSCROLL 5997
47#define MAC_SCROLLBAR_SIZE 16
48
49#include "wx/mac/uma.h"
50#ifndef __DARWIN__
51#include <Windows.h>
52#include <ToolUtils.h>
53#endif
54
55#if wxUSE_DRAG_AND_DROP
56#include "wx/dnd.h"
57#endif
58
59#include <string.h>
60
61extern wxList wxPendingDelete;
62wxWindowMac* gFocusWindow = NULL ;
63
64#ifdef __WXUNIVERSAL__
65 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
66#else // __WXMAC__
67 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
68#endif // __WXUNIVERSAL__/__WXMAC__
69
70#if !USE_SHARED_LIBRARY
71
72BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
73 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
74 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
75 EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
76 EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
77 EVT_IDLE(wxWindowMac::OnIdle)
78 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
79END_EVENT_TABLE()
80
81#endif
82
83#define wxMAC_DEBUG_REDRAW 0
84#ifndef wxMAC_DEBUG_REDRAW
85#define wxMAC_DEBUG_REDRAW 0
86#endif
87
88#define wxMAC_USE_THEME_BORDER 0
89
90
91// ===========================================================================
92// implementation
93// ===========================================================================
94
95
96// ----------------------------------------------------------------------------
97// constructors and such
98// ----------------------------------------------------------------------------
99
100void wxWindowMac::Init()
101{
102 // generic
103 InitBase();
104
105 // MSW specific
106 m_doubleClickAllowed = 0;
107 m_winCaptured = FALSE;
108
109 m_isBeingDeleted = FALSE;
110
111 m_useCtl3D = FALSE;
112 m_mouseInWindow = FALSE;
113
114 m_xThumbSize = 0;
115 m_yThumbSize = 0;
116 m_backgroundTransparent = FALSE;
117
118 // as all windows are created with WS_VISIBLE style...
119 m_isShown = TRUE;
120
121 m_x = 0;
122 m_y = 0 ;
123 m_width = 0 ;
124 m_height = 0 ;
125
126 m_hScrollBar = NULL ;
127 m_vScrollBar = NULL ;
128
129 m_label = wxEmptyString;
130}
131
132// Destructor
133wxWindowMac::~wxWindowMac()
134{
135 // deleting a window while it is shown invalidates the region
136 if ( IsShown() ) {
137 wxWindowMac* iter = this ;
138 while( iter ) {
139 if ( iter->IsTopLevel() )
140 {
141 Refresh() ;
142 break ;
143 }
144 iter = iter->GetParent() ;
145
146 }
147 }
148
149 m_isBeingDeleted = TRUE;
150
151 if ( s_lastMouseWindow == this )
152 {
153 s_lastMouseWindow = NULL ;
154 }
155
156 if ( gFocusWindow == this )
157 {
158 gFocusWindow = NULL ;
159 }
160
161 if ( m_parent )
162 m_parent->RemoveChild(this);
163
164 DestroyChildren();
165}
166
167// Constructor
168bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
169 const wxPoint& pos,
170 const wxSize& size,
171 long style,
172 const wxString& name)
173{
174 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
175
176 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
177 return FALSE;
178
179 parent->AddChild(this);
180
181 m_x = (int)pos.x;
182 m_y = (int)pos.y;
183 AdjustForParentClientOrigin(m_x, m_y, wxSIZE_USE_EXISTING);
184 m_width = WidthDefault( size.x );
185 m_height = HeightDefault( size.y ) ;
186#ifndef __WXUNIVERSAL__
187 if ( ! IsKindOf( CLASSINFO ( wxControl ) ) && ! IsKindOf( CLASSINFO( wxStatusBar ) ) )
188 {
189 MacCreateScrollBars( style ) ;
190 }
191#endif
192 return TRUE;
193}
194
195void wxWindowMac::SetFocus()
196{
197 if ( gFocusWindow == this )
198 return ;
199
200 if ( AcceptsFocus() )
201 {
202 if (gFocusWindow )
203 {
204 #if wxUSE_CARET
205 // Deal with caret
206 if ( gFocusWindow->m_caret )
207 {
208 gFocusWindow->m_caret->OnKillFocus();
209 }
210 #endif // wxUSE_CARET
211 #ifndef __WXUNIVERSAL__
212 wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ;
213 if ( control && control->GetMacControl() )
214 {
215 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNoPart ) ;
216 control->MacRedrawControl() ;
217 }
218 #endif
219 wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId);
220 event.SetEventObject(gFocusWindow);
221 gFocusWindow->GetEventHandler()->ProcessEvent(event) ;
222 }
223 gFocusWindow = this ;
224 {
225 #if wxUSE_CARET
226 // Deal with caret
227 if ( m_caret )
228 {
229 m_caret->OnSetFocus();
230 }
231 #endif // wxUSE_CARET
232 // panel wants to track the window which was the last to have focus in it
233 wxChildFocusEvent eventFocus(this);
234 GetEventHandler()->ProcessEvent(eventFocus);
235
236 #ifndef __WXUNIVERSAL__
237 wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ;
238 if ( control && control->GetMacControl() )
239 {
240 UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlEditTextPart ) ;
241 }
242 #endif
243 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
244 event.SetEventObject(this);
245 GetEventHandler()->ProcessEvent(event) ;
246 }
247 }
248}
249
250bool wxWindowMac::Enable(bool enable)
251{
252 if ( !wxWindowBase::Enable(enable) )
253 return FALSE;
254
255 MacSuperEnabled( enable ) ;
256
257 return TRUE;
258}
259
260void wxWindowMac::DoCaptureMouse()
261{
262 wxTheApp->s_captureWindow = this ;
263}
264
265wxWindow* wxWindowBase::GetCapture()
266{
267 return wxTheApp->s_captureWindow ;
268}
269
270void wxWindowMac::DoReleaseMouse()
271{
272 wxTheApp->s_captureWindow = NULL ;
273}
274
275#if wxUSE_DRAG_AND_DROP
276
277void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
278{
279 if ( m_dropTarget != 0 ) {
280 delete m_dropTarget;
281 }
282
283 m_dropTarget = pDropTarget;
284 if ( m_dropTarget != 0 )
285 {
286 // TODO
287 }
288}
289
290#endif
291
292// Old style file-manager drag&drop
293void wxWindowMac::DragAcceptFiles(bool accept)
294{
295 // TODO
296}
297
298// Get total size
299void wxWindowMac::DoGetSize(int *x, int *y) const
300{
301 if(x) *x = m_width ;
302 if(y) *y = m_height ;
303}
304
305void wxWindowMac::DoGetPosition(int *x, int *y) const
306{
307 int xx,yy;
308
309 xx = m_x ;
310 yy = m_y ;
311 if ( !IsTopLevel() && GetParent())
312 {
313 wxPoint pt(GetParent()->GetClientAreaOrigin());
314 xx -= pt.x;
315 yy -= pt.y;
316 }
317 if(x) *x = xx;
318 if(y) *y = yy;
319}
320
321#if wxUSE_MENUS
322bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
323{
324 menu->SetInvokingWindow(this);
325 menu->UpdateUI();
326 ClientToScreen( &x , &y ) ;
327
328 ::InsertMenu( (MenuHandle) menu->GetHMenu() , -1 ) ;
329 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;
330 menu->MacMenuSelect( this , TickCount() , HiWord(menuResult) , LoWord(menuResult) ) ;
331 ::DeleteMenu( menu->MacGetMenuId() ) ;
332 menu->SetInvokingWindow(NULL);
333
334 return TRUE;
335}
336#endif
337
338void wxWindowMac::DoScreenToClient(int *x, int *y) const
339{
340 WindowRef window = (WindowRef) MacGetRootWindow() ;
341
342 Point localwhere = {0,0} ;
343
344 if(x) localwhere.h = * x ;
345 if(y) localwhere.v = * y ;
346
347 GrafPtr port ;
348 ::GetPort( &port ) ;
349 ::SetPort( UMAGetWindowPort( window ) ) ;
350 ::GlobalToLocal( &localwhere ) ;
351 ::SetPort( port ) ;
352
353 if(x) *x = localwhere.h ;
354 if(y) *y = localwhere.v ;
355
356 MacRootWindowToWindow( x , y ) ;
357 if ( x )
358 x -= MacGetLeftBorderSize() ;
359 if ( y )
360 y -= MacGetTopBorderSize() ;
361}
362
363void wxWindowMac::DoClientToScreen(int *x, int *y) const
364{
365 WindowRef window = (WindowRef) MacGetRootWindow() ;
366
367 if ( x )
368 x += MacGetLeftBorderSize() ;
369 if ( y )
370 y += MacGetTopBorderSize() ;
371
372 MacWindowToRootWindow( x , y ) ;
373
374 Point localwhere = { 0,0 };
375 if(x) localwhere.h = * x ;
376 if(y) localwhere.v = * y ;
377
378 GrafPtr port ;
379 ::GetPort( &port ) ;
380 ::SetPort( UMAGetWindowPort( window ) ) ;
381
382 ::LocalToGlobal( &localwhere ) ;
383 ::SetPort( port ) ;
384 if(x) *x = localwhere.h ;
385 if(y) *y = localwhere.v ;
386}
387
388void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
389{
390 wxPoint origin = GetClientAreaOrigin() ;
391 if(x) *x += origin.x ;
392 if(y) *y += origin.y ;
393
394 MacWindowToRootWindow( x , y ) ;
395}
396
397void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
398{
399 wxPoint origin = GetClientAreaOrigin() ;
400 MacRootWindowToWindow( x , y ) ;
401 if(x) *x -= origin.x ;
402 if(y) *y -= origin.y ;
403}
404
405void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
406{
407 if ( !IsTopLevel() )
408 {
409 if(x) *x += m_x ;
410 if(y) *y += m_y ;
411 GetParent()->MacWindowToRootWindow( x , y ) ;
412 }
413}
414
415void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
416{
417 if ( !IsTopLevel() )
418 {
419 if(x) *x -= m_x ;
420 if(y) *y -= m_y ;
421 GetParent()->MacRootWindowToWindow( x , y ) ;
422 }
423}
424
425bool wxWindowMac::SetCursor(const wxCursor& cursor)
426{
427 if (m_cursor == cursor)
428 return FALSE;
429
430 if (wxNullCursor == cursor)
431 {
432 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
433 return FALSE ;
434 }
435 else
436 {
437 if ( ! wxWindowBase::SetCursor( cursor ) )
438 return FALSE ;
439 }
440
441 wxASSERT_MSG( m_cursor.Ok(),
442 wxT("cursor must be valid after call to the base version"));
443
444 Point pt ;
445 wxWindowMac *mouseWin ;
446 GetMouse( &pt ) ;
447
448 // Change the cursor NOW if we're within the correct window
449
450 if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) )
451 {
452 if ( mouseWin == this && !wxIsBusy() )
453 {
454 m_cursor.MacInstall() ;
455 }
456 }
457
458 return TRUE ;
459}
460
461
462// Get size *available for subwindows* i.e. excluding menu bar etc.
463void wxWindowMac::DoGetClientSize(int *x, int *y) const
464{
465 int ww, hh;
466 ww = m_width ;
467 hh = m_height ;
468
469 ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
470 hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( );
471
472 if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) )
473 {
474 int x1 = 0 ;
475 int y1 = 0 ;
476 int w = m_width ;
477 int h = m_height ;
478
479 MacClientToRootWindow( &x1 , &y1 ) ;
480 MacClientToRootWindow( &w , &h ) ;
481
482 wxWindowMac *iter = (wxWindowMac*)this ;
483
484 int totW = 10000 , totH = 10000;
485 while( iter )
486 {
487 if ( iter->IsTopLevel() )
488 {
489 totW = iter->m_width ;
490 totH = iter->m_height ;
491 break ;
492 }
493
494 iter = iter->GetParent() ;
495 }
496
497 if (m_hScrollBar && m_hScrollBar->IsShown() )
498 {
499 hh -= MAC_SCROLLBAR_SIZE;
500 if ( h-y1 >= totH )
501 {
502 hh += 1 ;
503 }
504 }
505 if (m_vScrollBar && m_vScrollBar->IsShown() )
506 {
507 ww -= MAC_SCROLLBAR_SIZE;
508 if ( w-x1 >= totW )
509 {
510 ww += 1 ;
511 }
512 }
513 }
514 if(x) *x = ww;
515 if(y) *y = hh;
516}
517
518
519// ----------------------------------------------------------------------------
520// tooltips
521// ----------------------------------------------------------------------------
522
523#if wxUSE_TOOLTIPS
524
525void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
526{
527 wxWindowBase::DoSetToolTip(tooltip);
528
529 if ( m_tooltip )
530 m_tooltip->SetWindow(this);
531}
532
533#endif // wxUSE_TOOLTIPS
534
535void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
536{
537 int former_x = m_x ;
538 int former_y = m_y ;
539 int former_w = m_width ;
540 int former_h = m_height ;
541
542 int actualWidth = width;
543 int actualHeight = height;
544 int actualX = x;
545 int actualY = y;
546
547 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
548 actualWidth = m_minWidth;
549 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
550 actualHeight = m_minHeight;
551 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
552 actualWidth = m_maxWidth;
553 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
554 actualHeight = m_maxHeight;
555
556 bool doMove = false ;
557 bool doResize = false ;
558
559 if ( actualX != former_x || actualY != former_y )
560 {
561 doMove = true ;
562 }
563 if ( actualWidth != former_w || actualHeight != former_h )
564 {
565 doResize = true ;
566 }
567
568 if ( doMove || doResize )
569 {
570 // erase former position
571
572 Refresh() ;
573
574 m_x = actualX ;
575 m_y = actualY ;
576 m_width = actualWidth ;
577 m_height = actualHeight ;
578
579 // erase new position
580
581 Refresh() ;
582 if ( doMove )
583 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
584
585 MacRepositionScrollBars() ;
586 if ( doMove )
587 {
588 wxPoint point(m_x, m_y);
589 wxMoveEvent event(point, m_windowId);
590 event.SetEventObject(this);
591 GetEventHandler()->ProcessEvent(event) ;
592 }
593 if ( doResize )
594 {
595 MacRepositionScrollBars() ;
596 wxSize size(m_width, m_height);
597 wxSizeEvent event(size, m_windowId);
598 event.SetEventObject(this);
599 GetEventHandler()->ProcessEvent(event);
600 }
601 }
602
603}
604
605// set the size of the window: if the dimensions are positive, just use them,
606// but if any of them is equal to -1, it means that we must find the value for
607// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
608// which case -1 is a valid value for x and y)
609//
610// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
611// the width/height to best suit our contents, otherwise we reuse the current
612// width/height
613void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
614{
615 // get the current size and position...
616 int currentX, currentY;
617 GetPosition(&currentX, &currentY);
618
619 int currentW,currentH;
620 GetSize(&currentW, &currentH);
621
622 // ... and don't do anything (avoiding flicker) if it's already ok
623 if ( x == currentX && y == currentY &&
624 width == currentW && height == currentH )
625 {
626 MacRepositionScrollBars() ; // we might have a real position shift
627 return;
628 }
629
630 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
631 x = currentX;
632 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
633 y = currentY;
634
635 AdjustForParentClientOrigin(x, y, sizeFlags);
636
637 wxSize size(-1, -1);
638 if ( width == -1 )
639 {
640 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
641 {
642 size = DoGetBestSize();
643 width = size.x;
644 }
645 else
646 {
647 // just take the current one
648 width = currentW;
649 }
650 }
651
652 if ( height == -1 )
653 {
654 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
655 {
656 if ( size.x == -1 )
657 {
658 size = DoGetBestSize();
659 }
660 //else: already called DoGetBestSize() above
661
662 height = size.y;
663 }
664 else
665 {
666 // just take the current one
667 height = currentH;
668 }
669 }
670
671 DoMoveWindow(x, y, width, height);
672
673}
674// For implementation purposes - sometimes decorations make the client area
675// smaller
676
677wxPoint wxWindowMac::GetClientAreaOrigin() const
678{
679 return wxPoint(MacGetLeftBorderSize( ) , MacGetTopBorderSize( ) );
680}
681
682void wxWindowMac::SetTitle(const wxString& title)
683{
684 m_label = title ;
685}
686
687wxString wxWindowMac::GetTitle() const
688{
689 return m_label ;
690}
691
692bool wxWindowMac::Show(bool show)
693{
694 if ( !wxWindowBase::Show(show) )
695 return FALSE;
696
697 MacSuperShown( show ) ;
698 if ( !show )
699 {
700 WindowRef window = (WindowRef) MacGetRootWindow() ;
701 wxWindowMac* win = wxFindWinFromMacWindow( window ) ;
702 if ( win && !win->m_isBeingDeleted )
703 Refresh() ;
704 }
705 else
706 {
707 Refresh() ;
708 }
709
710 return TRUE;
711}
712
713void wxWindowMac::MacSuperShown( bool show )
714{
715 wxNode *node = GetChildren().First();
716 while ( node )
717 {
718 wxWindowMac *child = (wxWindowMac *)node->Data();
719 if ( child->m_isShown )
720 child->MacSuperShown( show ) ;
721 node = node->Next();
722 }
723}
724
725void wxWindowMac::MacSuperEnabled( bool enabled )
726{
727 if ( !IsTopLevel() )
728 {
729 // to be absolutely correct we'd have to invalidate (with eraseBkground
730 // because unter MacOSX the frames are drawn with an addXXX mode)
731 // the borders area
732 }
733 wxNode *node = GetChildren().First();
734 while ( node )
735 {
736 wxWindowMac *child = (wxWindowMac *)node->Data();
737 if ( child->m_isShown )
738 child->MacSuperEnabled( enabled ) ;
739 node = node->Next();
740 }
741}
742
743bool wxWindowMac::MacIsReallyShown() const
744{
745 if ( m_isShown && (m_parent != NULL) ) {
746 return m_parent->MacIsReallyShown();
747 }
748 return m_isShown;
749/*
750 bool status = m_isShown ;
751 wxWindowMac * win = this ;
752 while ( status && win->m_parent != NULL )
753 {
754 win = win->m_parent ;
755 status = win->m_isShown ;
756 }
757 return status ;
758*/
759}
760
761int wxWindowMac::GetCharHeight() const
762{
763 wxClientDC dc ( (wxWindowMac*)this ) ;
764 return dc.GetCharHeight() ;
765}
766
767int wxWindowMac::GetCharWidth() const
768{
769 wxClientDC dc ( (wxWindowMac*)this ) ;
770 return dc.GetCharWidth() ;
771}
772
773void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
774 int *descent, int *externalLeading, const wxFont *theFont ) const
775{
776 const wxFont *fontToUse = theFont;
777 if ( !fontToUse )
778 fontToUse = &m_font;
779
780 wxClientDC dc( (wxWindowMac*) this ) ;
781 long lx,ly,ld,le ;
782 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
783 if ( externalLeading )
784 *externalLeading = le ;
785 if ( descent )
786 *descent = ld ;
787 if ( x )
788 *x = lx ;
789 if ( y )
790 *y = ly ;
791}
792
793/*
794 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
795 * we always intersect with the entire window, not only with the client area
796 */
797
798void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
799{
800 if ( MacGetTopLevelWindow() == NULL )
801 return ;
802
803 wxPoint client ;
804 client = GetClientAreaOrigin( ) ;
805 Rect clientrect = { -client.y , -client.x , m_height - client.y , m_width - client.x} ;
806 if ( rect )
807 {
808 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
809 SectRect( &clientrect , &r , &clientrect ) ;
810 }
811 if ( !EmptyRect( &clientrect ) )
812 {
813 int top = 0 , left = 0 ;
814
815 MacClientToRootWindow( &left , &top ) ;
816 OffsetRect( &clientrect , left , top ) ;
817
818 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
819 }
820}
821
822#if wxUSE_CARET && WXWIN_COMPATIBILITY
823// ---------------------------------------------------------------------------
824// Caret manipulation
825// ---------------------------------------------------------------------------
826
827void wxWindowMac::CreateCaret(int w, int h)
828{
829 SetCaret(new wxCaret(this, w, h));
830}
831
832void wxWindowMac::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
833{
834 wxFAIL_MSG("not implemented");
835}
836
837void wxWindowMac::ShowCaret(bool show)
838{
839 wxCHECK_RET( m_caret, "no caret to show" );
840
841 m_caret->Show(show);
842}
843
844void wxWindowMac::DestroyCaret()
845{
846 SetCaret(NULL);
847}
848
849void wxWindowMac::SetCaretPos(int x, int y)
850{
851 wxCHECK_RET( m_caret, "no caret to move" );
852
853 m_caret->Move(x, y);
854}
855
856void wxWindowMac::GetCaretPos(int *x, int *y) const
857{
858 wxCHECK_RET( m_caret, "no caret to get position of" );
859
860 m_caret->GetPosition(x, y);
861}
862#endif // wxUSE_CARET
863
864wxWindowMac *wxGetActiveWindow()
865{
866 // actually this is a windows-only concept
867 return NULL;
868}
869
870// Coordinates relative to the window
871void wxWindowMac::WarpPointer (int x_pos, int y_pos)
872{
873 // We really dont move the mouse programmatically under mac
874}
875
876const wxBrush& wxWindowMac::MacGetBackgroundBrush()
877{
878 if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
879 {
880 m_macBackgroundBrush.SetMacTheme( kThemeBrushDocumentWindowBackground ) ;
881 }
882 else if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
883 {
884 // on mac we have the difficult situation, that 3dface gray can be different colours, depending whether
885 // it is on a notebook panel or not, in order to take care of that we walk up the hierarchy until we have
886 // either a non gray background color or a non control window
887
888 WindowRef window = (WindowRef) MacGetRootWindow() ;
889
890 wxWindowMac* parent = GetParent() ;
891 while( parent )
892 {
893 if ( parent->MacGetRootWindow() != window )
894 {
895 // we are in a different window on the mac system
896 parent = NULL ;
897 break ;
898 }
899
900 {
901 if ( parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE )
902 && parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
903 {
904 // if we have any other colours in the hierarchy
905 m_macBackgroundBrush.SetColour( parent->m_backgroundColour ) ;
906 break ;
907 }
908 // if we have the normal colours in the hierarchy but another control etc. -> use it's background
909 if ( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
910 {
911 Rect extent = { 0 , 0 , 0 , 0 } ;
912 int x , y ;
913 x = y = 0 ;
914 wxSize size = GetSize() ;
915 parent->MacClientToRootWindow( &x , &y ) ;
916 extent.left = x ;
917 extent.top = y ;
918 extent.top-- ;
919 extent.right = x + size.x ;
920 extent.bottom = y + size.y ;
921 m_macBackgroundBrush.SetMacThemeBackground( kThemeBackgroundTabPane , (WXRECTPTR) &extent ) ; // todo eventually change for inactive
922 break ;
923 }
924 }
925 parent = parent->GetParent() ;
926 }
927 if ( !parent )
928 {
929 m_macBackgroundBrush.SetMacTheme( kThemeBrushDialogBackgroundActive ) ; // todo eventually change for inactive
930 }
931 }
932 else
933 {
934 m_macBackgroundBrush.SetColour( m_backgroundColour ) ;
935 }
936
937 return m_macBackgroundBrush ;
938
939}
940
941void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
942{
943 event.GetDC()->Clear() ;
944}
945
946void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
947{
948 wxWindowDC dc(this) ;
949 wxMacPortSetter helper(&dc) ;
950
951 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
952}
953
954int wxWindowMac::GetScrollPos(int orient) const
955{
956 if ( orient == wxHORIZONTAL )
957 {
958 if ( m_hScrollBar )
959 return m_hScrollBar->GetThumbPosition() ;
960 }
961 else
962 {
963 if ( m_vScrollBar )
964 return m_vScrollBar->GetThumbPosition() ;
965 }
966 return 0;
967}
968
969// This now returns the whole range, not just the number
970// of positions that we can scroll.
971int wxWindowMac::GetScrollRange(int orient) const
972{
973 if ( orient == wxHORIZONTAL )
974 {
975 if ( m_hScrollBar )
976 return m_hScrollBar->GetRange() ;
977 }
978 else
979 {
980 if ( m_vScrollBar )
981 return m_vScrollBar->GetRange() ;
982 }
983 return 0;
984}
985
986int wxWindowMac::GetScrollThumb(int orient) const
987{
988 if ( orient == wxHORIZONTAL )
989 {
990 if ( m_hScrollBar )
991 return m_hScrollBar->GetThumbSize() ;
992 }
993 else
994 {
995 if ( m_vScrollBar )
996 return m_vScrollBar->GetThumbSize() ;
997 }
998 return 0;
999}
1000
1001void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
1002{
1003 if ( orient == wxHORIZONTAL )
1004 {
1005 if ( m_hScrollBar )
1006 m_hScrollBar->SetThumbPosition( pos ) ;
1007 }
1008 else
1009 {
1010 if ( m_vScrollBar )
1011 m_vScrollBar->SetThumbPosition( pos ) ;
1012 }
1013}
1014
1015void wxWindowMac::MacPaintBorders( int left , int top )
1016{
1017 if( IsTopLevel() )
1018 return ;
1019
1020 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
1021 RGBColor black = { 0x0000, 0x0000 , 0x0000 } ;
1022 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
1023 RGBColor shadow = { 0x4444, 0x4444 , 0x4444 } ;
1024 PenNormal() ;
1025
1026 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
1027 {
1028#if wxMAC_USE_THEME_BORDER
1029 Rect rect = { top , left , m_height + top , m_width + left } ;
1030 SInt32 border = 0 ;
1031 /*
1032 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
1033 InsetRect( &rect , border , border );
1034 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1035 */
1036
1037 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
1038#else
1039 bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
1040 RGBForeColor( &face );
1041 MoveTo( left + 0 , top + m_height - 2 );
1042 LineTo( left + 0 , top + 0 );
1043 LineTo( left + m_width - 2 , top + 0 );
1044
1045 MoveTo( left + 2 , top + m_height - 3 );
1046 LineTo( left + m_width - 3 , top + m_height - 3 );
1047 LineTo( left + m_width - 3 , top + 2 );
1048
1049 RGBForeColor( sunken ? &face : &black );
1050 MoveTo( left + 0 , top + m_height - 1 );
1051 LineTo( left + m_width - 1 , top + m_height - 1 );
1052 LineTo( left + m_width - 1 , top + 0 );
1053
1054 RGBForeColor( sunken ? &shadow : &white );
1055 MoveTo( left + 1 , top + m_height - 3 );
1056 LineTo( left + 1, top + 1 );
1057 LineTo( left + m_width - 3 , top + 1 );
1058
1059 RGBForeColor( sunken ? &white : &shadow );
1060 MoveTo( left + 1 , top + m_height - 2 );
1061 LineTo( left + m_width - 2 , top + m_height - 2 );
1062 LineTo( left + m_width - 2 , top + 1 );
1063
1064 RGBForeColor( sunken ? &black : &face );
1065 MoveTo( left + 2 , top + m_height - 4 );
1066 LineTo( left + 2 , top + 2 );
1067 LineTo( left + m_width - 4 , top + 2 );
1068#endif
1069 }
1070 else if (HasFlag(wxSIMPLE_BORDER))
1071 {
1072 Rect rect = { top , left , m_height + top , m_width + left } ;
1073 RGBForeColor( &black ) ;
1074 FrameRect( &rect ) ;
1075 }
1076}
1077
1078void wxWindowMac::RemoveChild( wxWindowBase *child )
1079{
1080 if ( child == m_hScrollBar )
1081 m_hScrollBar = NULL ;
1082 if ( child == m_vScrollBar )
1083 m_vScrollBar = NULL ;
1084
1085 wxWindowBase::RemoveChild( child ) ;
1086}
1087
1088// New function that will replace some of the above.
1089void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
1090 int range, bool refresh)
1091{
1092 if ( orient == wxHORIZONTAL )
1093 {
1094 if ( m_hScrollBar )
1095 {
1096 if ( range == 0 || thumbVisible >= range )
1097 {
1098 if ( m_hScrollBar->IsShown() )
1099 m_hScrollBar->Show(false) ;
1100 }
1101 else
1102 {
1103 if ( !m_hScrollBar->IsShown() )
1104 m_hScrollBar->Show(true) ;
1105 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
1106 }
1107 }
1108 }
1109 else
1110 {
1111 if ( m_vScrollBar )
1112 {
1113 if ( range == 0 || thumbVisible >= range )
1114 {
1115 if ( m_vScrollBar->IsShown() )
1116 m_vScrollBar->Show(false) ;
1117 }
1118 else
1119 {
1120 if ( !m_vScrollBar->IsShown() )
1121 m_vScrollBar->Show(true) ;
1122 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
1123 }
1124 }
1125 }
1126 MacRepositionScrollBars() ;
1127}
1128
1129// Does a physical scroll
1130void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
1131{
1132 wxClientDC dc(this) ;
1133 wxMacPortSetter helper(&dc) ;
1134
1135 {
1136 int width , height ;
1137 GetClientSize( &width , &height ) ;
1138
1139 Rect scrollrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , dc.YLOG2DEVMAC(height) , dc.XLOG2DEVMAC(width) } ;
1140 RgnHandle updateRgn = NewRgn() ;
1141 ClipRect( &scrollrect ) ;
1142 if ( rect )
1143 {
1144 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
1145 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
1146 SectRect( &scrollrect , &r , &scrollrect ) ;
1147 }
1148 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
1149 InvalWindowRgn( (WindowRef) MacGetRootWindow() , updateRgn ) ;
1150 DisposeRgn( updateRgn ) ;
1151 }
1152
1153 for (wxNode *node = GetChildren().First(); node; node = node->Next())
1154 {
1155 wxWindowMac *child = (wxWindowMac*)node->Data();
1156 if (child == m_vScrollBar) continue;
1157 if (child == m_hScrollBar) continue;
1158 if (child->IsTopLevel()) continue;
1159 int x,y;
1160 child->GetPosition( &x, &y );
1161 int w,h;
1162 child->GetSize( &w, &h );
1163 child->SetSize( x+dx, y+dy, w, h );
1164 }
1165
1166}
1167
1168void wxWindowMac::MacOnScroll(wxScrollEvent &event )
1169{
1170 if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
1171 {
1172 wxScrollWinEvent wevent;
1173 wevent.SetPosition(event.GetPosition());
1174 wevent.SetOrientation(event.GetOrientation());
1175 wevent.m_eventObject = this;
1176
1177 if (event.m_eventType == wxEVT_SCROLL_TOP) {
1178 wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
1179 } else
1180 if (event.m_eventType == wxEVT_SCROLL_BOTTOM) {
1181 wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
1182 } else
1183 if (event.m_eventType == wxEVT_SCROLL_LINEUP) {
1184 wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
1185 } else
1186 if (event.m_eventType == wxEVT_SCROLL_LINEDOWN) {
1187 wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
1188 } else
1189 if (event.m_eventType == wxEVT_SCROLL_PAGEUP) {
1190 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
1191 } else
1192 if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN) {
1193 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
1194 } else
1195 if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK) {
1196 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
1197 }
1198
1199 GetEventHandler()->ProcessEvent(wevent);
1200 }
1201}
1202
1203// Get the window with the focus
1204wxWindowMac *wxWindowBase::FindFocus()
1205{
1206 return gFocusWindow ;
1207}
1208
1209#if WXWIN_COMPATIBILITY
1210// If nothing defined for this, try the parent.
1211// E.g. we may be a button loaded from a resource, with no callback function
1212// defined.
1213void wxWindowMac::OnCommand(wxWindowMac& win, wxCommandEvent& event)
1214{
1215 if ( GetEventHandler()->ProcessEvent(event) )
1216 return;
1217 if ( m_parent )
1218 m_parent->GetEventHandler()->OnCommand(win, event);
1219}
1220#endif // WXWIN_COMPATIBILITY_2
1221
1222#if WXWIN_COMPATIBILITY
1223wxObject* wxWindowMac::GetChild(int number) const
1224{
1225 // Return a pointer to the Nth object in the Panel
1226 wxNode *node = GetChildren().First();
1227 int n = number;
1228 while (node && n--)
1229 node = node->Next();
1230 if ( node )
1231 {
1232 wxObject *obj = (wxObject *)node->Data();
1233 return(obj);
1234 }
1235 else
1236 return NULL;
1237}
1238#endif // WXWIN_COMPATIBILITY
1239
1240void wxWindowMac::OnSetFocus(wxFocusEvent& event)
1241{
1242 // panel wants to track the window which was the last to have focus in it,
1243 // so we want to set ourselves as the window which last had focus
1244 //
1245 // notice that it's also important to do it upwards the tree becaus
1246 // otherwise when the top level panel gets focus, it won't set it back to
1247 // us, but to some other sibling
1248
1249 // CS:don't know if this is still needed:
1250 //wxChildFocusEvent eventFocus(this);
1251 //(void)GetEventHandler()->ProcessEvent(eventFocus);
1252
1253 event.Skip();
1254}
1255
1256void wxWindowMac::Clear()
1257{
1258 wxClientDC dc(this);
1259 wxBrush brush(GetBackgroundColour(), wxSOLID);
1260 dc.SetBackground(brush);
1261 dc.Clear();
1262}
1263
1264// Setup background and foreground colours correctly
1265void wxWindowMac::SetupColours()
1266{
1267 if ( GetParent() )
1268 SetBackgroundColour(GetParent()->GetBackgroundColour());
1269}
1270
1271void wxWindowMac::OnIdle(wxIdleEvent& event)
1272{
1273/*
1274 // Check if we need to send a LEAVE event
1275 if (m_mouseInWindow)
1276 {
1277 POINT pt;
1278 ::GetCursorPos(&pt);
1279 if (::WindowFromPoint(pt) != (HWND) GetHWND())
1280 {
1281 // Generate a LEAVE event
1282 m_mouseInWindow = FALSE;
1283 MSWOnMouseLeave(pt.x, pt.y, 0);
1284 }
1285 }
1286*/
1287
1288 // This calls the UI-update mechanism (querying windows for
1289 // menu/toolbar/control state information)
1290 UpdateWindowUI();
1291}
1292
1293// Raise the window to the top of the Z order
1294void wxWindowMac::Raise()
1295{
1296}
1297
1298// Lower the window to the bottom of the Z order
1299void wxWindowMac::Lower()
1300{
1301}
1302
1303void wxWindowMac::DoSetClientSize(int width, int height)
1304{
1305 if ( width != -1 || height != -1 )
1306 {
1307
1308 if ( width != -1 && m_vScrollBar )
1309 width += MAC_SCROLLBAR_SIZE ;
1310 if ( height != -1 && m_vScrollBar )
1311 height += MAC_SCROLLBAR_SIZE ;
1312
1313 width += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1314 height += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ;
1315
1316 DoSetSize( -1 , -1 , width , height ) ;
1317 }
1318}
1319
1320
1321wxWindowMac* wxWindowMac::s_lastMouseWindow = NULL ;
1322
1323bool wxWindowMac::MacGetWindowFromPointSub( const wxPoint &point , wxWindowMac** outWin )
1324{
1325 if ( IsTopLevel() )
1326 {
1327 if ((point.x < 0) || (point.y < 0) ||
1328 (point.x > (m_width)) || (point.y > (m_height)))
1329 return FALSE;
1330 }
1331 else
1332 {
1333 if ((point.x < m_x) || (point.y < m_y) ||
1334 (point.x > (m_x + m_width)) || (point.y > (m_y + m_height)))
1335 return FALSE;
1336 }
1337
1338 WindowRef window = (WindowRef) MacGetRootWindow() ;
1339
1340 wxPoint newPoint( point ) ;
1341
1342 if ( !IsTopLevel() )
1343 {
1344 newPoint.x -= m_x;
1345 newPoint.y -= m_y;
1346 }
1347
1348 for (wxNode *node = GetChildren().First(); node; node = node->Next())
1349 {
1350 wxWindowMac *child = (wxWindowMac*)node->Data();
1351 // added the m_isShown test --dmazzoni
1352 if ( child->MacGetRootWindow() == window && child->m_isShown )
1353 {
1354 if (child->MacGetWindowFromPointSub(newPoint , outWin ))
1355 return TRUE;
1356 }
1357 }
1358
1359 *outWin = this ;
1360 return TRUE;
1361}
1362
1363bool wxWindowMac::MacGetWindowFromPoint( const wxPoint &screenpoint , wxWindowMac** outWin )
1364{
1365 WindowRef window ;
1366
1367 Point pt = { screenpoint.y , screenpoint.x } ;
1368 if ( ::FindWindow( pt , &window ) == 3 )
1369 {
1370
1371 wxWindowMac* win = wxFindWinFromMacWindow( window ) ;
1372 if ( win )
1373 {
1374 // No, this yields the CLIENT are, we need the whole frame. RR.
1375 // point = win->ScreenToClient( point ) ;
1376
1377 GrafPtr port;
1378 ::GetPort( &port ) ;
1379 ::SetPort( UMAGetWindowPort( window ) ) ;
1380 ::GlobalToLocal( &pt ) ;
1381 ::SetPort( port ) ;
1382
1383 wxPoint point( pt.h, pt.v ) ;
1384
1385 return win->MacGetWindowFromPointSub( point , outWin ) ;
1386 }
1387 }
1388 return FALSE ;
1389}
1390
1391extern int wxBusyCursorCount ;
1392static wxWindow *gs_lastWhich = NULL;
1393
1394bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event)
1395{
1396 if ((event.m_x < m_x) || (event.m_y < m_y) ||
1397 (event.m_x > (m_x + m_width)) || (event.m_y > (m_y + m_height)))
1398 return FALSE;
1399
1400
1401 if ( IsKindOf( CLASSINFO ( wxStaticBox ) ) || IsKindOf( CLASSINFO( wxSpinCtrl ) ))
1402 return FALSE ;
1403
1404 WindowRef window = (WindowRef) MacGetRootWindow() ;
1405
1406 event.m_x -= m_x;
1407 event.m_y -= m_y;
1408
1409 int x = event.m_x ;
1410 int y = event.m_y ;
1411
1412 for (wxNode *node = GetChildren().First(); node; node = node->Next())
1413 {
1414 wxWindowMac *child = (wxWindowMac*)node->Data();
1415 if ( child->MacGetRootWindow() == window && child->IsShown() && child->IsEnabled() )
1416 {
1417 if (child->MacDispatchMouseEvent(event))
1418 return TRUE;
1419 }
1420 }
1421
1422 event.m_x = x ;
1423 event.m_y = y ;
1424 event.SetEventObject( this ) ;
1425
1426 if ( wxBusyCursorCount == 0 )
1427 {
1428 m_cursor.MacInstall() ;
1429 }
1430
1431 if ( event.GetEventType() == wxEVT_LEFT_DOWN )
1432 {
1433 // set focus to this window
1434 if (AcceptsFocus() && FindFocus()!=this)
1435 SetFocus();
1436 }
1437
1438#if wxUSE_TOOLTIPS
1439 if ( event.GetEventType() == wxEVT_MOTION
1440 || event.GetEventType() == wxEVT_ENTER_WINDOW
1441 || event.GetEventType() == wxEVT_LEAVE_WINDOW )
1442 wxToolTip::RelayEvent( this , event);
1443#endif // wxUSE_TOOLTIPS
1444
1445 if (gs_lastWhich != this)
1446 {
1447 gs_lastWhich = this;
1448
1449 // Double clicks must always occur on the same window
1450 if (event.GetEventType() == wxEVT_LEFT_DCLICK)
1451 event.SetEventType( wxEVT_LEFT_DOWN );
1452 if (event.GetEventType() == wxEVT_RIGHT_DCLICK)
1453 event.SetEventType( wxEVT_RIGHT_DOWN );
1454
1455 // Same for mouse up events
1456 if (event.GetEventType() == wxEVT_LEFT_UP)
1457 return TRUE;
1458 if (event.GetEventType() == wxEVT_RIGHT_UP)
1459 return TRUE;
1460 }
1461
1462 GetEventHandler()->ProcessEvent( event ) ;
1463
1464 return TRUE;
1465}
1466
1467wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
1468{
1469 if ( m_tooltip )
1470 {
1471 return m_tooltip->GetTip() ;
1472 }
1473 return "" ;
1474}
1475
1476void wxWindowMac::Update()
1477{
1478 wxTopLevelWindowMac* win = MacGetTopLevelWindow( ) ;
1479 if ( win )
1480 {
1481 win->MacUpdate( 0 ) ;
1482#if TARGET_API_MAC_CARBON
1483 if ( QDIsPortBuffered( GetWindowPort( (WindowRef) win->MacGetWindowRef() ) ) )
1484 {
1485 QDFlushPortBuffer( GetWindowPort( (WindowRef) win->MacGetWindowRef() ) , NULL ) ;
1486 }
1487#endif
1488 }
1489}
1490
1491wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
1492{
1493 wxTopLevelWindowMac* win = NULL ;
1494 WindowRef window = (WindowRef) MacGetRootWindow() ;
1495 if ( window )
1496 {
1497 win = wxFindWinFromMacWindow( window ) ;
1498 }
1499 return win ;
1500}
1501
1502const wxRegion& wxWindowMac::MacGetVisibleRegion()
1503{
1504 RgnHandle visRgn = NewRgn() ;
1505 RgnHandle tempRgn = NewRgn() ;
1506
1507 SetRectRgn( visRgn , 0 , 0 , m_width , m_height ) ;
1508
1509 //TODO : as soon as the new scheme has proven to work correctly, move this to wxStaticBox
1510 if ( IsKindOf( CLASSINFO( wxStaticBox ) ) )
1511 {
1512 int borderTop = 14 ;
1513 int borderOther = 4 ;
1514
1515 SetRectRgn( tempRgn , borderOther , borderTop , m_width - borderOther , m_height - borderOther ) ;
1516 DiffRgn( visRgn , tempRgn , visRgn ) ;
1517 }
1518
1519 if ( !IsTopLevel() )
1520 {
1521 wxWindow* parent = GetParent() ;
1522 while( parent )
1523 {
1524 wxSize size = parent->GetSize() ;
1525 int x , y ;
1526 x = y = 0 ;
1527 parent->MacWindowToRootWindow( &x, &y ) ;
1528 MacRootWindowToWindow( &x , &y ) ;
1529 SetRectRgn( tempRgn , x , y , x + size.x , y + size.y ) ;
1530 SectRgn( visRgn , tempRgn , visRgn ) ;
1531 if ( parent->IsTopLevel() )
1532 break ;
1533 parent = parent->GetParent() ;
1534 }
1535 }
1536 if ( GetWindowStyle() & wxCLIP_CHILDREN )
1537 {
1538 for (wxNode *node = GetChildren().First(); node; node = node->Next())
1539 {
1540 wxWindowMac *child = (wxWindowMac*)node->Data();
1541
1542 if ( !child->IsTopLevel() && child->IsShown() )
1543 {
1544 SetRectRgn( tempRgn , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ;
1545 DiffRgn( visRgn , tempRgn , visRgn ) ;
1546 }
1547 }
1548 }
1549
1550 if ( (GetWindowStyle() & wxCLIP_SIBLINGS) && GetParent() )
1551 {
1552 bool thisWindowThrough = false ;
1553 for (wxNode *node = GetParent()->GetChildren().First(); node; node = node->Next())
1554 {
1555 wxWindowMac *sibling = (wxWindowMac*)node->Data();
1556 if ( sibling == this )
1557 {
1558 thisWindowThrough = true ;
1559 continue ;
1560 }
1561 if( !thisWindowThrough )
1562 {
1563 continue ;
1564 }
1565
1566 if ( !sibling->IsTopLevel() && sibling->IsShown() )
1567 {
1568 SetRectRgn( tempRgn , sibling->m_x - m_x , sibling->m_y - m_y , sibling->m_x + sibling->m_width - m_x , sibling->m_y + sibling->m_height - m_y ) ;
1569 DiffRgn( visRgn , tempRgn , visRgn ) ;
1570 }
1571 }
1572 }
1573 m_macVisibleRegion = visRgn ;
1574 DisposeRgn( visRgn ) ;
1575 DisposeRgn( tempRgn ) ;
1576 return m_macVisibleRegion ;
1577}
1578
1579void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
1580{
1581 RgnHandle updatergn = (RgnHandle) updatergnr ;
1582 // updatergn is always already clipped to our boundaries
1583 // it is in window coordinates, not in client coordinates
1584
1585 WindowRef window = (WindowRef) MacGetRootWindow() ;
1586
1587 {
1588 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
1589 RgnHandle ownUpdateRgn = NewRgn() ;
1590 CopyRgn( updatergn , ownUpdateRgn ) ;
1591
1592 SectRgn( ownUpdateRgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , ownUpdateRgn ) ;
1593
1594 // newupdate is the update region in client coordinates
1595 RgnHandle newupdate = NewRgn() ;
1596 wxSize point = GetClientSize() ;
1597 wxPoint origin = GetClientAreaOrigin() ;
1598 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
1599 SectRgn( newupdate , ownUpdateRgn , newupdate ) ;
1600 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
1601 m_updateRegion = newupdate ;
1602 DisposeRgn( newupdate ) ; // it's been cloned to m_updateRegion
1603
1604 if ( erase && !EmptyRgn(ownUpdateRgn) )
1605 {
1606 wxWindowDC dc(this);
1607 dc.SetClippingRegion(wxRegion(ownUpdateRgn));
1608 wxEraseEvent eevent( GetId(), &dc );
1609 eevent.SetEventObject( this );
1610 GetEventHandler()->ProcessEvent( eevent );
1611
1612 wxNcPaintEvent eventNc( GetId() );
1613 eventNc.SetEventObject( this );
1614 GetEventHandler()->ProcessEvent( eventNc );
1615 }
1616 DisposeRgn( ownUpdateRgn ) ;
1617 if ( !m_updateRegion.Empty() )
1618 {
1619 wxPaintEvent event;
1620 event.m_timeStamp = time ;
1621 event.SetEventObject(this);
1622 GetEventHandler()->ProcessEvent(event);
1623 }
1624 }
1625
1626 // now intersect for each of the children their rect with the updateRgn and call MacRedraw recursively
1627
1628 RgnHandle childupdate = NewRgn() ;
1629 for (wxNode *node = GetChildren().First(); node; node = node->Next())
1630 {
1631 // calculate the update region for the child windows by intersecting the window rectangle with our own
1632 // passed in update region and then offset it to be client-wise window coordinates again
1633 wxWindowMac *child = (wxWindowMac*)node->Data();
1634 SetRectRgn( childupdate , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ;
1635 SectRgn( childupdate , updatergn , childupdate ) ;
1636 OffsetRgn( childupdate , -child->m_x , -child->m_y ) ;
1637 if ( child->MacGetRootWindow() == window && child->IsShown() && !EmptyRgn( childupdate ) )
1638 {
1639 // because dialogs may also be children
1640 child->MacRedraw( childupdate , time , erase ) ;
1641 }
1642 }
1643 DisposeRgn( childupdate ) ;
1644 // eventually a draw grow box here
1645
1646}
1647
1648WXHWND wxWindowMac::MacGetRootWindow() const
1649{
1650 wxWindowMac *iter = (wxWindowMac*)this ;
1651
1652 while( iter )
1653 {
1654 if ( iter->IsTopLevel() )
1655 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
1656
1657 iter = iter->GetParent() ;
1658 }
1659 wxASSERT_MSG( 1 , "No valid mac root window" ) ;
1660 return NULL ;
1661}
1662
1663void wxWindowMac::MacCreateScrollBars( long style )
1664{
1665 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , "attempt to create window twice" ) ;
1666
1667 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
1668 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
1669 int width, height ;
1670 GetClientSize( &width , &height ) ;
1671
1672 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
1673 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
1674 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
1675 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
1676
1677 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
1678 vSize , wxVERTICAL);
1679
1680 if ( style & wxVSCROLL )
1681 {
1682
1683 }
1684 else
1685 {
1686 m_vScrollBar->Show(false) ;
1687 }
1688 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
1689 hSize , wxHORIZONTAL);
1690 if ( style & wxHSCROLL )
1691 {
1692 }
1693 else
1694 {
1695 m_hScrollBar->Show(false) ;
1696 }
1697
1698 // because the create does not take into account the client area origin
1699 MacRepositionScrollBars() ; // we might have a real position shift
1700}
1701
1702void wxWindowMac::MacRepositionScrollBars()
1703{
1704 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
1705 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
1706
1707 // get real client area
1708
1709 int width = m_width ;
1710 int height = m_height ;
1711
1712 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
1713 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
1714
1715 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
1716 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
1717 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
1718 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
1719
1720 int x = 0 ;
1721 int y = 0 ;
1722 int w = m_width ;
1723 int h = m_height ;
1724
1725 MacClientToRootWindow( &x , &y ) ;
1726 MacClientToRootWindow( &w , &h ) ;
1727
1728 wxWindowMac *iter = (wxWindowMac*)this ;
1729
1730 int totW = 10000 , totH = 10000;
1731 while( iter )
1732 {
1733 if ( iter->IsTopLevel() )
1734 {
1735 totW = iter->m_width ;
1736 totH = iter->m_height ;
1737 break ;
1738 }
1739
1740 iter = iter->GetParent() ;
1741 }
1742
1743 if ( x == 0 )
1744 {
1745 hPoint.x = -1 ;
1746 hSize.x += 1 ;
1747 }
1748 if ( y == 0 )
1749 {
1750 vPoint.y = -1 ;
1751 vSize.y += 1 ;
1752 }
1753
1754 if ( w-x >= totW )
1755 {
1756 hSize.x += 1 ;
1757 vPoint.x += 1 ;
1758 }
1759
1760 if ( h-y >= totH )
1761 {
1762 vSize.y += 1 ;
1763 hPoint.y += 1 ;
1764 }
1765
1766 if ( m_vScrollBar )
1767 {
1768 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
1769 }
1770 if ( m_hScrollBar )
1771 {
1772 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
1773 }
1774}
1775
1776bool wxWindowMac::AcceptsFocus() const
1777{
1778 return MacCanFocus() && wxWindowBase::AcceptsFocus();
1779}
1780
1781WXWidget wxWindowMac::MacGetContainerForEmbedding()
1782{
1783 return GetParent()->MacGetContainerForEmbedding() ;
1784}
1785
1786void wxWindowMac::MacSuperChangedPosition()
1787{
1788 // only window-absolute structures have to be moved i.e. controls
1789
1790 wxNode *node = GetChildren().First();
1791 while ( node )
1792 {
1793 wxWindowMac *child = (wxWindowMac *)node->Data();
1794 child->MacSuperChangedPosition() ;
1795 node = node->Next();
1796 }
1797}
1798
1799void wxWindowMac::MacTopLevelWindowChangedPosition()
1800{
1801 // only screen-absolute structures have to be moved i.e. glcanvas
1802
1803 wxNode *node = GetChildren().First();
1804 while ( node )
1805 {
1806 wxWindowMac *child = (wxWindowMac *)node->Data();
1807 child->MacTopLevelWindowChangedPosition() ;
1808 node = node->Next();
1809 }
1810}
1811long wxWindowMac::MacGetLeftBorderSize( ) const
1812{
1813 if( IsTopLevel() )
1814 return 0 ;
1815
1816 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
1817 {
1818 SInt32 border = 3 ;
1819#if wxMAC_USE_THEME_BORDER
1820#if TARGET_CARBON
1821 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
1822#endif
1823#endif
1824 return border ;
1825 }
1826 else if ( m_windowStyle &wxDOUBLE_BORDER)
1827 {
1828 SInt32 border = 3 ;
1829#if wxMAC_USE_THEME_BORDER
1830#if TARGET_CARBON
1831 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
1832#endif
1833#endif
1834 return border ;
1835 }
1836 else if (m_windowStyle &wxSIMPLE_BORDER)
1837 {
1838 return 1 ;
1839 }
1840 return 0 ;
1841}
1842
1843long wxWindowMac::MacGetRightBorderSize( ) const
1844{
1845 // they are all symmetric in mac themes
1846 return MacGetLeftBorderSize() ;
1847}
1848
1849long wxWindowMac::MacGetTopBorderSize( ) const
1850{
1851 // they are all symmetric in mac themes
1852 return MacGetLeftBorderSize() ;
1853}
1854
1855long wxWindowMac::MacGetBottomBorderSize( ) const
1856{
1857 // they are all symmetric in mac themes
1858 return MacGetLeftBorderSize() ;
1859}
1860
1861long wxWindowMac::MacRemoveBordersFromStyle( long style )
1862{
1863 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
1864}
1865
1866// Find the wxWindowMac at the current mouse position, returning the mouse
1867// position.
1868wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
1869{
1870 pt = wxGetMousePosition();
1871 wxWindowMac* found = wxFindWindowAtPoint(pt);
1872 return found;
1873}
1874
1875// Get the current mouse position.
1876wxPoint wxGetMousePosition()
1877{
1878 int x, y;
1879 wxGetMousePosition(& x, & y);
1880 return wxPoint(x, y);
1881}
1882