]> git.saurik.com Git - wxWidgets.git/blame - src/osx/window_osx.cpp
use wxOSX_USE_COCOA instead of __WXOSX_COCOA__ (which was checked incorrectly)
[wxWidgets.git] / src / osx / window_osx.cpp
CommitLineData
524c47aa
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/carbon/window.cpp
3// Purpose: wxWindowMac
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id: window.cpp 54981 2008-08-05 17:52:02Z SC $
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#include "wx/window.h"
15
16#ifndef WX_PRECOMP
17 #include "wx/log.h"
18 #include "wx/app.h"
19 #include "wx/utils.h"
20 #include "wx/panel.h"
21 #include "wx/frame.h"
22 #include "wx/dc.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.h"
25 #include "wx/menu.h"
26 #include "wx/dialog.h"
27 #include "wx/settings.h"
28 #include "wx/msgdlg.h"
29 #include "wx/scrolbar.h"
30 #include "wx/statbox.h"
31 #include "wx/textctrl.h"
32 #include "wx/toolbar.h"
33 #include "wx/layout.h"
34 #include "wx/statusbr.h"
35 #include "wx/menuitem.h"
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
38#endif
39
40#include "wx/tooltip.h"
41#include "wx/spinctrl.h"
42#include "wx/geometry.h"
43
44#if wxUSE_LISTCTRL
45 #include "wx/listctrl.h"
46#endif
47
48#if wxUSE_TREECTRL
49 #include "wx/treectrl.h"
50#endif
51
52#if wxUSE_CARET
53 #include "wx/caret.h"
54#endif
55
56#if wxUSE_POPUPWIN
57 #include "wx/popupwin.h"
58#endif
59
60#if wxUSE_DRAG_AND_DROP
61#include "wx/dnd.h"
62#endif
63
f55d9f74
SC
64#include "wx/graphics.h"
65
524c47aa
SC
66#if wxOSX_USE_CARBON
67#include "wx/osx/uma.h"
68#else
69#include "wx/osx/private.h"
70// bring in themeing
71#include <Carbon/Carbon.h>
72#endif
73
74#define MAC_SCROLLBAR_SIZE 15
75#define MAC_SMALL_SCROLLBAR_SIZE 11
76
77#include <string.h>
78
79#ifdef __WXUNIVERSAL__
80 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
81#else
82 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
83#endif
84
85BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
86 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
87 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
524c47aa
SC
88 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
89END_EVENT_TABLE()
90
91#define wxMAC_DEBUG_REDRAW 0
92#ifndef wxMAC_DEBUG_REDRAW
93#define wxMAC_DEBUG_REDRAW 0
94#endif
95
96// ===========================================================================
97// implementation
98// ===========================================================================
99
100// ----------------------------------------------------------------------------
101 // constructors and such
102// ----------------------------------------------------------------------------
103
104wxWindowMac::wxWindowMac()
105{
106 Init();
107}
108
109wxWindowMac::wxWindowMac(wxWindowMac *parent,
110 wxWindowID id,
111 const wxPoint& pos ,
112 const wxSize& size ,
113 long style ,
114 const wxString& name )
115{
116 Init();
117 Create(parent, id, pos, size, style, name);
118}
119
120void wxWindowMac::Init()
121{
122 m_peer = NULL ;
123 m_macAlpha = 255 ;
124 m_cgContextRef = NULL ;
125
126 // as all windows are created with WS_VISIBLE style...
127 m_isShown = true;
128
129 m_hScrollBar = NULL ;
130 m_vScrollBar = NULL ;
131 m_hScrollBarAlwaysShown = false;
132 m_vScrollBarAlwaysShown = false;
133
134 m_macIsUserPane = true;
135 m_clipChildren = false ;
136 m_cachedClippedRectValid = false ;
137}
138
139wxWindowMac::~wxWindowMac()
140{
141 SendDestroyEvent();
142
524c47aa
SC
143 MacInvalidateBorders() ;
144
145#ifndef __WXUNIVERSAL__
146 // VS: make sure there's no wxFrame with last focus set to us:
147 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
148 {
149 wxFrame *frame = wxDynamicCast(win, wxFrame);
150 if ( frame )
151 {
152 if ( frame->GetLastFocus() == this )
d3b9f782 153 frame->SetLastFocus(NULL);
524c47aa
SC
154 break;
155 }
156 }
157#endif
158
159 // destroy children before destroying this window itself
160 DestroyChildren();
161
162 // wxRemoveMacControlAssociation( this ) ;
163 // If we delete an item, we should initialize the parent panel,
164 // because it could now be invalid.
165 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this), wxTopLevelWindow);
166 if ( tlw )
167 {
168 if ( tlw->GetDefaultItem() == (wxButton*) this)
169 tlw->SetDefaultItem(NULL);
170 }
171
172 if ( g_MacLastWindow == this )
173 g_MacLastWindow = NULL ;
174
175#ifndef __WXUNIVERSAL__
176 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ;
177 if ( frame )
178 {
179 if ( frame->GetLastFocus() == this )
180 frame->SetLastFocus( NULL ) ;
181 }
182#endif
183
184 // delete our drop target if we've got one
185#if wxUSE_DRAG_AND_DROP
186 if ( m_dropTarget != NULL )
187 {
188 delete m_dropTarget;
189 m_dropTarget = NULL;
190 }
191#endif
192
193 delete m_peer ;
194}
195
196WXWidget wxWindowMac::GetHandle() const
197{
d4e4ba48
SC
198 if ( m_peer )
199 return (WXWidget) m_peer->GetWXWidget() ;
200 return NULL;
524c47aa
SC
201}
202
524c47aa
SC
203// ---------------------------------------------------------------------------
204// Utility Routines to move between different coordinate systems
205// ---------------------------------------------------------------------------
206
207/*
208 * Right now we have the following setup :
209 * a border that is not part of the native control is always outside the
210 * control's border (otherwise we loose all native intelligence, future ways
211 * may be to have a second embedding control responsible for drawing borders
212 * and backgrounds eventually)
213 * so all this border calculations have to be taken into account when calling
214 * native methods or getting native oriented data
215 * so we have three coordinate systems here
216 * wx client coordinates
217 * wx window coordinates (including window frames)
218 * native coordinates
219 */
220
221//
222//
223
224// Constructor
225bool wxWindowMac::Create(wxWindowMac *parent,
226 wxWindowID id,
227 const wxPoint& pos,
228 const wxSize& size,
229 long style,
230 const wxString& name)
231{
232 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
233
234 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
235 return false;
236
237 m_windowVariant = parent->GetWindowVariant() ;
238
239 if ( m_macIsUserPane )
240 {
241 m_peer = wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() );
242 MacPostControlCreate(pos, size) ;
243 }
244
245#ifndef __WXUNIVERSAL__
246 // Don't give scrollbars to wxControls unless they ask for them
247 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar)))
248 || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
249 {
250 MacCreateScrollBars( style ) ;
251 }
252#endif
253
254 wxWindowCreateEvent event((wxWindow*)this);
255 GetEventHandler()->AddPendingEvent(event);
256
257 return true;
258}
259
260void wxWindowMac::MacChildAdded()
261{
262 if ( m_vScrollBar )
263 m_vScrollBar->Raise() ;
264 if ( m_hScrollBar )
265 m_hScrollBar->Raise() ;
266}
267
268void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size)
269{
270 wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid mac control") ) ;
271
524c47aa
SC
272 GetParent()->AddChild( this );
273
524c47aa 274 m_peer->InstallEventHandler();
c4825ef7 275 m_peer->Embed(GetParent()->GetPeer());
524c47aa 276
524c47aa
SC
277 GetParent()->MacChildAdded() ;
278
279 // adjust font, controlsize etc
280 DoSetWindowVariant( m_windowVariant ) ;
281
282 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ;
283
f55d9f74
SC
284 // for controls we want to use best size for wxDefaultSize params )
285 if ( !m_macIsUserPane )
524c47aa
SC
286 SetInitialSize(size);
287
288 SetCursor( *wxSTANDARD_CURSOR ) ;
289}
290
291void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
292{
293 // Don't assert, in case we set the window variant before
294 // the window is created
295 // wxASSERT( m_peer->Ok() ) ;
296
297 m_windowVariant = variant ;
298
299 if (m_peer == NULL || !m_peer->IsOk())
300 return;
301
302 m_peer->SetControlSize( variant );
7ac5e1c9
SC
303#if wxOSX_USE_CARBON
304 ControlSize size ;
305
306 // we will get that from the settings later
307 // and make this NORMAL later, but first
308 // we have a few calculations that we must fix
309
310 switch ( variant )
311 {
312 case wxWINDOW_VARIANT_NORMAL :
313 size = kControlSizeNormal;
314 break ;
315
316 case wxWINDOW_VARIANT_SMALL :
317 size = kControlSizeSmall;
318 break ;
319
320 case wxWINDOW_VARIANT_MINI :
321 // not always defined in the headers
322 size = 3 ;
323 break ;
324
325 case wxWINDOW_VARIANT_LARGE :
326 size = kControlSizeLarge;
327 break ;
328
329 default:
330 wxFAIL_MSG(_T("unexpected window variant"));
331 break ;
332 }
333 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
334#endif
335
524c47aa
SC
336 wxFont font ;
337
b2088388 338 wxOSXSystemFont systemFont = wxOSX_SYSTEM_FONT_NORMAL ;
524c47aa
SC
339
340 switch ( variant )
341 {
342 case wxWINDOW_VARIANT_NORMAL :
b2088388 343 systemFont = wxOSX_SYSTEM_FONT_NORMAL ;
524c47aa
SC
344 break ;
345
346 case wxWINDOW_VARIANT_SMALL :
b2088388 347 systemFont = wxOSX_SYSTEM_FONT_SMALL ;
524c47aa
SC
348 break ;
349
350 case wxWINDOW_VARIANT_MINI :
b2088388 351 systemFont = wxOSX_SYSTEM_FONT_MINI ;
524c47aa
SC
352 break ;
353
354 case wxWINDOW_VARIANT_LARGE :
b2088388 355 systemFont = wxOSX_SYSTEM_FONT_NORMAL ;
524c47aa
SC
356 break ;
357
358 default:
359 wxFAIL_MSG(_T("unexpected window variant"));
360 break ;
361 }
362
b2088388 363 font.CreateSystemFont( systemFont ) ;
524c47aa
SC
364
365 SetFont( font ) ;
524c47aa
SC
366}
367
368void wxWindowMac::MacUpdateControlFont()
369{
f55d9f74
SC
370 if ( m_peer )
371 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1e181c7a 372
524c47aa
SC
373 // do not trigger refreshes upon invisible and possible partly created objects
374 if ( IsShownOnScreen() )
375 Refresh() ;
376}
377
378bool wxWindowMac::SetFont(const wxFont& font)
379{
380 bool retval = wxWindowBase::SetFont( font );
381
382 MacUpdateControlFont() ;
383
384 return retval;
385}
386
387bool wxWindowMac::SetForegroundColour(const wxColour& col )
388{
389 bool retval = wxWindowBase::SetForegroundColour( col );
390
391 if (retval)
392 MacUpdateControlFont();
393
394 return retval;
395}
396
397bool wxWindowMac::SetBackgroundColour(const wxColour& col )
398{
399 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
400 return false ;
401
402 if ( m_peer )
403 m_peer->SetBackgroundColour( col ) ;
404
405 return true ;
406}
407
77a246e1
JS
408static bool wxIsWindowOrParentDisabled(wxWindow* w)
409{
410 while (w && !w->IsTopLevel())
411 {
412 if (!w->IsEnabled())
413 return true;
414 w = w->GetParent();
415 }
416 return false;
417}
418
524c47aa
SC
419void wxWindowMac::SetFocus()
420{
421 if ( !AcceptsFocus() )
422 return ;
423
77a246e1
JS
424 if (wxIsWindowOrParentDisabled((wxWindow*) this))
425 return;
426
524c47aa
SC
427 wxWindow* former = FindFocus() ;
428 if ( former == this )
429 return ;
430
431 m_peer->SetFocus() ;
432}
433
434void wxWindowMac::DoCaptureMouse()
435{
436 wxApp::s_captureWindow = (wxWindow*) this ;
54f11060 437 m_peer->CaptureMouse() ;
524c47aa
SC
438}
439
440wxWindow * wxWindowBase::GetCapture()
441{
442 return wxApp::s_captureWindow ;
443}
444
445void wxWindowMac::DoReleaseMouse()
446{
447 wxApp::s_captureWindow = NULL ;
54f11060
SC
448
449 m_peer->ReleaseMouse() ;
524c47aa
SC
450}
451
452#if wxUSE_DRAG_AND_DROP
453
454void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
455{
0b1ca117 456 delete m_dropTarget;
524c47aa
SC
457
458 m_dropTarget = pDropTarget;
459 if ( m_dropTarget != NULL )
460 {
461 // TODO:
462 }
463}
464
465#endif
466
467// Old-style File Manager Drag & Drop
468void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept))
469{
470 // TODO:
471}
472
473// From a wx position / size calculate the appropriate size of the native control
474
475bool wxWindowMac::MacGetBoundsForControl(
476 const wxPoint& pos,
477 const wxSize& size,
478 int& x, int& y,
479 int& w, int& h , bool adjustOrigin ) const
480{
481 // the desired size, minus the border pixels gives the correct size of the control
482 x = (int)pos.x;
483 y = (int)pos.y;
484
f55d9f74
SC
485 w = WidthDefault( size.x );
486 h = HeightDefault( size.y );
524c47aa
SC
487
488 x += MacGetLeftBorderSize() ;
489 y += MacGetTopBorderSize() ;
490 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
491 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
492
493 if ( adjustOrigin )
494 AdjustForParentClientOrigin( x , y ) ;
495
496 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1a4e2d5b 497 if ( GetParent() && !GetParent()->IsTopLevel() )
524c47aa
SC
498 {
499 x -= GetParent()->MacGetLeftBorderSize() ;
500 y -= GetParent()->MacGetTopBorderSize() ;
501 }
502
503 return true ;
504}
505
506// Get window size (not client size)
507void wxWindowMac::DoGetSize(int *x, int *y) const
508{
509 int width, height;
510 m_peer->GetSize( width, height );
511
512 if (x)
513 *x = width + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
514 if (y)
515 *y = height + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
516}
517
518// get the position of the bounds of this window in client coordinates of its parent
519void wxWindowMac::DoGetPosition(int *x, int *y) const
520{
521 int x1, y1;
522
523 m_peer->GetPosition( x1, y1 ) ;
524
525 // get the wx window position from the native one
526 x1 -= MacGetLeftBorderSize() ;
527 y1 -= MacGetTopBorderSize() ;
528
529 if ( !IsTopLevel() )
530 {
531 wxWindow *parent = GetParent();
532 if ( parent )
533 {
534 // we must first adjust it to be in window coordinates of the parent,
535 // as otherwise it gets lost by the ClientAreaOrigin fix
536 x1 += parent->MacGetLeftBorderSize() ;
537 y1 += parent->MacGetTopBorderSize() ;
538
539 // and now to client coordinates
540 wxPoint pt(parent->GetClientAreaOrigin());
541 x1 -= pt.x ;
542 y1 -= pt.y ;
543 }
544 }
545
546 if (x)
547 *x = x1 ;
548 if (y)
549 *y = y1 ;
550}
551
552void wxWindowMac::DoScreenToClient(int *x, int *y) const
553{
554 wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ;
555 wxCHECK_RET( tlw , wxT("TopLevel Window missing") ) ;
556 tlw->GetNonOwnedPeer()->ScreenToWindow( x, y);
557 MacRootWindowToWindow( x , y ) ;
558
559 wxPoint origin = GetClientAreaOrigin() ;
560 if (x)
561 *x -= origin.x ;
562 if (y)
563 *y -= origin.y ;
564}
565
566void wxWindowMac::DoClientToScreen(int *x, int *y) const
567{
568 wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ;
569 wxCHECK_RET( tlw , wxT("TopLevel window missing") ) ;
570
571 wxPoint origin = GetClientAreaOrigin() ;
572 if (x)
573 *x += origin.x ;
574 if (y)
575 *y += origin.y ;
576
577 MacWindowToRootWindow( x , y ) ;
578 tlw->GetNonOwnedPeer()->WindowToScreen( x , y );
579}
580
581void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
582{
583 wxPoint origin = GetClientAreaOrigin() ;
584 if (x)
585 *x += origin.x ;
586 if (y)
587 *y += origin.y ;
588
589 MacWindowToRootWindow( x , y ) ;
590}
591
592void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
593{
594 wxPoint pt ;
595
596 if (x)
597 pt.x = *x ;
598 if (y)
599 pt.y = *y ;
600
601 if ( !IsTopLevel() )
602 {
603 wxNonOwnedWindow* top = MacGetTopLevelWindow();
604 if (top)
605 {
606 pt.x -= MacGetLeftBorderSize() ;
607 pt.y -= MacGetTopBorderSize() ;
608 wxWidgetImpl::Convert( &pt , m_peer , top->m_peer ) ;
609 }
610 }
611
612 if (x)
613 *x = (int) pt.x ;
614 if (y)
615 *y = (int) pt.y ;
616}
617
618void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
619{
620 wxPoint pt ;
621
622 if (x)
623 pt.x = *x ;
624 if (y)
625 pt.y = *y ;
626
627 if ( !IsTopLevel() )
628 {
629 wxNonOwnedWindow* top = MacGetTopLevelWindow();
630 if (top)
631 {
632 wxWidgetImpl::Convert( &pt , top->m_peer , m_peer ) ;
633 pt.x += MacGetLeftBorderSize() ;
634 pt.y += MacGetTopBorderSize() ;
635 }
636 }
637
638 if (x)
639 *x = (int) pt.x ;
640 if (y)
641 *y = (int) pt.y ;
642}
643
644wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
645{
646 wxSize sizeTotal = size;
647
648 int innerwidth, innerheight;
649 int left, top;
650 int outerwidth, outerheight;
651
652 m_peer->GetContentArea( left, top, innerwidth, innerheight );
653 m_peer->GetSize( outerwidth, outerheight );
654
0c530e5a
SC
655 sizeTotal.x += outerwidth-innerwidth;
656 sizeTotal.y += outerheight-innerheight;
524c47aa
SC
657
658 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
659 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
660
661 return sizeTotal;
662}
663
664// Get size *available for subwindows* i.e. excluding menu bar etc.
665void wxWindowMac::DoGetClientSize( int *x, int *y ) const
666{
667 int ww, hh;
668
669 int left, top;
670
671 m_peer->GetContentArea( left, top, ww, hh );
672
673 if (m_hScrollBar && m_hScrollBar->IsShown() )
674 hh -= m_hScrollBar->GetSize().y ;
675
676 if (m_vScrollBar && m_vScrollBar->IsShown() )
677 ww -= m_vScrollBar->GetSize().x ;
678
679 if (x)
680 *x = ww;
681 if (y)
682 *y = hh;
683}
684
685bool wxWindowMac::SetCursor(const wxCursor& cursor)
686{
687 if (m_cursor.IsSameAs(cursor))
688 return false;
689
690 if (!cursor.IsOk())
691 {
692 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
693 return false ;
694 }
695 else
696 {
697 if ( ! wxWindowBase::SetCursor( cursor ) )
698 return false ;
699 }
700
701 wxASSERT_MSG( m_cursor.Ok(),
702 wxT("cursor must be valid after call to the base version"));
703
54f11060
SC
704 if ( GetPeer() != NULL )
705 GetPeer()->SetCursor( m_cursor );
524c47aa
SC
706
707 return true ;
708}
709
710#if wxUSE_MENUS
711bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
712{
713#ifndef __WXUNIVERSAL__
714 menu->SetInvokingWindow((wxWindow*)this);
715 menu->UpdateUI();
716
717 if ( x == wxDefaultCoord && y == wxDefaultCoord )
718 {
719 wxPoint mouse = wxGetMousePosition();
720 x = mouse.x;
721 y = mouse.y;
722 }
723 else
724 {
725 ClientToScreen( &x , &y ) ;
726 }
2cb5d2d2 727 menu->GetPeer()->PopUp(this, x, y);
524c47aa 728 menu->SetInvokingWindow( NULL );
524c47aa
SC
729 return true;
730#else
731 // actually this shouldn't be called, because universal is having its own implementation
732 return false;
733#endif
734}
735#endif
736
737// ----------------------------------------------------------------------------
738// tooltips
739// ----------------------------------------------------------------------------
740
741#if wxUSE_TOOLTIPS
742
743void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
744{
745 wxWindowBase::DoSetToolTip(tooltip);
746
747 if ( m_tooltip )
748 m_tooltip->SetWindow(this);
749}
750
751#endif
752
753void wxWindowMac::MacInvalidateBorders()
754{
755 if ( m_peer == NULL )
756 return ;
757
758 bool vis = IsShownOnScreen() ;
759 if ( !vis )
760 return ;
761
762 int outerBorder = MacGetLeftBorderSize() ;
b2088388
SC
763
764 if ( m_peer->NeedsFocusRect() )
524c47aa 765 outerBorder += 4 ;
524c47aa
SC
766
767 if ( outerBorder == 0 )
768 return ;
769
770 // now we know that we have something to do at all
524c47aa
SC
771
772 int tx,ty,tw,th;
773
774 m_peer->GetSize( tw, th );
775 m_peer->GetPosition( tx, ty );
776
777 wxRect leftupdate( tx-outerBorder,ty,outerBorder,th );
778 wxRect rightupdate( tx+tw, ty, outerBorder, th );
779 wxRect topupdate( tx-outerBorder, ty-outerBorder, tw + 2 * outerBorder, outerBorder );
780 wxRect bottomupdate( tx-outerBorder, ty + th, tw + 2 * outerBorder, outerBorder );
781
1a4e2d5b
KO
782 if (GetParent()) {
783 GetParent()->m_peer->SetNeedsDisplay(&leftupdate);
784 GetParent()->m_peer->SetNeedsDisplay(&rightupdate);
785 GetParent()->m_peer->SetNeedsDisplay(&topupdate);
786 GetParent()->m_peer->SetNeedsDisplay(&bottomupdate);
787 }
524c47aa
SC
788}
789
790void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
791{
792 // this is never called for a toplevel window, so we know we have a parent
793 int former_x , former_y , former_w, former_h ;
794
795 // Get true coordinates of former position
796 DoGetPosition( &former_x , &former_y ) ;
797 DoGetSize( &former_w , &former_h ) ;
798
799 wxWindow *parent = GetParent();
800 if ( parent )
801 {
802 wxPoint pt(parent->GetClientAreaOrigin());
803 former_x += pt.x ;
804 former_y += pt.y ;
805 }
806
807 int actualWidth = width ;
808 int actualHeight = height ;
809 int actualX = x;
810 int actualY = y;
811
f1b1c779
SC
812#if 0
813 // min and max sizes are only for sizers, not for explicit size setting
524c47aa
SC
814 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
815 actualWidth = m_minWidth;
816 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
817 actualHeight = m_minHeight;
818 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
819 actualWidth = m_maxWidth;
820 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
821 actualHeight = m_maxHeight;
f1b1c779 822#endif
524c47aa
SC
823
824 bool doMove = false, doResize = false ;
825
826 if ( actualX != former_x || actualY != former_y )
827 doMove = true ;
828
829 if ( actualWidth != former_w || actualHeight != former_h )
830 doResize = true ;
831
832 if ( doMove || doResize )
833 {
834 // as the borders are drawn outside the native control, we adjust now
835
836 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
837 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
838 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
839
1a4e2d5b 840 if ( parent && !parent->IsTopLevel() )
524c47aa 841 {
1a4e2d5b 842 bounds.Offset( -parent->MacGetLeftBorderSize(), -parent->MacGetTopBorderSize() );
524c47aa
SC
843 }
844
845 MacInvalidateBorders() ;
846
847 m_cachedClippedRectValid = false ;
848
849 m_peer->Move( bounds.x, bounds.y, bounds.width, bounds.height);
850
851 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
852
853 MacInvalidateBorders() ;
854
855 MacRepositionScrollBars() ;
856 if ( doMove )
857 {
858 wxPoint point(actualX, actualY);
859 wxMoveEvent event(point, m_windowId);
860 event.SetEventObject(this);
861 HandleWindowEvent(event) ;
862 }
863
864 if ( doResize )
865 {
866 MacRepositionScrollBars() ;
867 wxSize size(actualWidth, actualHeight);
868 wxSizeEvent event(size, m_windowId);
869 event.SetEventObject(this);
870 HandleWindowEvent(event);
871 }
872 }
873}
874
875wxSize wxWindowMac::DoGetBestSize() const
876{
877 if ( m_macIsUserPane || IsTopLevel() )
878 {
879 return wxWindowBase::DoGetBestSize() ;
880 }
881 else
882 {
883 wxRect r ;
884
885 m_peer->GetBestRect(&r);
886
887 if ( r.GetWidth() == 0 && r.GetHeight() == 0 )
888 {
889 r.x =
890 r.y = 0 ;
891 r.width =
892 r.height = 16 ;
893
894 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
895 {
896 r.height = 16 ;
897 }
898 #if wxUSE_SPINBTN
899 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
900 {
901 r.height = 24 ;
902 }
903 #endif
904 else
905 {
906 // return wxWindowBase::DoGetBestSize() ;
907 }
908 }
909
910 int bestWidth = r.width + MacGetLeftBorderSize() +
911 MacGetRightBorderSize();
912 int bestHeight = r.height + MacGetTopBorderSize() +
913 MacGetBottomBorderSize();
914 if ( bestHeight < 10 )
915 bestHeight = 13 ;
916
917 return wxSize(bestWidth, bestHeight);
918 }
919}
920
921// set the size of the window: if the dimensions are positive, just use them,
922// but if any of them is equal to -1, it means that we must find the value for
923// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
924// which case -1 is a valid value for x and y)
925//
926// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
927// the width/height to best suit our contents, otherwise we reuse the current
928// width/height
929void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
930{
931 // get the current size and position...
932 int currentX, currentY;
933 int currentW, currentH;
934
935 GetPosition(&currentX, &currentY);
936 GetSize(&currentW, &currentH);
937
938 // ... and don't do anything (avoiding flicker) if it's already ok
939 if ( x == currentX && y == currentY &&
940 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
941 {
942 // TODO: REMOVE
943 MacRepositionScrollBars() ; // we might have a real position shift
944
e47e063a
RR
945 if (sizeFlags & wxSIZE_FORCE_EVENT)
946 {
947 wxSizeEvent event( wxSize(width,height), GetId() );
948 event.SetEventObject( this );
949 HandleWindowEvent( event );
950 }
951
524c47aa
SC
952 return;
953 }
954
955 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
956 {
957 if ( x == wxDefaultCoord )
958 x = currentX;
959 if ( y == wxDefaultCoord )
960 y = currentY;
961 }
962
963 AdjustForParentClientOrigin( x, y, sizeFlags );
964
965 wxSize size = wxDefaultSize;
966 if ( width == wxDefaultCoord )
967 {
968 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
969 {
970 size = DoGetBestSize();
971 width = size.x;
972 }
973 else
974 {
975 // just take the current one
976 width = currentW;
977 }
978 }
979
980 if ( height == wxDefaultCoord )
981 {
982 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
983 {
984 if ( size.x == wxDefaultCoord )
985 size = DoGetBestSize();
986 // else: already called DoGetBestSize() above
987
988 height = size.y;
989 }
990 else
991 {
992 // just take the current one
993 height = currentH;
994 }
995 }
996
997 DoMoveWindow( x, y, width, height );
998}
999
1000wxPoint wxWindowMac::GetClientAreaOrigin() const
1001{
1002 int left,top,width,height;
1003 m_peer->GetContentArea( left , top , width , height);
1004 return wxPoint( left + MacGetLeftBorderSize() , top + MacGetTopBorderSize() );
1005}
1006
1007void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1008{
1009 if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
1010 {
1011 int currentclientwidth , currentclientheight ;
1012 int currentwidth , currentheight ;
1013
1014 GetClientSize( &currentclientwidth , &currentclientheight ) ;
1015 GetSize( &currentwidth , &currentheight ) ;
1016
1017 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
1018 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1019 }
1020}
1021
1022void wxWindowMac::SetLabel(const wxString& title)
1023{
1024 m_label = title ;
1025
423939b2 1026 if ( m_peer && m_peer->IsOk() && !(IsKindOf( CLASSINFO(wxButton) ) && GetId() == wxID_HELP) )
524c47aa
SC
1027 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ;
1028
1029 // do not trigger refreshes upon invisible and possible partly created objects
1030 if ( IsShownOnScreen() )
1031 Refresh() ;
1032}
1033
1034wxString wxWindowMac::GetLabel() const
1035{
1036 return m_label ;
1037}
1038
1039bool wxWindowMac::Show(bool show)
1040{
1041 if ( !wxWindowBase::Show(show) )
1042 return false;
1043
1044 if ( m_peer )
1045 m_peer->SetVisibility( show ) ;
1046
1047 return true;
1048}
1049
1050void wxWindowMac::DoEnable(bool enable)
1051{
1052 m_peer->Enable( enable ) ;
1053}
1054
1055//
1056// status change notifications
1057//
1058
1059void wxWindowMac::MacVisibilityChanged()
1060{
1061}
1062
1063void wxWindowMac::MacHiliteChanged()
1064{
1065}
1066
1067void wxWindowMac::MacEnabledStateChanged()
1068{
1069 OnEnabled( m_peer->IsEnabled() );
1070}
1071
1072//
1073// status queries on the inherited window's state
1074//
1075
1076bool wxWindowMac::MacIsReallyEnabled()
1077{
1078 return m_peer->IsEnabled() ;
1079}
1080
1081bool wxWindowMac::MacIsReallyHilited()
1082{
1083#if wxOSX_USE_CARBON
1084 return m_peer->IsActive();
1085#else
1086 return true; // TODO
1087#endif
1088}
1089
1090int wxWindowMac::GetCharHeight() const
1091{
f55d9f74
SC
1092 wxCoord height;
1093 GetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL );
524c47aa 1094
f55d9f74 1095 return height;
524c47aa
SC
1096}
1097
1098int wxWindowMac::GetCharWidth() const
1099{
f55d9f74
SC
1100 wxCoord width;
1101 GetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL );
524c47aa 1102
f55d9f74 1103 return width;
524c47aa
SC
1104}
1105
6de70470
VZ
1106void wxWindowMac::DoGetTextExtent(const wxString& str,
1107 int *x, int *y,
1108 int *descent,
1109 int *externalLeading,
1110 const wxFont *theFont) const
524c47aa
SC
1111{
1112 const wxFont *fontToUse = theFont;
1113 wxFont tempFont;
1114 if ( !fontToUse )
1115 {
1116 tempFont = GetFont();
1117 fontToUse = &tempFont;
1118 }
1119
f55d9f74
SC
1120 wxGraphicsContext* ctx = wxGraphicsContext::Create();
1121 ctx->SetFont( *fontToUse, *wxBLACK );
1122
1123 wxDouble h , d , e , w;
1124 ctx->GetTextExtent( str, &w, &h, &d, &e );
1125
1126 delete ctx;
1127
524c47aa 1128 if ( externalLeading )
f55d9f74 1129 *externalLeading = (wxCoord)(e+0.5);
524c47aa 1130 if ( descent )
f55d9f74 1131 *descent = (wxCoord)(d+0.5);
524c47aa 1132 if ( x )
f55d9f74 1133 *x = (wxCoord)(w+0.5);
524c47aa 1134 if ( y )
f55d9f74 1135 *y = (wxCoord)(h+0.5);
524c47aa
SC
1136}
1137
1138/*
1139 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1140 * we always intersect with the entire window, not only with the client area
1141 */
1142
1143void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
1144{
1145 if ( m_peer == NULL )
1146 return ;
1147
1148 if ( !IsShownOnScreen() )
1149 return ;
1150
1151 m_peer->SetNeedsDisplay( rect ) ;
1152}
1153
1154void wxWindowMac::DoFreeze()
1155{
1156#if wxOSX_USE_CARBON
1157 if ( m_peer && m_peer->IsOk() )
1158 m_peer->SetDrawingEnabled( false ) ;
1159#endif
1160}
1161
1162void wxWindowMac::DoThaw()
1163{
1164#if wxOSX_USE_CARBON
1165 if ( m_peer && m_peer->IsOk() )
1166 {
1167 m_peer->SetDrawingEnabled( true ) ;
1168 m_peer->InvalidateWithChildren() ;
1169 }
1170#endif
1171}
1172
1173wxWindow *wxGetActiveWindow()
1174{
1175 // actually this is a windows-only concept
1176 return NULL;
1177}
1178
1179// Coordinates relative to the window
1180void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos))
1181{
1182 // We really don't move the mouse programmatically under Mac.
1183}
1184
1185void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
1186{
1187 if ( MacGetTopLevelWindow() == NULL )
1188 return ;
1189/*
1190#if TARGET_API_MAC_OSX
1191 if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
1192 {
1193 }
1194 else
1195#endif
1196*/
1197 if ( GetBackgroundStyle() == wxBG_STYLE_COLOUR )
1198 {
1199 event.GetDC()->Clear() ;
1200 }
1201 else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
1202 {
1203 // don't skip the event here, custom background means that the app
1204 // is drawing it itself in its OnPaint(), so don't draw it at all
1205 // now to avoid flicker
1206 }
1207 else
1208 {
1209 event.Skip() ;
1210 }
1211}
1212
1213void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
1214{
1215 event.Skip() ;
1216}
1217
1218int wxWindowMac::GetScrollPos(int orient) const
1219{
1220 if ( orient == wxHORIZONTAL )
1221 {
1222 if ( m_hScrollBar )
1223 return m_hScrollBar->GetThumbPosition() ;
1224 }
1225 else
1226 {
1227 if ( m_vScrollBar )
1228 return m_vScrollBar->GetThumbPosition() ;
1229 }
1230
1231 return 0;
1232}
1233
1234// This now returns the whole range, not just the number
1235// of positions that we can scroll.
1236int wxWindowMac::GetScrollRange(int orient) const
1237{
1238 if ( orient == wxHORIZONTAL )
1239 {
1240 if ( m_hScrollBar )
1241 return m_hScrollBar->GetRange() ;
1242 }
1243 else
1244 {
1245 if ( m_vScrollBar )
1246 return m_vScrollBar->GetRange() ;
1247 }
1248
1249 return 0;
1250}
1251
1252int wxWindowMac::GetScrollThumb(int orient) const
1253{
1254 if ( orient == wxHORIZONTAL )
1255 {
1256 if ( m_hScrollBar )
1257 return m_hScrollBar->GetThumbSize() ;
1258 }
1259 else
1260 {
1261 if ( m_vScrollBar )
1262 return m_vScrollBar->GetThumbSize() ;
1263 }
1264
1265 return 0;
1266}
1267
1268void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
1269{
1270 if ( orient == wxHORIZONTAL )
1271 {
1272 if ( m_hScrollBar )
1273 m_hScrollBar->SetThumbPosition( pos ) ;
1274 }
1275 else
1276 {
1277 if ( m_vScrollBar )
1278 m_vScrollBar->SetThumbPosition( pos ) ;
1279 }
1280}
1281
1282void
1283wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag)
1284{
1285 bool needVisibilityUpdate = false;
1286
1287 if ( m_hScrollBarAlwaysShown != hflag )
1288 {
1289 m_hScrollBarAlwaysShown = hflag;
1290 needVisibilityUpdate = true;
1291 }
1292
1293 if ( m_vScrollBarAlwaysShown != vflag )
1294 {
1295 m_vScrollBarAlwaysShown = vflag;
1296 needVisibilityUpdate = true;
1297 }
1298
1299 if ( needVisibilityUpdate )
1300 DoUpdateScrollbarVisibility();
1301}
1302
1303//
1304// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
1305// our own window origin is at leftOrigin/rightOrigin
1306//
1307
1308void wxWindowMac::MacPaintGrowBox()
1309{
1310 if ( IsTopLevel() )
1311 return ;
1312
1313 if ( MacHasScrollBarCorner() )
1314 {
1315 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
1316 wxASSERT( cgContext ) ;
1317
1318 int tx,ty,tw,th;
1319
1320 m_peer->GetSize( tw, th );
1321 m_peer->GetPosition( tx, ty );
1322
1323 Rect rect = { ty,tx, ty+th, tx+tw };
1324
1325
1326 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
1327 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
524c47aa
SC
1328 CGContextSaveGState( cgContext );
1329
1330 if ( m_backgroundColour.Ok() )
1331 {
1332 CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() );
1333 }
1334 else
1335 {
1336 CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 );
1337 }
1338 CGContextFillRect( cgContext, cgrect );
1339 CGContextRestoreGState( cgContext );
1340 }
1341}
1342
1343void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) )
1344{
1345 if ( IsTopLevel() )
1346 return ;
1347
1348 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
1349
1350 // back to the surrounding frame rectangle
1351 int tx,ty,tw,th;
1352
1353 m_peer->GetSize( tw, th );
1354 m_peer->GetPosition( tx, ty );
1355
1356 Rect rect = { ty,tx, ty+th, tx+tw };
1357
1358#if wxOSX_USE_COCOA_OR_CARBON
1359
1360 InsetRect( &rect, -1 , -1 ) ;
1361
1362 {
1363 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
1364 rect.bottom - rect.top ) ;
1365
524c47aa
SC
1366 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
1367 wxASSERT( cgContext ) ;
1368
f2f6030e 1369 if ( m_peer->NeedsFrame() )
524c47aa 1370 {
f2f6030e
SC
1371 HIThemeFrameDrawInfo info ;
1372 memset( &info, 0 , sizeof(info) ) ;
1373
1374 info.version = 0 ;
1375 info.kind = 0 ;
1376 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
1377 info.isFocused = hasFocus ;
1378
1379 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
1380 {
1381 info.kind = kHIThemeFrameTextFieldSquare ;
1382 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
1383 }
1384 else if ( HasFlag(wxSIMPLE_BORDER) )
1385 {
1386 info.kind = kHIThemeFrameListBox ;
1387 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
1388 }
524c47aa 1389 }
f2f6030e
SC
1390
1391 if ( hasFocus )
524c47aa
SC
1392 {
1393 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
1394 }
524c47aa
SC
1395 }
1396#endif // wxOSX_USE_COCOA_OR_CARBON
1397}
1398
1399void wxWindowMac::RemoveChild( wxWindowBase *child )
1400{
1401 if ( child == m_hScrollBar )
1402 m_hScrollBar = NULL ;
1403 if ( child == m_vScrollBar )
1404 m_vScrollBar = NULL ;
1405
1406 wxWindowBase::RemoveChild( child ) ;
1407}
1408
1409void wxWindowMac::DoUpdateScrollbarVisibility()
1410{
1411 bool triggerSizeEvent = false;
1412
1413 if ( m_hScrollBar )
1414 {
1415 bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded();
1416
1417 if ( m_hScrollBar->IsShown() != showHScrollBar )
1418 {
1419 m_hScrollBar->Show( showHScrollBar );
1420 triggerSizeEvent = true;
1421 }
1422 }
1423
1424 if ( m_vScrollBar)
1425 {
1426 bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded();
1427
1428 if ( m_vScrollBar->IsShown() != showVScrollBar )
1429 {
1430 m_vScrollBar->Show( showVScrollBar ) ;
1431 triggerSizeEvent = true;
1432 }
1433 }
1434
1435 MacRepositionScrollBars() ;
1436 if ( triggerSizeEvent )
1437 {
1438 wxSizeEvent event(GetSize(), m_windowId);
1439 event.SetEventObject(this);
1440 HandleWindowEvent(event);
1441 }
1442}
1443
1444// New function that will replace some of the above.
1445void wxWindowMac::SetScrollbar(int orient, int pos, int thumb,
1446 int range, bool refresh)
1447{
1448 if ( orient == wxHORIZONTAL && m_hScrollBar )
1449 m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
1450 else if ( orient == wxVERTICAL && m_vScrollBar )
1451 m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
1452
1453 DoUpdateScrollbarVisibility();
1454}
1455
1456// Does a physical scroll
1457void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
1458{
1459 if ( dx == 0 && dy == 0 )
1460 return ;
1461
1462 int width , height ;
1463 GetClientSize( &width , &height ) ;
1464
1465 {
1466 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
1467 if ( rect )
1468 scrollrect.Intersect( *rect ) ;
1469 // as the native control might be not a 0/0 wx window coordinates, we have to offset
1470 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
1471
1472 m_peer->ScrollRect( &scrollrect, dx, dy );
1473 }
1474
1475 wxWindowMac *child;
1476 int x, y, w, h;
1477 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
1478 {
1479 child = node->GetData();
1480 if (child == NULL)
1481 continue;
1482 if (child == m_vScrollBar)
1483 continue;
1484 if (child == m_hScrollBar)
1485 continue;
1486 if (child->IsTopLevel())
1487 continue;
1488
1489 child->GetPosition( &x, &y );
1490 child->GetSize( &w, &h );
1491 if (rect)
1492 {
1493 wxRect rc( x, y, w, h );
1494 if (rect->Intersects( rc ))
1495 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
1496 }
1497 else
1498 {
1499 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
1500 }
1501 }
1502}
1503
1504void wxWindowMac::MacOnScroll( wxScrollEvent &event )
1505{
1506 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
1507 {
1508 wxScrollWinEvent wevent;
1509 wevent.SetPosition(event.GetPosition());
1510 wevent.SetOrientation(event.GetOrientation());
1511 wevent.SetEventObject(this);
1512
1513 if (event.GetEventType() == wxEVT_SCROLL_TOP)
1514 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
1515 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
1516 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
1517 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
1518 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
1519 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
1520 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
1521 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
1522 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
1523 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
1524 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
1525 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
1526 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
1527 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
1528 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
1529
1530 HandleWindowEvent(wevent);
1531 }
1532}
1533
524c47aa
SC
1534wxWindow *wxWindowBase::DoFindFocus()
1535{
f06e0fea 1536 return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus());
524c47aa
SC
1537}
1538
1539void wxWindowMac::OnInternalIdle()
1540{
1541 // This calls the UI-update mechanism (querying windows for
1542 // menu/toolbar/control state information)
1543 if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
1544 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
1545}
1546
1547// Raise the window to the top of the Z order
1548void wxWindowMac::Raise()
1549{
1550 m_peer->Raise();
1551}
1552
1553// Lower the window to the bottom of the Z order
1554void wxWindowMac::Lower()
1555{
1556 m_peer->Lower();
1557}
1558
1559// static wxWindow *gs_lastWhich = NULL;
1560
1561bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
1562{
1563 // first trigger a set cursor event
1564
1565 wxPoint clientorigin = GetClientAreaOrigin() ;
1566 wxSize clientsize = GetClientSize() ;
1567 wxCursor cursor ;
1568 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
1569 {
1570 wxSetCursorEvent event( pt.x , pt.y );
1571
1572 bool processedEvtSetCursor = HandleWindowEvent(event);
1573 if ( processedEvtSetCursor && event.HasCursor() )
1574 {
1575 cursor = event.GetCursor() ;
1576 }
1577 else
1578 {
1579 // the test for processedEvtSetCursor is here to prevent using m_cursor
1580 // if the user code caught EVT_SET_CURSOR() and returned nothing from
1581 // it - this is a way to say that our cursor shouldn't be used for this
1582 // point
1583 if ( !processedEvtSetCursor && m_cursor.Ok() )
1584 cursor = m_cursor ;
1585
1586 if ( !wxIsBusy() && !GetParent() )
1587 cursor = *wxSTANDARD_CURSOR ;
1588 }
1589
1590 if ( cursor.Ok() )
1591 cursor.MacInstall() ;
1592 }
1593
1594 return cursor.Ok() ;
1595}
1596
1597wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
1598{
1599#if wxUSE_TOOLTIPS
1600 if ( m_tooltip )
1601 return m_tooltip->GetTip() ;
1602#endif
1603
1604 return wxEmptyString ;
1605}
1606
1607void wxWindowMac::ClearBackground()
1608{
1609 Refresh() ;
1610 Update() ;
1611}
1612
1613void wxWindowMac::Update()
1614{
1615 wxNonOwnedWindow* top = MacGetTopLevelWindow();
1616 if (top)
1617 top->Update() ;
1618}
1619
1620wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const
1621{
1622 wxWindowMac *iter = (wxWindowMac*)this ;
1623
1624 while ( iter )
1625 {
1626 if ( iter->IsTopLevel() )
1627 {
1628 wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
1629 if ( toplevel )
1630 return toplevel;
1631#if wxUSE_POPUPWIN
1632 wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
1633 if ( popupwin )
1634 return popupwin;
1635#endif
1636 }
1637 iter = iter->GetParent() ;
1638 }
1639
1640 return NULL ;
1641}
1642
1643const wxRect& wxWindowMac::MacGetClippedClientRect() const
1644{
1645 MacUpdateClippedRects() ;
1646
1647 return m_cachedClippedClientRect ;
1648}
1649
1650const wxRect& wxWindowMac::MacGetClippedRect() const
1651{
1652 MacUpdateClippedRects() ;
1653
1654 return m_cachedClippedRect ;
1655}
1656
1657const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
1658{
1659 MacUpdateClippedRects() ;
1660
1661 return m_cachedClippedRectWithOuterStructure ;
1662}
1663
1664const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
1665{
1666 static wxRegion emptyrgn ;
1667
1668 if ( !m_isBeingDeleted && IsShownOnScreen() )
1669 {
1670 MacUpdateClippedRects() ;
1671 if ( includeOuterStructures )
1672 return m_cachedClippedRegionWithOuterStructure ;
1673 else
1674 return m_cachedClippedRegion ;
1675 }
1676 else
1677 {
1678 return emptyrgn ;
1679 }
1680}
1681
1682void wxWindowMac::MacUpdateClippedRects() const
1683{
1684#if wxOSX_USE_CARBON
1685 if ( m_cachedClippedRectValid )
1686 return ;
1687
1688 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
1689 // also a window dc uses this, in this case we only clip in the hierarchy for hard
1690 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
1691 // to add focus borders everywhere
1692
1693 Rect rIncludingOuterStructures ;
1694
1695 int tx,ty,tw,th;
1696
1697 m_peer->GetSize( tw, th );
1698 m_peer->GetPosition( tx, ty );
1699
1700 Rect r = { ty,tx, ty+th, tx+tw };
1701
1702 r.left -= MacGetLeftBorderSize() ;
1703 r.top -= MacGetTopBorderSize() ;
1704 r.bottom += MacGetBottomBorderSize() ;
1705 r.right += MacGetRightBorderSize() ;
1706
1707 r.right -= r.left ;
1708 r.bottom -= r.top ;
1709 r.left = 0 ;
1710 r.top = 0 ;
1711
1712 rIncludingOuterStructures = r ;
1713 InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
1714
1715 wxRect cl = GetClientRect() ;
1716 Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
1717
1718 int x , y ;
1719 wxSize size ;
1720 const wxWindow* child = (wxWindow*) this ;
1721 const wxWindow* parent = NULL ;
1722
1723 while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
1724 {
1725 if ( parent->MacIsChildOfClientArea(child) )
1726 {
1727 size = parent->GetClientSize() ;
1728 wxPoint origin = parent->GetClientAreaOrigin() ;
1729 x = origin.x ;
1730 y = origin.y ;
1731 }
1732 else
1733 {
1734 // this will be true for scrollbars, toolbars etc.
1735 size = parent->GetSize() ;
1736 y = parent->MacGetTopBorderSize() ;
1737 x = parent->MacGetLeftBorderSize() ;
1738 size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
1739 size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
1740 }
1741
1742 parent->MacWindowToRootWindow( &x, &y ) ;
1743 MacRootWindowToWindow( &x , &y ) ;
1744
1745 Rect rparent = { y , x , y + size.y , x + size.x } ;
1746
1747 // the wxwindow and client rects will always be clipped
1748 SectRect( &r , &rparent , &r ) ;
1749 SectRect( &rClient , &rparent , &rClient ) ;
1750
1751 // the structure only at 'hard' borders
1752 if ( parent->MacClipChildren() ||
1753 ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
1754 {
1755 SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
1756 }
1757
1758 child = parent ;
1759 }
1760
1761 m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
1762 m_cachedClippedClientRect = wxRect( rClient.left , rClient.top ,
1763 rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
1764 m_cachedClippedRectWithOuterStructure = wxRect(
1765 rIncludingOuterStructures.left , rIncludingOuterStructures.top ,
1766 rIncludingOuterStructures.right - rIncludingOuterStructures.left ,
1767 rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
1768
1769 m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
1770 m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
1771 m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
1772
1773 m_cachedClippedRectValid = true ;
1774#endif
1775}
1776
1777/*
1778 This function must not change the updatergn !
1779 */
5398a2e0 1780bool wxWindowMac::MacDoRedraw( long time )
524c47aa
SC
1781{
1782 bool handled = false ;
5398a2e0
SC
1783
1784 wxRegion formerUpdateRgn = m_updateRegion;
1785 wxRegion clientUpdateRgn = formerUpdateRgn;
524c47aa 1786
5398a2e0
SC
1787 wxSize sz = GetClientSize() ;
1788 wxPoint origin = GetClientAreaOrigin() ;
1789
1790 clientUpdateRgn.Intersect(origin.x , origin.y , origin.x + sz.x , origin.y + sz.y);
1791
1792 // first send an erase event to the entire update area
524c47aa 1793 {
5398a2e0
SC
1794 // for the toplevel window this really is the entire area
1795 // for all the others only their client area, otherwise they
1796 // might be drawing with full alpha and eg put blue into
1797 // the grow-box area of a scrolled window (scroll sample)
1798 wxDC* dc = new wxWindowDC(this);
1799 if ( IsTopLevel() )
1800 dc->SetDeviceClippingRegion(formerUpdateRgn);
1801 else
1802 dc->SetDeviceClippingRegion(clientUpdateRgn);
524c47aa 1803
5398a2e0
SC
1804 wxEraseEvent eevent( GetId(), dc );
1805 eevent.SetEventObject( this );
1806 HandleWindowEvent( eevent );
1807 delete dc ;
1808 }
524c47aa 1809
5398a2e0 1810 MacPaintGrowBox();
524c47aa 1811
5398a2e0
SC
1812 // calculate a client-origin version of the update rgn and set m_updateRegion to that
1813 clientUpdateRgn.Offset( -origin.x , -origin.y );
1814 m_updateRegion = clientUpdateRgn ;
524c47aa 1815
5398a2e0
SC
1816 if ( !m_updateRegion.Empty() )
1817 {
1818 // paint the window itself
524c47aa 1819
45f5bb03 1820 wxPaintEvent event(GetId());
5398a2e0
SC
1821 event.SetTimestamp(time);
1822 event.SetEventObject(this);
1823 handled = HandleWindowEvent(event);
1824 }
524c47aa 1825
5398a2e0
SC
1826 m_updateRegion = formerUpdateRgn;
1827 return handled;
1828}
524c47aa 1829
5398a2e0
SC
1830void wxWindowMac::MacPaintChildrenBorders()
1831{
1832 // now we cannot rely on having its borders drawn by a window itself, as it does not
1833 // get the updateRgn wide enough to always do so, so we do it from the parent
1834 // this would also be the place to draw any custom backgrounds for native controls
1835 // in Composited windowing
1836 wxPoint clientOrigin = GetClientAreaOrigin() ;
524c47aa 1837
5398a2e0
SC
1838 wxWindowMac *child;
1839 int x, y, w, h;
1840 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
1841 {
1842 child = node->GetData();
1843 if (child == NULL)
1844 continue;
1845 if (child == m_vScrollBar)
1846 continue;
1847 if (child == m_hScrollBar)
1848 continue;
1849 if (child->IsTopLevel())
1850 continue;
1851 if (!child->IsShown())
1852 continue;
1853
1854 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
1855
1856 child->GetPosition( &x, &y );
1857 child->GetSize( &w, &h );
1858
1859 if ( m_updateRegion.Contains(clientOrigin.x+x-10, clientOrigin.y+y-10, w+20, h+20) )
524c47aa 1860 {
5398a2e0
SC
1861 // paint custom borders
1862 wxNcPaintEvent eventNc( child->GetId() );
1863 eventNc.SetEventObject( child );
1864 if ( !child->HandleWindowEvent( eventNc ) )
524c47aa 1865 {
5398a2e0 1866 child->MacPaintBorders(0, 0) ;
524c47aa
SC
1867 }
1868 }
1869 }
524c47aa
SC
1870}
1871
1872
1873WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
1874{
1875 wxNonOwnedWindow* tlw = MacGetTopLevelWindow();
1876 return tlw ? tlw->GetWXWindow() : NULL ;
1877}
1878
1879bool wxWindowMac::MacHasScrollBarCorner() const
1880{
1881 /* Returns whether the scroll bars in a wxScrolledWindow should be
1882 * shortened. Scroll bars should be shortened if either:
1883 *
1884 * - both scroll bars are visible, or
1885 *
1886 * - there is a resize box in the parent frame's corner and this
1887 * window shares the bottom and right edge with the parent
1888 * frame.
1889 */
1890
1891 if ( m_hScrollBar == NULL && m_vScrollBar == NULL )
1892 return false;
1893
1894 if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
1895 && ( m_vScrollBar && m_vScrollBar->IsShown() ) )
1896 {
1897 // Both scroll bars visible
1898 return true;
1899 }
1900 else
1901 {
1902 wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight();
1903
1904 for ( const wxWindow *win = (wxWindow*)this; win; win = win->GetParent() )
1905 {
1906 const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
1907 if ( frame )
1908 {
1909 if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
1910 {
1911 // Parent frame has resize handle
1912 wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
1913
1914 // Note: allow for some wiggle room here as wxMac's
1915 // window rect calculations seem to be imprecise
1916 if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2
1917 && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 )
1918 {
1919 // Parent frame has resize handle and shares
1920 // right bottom corner
1921 return true ;
1922 }
1923 else
1924 {
1925 // Parent frame has resize handle but doesn't
1926 // share right bottom corner
1927 return false ;
1928 }
1929 }
1930 else
1931 {
1932 // Parent frame doesn't have resize handle
1933 return false ;
1934 }
1935 }
1936 }
1937
1938 // No parent frame found
1939 return false ;
1940 }
1941}
1942
1943void wxWindowMac::MacCreateScrollBars( long style )
1944{
1945 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
1946
1947 if ( style & ( wxVSCROLL | wxHSCROLL ) )
1948 {
1949 int scrlsize = MAC_SCROLLBAR_SIZE ;
1950 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
1951 {
1952 scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
1953 }
1954
1955 int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
1956 int width, height ;
1957 GetClientSize( &width , &height ) ;
1958
1959 wxPoint vPoint(width - scrlsize, 0) ;
1960 wxSize vSize(scrlsize, height - adjust) ;
1961 wxPoint hPoint(0, height - scrlsize) ;
1962 wxSize hSize(width - adjust, scrlsize) ;
1963
1964 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
1965 if ( style & wxVSCROLL )
1966 {
1967 m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
1968 m_vScrollBar->SetMinSize( wxDefaultSize );
1969 }
1970
1971 if ( style & wxHSCROLL )
1972 {
1973 m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
1974 m_hScrollBar->SetMinSize( wxDefaultSize );
1975 }
1976 }
1977
1978 // because the create does not take into account the client area origin
1979 // we might have a real position shift
1980 MacRepositionScrollBars() ;
1981}
1982
1983bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
1984{
1985 bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar)));
1986
1987 return result ;
1988}
1989
1990void wxWindowMac::MacRepositionScrollBars()
1991{
1992 if ( !m_hScrollBar && !m_vScrollBar )
1993 return ;
1994
1995 int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
1996 int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ;
1997
1998 // get real client area
1999 int width, height ;
2000 GetSize( &width , &height );
2001
2002 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2003 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2004
2005 wxPoint vPoint( width - scrlsize, 0 ) ;
2006 wxSize vSize( scrlsize, height - adjust ) ;
2007 wxPoint hPoint( 0 , height - scrlsize ) ;
2008 wxSize hSize( width - adjust, scrlsize ) ;
2009
2010 if ( m_vScrollBar )
2011 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
2012 if ( m_hScrollBar )
2013 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
2014}
2015
2016bool wxWindowMac::AcceptsFocus() const
2017{
f06e0fea
SC
2018 if ( MacIsUserPane() )
2019 return wxWindowBase::AcceptsFocus();
2020 else
2021 return m_peer->CanFocus();
524c47aa
SC
2022}
2023
2024void wxWindowMac::MacSuperChangedPosition()
2025{
2026 // only window-absolute structures have to be moved i.e. controls
2027
2028 m_cachedClippedRectValid = false ;
2029
2030 wxWindowMac *child;
2031 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2032 while ( node )
2033 {
2034 child = node->GetData();
2035 child->MacSuperChangedPosition() ;
2036
2037 node = node->GetNext();
2038 }
2039}
2040
2041void wxWindowMac::MacTopLevelWindowChangedPosition()
2042{
2043 // only screen-absolute structures have to be moved i.e. glcanvas
2044
2045 wxWindowMac *child;
2046 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2047 while ( node )
2048 {
2049 child = node->GetData();
2050 child->MacTopLevelWindowChangedPosition() ;
2051
2052 node = node->GetNext();
2053 }
2054}
2055
2056long wxWindowMac::MacGetLeftBorderSize() const
2057{
2058 if ( IsTopLevel() )
2059 return 0 ;
2060
2061 SInt32 border = 0 ;
2062
7185918d 2063 if ( m_peer && m_peer->NeedsFrame() )
524c47aa 2064 {
f2f6030e
SC
2065 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
2066 {
524c47aa 2067#if wxOSX_USE_COCOA_OR_CARBON
f2f6030e
SC
2068 // this metric is only the 'outset' outside the simple frame rect
2069 GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
2070 border += 1;
524c47aa 2071#else
f2f6030e 2072 border += 2;
524c47aa 2073#endif
f2f6030e
SC
2074 }
2075 else if (HasFlag(wxSIMPLE_BORDER))
2076 {
524c47aa 2077#if wxOSX_USE_COCOA_OR_CARBON
f2f6030e
SC
2078 // this metric is only the 'outset' outside the simple frame rect
2079 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2080 border += 1;
524c47aa 2081#else
f2f6030e 2082 border += 1;
524c47aa 2083#endif
f2f6030e 2084 }
524c47aa
SC
2085 }
2086
2087 return border ;
2088}
2089
2090long wxWindowMac::MacGetRightBorderSize() const
2091{
2092 // they are all symmetric in mac themes
2093 return MacGetLeftBorderSize() ;
2094}
2095
2096long wxWindowMac::MacGetTopBorderSize() const
2097{
2098 // they are all symmetric in mac themes
2099 return MacGetLeftBorderSize() ;
2100}
2101
2102long wxWindowMac::MacGetBottomBorderSize() const
2103{
2104 // they are all symmetric in mac themes
2105 return MacGetLeftBorderSize() ;
2106}
2107
2108long wxWindowMac::MacRemoveBordersFromStyle( long style )
2109{
2110 return style & ~wxBORDER_MASK ;
2111}
2112
2113// Find the wxWindowMac at the current mouse position, returning the mouse
2114// position.
2115wxWindow * wxFindWindowAtPointer( wxPoint& pt )
2116{
2117 pt = wxGetMousePosition();
2118 wxWindowMac* found = wxFindWindowAtPoint(pt);
2119
2120 return (wxWindow*) found;
2121}
2122
2123// Get the current mouse position.
2124wxPoint wxGetMousePosition()
2125{
2126 int x, y;
2127
2128 wxGetMousePosition( &x, &y );
2129
2130 return wxPoint(x, y);
2131}
2132
2133void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2134{
2135 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2136 {
2137 // copied from wxGTK : CS
2138 // VZ: shouldn't we move this to base class then?
2139
2140 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
2141 // except that:
2142 //
2143 // (a) it's a command event and so is propagated to the parent
2144 // (b) under MSW it can be generated from kbd too
2145 // (c) it uses screen coords (because of (a))
2146 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
2147 this->GetId(),
2148 this->ClientToScreen(event.GetPosition()));
2149 evtCtx.SetEventObject(this);
2150 if ( ! HandleWindowEvent(evtCtx) )
2151 event.Skip() ;
2152 }
2153 else
2154 {
2155 event.Skip() ;
2156 }
2157}
2158
19c7ac3d 2159void wxWindowMac::TriggerScrollEvent( wxEventType WXUNUSED(scrollEvent) )
524c47aa
SC
2160{
2161}
2162
2163Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
2164{
2165 int x, y, w, h ;
2166
2167 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
2168 Rect bounds = { y, x, y + h, x + w };
2169
2170 return bounds ;
2171}
2172
0faf03bf 2173bool wxWindowMac::OSXHandleClicked( double WXUNUSED(timestampsec) )
524c47aa
SC
2174{
2175 return false;
2176}
2177
2178wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF event )
2179{
2180#if wxOSX_USE_COCOA_OR_CARBON
4eb5a0ec 2181 if ( OSXHandleClicked( GetEventTime((EventRef)event) ) )
524c47aa
SC
2182 return noErr;
2183
2184 return eventNotHandledErr ;
2185#else
2186 return 0;
2187#endif
2188}
2189
2190bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
2191{
2192 wxWindowMac *newParent = (wxWindowMac *)newParentBase;
2193 if ( !wxWindowBase::Reparent(newParent) )
2194 return false;
2195
2196 m_peer->RemoveFromParent();
2197 m_peer->Embed( GetParent()->GetPeer() );
2198 return true;
2199}
2200
2201bool wxWindowMac::SetTransparent(wxByte alpha)
2202{
2203 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
2204
2205 if ( alpha != m_macAlpha )
2206 {
2207 m_macAlpha = alpha ;
2208 Refresh() ;
2209 }
2210 return true ;
2211}
2212
2213
2214bool wxWindowMac::CanSetTransparent()
2215{
2216 return true ;
2217}
2218
2219wxByte wxWindowMac::GetTransparent() const
2220{
2221 return m_macAlpha ;
2222}
2223
2224bool wxWindowMac::IsShownOnScreen() const
2225{
2226 if ( m_peer && m_peer->IsOk() )
2227 {
2228 bool peerVis = m_peer->IsVisible();
2229 bool wxVis = wxWindowBase::IsShownOnScreen();
2230 if( peerVis != wxVis )
2231 {
2232 // CS : put a breakpoint here to investigate differences
2233 // between native an wx visibilities
2234 // the only place where I've encountered them until now
2235 // are the hiding/showing sequences where the vis-changed event is
2236 // first sent to the innermost control, while wx does things
2237 // from the outmost control
2238 wxVis = wxWindowBase::IsShownOnScreen();
2239 return wxVis;
2240 }
2241
2242 return m_peer->IsVisible();
2243 }
2244 return wxWindowBase::IsShownOnScreen();
2245}
2246
4eb5a0ec 2247bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event )
19c7ac3d
SC
2248{
2249 bool handled = HandleWindowEvent( event ) ;
2250 if ( handled && event.GetSkipped() )
2251 handled = false ;
2252
2253#if wxUSE_ACCEL
2254 if ( !handled && event.GetEventType() == wxEVT_KEY_DOWN)
2255 {
2256 wxWindow *ancestor = this;
2257 while (ancestor)
2258 {
2259 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
2260 if (command != -1)
2261 {
2262 wxEvtHandler * const handler = ancestor->GetEventHandler();
2263
2264 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
2265 handled = handler->ProcessEvent( command_event );
2266
2267 if ( !handled )
2268 {
2269 // accelerators can also be used with buttons, try them too
2270 command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
2271 handled = handler->ProcessEvent( command_event );
2272 }
2273
2274 break;
2275 }
2276
2277 if (ancestor->IsTopLevel())
2278 break;
2279
2280 ancestor = ancestor->GetParent();
2281 }
2282 }
2283#endif // wxUSE_ACCEL
2284
2285 return handled ;
2286}
2287
524c47aa
SC
2288//
2289// wxWidgetImpl
2290//
2291
f55d9f74
SC
2292WX_DECLARE_HASH_MAP(WXWidget, wxWidgetImpl*, wxPointerHash, wxPointerEqual, MacControlMap);
2293
2294static MacControlMap wxWinMacControlList;
2295
2296wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl )
2297{
2298 wxWidgetImpl* impl = wxWidgetImpl::FindFromWXWidget( inControl );
2299 if ( impl )
2300 return impl->GetWXPeer();
2301
2302 return NULL;
2303}
2304
2305wxWidgetImpl *wxWidgetImpl::FindFromWXWidget(WXWidget inControl )
2306{
2307 MacControlMap::iterator node = wxWinMacControlList.find(inControl);
2308
2309 return (node == wxWinMacControlList.end()) ? NULL : node->second;
2310}
2311
2312void wxWidgetImpl::Associate(WXWidget inControl, wxWidgetImpl *impl)
2313{
2314 // adding NULL ControlRef is (first) surely a result of an error and
2315 // (secondly) breaks native event processing
2316 wxCHECK_RET( inControl != (WXWidget) NULL, wxT("attempt to add a NULL WXWidget to control map") );
2317
2318 wxWinMacControlList[inControl] = impl;
2319}
2320
2321void wxWidgetImpl::RemoveAssociations(wxWidgetImpl* impl)
2322{
2323 // iterate over all the elements in the class
2324 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
2325 // we should go on...
2326
2327 bool found = true ;
2328 while ( found )
2329 {
2330 found = false ;
2331 MacControlMap::iterator it;
2332 for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
2333 {
2334 if ( it->second == impl )
2335 {
2336 wxWinMacControlList.erase(it);
2337 found = true ;
2338 break;
2339 }
2340 }
2341 }
2342}
2343
524c47aa
SC
2344IMPLEMENT_ABSTRACT_CLASS( wxWidgetImpl , wxObject )
2345
2346wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl )
2347{
2348 Init();
2349 m_isRootControl = isRootControl;
2350 m_wxPeer = peer;
2351}
2352
2353wxWidgetImpl::wxWidgetImpl()
2354{
2355 Init();
2356}
2357
2358wxWidgetImpl::~wxWidgetImpl()
2359{
2360}
2361
2362void wxWidgetImpl::Init()
2363{
2364 m_isRootControl = false;
2365 m_wxPeer = NULL;
2366 m_needsFocusRect = false;
f2f6030e 2367 m_needsFrame = true;
524c47aa
SC
2368}
2369
2370void wxWidgetImpl::SetNeedsFocusRect( bool needs )
2371{
2372 m_needsFocusRect = needs;
2373}
2374
2375bool wxWidgetImpl::NeedsFocusRect() const
2376{
2377 return m_needsFocusRect;
2378}
2379
f2f6030e
SC
2380void wxWidgetImpl::SetNeedsFrame( bool needs )
2381{
2382 m_needsFrame = needs;
2383}
2384
2385bool wxWidgetImpl::NeedsFrame() const
2386{
2387 return m_needsFrame;
2388}