]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/window.cpp
switching to native focus handling
[wxWidgets.git] / src / mac / carbon / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
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/scrolbar.h"
27 #include "wx/statbox.h"
28 #include "wx/button.h"
29 #include "wx/settings.h"
30 #include "wx/msgdlg.h"
31 #include "wx/frame.h"
32 #include "wx/tooltip.h"
33 #include "wx/statusbr.h"
34 #include "wx/menuitem.h"
35 #include "wx/spinctrl.h"
36 #include "wx/log.h"
37 #include "wx/geometry.h"
38
39 #include "wx/toolbar.h"
40 #include "wx/dc.h"
41
42 #if wxUSE_CARET
43 #include "wx/caret.h"
44 #endif // wxUSE_CARET
45
46 #define wxWINDOW_HSCROLL 5998
47 #define wxWINDOW_VSCROLL 5997
48 #define MAC_SCROLLBAR_SIZE 16
49
50 #include "wx/mac/uma.h"
51 #ifndef __DARWIN__
52 #include <Windows.h>
53 #include <ToolUtils.h>
54 #endif
55
56 #if TARGET_API_MAC_OSX
57 #ifndef __HIVIEW__
58 #include <HIToolbox/HIView.h>
59 #endif
60 #endif
61
62 #if wxUSE_DRAG_AND_DROP
63 #include "wx/dnd.h"
64 #endif
65
66 #include <string.h>
67
68 extern wxList wxPendingDelete;
69
70 #ifdef __WXUNIVERSAL__
71 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
72 #else // __WXMAC__
73 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
74 #endif // __WXUNIVERSAL__/__WXMAC__
75
76 #if !USE_SHARED_LIBRARY
77
78 BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
79 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
80 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
81 // TODO EVT_PAINT(wxWindowMac::OnPaint)
82 EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
83 EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
84 // EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
85 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
86 END_EVENT_TABLE()
87
88 #endif
89
90 #define wxMAC_DEBUG_REDRAW 0
91 #ifndef wxMAC_DEBUG_REDRAW
92 #define wxMAC_DEBUG_REDRAW 0
93 #endif
94
95 #define wxMAC_USE_THEME_BORDER 0
96
97 // ---------------------------------------------------------------------------
98 // Carbon Events
99 // ---------------------------------------------------------------------------
100
101 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
102 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
103
104 #if TARGET_API_MAC_OSX
105
106 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
107 enum {
108 kEventControlVisibilityChanged = 157
109 };
110 #endif
111
112 #endif
113
114 static const EventTypeSpec eventList[] =
115 {
116 { kEventClassControl , kEventControlHit } ,
117 #if TARGET_API_MAC_OSX
118 { kEventClassControl , kEventControlDraw } ,
119 { kEventClassControl , kEventControlVisibilityChanged } ,
120 { kEventClassControl , kEventControlEnabledStateChanged } ,
121 { kEventClassControl , kEventControlHiliteChanged } ,
122 { kEventClassControl , kEventControlSetFocusPart } ,
123 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
124 // { kEventClassControl , kEventControlBoundsChanged } ,
125 #endif
126 } ;
127
128 static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
129 {
130 OSStatus result = eventNotHandledErr ;
131
132 wxMacCarbonEvent cEvent( event ) ;
133
134 ControlRef controlRef ;
135 wxWindowMac* thisWindow = (wxWindowMac*) data ;
136
137 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
138
139 switch( GetEventKind( event ) )
140 {
141 #if TARGET_API_MAC_OSX
142 case kEventControlDraw :
143 {
144 RgnHandle updateRgn = NULL ;
145
146 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
147 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
148 {
149 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
150 }
151 // GrafPtr myport = cEvent.GetParameter<GrafPtr>(kEventParamGrafPort,typeGrafPtr) ;
152
153 #if 0
154 // in case we would need a coregraphics compliant background erase first
155 // now usable to track redraws
156 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
157 if ( thisWindow->MacIsUserPane() )
158 {
159 static float color = 0.5 ;
160 static channel = 0 ;
161 HIRect bounds;
162 HIViewGetBounds( controlRef, &bounds );
163 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
164 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
165 CGContextFillRect( cgContext, bounds );
166 color += 0.1 ;
167 if ( color > 0.9 )
168 {
169 color = 0.5 ;
170 channel++ ;
171 if ( channel == 3 )
172 channel = 0 ;
173 }
174 }
175 #endif
176 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
177 result = noErr ;
178 }
179 break ;
180 case kEventControlVisibilityChanged :
181 thisWindow->MacVisibilityChanged() ;
182 break ;
183 case kEventControlEnabledStateChanged :
184 thisWindow->MacEnabledStateChanged() ;
185 break ;
186 case kEventControlHiliteChanged :
187 thisWindow->MacHiliteChanged() ;
188 break ;
189 case kEventControlSetFocusPart :
190 {
191 Boolean focusEverything = false ;
192 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
193 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
194 {
195 }
196 if ( controlPart == kControlFocusNoPart )
197 {
198 #if wxUSE_CARET
199 if ( thisWindow->GetCaret() )
200 {
201 thisWindow->GetCaret()->OnKillFocus();
202 }
203 #endif // wxUSE_CARET
204 wxFocusEvent event(wxEVT_KILL_FOCUS, thisWindow->GetId());
205 event.SetEventObject(thisWindow);
206 thisWindow->GetEventHandler()->ProcessEvent(event) ;
207 }
208 else
209 {
210 // panel wants to track the window which was the last to have focus in it
211 wxChildFocusEvent eventFocus(thisWindow);
212 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
213
214 #if wxUSE_CARET
215 if ( thisWindow->GetCaret() )
216 {
217 thisWindow->GetCaret()->OnSetFocus();
218 }
219 #endif // wxUSE_CARET
220
221 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
222 event.SetEventObject(thisWindow);
223 thisWindow->GetEventHandler()->ProcessEvent(event) ;
224 }
225 }
226 break ;
227 #endif
228 case kEventControlHit :
229 {
230 result = thisWindow->MacControlHit( handler , event ) ;
231 }
232 break ;
233 default :
234 break ;
235 }
236 return result ;
237 }
238
239 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
240 {
241 OSStatus result = eventNotHandledErr ;
242
243 switch ( GetEventClass( event ) )
244 {
245 case kEventClassControl :
246 result = wxMacWindowControlEventHandler( handler, event, data ) ;
247 break ;
248 default :
249 break ;
250 }
251 return result ;
252 }
253
254 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
255
256 // ---------------------------------------------------------------------------
257 // UserPane events for non OSX builds
258 // ---------------------------------------------------------------------------
259
260 static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
261 {
262 wxWindow * win = wxFindControlFromMacControl(control) ;
263 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
264 win->MacControlUserPaneDrawProc(part) ;
265 }
266
267 static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
268 {
269 wxWindow * win = wxFindControlFromMacControl(control) ;
270 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
271 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
272 }
273
274 static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
275 {
276 wxWindow * win = wxFindControlFromMacControl(control) ;
277 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
278 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
279 }
280
281 static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
282 {
283 wxWindow * win = wxFindControlFromMacControl(control) ;
284 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
285 win->MacControlUserPaneIdleProc() ;
286 }
287
288 static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
289 {
290 wxWindow * win = wxFindControlFromMacControl(control) ;
291 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
292 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
293 }
294
295 static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
296 {
297 wxWindow * win = wxFindControlFromMacControl(control) ;
298 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
299 win->MacControlUserPaneActivateProc(activating) ;
300 }
301
302 static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
303 {
304 wxWindow * win = wxFindControlFromMacControl(control) ;
305 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
306 return win->MacControlUserPaneFocusProc(action) ;
307 }
308
309 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
310 {
311 wxWindow * win = wxFindControlFromMacControl(control) ;
312 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
313 win->MacControlUserPaneBackgroundProc(info) ;
314 }
315
316 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
317 {
318 RgnHandle rgn = NewRgn() ;
319 GetClip( rgn ) ;
320 wxMacWindowStateSaver sv( this ) ;
321 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
322 MacDoRedraw( rgn , 0 ) ;
323 DisposeRgn( rgn ) ;
324 }
325
326 wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
327 {
328 return kControlNoPart ;
329 }
330
331 wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
332 {
333 return kControlNoPart ;
334 }
335
336 void wxWindowMac::MacControlUserPaneIdleProc()
337 {
338 }
339
340 wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
341 {
342 return kControlNoPart ;
343 }
344
345 void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
346 {
347 }
348
349 wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
350 {
351 return kControlNoPart ;
352 }
353
354 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
355 {
356 }
357
358 ControlUserPaneDrawUPP gControlUserPaneDrawUPP = NULL ;
359 ControlUserPaneHitTestUPP gControlUserPaneHitTestUPP = NULL ;
360 ControlUserPaneTrackingUPP gControlUserPaneTrackingUPP = NULL ;
361 ControlUserPaneIdleUPP gControlUserPaneIdleUPP = NULL ;
362 ControlUserPaneKeyDownUPP gControlUserPaneKeyDownUPP = NULL ;
363 ControlUserPaneActivateUPP gControlUserPaneActivateUPP = NULL ;
364 ControlUserPaneFocusUPP gControlUserPaneFocusUPP = NULL ;
365 ControlUserPaneBackgroundUPP gControlUserPaneBackgroundUPP = NULL ;
366
367 // ===========================================================================
368 // implementation
369 // ===========================================================================
370
371 wxList wxWinMacControlList(wxKEY_INTEGER);
372
373 wxWindow *wxFindControlFromMacControl(ControlRef inControl )
374 {
375 wxNode *node = wxWinMacControlList.Find((long)inControl);
376 if (!node)
377 return NULL;
378 return (wxControl *)node->GetData();
379 }
380
381 void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
382 {
383 // adding NULL ControlRef is (first) surely a result of an error and
384 // (secondly) breaks native event processing
385 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
386
387 if ( !wxWinMacControlList.Find((long)inControl) )
388 wxWinMacControlList.Append((long)inControl, control);
389 }
390
391 void wxRemoveMacControlAssociation(wxWindow *control)
392 {
393 wxWinMacControlList.DeleteObject(control);
394 }
395
396 // UPP functions
397 ControlActionUPP wxMacLiveScrollbarActionUPP = NULL ;
398
399 ControlColorUPP wxMacSetupControlBackgroundUPP = NULL ;
400
401 // we have to setup the brush in the current port and return noErr
402 // or return an error code so that the control manager walks further up the
403 // hierarchy to find a correct background
404
405 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor )
406 {
407 OSStatus status = paramErr ;
408 switch( iMessage )
409 {
410 case kControlMsgApplyTextColor :
411 break ;
412 case kControlMsgSetUpBackground :
413 {
414 wxWindow* wx = (wxWindow*) wxFindControlFromMacControl( iControl ) ;
415 if ( wx != NULL )
416 {
417 /*
418 const wxBrush &brush = wx->MacGetBackgroundBrush() ;
419 if ( brush.Ok() )
420 {
421
422 wxDC::MacSetupBackgroundForCurrentPort( brush ) ;
423 */
424 // this clipping is only needed for non HIView
425
426 RgnHandle clip = NewRgn() ;
427 int x = 0 , y = 0;
428
429 wx->MacWindowToRootWindow( &x,&y ) ;
430 CopyRgn( (RgnHandle) wx->MacGetVisibleRegion().GetWXHRGN() , clip ) ;
431 OffsetRgn( clip , x , y ) ;
432 SetClip( clip ) ;
433 DisposeRgn( clip ) ;
434
435 status = noErr ;
436 /*
437 }
438 else if ( wx->MacIsUserPane() )
439 {
440 // if we don't have a valid brush for such a control, we have to call the
441 // setup of our parent ourselves
442 status = SetUpControlBackground( (ControlRef) wx->GetParent()->GetHandle() , iDepth , iIsColor ) ;
443 }
444 */
445 }
446 }
447 break ;
448 default :
449 break ;
450 }
451 return status ;
452 }
453
454
455 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
456 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
457 {
458 if ( partCode != 0)
459 {
460 wxWindow* wx = wxFindControlFromMacControl( control ) ;
461 if ( wx )
462 {
463 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
464 }
465 }
466 }
467
468 // ----------------------------------------------------------------------------
469 // constructors and such
470 // ----------------------------------------------------------------------------
471
472 void wxWindowMac::Init()
473 {
474 m_frozenness = 0 ;
475 #if WXWIN_COMPATIBILITY_2_4
476 m_backgroundTransparent = FALSE;
477 #endif
478
479 // as all windows are created with WS_VISIBLE style...
480 m_isShown = TRUE;
481
482 m_hScrollBar = NULL ;
483 m_vScrollBar = NULL ;
484 m_macBackgroundBrush = wxNullBrush ;
485
486 m_macControl = NULL ;
487
488 m_macIsUserPane = TRUE;
489
490 // make sure all proc ptrs are available
491
492 if ( gControlUserPaneDrawUPP == NULL )
493 {
494 gControlUserPaneDrawUPP = NewControlUserPaneDrawUPP( wxMacControlUserPaneDrawProc ) ;
495 gControlUserPaneHitTestUPP = NewControlUserPaneHitTestUPP( wxMacControlUserPaneHitTestProc ) ;
496 gControlUserPaneTrackingUPP = NewControlUserPaneTrackingUPP( wxMacControlUserPaneTrackingProc ) ;
497 gControlUserPaneIdleUPP = NewControlUserPaneIdleUPP( wxMacControlUserPaneIdleProc ) ;
498 gControlUserPaneKeyDownUPP = NewControlUserPaneKeyDownUPP( wxMacControlUserPaneKeyDownProc ) ;
499 gControlUserPaneActivateUPP = NewControlUserPaneActivateUPP( wxMacControlUserPaneActivateProc ) ;
500 gControlUserPaneFocusUPP = NewControlUserPaneFocusUPP( wxMacControlUserPaneFocusProc ) ;
501 gControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP( wxMacControlUserPaneBackgroundProc ) ;
502 }
503 if ( wxMacLiveScrollbarActionUPP == NULL )
504 {
505 wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc );
506 }
507
508 if ( wxMacSetupControlBackgroundUPP == NULL )
509 {
510 wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
511 }
512
513 // we need a valid font for the encodings
514 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
515 }
516
517 // Destructor
518 wxWindowMac::~wxWindowMac()
519 {
520 SendDestroyEvent();
521
522 m_isBeingDeleted = TRUE;
523
524 #ifndef __WXUNIVERSAL__
525 // VS: make sure there's no wxFrame with last focus set to us:
526 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
527 {
528 wxFrame *frame = wxDynamicCast(win, wxFrame);
529 if ( frame )
530 {
531 if ( frame->GetLastFocus() == this )
532 {
533 frame->SetLastFocus((wxWindow*)NULL);
534 }
535 break;
536 }
537 }
538 #endif // __WXUNIVERSAL__
539
540 // wxRemoveMacControlAssociation( this ) ;
541 // If we delete an item, we should initialize the parent panel,
542 // because it could now be invalid.
543 wxWindow *parent = GetParent() ;
544 if ( parent )
545 {
546 if (parent->GetDefaultItem() == (wxButton*) this)
547 parent->SetDefaultItem(NULL);
548 }
549 if ( (ControlRef) m_macControl )
550 {
551 // in case the callback might be called during destruction
552 wxRemoveMacControlAssociation( this) ;
553 ::SetControlColorProc( (ControlRef) m_macControl , NULL ) ;
554 ::DisposeControl( (ControlRef) m_macControl ) ;
555 m_macControl = NULL ;
556 }
557
558 if ( g_MacLastWindow == this )
559 {
560 g_MacLastWindow = NULL ;
561 }
562
563 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
564 if ( frame )
565 {
566 if ( frame->GetLastFocus() == this )
567 frame->SetLastFocus( NULL ) ;
568 }
569
570 DestroyChildren();
571
572 // delete our drop target if we've got one
573 #if wxUSE_DRAG_AND_DROP
574 if ( m_dropTarget != NULL )
575 {
576 delete m_dropTarget;
577 m_dropTarget = NULL;
578 }
579 #endif // wxUSE_DRAG_AND_DROP
580 }
581
582 //
583
584 void wxWindowMac::MacInstallEventHandler()
585 {
586 wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ;
587 InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(),
588 GetEventTypeCount(eventList), eventList, this,
589 (EventHandlerRef *)&m_macControlEventHandler);
590
591 }
592
593 // Constructor
594 bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
595 const wxPoint& pos,
596 const wxSize& size,
597 long style,
598 const wxString& name)
599 {
600 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
601
602 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
603 return FALSE;
604
605 parent->AddChild(this);
606
607 m_windowVariant = parent->GetWindowVariant() ;
608
609 if ( m_macIsUserPane )
610 {
611 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
612
613 UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback | kControlHasSpecialBackground |
614 kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle;
615
616 ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, kControlSupportsEmbedding , (ControlRef*) &m_macControl);
617
618 MacPostControlCreate(pos,size) ;
619 #if !TARGET_API_MAC_OSX
620 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneDrawProcTag,
621 sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP);
622 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneHitTestProcTag,
623 sizeof(gControlUserPaneHitTestUPP),(Ptr) &gControlUserPaneHitTestUPP);
624 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneTrackingProcTag,
625 sizeof(gControlUserPaneTrackingUPP),(Ptr) &gControlUserPaneTrackingUPP);
626 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneIdleProcTag,
627 sizeof(gControlUserPaneIdleUPP),(Ptr) &gControlUserPaneIdleUPP);
628 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneKeyDownProcTag,
629 sizeof(gControlUserPaneKeyDownUPP),(Ptr) &gControlUserPaneKeyDownUPP);
630 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneActivateProcTag,
631 sizeof(gControlUserPaneActivateUPP),(Ptr) &gControlUserPaneActivateUPP);
632 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneFocusProcTag,
633 sizeof(gControlUserPaneFocusUPP),(Ptr) &gControlUserPaneFocusUPP);
634 SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneBackgroundProcTag,
635 sizeof(gControlUserPaneBackgroundUPP),(Ptr) &gControlUserPaneBackgroundUPP);
636 #endif
637 }
638 #ifndef __WXUNIVERSAL__
639 // Don't give scrollbars to wxControls unless they ask for them
640 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) ||
641 (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL)))
642 {
643 MacCreateScrollBars( style ) ;
644 }
645 #endif
646
647 wxWindowCreateEvent event(this);
648 GetEventHandler()->AddPendingEvent(event);
649
650 return TRUE;
651 }
652
653 void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
654 {
655 wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ;
656
657 ::SetControlReference( (ControlRef) m_macControl , (long) this ) ;
658
659 MacInstallEventHandler();
660
661 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
662 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
663 ::EmbedControl( (ControlRef) m_macControl , container ) ;
664
665 // adjust font, controlsize etc
666 DoSetWindowVariant( m_windowVariant ) ;
667
668 #if !TARGET_API_MAC_OSX
669 // eventually we can fix some clipping issues be reactivating this hook
670 //if ( m_macIsUserPane )
671 // SetControlColorProc( (ControlRef) m_macControl , wxMacSetupControlBackgroundUPP ) ;
672 #endif
673
674 UMASetControlTitle( (ControlRef) m_macControl , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ;
675
676 wxSize new_size = size ;
677 if (!m_macIsUserPane)
678 {
679 wxSize best_size( DoGetBestSize() );
680
681 if (size.x == -1) {
682 new_size.x = best_size.x;
683 }
684 if (size.y == -1) {
685 new_size.y = best_size.y;
686 }
687 SetSize( pos.x, pos.y , new_size.x, new_size.y,wxSIZE_USE_EXISTING );
688 }
689
690 SetCursor( *wxSTANDARD_CURSOR ) ;
691
692 }
693
694 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
695 {
696 // Don't assert, in case we set the window variant before
697 // the window is created
698 // wxASSERT( m_macControl != NULL ) ;
699
700 m_windowVariant = variant ;
701
702 if (!m_macControl)
703 return;
704
705 ControlSize size ;
706 ThemeFontID themeFont = kThemeSystemFont ;
707
708 // we will get that from the settings later
709 // and make this NORMAL later, but first
710 // we have a few calculations that we must fix
711
712 switch ( variant )
713 {
714 case wxWINDOW_VARIANT_NORMAL :
715 size = kControlSizeNormal;
716 themeFont = kThemeSystemFont ;
717 break ;
718 case wxWINDOW_VARIANT_SMALL :
719 size = kControlSizeSmall;
720 themeFont = kThemeSmallSystemFont ;
721 break ;
722 case wxWINDOW_VARIANT_MINI :
723 if (UMAGetSystemVersion() >= 0x1030 )
724 {
725 // not always defined in the headers
726 size = 3 ;
727 themeFont = 109 ;
728 }
729 else
730 {
731 size = kControlSizeSmall;
732 themeFont = kThemeSmallSystemFont ;
733 }
734 break ;
735 case wxWINDOW_VARIANT_LARGE :
736 size = kControlSizeLarge;
737 themeFont = kThemeSystemFont ;
738 break ;
739 default:
740 wxFAIL_MSG(_T("unexpected window variant"));
741 break ;
742 }
743 ::SetControlData( (ControlRef) m_macControl , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size );
744
745 wxFont font ;
746 font.MacCreateThemeFont( themeFont ) ;
747 SetFont( font ) ;
748 }
749
750 void wxWindowMac::MacUpdateControlFont()
751 {
752 ControlFontStyleRec fontStyle;
753 if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont )
754 {
755 switch( m_font.MacGetThemeFontID() )
756 {
757 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
758 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
759 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
760 default : fontStyle.font = kControlFontBigSystemFont ; break ;
761 }
762 fontStyle.flags = kControlUseFontMask ;
763 }
764 else
765 {
766 fontStyle.font = m_font.MacGetFontNum() ;
767 fontStyle.style = m_font.MacGetFontStyle() ;
768 fontStyle.size = m_font.MacGetFontSize() ;
769 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
770 }
771
772 fontStyle.just = teJustLeft ;
773 fontStyle.flags |= kControlUseJustMask ;
774 if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
775 fontStyle.just = teJustCenter ;
776 else if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_RIGHT )
777 fontStyle.just = teJustRight ;
778
779
780 fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ;
781 fontStyle.flags |= kControlUseForeColorMask ;
782
783 ::SetControlFontStyle( (ControlRef) m_macControl , &fontStyle );
784 Refresh() ;
785 }
786
787 bool wxWindowMac::SetFont(const wxFont& font)
788 {
789 bool retval = !wxWindowBase::SetFont( font ) ;
790
791 MacUpdateControlFont() ;
792
793 return retval;
794 }
795
796 bool wxWindowMac::SetForegroundColour(const wxColour& col )
797 {
798 if ( !wxWindowBase::SetForegroundColour(col) )
799 return false ;
800
801 MacUpdateControlFont() ;
802
803 return true ;
804 }
805
806 bool wxWindowMac::SetBackgroundColour(const wxColour& col )
807 {
808 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
809 return false ;
810
811 wxBrush brush ;
812 if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
813 {
814 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
815 }
816 else if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
817 {
818 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
819 }
820 else
821 {
822 brush.SetColour( col ) ;
823 }
824 MacSetBackgroundBrush( brush ) ;
825
826 MacUpdateControlFont() ;
827
828 return true ;
829 }
830
831
832 bool wxWindowMac::MacCanFocus() const
833 {
834 #if 0
835 // there is currently no way to determinate whether the window is running in full keyboard
836 // access mode, therefore we cannot rely on these features yet
837 UInt32 features = 0 ;
838 GetControlFeatures( (ControlRef) m_macControl , &features ) ;
839 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
840 #endif
841 return true ;
842 }
843
844
845 void wxWindowMac::SetFocus()
846 {
847 if ( AcceptsFocus() )
848 {
849 #if !TARGET_API_MAC_OSX
850 wxWindow* former = FindFocus() ;
851 #endif
852 OSStatus err = SetKeyboardFocus( (WindowRef) MacGetTopLevelWindowRef() , (ControlRef) GetHandle() , kControlFocusNextPart ) ;
853 // as we cannot rely on the control features to find out whether we are in full keyboard mode, we can only
854 // leave in case of an error
855 if ( err == errCouldntSetFocus )
856 return ;
857
858 #if !TARGET_API_MAC_OSX
859 // emulate carbon events when running under carbonlib where they are not natively available
860 if ( former )
861 {
862 EventRef evRef = NULL ;
863 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
864 &evRef ) );
865
866 wxMacCarbonEvent cEvent( evRef ) ;
867 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
868 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
869
870 wxMacWindowEventHandler( NULL , evRef , former ) ;
871 ReleaseEvent(evRef) ;
872 }
873 // send new focus event
874 {
875 EventRef evRef = NULL ;
876 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
877 &evRef ) );
878
879 wxMacCarbonEvent cEvent( evRef ) ;
880 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
881 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
882
883 wxMacWindowEventHandler( NULL , evRef , this ) ;
884 ReleaseEvent(evRef) ;
885 }
886 #endif
887 }
888 }
889
890
891 void wxWindowMac::DoCaptureMouse()
892 {
893 wxTheApp->s_captureWindow = this ;
894 }
895
896 wxWindow* wxWindowBase::GetCapture()
897 {
898 return wxTheApp->s_captureWindow ;
899 }
900
901 void wxWindowMac::DoReleaseMouse()
902 {
903 wxTheApp->s_captureWindow = NULL ;
904 }
905
906 #if wxUSE_DRAG_AND_DROP
907
908 void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
909 {
910 if ( m_dropTarget != 0 ) {
911 delete m_dropTarget;
912 }
913
914 m_dropTarget = pDropTarget;
915 if ( m_dropTarget != 0 )
916 {
917 // TODO
918 }
919 }
920
921 #endif
922
923 // Old style file-manager drag&drop
924 void wxWindowMac::DragAcceptFiles(bool accept)
925 {
926 // TODO
927 }
928
929 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
930 int& w, int& h) const
931 {
932 Rect bounds ;
933 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
934
935
936 x = bounds.left ;
937 y = bounds.top ;
938 w = bounds.right - bounds.left ;
939 h = bounds.bottom - bounds.top ;
940
941 wxTopLevelWindow* tlw = wxDynamicCast( this , wxTopLevelWindow ) ;
942 if ( tlw )
943 {
944 Point tlworigin = { 0 , 0 } ;
945 GrafPtr port ;
946 bool swapped = QDSwapPort( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) , &port ) ;
947 ::LocalToGlobal( &tlworigin ) ;
948 if ( swapped )
949 ::SetPort( port ) ;
950 x = tlworigin.h ;
951 y = tlworigin.v ;
952 }
953 }
954
955 bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos,
956 const wxSize& size,
957 int& x, int& y,
958 int& w, int& h , bool adjustOrigin ) const
959 {
960 x = (int)pos.x;
961 y = (int)pos.y;
962 // todo the default calls may be used as soon as PostCreateControl Is moved here
963 w = size.x ; // WidthDefault( size.x );
964 h = size.y ; // HeightDefault( size.y ) ;
965 #if !TARGET_API_MAC_OSX
966 GetParent()->MacWindowToRootWindow( &x , &y ) ;
967 #endif
968 if ( adjustOrigin )
969 AdjustForParentClientOrigin( x , y ) ;
970 return true ;
971 }
972
973 // Get total size
974 void wxWindowMac::DoGetSize(int *x, int *y) const
975 {
976 #if TARGET_API_MAC_OSX
977 int x1 , y1 , w1 ,h1 ;
978 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
979 if(x) *x = w1 ;
980 if(y) *y = h1 ;
981
982 #else
983 Rect bounds ;
984 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
985 if(x) *x = bounds.right - bounds.left ;
986 if(y) *y = bounds.bottom - bounds.top ;
987 #endif
988 }
989
990 void wxWindowMac::DoGetPosition(int *x, int *y) const
991 {
992 #if TARGET_API_MAC_OSX
993 int x1 , y1 , w1 ,h1 ;
994 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
995 if ( !IsTopLevel() )
996 {
997 wxWindow *parent = GetParent();
998 if ( parent )
999 {
1000 wxPoint pt(parent->GetClientAreaOrigin());
1001 x1 -= pt.x ;
1002 y1 -= pt.y ;
1003 }
1004 }
1005 if(x) *x = x1 ;
1006 if(y) *y = y1 ;
1007 #else
1008 Rect bounds ;
1009 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
1010 wxCHECK_RET( GetParent() , wxT("Missing Parent") ) ;
1011
1012 int xx = bounds.left ;
1013 int yy = bounds.top ;
1014
1015 if ( !GetParent()->IsTopLevel() )
1016 {
1017 GetControlBounds( (ControlRef) GetParent()->GetHandle() , &bounds ) ;
1018
1019 xx -= bounds.left ;
1020 yy -= bounds.top ;
1021 }
1022
1023 wxPoint pt(GetParent()->GetClientAreaOrigin());
1024 xx -= pt.x;
1025 yy -= pt.y;
1026
1027 if(x) *x = xx;
1028 if(y) *y = yy;
1029 #endif
1030 }
1031
1032 void wxWindowMac::DoScreenToClient(int *x, int *y) const
1033 {
1034 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1035
1036 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
1037
1038 {
1039 Point localwhere = {0,0} ;
1040
1041 if(x) localwhere.h = * x ;
1042 if(y) localwhere.v = * y ;
1043
1044 wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ;
1045 ::GlobalToLocal( &localwhere ) ;
1046 if(x) *x = localwhere.h ;
1047 if(y) *y = localwhere.v ;
1048
1049 }
1050 MacRootWindowToWindow( x , y ) ;
1051
1052 wxPoint origin = GetClientAreaOrigin() ;
1053 if(x) *x -= origin.x ;
1054 if(y) *y -= origin.y ;
1055 }
1056
1057 void wxWindowMac::DoClientToScreen(int *x, int *y) const
1058 {
1059 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1060 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
1061
1062 wxPoint origin = GetClientAreaOrigin() ;
1063 if(x) *x += origin.x ;
1064 if(y) *y += origin.y ;
1065
1066 MacWindowToRootWindow( x , y ) ;
1067
1068 {
1069 Point localwhere = { 0,0 };
1070 if(x) localwhere.h = * x ;
1071 if(y) localwhere.v = * y ;
1072
1073 wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ;
1074 ::LocalToGlobal( &localwhere ) ;
1075 if(x) *x = localwhere.h ;
1076 if(y) *y = localwhere.v ;
1077 }
1078 }
1079
1080 void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
1081 {
1082 wxPoint origin = GetClientAreaOrigin() ;
1083 if(x) *x += origin.x ;
1084 if(y) *y += origin.y ;
1085
1086 MacWindowToRootWindow( x , y ) ;
1087 }
1088
1089 void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1090 {
1091 MacRootWindowToWindow( x , y ) ;
1092
1093 wxPoint origin = GetClientAreaOrigin() ;
1094 if(x) *x -= origin.x ;
1095 if(y) *y -= origin.y ;
1096 }
1097
1098 void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1099 {
1100 #if TARGET_API_MAC_OSX
1101 HIPoint pt ;
1102 if ( x ) pt.x = *x ;
1103 if ( y ) pt.y = *y ;
1104
1105 if ( !IsTopLevel() )
1106 HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ;
1107
1108 if ( x ) *x = (int) pt.x ;
1109 if ( y ) *y = (int) pt.y ;
1110 #else
1111 if ( !IsTopLevel() )
1112 {
1113 Rect bounds ;
1114 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
1115 if(x) *x += bounds.left ;
1116 if(y) *y += bounds.top ;
1117 }
1118 #endif
1119 }
1120
1121 void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1122 {
1123 int x1 , y1 ;
1124 if ( x ) x1 = *x ;
1125 if ( y ) y1 = *y ;
1126 MacWindowToRootWindow( &x1 , &y1 ) ;
1127 if ( x ) *x = x1 ;
1128 if ( y ) *y = y1 ;
1129 }
1130
1131 void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
1132 {
1133 #if TARGET_API_MAC_OSX
1134 HIPoint pt ;
1135 if ( x ) pt.x = *x ;
1136 if ( y ) pt.y = *y ;
1137
1138 if ( !IsTopLevel() )
1139 HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ;
1140
1141 if ( x ) *x = (int) pt.x ;
1142 if ( y ) *y = (int) pt.y ;
1143 #else
1144 if ( !IsTopLevel() )
1145 {
1146 Rect bounds ;
1147 GetControlBounds( (ControlRef) m_macControl , &bounds ) ;
1148 if(x) *x -= bounds.left ;
1149 if(y) *y -= bounds.top ;
1150 }
1151 #endif
1152 }
1153
1154 void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
1155 {
1156 int x1 , y1 ;
1157 if ( x ) x1 = *x ;
1158 if ( y ) y1 = *y ;
1159 MacRootWindowToWindow( &x1 , &y1 ) ;
1160 if ( x ) *x = x1 ;
1161 if ( y ) *y = y1 ;
1162 }
1163
1164 void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1165 {
1166 RgnHandle rgn = NewRgn() ;
1167 Rect content ;
1168 if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr )
1169 {
1170 GetRegionBounds( rgn , &content ) ;
1171 DisposeRgn( rgn ) ;
1172 }
1173 else
1174 {
1175 GetControlBounds( (ControlRef) m_macControl , &content ) ;
1176 }
1177 Rect structure ;
1178 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1179 #if !TARGET_API_MAC_OSX
1180 OffsetRect( &content , -structure.left , -structure.top ) ;
1181 #endif
1182 left = content.left - structure.left ;
1183 top = content.top - structure.top ;
1184 right = structure.right - content.right ;
1185 bottom = structure.bottom - content.bottom ;
1186 }
1187
1188 wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1189 {
1190 wxSize sizeTotal = size;
1191
1192 RgnHandle rgn = NewRgn() ;
1193
1194 Rect content ;
1195
1196 if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr )
1197 {
1198 GetRegionBounds( rgn , &content ) ;
1199 DisposeRgn( rgn ) ;
1200 }
1201 else
1202 {
1203 GetControlBounds( (ControlRef) m_macControl , &content ) ;
1204 }
1205 Rect structure ;
1206 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1207 #if !TARGET_API_MAC_OSX
1208 OffsetRect( &content , -structure.left , -structure.top ) ;
1209 #endif
1210
1211 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
1212 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top ) ;
1213
1214 sizeTotal.x += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1215 sizeTotal.y += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ;
1216
1217 return sizeTotal;
1218 }
1219
1220
1221 // Get size *available for subwindows* i.e. excluding menu bar etc.
1222 void wxWindowMac::DoGetClientSize(int *x, int *y) const
1223 {
1224 int ww, hh;
1225
1226 RgnHandle rgn = NewRgn() ;
1227 Rect content ;
1228 if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr )
1229 {
1230 GetRegionBounds( rgn , &content ) ;
1231 DisposeRgn( rgn ) ;
1232 }
1233 else
1234 {
1235 GetControlBounds( (ControlRef) m_macControl , &content ) ;
1236 }
1237 #if !TARGET_API_MAC_OSX
1238 Rect structure ;
1239 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1240 OffsetRect( &content , -structure.left , -structure.top ) ;
1241 #endif
1242 ww = content.right - content.left ;
1243 hh = content.bottom - content.top ;
1244
1245 ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1246 hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( );
1247
1248 if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) )
1249 {
1250 int x1 = 0 ;
1251 int y1 = 0 ;
1252 int w ;
1253 int h ;
1254 GetSize( &w , &h ) ;
1255
1256 MacClientToRootWindow( &x1 , &y1 ) ;
1257 MacClientToRootWindow( &w , &h ) ;
1258
1259 wxWindowMac *iter = (wxWindowMac*)this ;
1260
1261 int totW = 10000 , totH = 10000;
1262 while( iter )
1263 {
1264 if ( iter->IsTopLevel() )
1265 {
1266 iter->GetSize( &totW , &totH ) ;
1267 break ;
1268 }
1269
1270 iter = iter->GetParent() ;
1271 }
1272
1273 if (m_hScrollBar && m_hScrollBar->IsShown() )
1274 {
1275 hh -= MAC_SCROLLBAR_SIZE;
1276 if ( h-y1 >= totH )
1277 {
1278 hh += 1 ;
1279 }
1280 }
1281 if (m_vScrollBar && m_vScrollBar->IsShown() )
1282 {
1283 ww -= MAC_SCROLLBAR_SIZE;
1284 if ( w-x1 >= totW )
1285 {
1286 ww += 1 ;
1287 }
1288 }
1289 }
1290 if(x) *x = ww;
1291 if(y) *y = hh;
1292
1293 }
1294
1295 bool wxWindowMac::SetCursor(const wxCursor& cursor)
1296 {
1297 if (m_cursor == cursor)
1298 return FALSE;
1299
1300 if (wxNullCursor == cursor)
1301 {
1302 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
1303 return FALSE ;
1304 }
1305 else
1306 {
1307 if ( ! wxWindowBase::SetCursor( cursor ) )
1308 return FALSE ;
1309 }
1310
1311 wxASSERT_MSG( m_cursor.Ok(),
1312 wxT("cursor must be valid after call to the base version"));
1313
1314 /*
1315
1316 TODO why do we have to use current coordinates ?
1317
1318 Point pt ;
1319 wxWindowMac *mouseWin ;
1320 GetMouse( &pt ) ;
1321
1322 // Change the cursor NOW if we're within the correct window
1323
1324
1325 if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) )
1326 {
1327 if ( mouseWin == this && !wxIsBusy() )
1328 {
1329 m_cursor.MacInstall() ;
1330 }
1331 }
1332 */
1333 if ( !wxIsBusy() )
1334 {
1335 m_cursor.MacInstall() ;
1336 }
1337
1338 return TRUE ;
1339 }
1340
1341 #if wxUSE_MENUS
1342 bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1343 {
1344 menu->SetInvokingWindow(this);
1345 menu->UpdateUI();
1346 ClientToScreen( &x , &y ) ;
1347
1348 menu->MacBeforeDisplay( true ) ;
1349 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;
1350 if ( HiWord(menuResult) != 0 )
1351 {
1352 MenuCommand id ;
1353 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
1354 wxMenuItem* item = NULL ;
1355 wxMenu* realmenu ;
1356 item = menu->FindItem(id, &realmenu) ;
1357 if (item->IsCheckable())
1358 {
1359 item->Check( !item->IsChecked() ) ;
1360 }
1361 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1362 }
1363 menu->MacAfterDisplay( true ) ;
1364
1365 menu->SetInvokingWindow(NULL);
1366
1367 return TRUE;
1368 }
1369 #endif
1370
1371 // ----------------------------------------------------------------------------
1372 // tooltips
1373 // ----------------------------------------------------------------------------
1374
1375 #if wxUSE_TOOLTIPS
1376
1377 void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
1378 {
1379 wxWindowBase::DoSetToolTip(tooltip);
1380
1381 if ( m_tooltip )
1382 m_tooltip->SetWindow(this);
1383 }
1384
1385 #endif // wxUSE_TOOLTIPS
1386
1387 void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
1388 {
1389 int former_x , former_y , former_w, former_h ;
1390 #if !TARGET_API_MAC_OSX
1391 DoGetPosition( &former_x , &former_y ) ;
1392 DoGetSize( &former_w , &former_h ) ;
1393 #else
1394 MacGetPositionAndSizeFromControl( former_x , former_y , former_w , former_h ) ;
1395 #endif
1396
1397 int actualWidth = width;
1398 int actualHeight = height;
1399 int actualX = x;
1400 int actualY = y;
1401
1402 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
1403 actualWidth = m_minWidth;
1404 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
1405 actualHeight = m_minHeight;
1406 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
1407 actualWidth = m_maxWidth;
1408 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
1409 actualHeight = m_maxHeight;
1410
1411 bool doMove = false ;
1412 bool doResize = false ;
1413
1414 if ( actualX != former_x || actualY != former_y )
1415 {
1416 doMove = true ;
1417 }
1418 if ( actualWidth != former_w || actualHeight != former_h )
1419 {
1420 doResize = true ;
1421 }
1422
1423 if ( doMove || doResize )
1424 {
1425 // we don't adjust twice for the origin
1426 Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ;
1427 bool vis = IsControlVisible( (ControlRef) m_macControl ) ;
1428 #if TARGET_API_MAC_OSX
1429 // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not !
1430 if ( vis )
1431 SetControlVisibility( (ControlRef)m_macControl , false , true ) ;
1432 HIRect hir = { r.left , r.top , r.right - r.left , r.bottom - r.top } ;
1433 HIViewSetFrame ( (ControlRef) m_macControl , &hir ) ;
1434 if ( vis )
1435 SetControlVisibility( (ControlRef)m_macControl , true , true ) ;
1436 #else
1437 // TODO TEST SetControlBounds( (ControlRef) m_macControl , &r ) ;
1438 if ( vis )
1439 SetControlVisibility( (ControlRef)m_macControl , false , true ) ;
1440 if ( doMove )
1441 MoveControl( (ControlRef) m_macControl , r.left , r.top ) ;
1442 if ( doSize )
1443 SizeControl( (ControlRef) m_macControl , r.right-r.left , r.bottom-r.top ) ;
1444 if ( vis )
1445 SetControlVisibility( (ControlRef)m_macControl , true , true ) ;
1446 #endif
1447 MacRepositionScrollBars() ;
1448 if ( doMove )
1449 {
1450 wxPoint point(actualX,actualY);
1451 wxMoveEvent event(point, m_windowId);
1452 event.SetEventObject(this);
1453 GetEventHandler()->ProcessEvent(event) ;
1454 }
1455 if ( doResize )
1456 {
1457 MacRepositionScrollBars() ;
1458 wxSize size(actualWidth, actualHeight);
1459 wxSizeEvent event(size, m_windowId);
1460 event.SetEventObject(this);
1461 GetEventHandler()->ProcessEvent(event);
1462 }
1463 }
1464
1465 }
1466
1467 wxSize wxWindowMac::DoGetBestSize() const
1468 {
1469 if ( m_macIsUserPane || IsTopLevel() )
1470 return wxWindowBase::DoGetBestSize() ;
1471
1472 Rect bestsize = { 0 , 0 , 0 , 0 } ;
1473 short baselineoffset ;
1474 int bestWidth, bestHeight ;
1475 ::GetBestControlRect( (ControlRef) m_macControl , &bestsize , &baselineoffset ) ;
1476
1477 if ( EmptyRect( &bestsize ) )
1478 {
1479 baselineoffset = 0;
1480 bestsize.left = bestsize.top = 0 ;
1481 bestsize.right = 16 ;
1482 bestsize.bottom = 16 ;
1483 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1484 {
1485 bestsize.bottom = 16 ;
1486 }
1487 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1488 {
1489 bestsize.bottom = 24 ;
1490 }
1491 else
1492 {
1493 // return wxWindowBase::DoGetBestSize() ;
1494 }
1495 }
1496
1497 bestWidth = bestsize.right - bestsize.left ;
1498 bestHeight = bestsize.bottom - bestsize.top ;
1499 if ( bestHeight < 10 )
1500 bestHeight = 13 ;
1501
1502 return wxSize(bestWidth, bestHeight);
1503 // return wxWindowBase::DoGetBestSize() ;
1504 }
1505
1506
1507 // set the size of the window: if the dimensions are positive, just use them,
1508 // but if any of them is equal to -1, it means that we must find the value for
1509 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1510 // which case -1 is a valid value for x and y)
1511 //
1512 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1513 // the width/height to best suit our contents, otherwise we reuse the current
1514 // width/height
1515 void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1516 {
1517 // get the current size and position...
1518 int currentX, currentY;
1519 GetPosition(&currentX, &currentY);
1520
1521 int currentW,currentH;
1522 GetSize(&currentW, &currentH);
1523
1524 // ... and don't do anything (avoiding flicker) if it's already ok
1525 if ( x == currentX && y == currentY &&
1526 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
1527 {
1528 // TODO REMOVE
1529 MacRepositionScrollBars() ; // we might have a real position shift
1530 return;
1531 }
1532
1533 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1534 x = currentX;
1535 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1536 y = currentY;
1537
1538 AdjustForParentClientOrigin(x, y, sizeFlags);
1539
1540 wxSize size(-1, -1);
1541 if ( width == -1 )
1542 {
1543 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1544 {
1545 size = DoGetBestSize();
1546 width = size.x;
1547 }
1548 else
1549 {
1550 // just take the current one
1551 width = currentW;
1552 }
1553 }
1554
1555 if ( height == -1 )
1556 {
1557 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
1558 {
1559 if ( size.x == -1 )
1560 {
1561 size = DoGetBestSize();
1562 }
1563 //else: already called DoGetBestSize() above
1564
1565 height = size.y;
1566 }
1567 else
1568 {
1569 // just take the current one
1570 height = currentH;
1571 }
1572 }
1573
1574 DoMoveWindow(x, y, width, height);
1575
1576 }
1577
1578 wxPoint wxWindowMac::GetClientAreaOrigin() const
1579 {
1580 RgnHandle rgn = NewRgn() ;
1581 Rect content ;
1582 GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) ;
1583 GetRegionBounds( rgn , &content ) ;
1584 DisposeRgn( rgn ) ;
1585 #if !TARGET_API_MAC_OSX
1586 Rect structure ;
1587 GetControlBounds( (ControlRef) m_macControl , &structure ) ;
1588 OffsetRect( &content , -structure.left , -structure.top ) ;
1589 #endif
1590
1591 return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) );
1592 }
1593
1594 void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1595 {
1596 if ( clientheight != -1 || clientheight != -1 )
1597 {
1598 int currentclientwidth , currentclientheight ;
1599 int currentwidth , currentheight ;
1600
1601 GetClientSize( &currentclientwidth , &currentclientheight ) ;
1602 GetSize( &currentwidth , &currentheight ) ;
1603
1604 DoSetSize( -1 , -1 , currentwidth + clientwidth - currentclientwidth ,
1605 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1606 }
1607 }
1608
1609 void wxWindowMac::SetTitle(const wxString& title)
1610 {
1611 m_label = wxStripMenuCodes(title) ;
1612
1613 if ( m_macControl )
1614 {
1615 UMASetControlTitle( (ControlRef) m_macControl , m_label , m_font.GetEncoding() ) ;
1616 }
1617 Refresh() ;
1618 }
1619
1620 wxString wxWindowMac::GetTitle() const
1621 {
1622 return m_label ;
1623 }
1624
1625 bool wxWindowMac::Show(bool show)
1626 {
1627 if ( !wxWindowBase::Show(show) )
1628 return FALSE;
1629
1630 // TODO use visibilityChanged Carbon Event for OSX
1631 bool former = MacIsReallyShown() ;
1632
1633 SetControlVisibility( (ControlRef) m_macControl , show , true ) ;
1634 if ( former != MacIsReallyShown() )
1635 MacPropagateVisibilityChanged() ;
1636 return TRUE;
1637 }
1638
1639 bool wxWindowMac::Enable(bool enable)
1640 {
1641 wxASSERT( m_macControl != NULL ) ;
1642 if ( !wxWindowBase::Enable(enable) )
1643 return FALSE;
1644
1645 bool former = MacIsReallyEnabled() ;
1646 if ( enable )
1647 EnableControl( (ControlRef) m_macControl ) ;
1648 else
1649 DisableControl( (ControlRef) m_macControl ) ;
1650
1651 if ( former != MacIsReallyEnabled() )
1652 MacPropagateEnabledStateChanged() ;
1653 return TRUE;
1654 }
1655
1656 //
1657 // status change propagations (will be not necessary for OSX later )
1658 //
1659
1660 void wxWindowMac::MacPropagateVisibilityChanged()
1661 {
1662 #if !TARGET_API_MAC_OSX
1663 MacVisibilityChanged() ;
1664
1665 wxWindowListNode *node = GetChildren().GetFirst();
1666 while ( node )
1667 {
1668 wxWindowMac *child = node->GetData();
1669 if ( child->IsShown() )
1670 child->MacPropagateVisibilityChanged( ) ;
1671 node = node->GetNext();
1672 }
1673 #endif
1674 }
1675
1676 void wxWindowMac::MacPropagateEnabledStateChanged( )
1677 {
1678 #if !TARGET_API_MAC_OSX
1679 MacEnabledStateChanged() ;
1680
1681 wxWindowListNode *node = GetChildren().GetFirst();
1682 while ( node )
1683 {
1684 wxWindowMac *child = node->GetData();
1685 if ( child->IsEnabled() )
1686 child->MacPropagateEnabledStateChanged() ;
1687 node = node->GetNext();
1688 }
1689 #endif
1690 }
1691
1692 void wxWindowMac::MacPropagateHiliteChanged( )
1693 {
1694 #if !TARGET_API_MAC_OSX
1695 MacHiliteChanged() ;
1696
1697 wxWindowListNode *node = GetChildren().GetFirst();
1698 while ( node )
1699 {
1700 wxWindowMac *child = node->GetData();
1701 // if ( child->IsEnabled() )
1702 child->MacPropagateHiliteChanged() ;
1703 node = node->GetNext();
1704 }
1705 #endif
1706 }
1707
1708 //
1709 // status change notifications
1710 //
1711
1712 void wxWindowMac::MacVisibilityChanged()
1713 {
1714 }
1715
1716 void wxWindowMac::MacHiliteChanged()
1717 {
1718 }
1719
1720 void wxWindowMac::MacEnabledStateChanged()
1721 {
1722 }
1723
1724 //
1725 // status queries on the inherited window's state
1726 //
1727
1728 bool wxWindowMac::MacIsReallyShown()
1729 {
1730 // only under OSX the visibility of the TLW is taken into account
1731 #if TARGET_API_MAC_OSX
1732 return IsControlVisible( (ControlRef) m_macControl ) ;
1733 #else
1734 wxWindow* win = this ;
1735 while( win->IsShown() )
1736 {
1737 if ( win->IsTopLevel() )
1738 return true ;
1739
1740 win = win->GetParent() ;
1741 if ( win == NULL )
1742 return true ;
1743
1744 } ;
1745 return false ;
1746 #endif
1747 }
1748
1749 bool wxWindowMac::MacIsReallyEnabled()
1750 {
1751 return IsControlEnabled( (ControlRef) m_macControl ) ;
1752 }
1753
1754 bool wxWindowMac::MacIsReallyHilited()
1755 {
1756 return IsControlActive( (ControlRef) m_macControl ) ;
1757 }
1758
1759 //
1760 //
1761 //
1762
1763 int wxWindowMac::GetCharHeight() const
1764 {
1765 wxClientDC dc ( (wxWindowMac*)this ) ;
1766 return dc.GetCharHeight() ;
1767 }
1768
1769 int wxWindowMac::GetCharWidth() const
1770 {
1771 wxClientDC dc ( (wxWindowMac*)this ) ;
1772 return dc.GetCharWidth() ;
1773 }
1774
1775 void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
1776 int *descent, int *externalLeading, const wxFont *theFont ) const
1777 {
1778 const wxFont *fontToUse = theFont;
1779 if ( !fontToUse )
1780 fontToUse = &m_font;
1781
1782 wxClientDC dc( (wxWindowMac*) this ) ;
1783 long lx,ly,ld,le ;
1784 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
1785 if ( externalLeading )
1786 *externalLeading = le ;
1787 if ( descent )
1788 *descent = ld ;
1789 if ( x )
1790 *x = lx ;
1791 if ( y )
1792 *y = ly ;
1793 }
1794
1795 /*
1796 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1797 * we always intersect with the entire window, not only with the client area
1798 */
1799
1800 void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
1801 {
1802 #if TARGET_API_MAC_OSX
1803 if ( rect == NULL )
1804 HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
1805 else
1806 {
1807 RgnHandle update = NewRgn() ;
1808 SetRectRgn( update , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1809 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ;
1810 wxPoint origin = GetClientAreaOrigin() ;
1811 OffsetRgn( update, origin.x , origin.y ) ;
1812 HIViewSetNeedsDisplayInRegion( (ControlRef) m_macControl , update , true ) ;
1813 }
1814 #else
1815 /*
1816 RgnHandle updateRgn = NewRgn() ;
1817 if ( rect == NULL )
1818 {
1819 CopyRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn ) ;
1820 }
1821 else
1822 {
1823 SetRectRgn( updateRgn , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1824 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn , updateRgn ) ;
1825 }
1826 InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ;
1827 DisposeRgn(updateRgn) ;
1828 */
1829 if ( IsControlVisible( (ControlRef) m_macControl ) )
1830 {
1831 SetControlVisibility( (ControlRef) m_macControl , false , false ) ;
1832 SetControlVisibility( (ControlRef) m_macControl , true , true ) ;
1833 }
1834 /*
1835 if ( MacGetTopLevelWindow() == NULL )
1836 return ;
1837
1838 if ( !IsControlVisible( (ControlRef) m_macControl ) )
1839 return ;
1840
1841 wxPoint client = GetClientAreaOrigin();
1842 int x1 = -client.x;
1843 int y1 = -client.y;
1844 int x2 = m_width - client.x;
1845 int y2 = m_height - client.y;
1846
1847 if (IsKindOf( CLASSINFO(wxButton)))
1848 {
1849 // buttons have an "aura"
1850 y1 -= 5;
1851 x1 -= 5;
1852 y2 += 5;
1853 x2 += 5;
1854 }
1855
1856 Rect clientrect = { y1, x1, y2, x2 };
1857
1858 if ( rect )
1859 {
1860 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
1861 SectRect( &clientrect , &r , &clientrect ) ;
1862 }
1863
1864 if ( !EmptyRect( &clientrect ) )
1865 {
1866 int top = 0 , left = 0 ;
1867
1868 MacClientToRootWindow( &left , &top ) ;
1869 OffsetRect( &clientrect , left , top ) ;
1870
1871 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
1872 }
1873 */
1874 #endif
1875 }
1876
1877 void wxWindowMac::Freeze()
1878 {
1879 #if TARGET_API_MAC_OSX
1880 if ( !m_frozenness++ )
1881 {
1882 HIViewSetDrawingEnabled( (HIViewRef) m_macControl , false ) ;
1883 }
1884 #endif
1885 }
1886
1887 #if TARGET_API_MAC_OSX
1888 static void InvalidateControlAndChildren( HIViewRef control )
1889 {
1890 HIViewSetNeedsDisplay( control , true ) ;
1891 UInt16 childrenCount = 0 ;
1892 OSStatus err = CountSubControls( control , &childrenCount ) ;
1893 if ( err == errControlIsNotEmbedder )
1894 return ;
1895 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
1896
1897 for ( UInt16 i = childrenCount ; i >=1 ; --i )
1898 {
1899 HIViewRef child ;
1900 err = GetIndexedSubControl( control , i , & child ) ;
1901 if ( err == errControlIsNotEmbedder )
1902 return ;
1903 InvalidateControlAndChildren( child ) ;
1904 }
1905 }
1906 #endif
1907
1908 void wxWindowMac::Thaw()
1909 {
1910 #if TARGET_API_MAC_OSX
1911 wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
1912
1913 if ( !--m_frozenness )
1914 {
1915 HIViewSetDrawingEnabled( (HIViewRef) m_macControl , true ) ;
1916 InvalidateControlAndChildren( (HIViewRef) m_macControl ) ;
1917 // HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ;
1918 }
1919 #endif
1920 }
1921
1922 void wxWindowMac::MacRedrawControl()
1923 {
1924 /*
1925 if ( (ControlRef) m_macControl && MacGetTopLevelWindowRef() && IsControlVisible( (ControlRef) m_macControl ) )
1926 {
1927 #if TARGET_API_MAC_CARBON
1928 Update() ;
1929 #else
1930 wxClientDC dc(this) ;
1931 wxMacPortSetter helper(&dc) ;
1932 wxMacWindowClipper clipper(this) ;
1933 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
1934 UMADrawControl( (ControlRef) m_macControl ) ;
1935 #endif
1936 }
1937 */
1938 }
1939
1940 /* TODO
1941 void wxWindowMac::OnPaint(wxPaintEvent& event)
1942 {
1943 // why don't we skip that here ?
1944 }
1945 */
1946
1947 wxWindowMac *wxGetActiveWindow()
1948 {
1949 // actually this is a windows-only concept
1950 return NULL;
1951 }
1952
1953 // Coordinates relative to the window
1954 void wxWindowMac::WarpPointer (int x_pos, int y_pos)
1955 {
1956 // We really don't move the mouse programmatically under Mac.
1957 }
1958
1959 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
1960 {
1961 if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
1962 {
1963 event.Skip() ;
1964 }
1965 else
1966 event.GetDC()->Clear() ;
1967 }
1968
1969 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
1970 {
1971 wxWindowDC dc(this) ;
1972 wxMacPortSetter helper(&dc) ;
1973
1974 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
1975 }
1976
1977 int wxWindowMac::GetScrollPos(int orient) const
1978 {
1979 if ( orient == wxHORIZONTAL )
1980 {
1981 if ( m_hScrollBar )
1982 return m_hScrollBar->GetThumbPosition() ;
1983 }
1984 else
1985 {
1986 if ( m_vScrollBar )
1987 return m_vScrollBar->GetThumbPosition() ;
1988 }
1989 return 0;
1990 }
1991
1992 // This now returns the whole range, not just the number
1993 // of positions that we can scroll.
1994 int wxWindowMac::GetScrollRange(int orient) const
1995 {
1996 if ( orient == wxHORIZONTAL )
1997 {
1998 if ( m_hScrollBar )
1999 return m_hScrollBar->GetRange() ;
2000 }
2001 else
2002 {
2003 if ( m_vScrollBar )
2004 return m_vScrollBar->GetRange() ;
2005 }
2006 return 0;
2007 }
2008
2009 int wxWindowMac::GetScrollThumb(int orient) const
2010 {
2011 if ( orient == wxHORIZONTAL )
2012 {
2013 if ( m_hScrollBar )
2014 return m_hScrollBar->GetThumbSize() ;
2015 }
2016 else
2017 {
2018 if ( m_vScrollBar )
2019 return m_vScrollBar->GetThumbSize() ;
2020 }
2021 return 0;
2022 }
2023
2024 void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
2025 {
2026 if ( orient == wxHORIZONTAL )
2027 {
2028 if ( m_hScrollBar )
2029 m_hScrollBar->SetThumbPosition( pos ) ;
2030 }
2031 else
2032 {
2033 if ( m_vScrollBar )
2034 m_vScrollBar->SetThumbPosition( pos ) ;
2035 }
2036 }
2037
2038 void wxWindowMac::MacPaintBorders( int left , int top )
2039 {
2040 if( IsTopLevel() )
2041 return ;
2042
2043 int major,minor;
2044 wxGetOsVersion( &major, &minor );
2045
2046 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
2047 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
2048
2049 RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
2050 RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
2051 // OS X has lighter border edges than classic:
2052 if (major >= 10)
2053 {
2054 darkShadow.red = 0x8E8E;
2055 darkShadow.green = 0x8E8E;
2056 darkShadow.blue = 0x8E8E;
2057 lightShadow.red = 0xBDBD;
2058 lightShadow.green = 0xBDBD;
2059 lightShadow.blue = 0xBDBD;
2060 }
2061
2062 PenNormal() ;
2063
2064 int w , h ;
2065 GetSize( &w , &h ) ;
2066 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2067 {
2068 #if wxMAC_USE_THEME_BORDER
2069 Rect rect = { top , left , m_height + top , m_width + left } ;
2070 SInt32 border = 0 ;
2071 /*
2072 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2073 InsetRect( &rect , border , border );
2074 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
2075 */
2076
2077 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
2078 #else
2079 bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
2080 RGBForeColor( &face );
2081 MoveTo( left + 0 , top + h - 2 );
2082 LineTo( left + 0 , top + 0 );
2083 LineTo( left + w - 2 , top + 0 );
2084
2085 MoveTo( left + 2 , top + h - 3 );
2086 LineTo( left + w - 3 , top + h - 3 );
2087 LineTo( left + w - 3 , top + 2 );
2088
2089 RGBForeColor( sunken ? &face : &darkShadow );
2090 MoveTo( left + 0 , top + h - 1 );
2091 LineTo( left + w - 1 , top + h - 1 );
2092 LineTo( left + w - 1 , top + 0 );
2093
2094 RGBForeColor( sunken ? &lightShadow : &white );
2095 MoveTo( left + 1 , top + h - 3 );
2096 LineTo( left + 1, top + 1 );
2097 LineTo( left + w - 3 , top + 1 );
2098
2099 RGBForeColor( sunken ? &white : &lightShadow );
2100 MoveTo( left + 1 , top + h - 2 );
2101 LineTo( left + w - 2 , top + h - 2 );
2102 LineTo( left + w - 2 , top + 1 );
2103
2104 RGBForeColor( sunken ? &darkShadow : &face );
2105 MoveTo( left + 2 , top + h - 4 );
2106 LineTo( left + 2 , top + 2 );
2107 LineTo( left + w - 4 , top + 2 );
2108 #endif
2109 }
2110 else if (HasFlag(wxSIMPLE_BORDER))
2111 {
2112 Rect rect = { top , left , h + top , w + left } ;
2113 RGBForeColor( &darkShadow ) ;
2114 FrameRect( &rect ) ;
2115 }
2116 }
2117
2118 void wxWindowMac::RemoveChild( wxWindowBase *child )
2119 {
2120 if ( child == m_hScrollBar )
2121 m_hScrollBar = NULL ;
2122 if ( child == m_vScrollBar )
2123 m_vScrollBar = NULL ;
2124
2125 wxWindowBase::RemoveChild( child ) ;
2126 }
2127
2128 // New function that will replace some of the above.
2129 void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
2130 int range, bool refresh)
2131 {
2132 if ( orient == wxHORIZONTAL )
2133 {
2134 if ( m_hScrollBar )
2135 {
2136 if ( range == 0 || thumbVisible >= range )
2137 {
2138 if ( m_hScrollBar->IsShown() )
2139 m_hScrollBar->Show(false) ;
2140 }
2141 else
2142 {
2143 if ( !m_hScrollBar->IsShown() )
2144 m_hScrollBar->Show(true) ;
2145 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2146 }
2147 }
2148 }
2149 else
2150 {
2151 if ( m_vScrollBar )
2152 {
2153 if ( range == 0 || thumbVisible >= range )
2154 {
2155 if ( m_vScrollBar->IsShown() )
2156 m_vScrollBar->Show(false) ;
2157 }
2158 else
2159 {
2160 if ( !m_vScrollBar->IsShown() )
2161 m_vScrollBar->Show(true) ;
2162 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2163 }
2164 }
2165 }
2166 MacRepositionScrollBars() ;
2167 }
2168
2169 // Does a physical scroll
2170 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2171 {
2172 if( dx == 0 && dy ==0 )
2173 return ;
2174
2175
2176 {
2177 wxClientDC dc(this) ;
2178 wxMacPortSetter helper(&dc) ;
2179
2180 int width , height ;
2181 GetClientSize( &width , &height ) ;
2182
2183
2184 wxPoint pos;
2185 pos.x = pos.y = 0;
2186
2187 Rect scrollrect;
2188 // TODO take out the boundaries
2189 GetControlBounds( (ControlRef) m_macControl, &scrollrect);
2190
2191 RgnHandle updateRgn = NewRgn() ;
2192 if ( rect )
2193 {
2194 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
2195 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
2196 SectRect( &scrollrect , &r , &scrollrect ) ;
2197 }
2198 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
2199 #if TARGET_CARBON
2200 //KO: The docs say ScrollRect creates an update region, which thus calls an update event
2201 // but it seems the update only refreshes the background of the control, rather than calling
2202 // kEventControlDraw, so we need to force a proper update here. There has to be a better
2203 // way of doing this... (Note that code below under !TARGET_CARBON does not work either...)
2204 Update();
2205 #endif
2206 // we also have to scroll the update rgn in this rectangle
2207 // in order not to loose updates
2208 #if !TARGET_CARBON
2209 WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ;
2210 RgnHandle formerUpdateRgn = NewRgn() ;
2211 RgnHandle scrollRgn = NewRgn() ;
2212 RectRgn( scrollRgn , &scrollrect ) ;
2213 GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
2214 Point pt = {0,0} ;
2215 LocalToGlobal( &pt ) ;
2216 OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
2217 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2218 if ( !EmptyRgn( formerUpdateRgn ) )
2219 {
2220 MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
2221 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
2222 InvalWindowRgn(rootWindow , formerUpdateRgn ) ;
2223 }
2224 InvalWindowRgn(rootWindow , updateRgn ) ;
2225 DisposeRgn( updateRgn ) ;
2226 DisposeRgn( formerUpdateRgn ) ;
2227 DisposeRgn( scrollRgn ) ;
2228 #endif
2229 }
2230
2231 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
2232 {
2233 wxWindowMac *child = node->GetData();
2234 if (child == m_vScrollBar) continue;
2235 if (child == m_hScrollBar) continue;
2236 if (child->IsTopLevel()) continue;
2237
2238 int x,y;
2239 child->GetPosition( &x, &y );
2240 int w,h;
2241 child->GetSize( &w, &h );
2242 if (rect)
2243 {
2244 wxRect rc(x,y,w,h);
2245 if (rect->Intersects(rc))
2246 child->SetSize( x+dx, y+dy, w, h );
2247 }
2248 else
2249 {
2250 child->SetSize( x+dx, y+dy, w, h );
2251 }
2252 }
2253
2254 // TODO remove, was moved higher up Update() ;
2255
2256 }
2257
2258 void wxWindowMac::MacOnScroll(wxScrollEvent &event )
2259 {
2260 if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
2261 {
2262 wxScrollWinEvent wevent;
2263 wevent.SetPosition(event.GetPosition());
2264 wevent.SetOrientation(event.GetOrientation());
2265 wevent.m_eventObject = this;
2266
2267 if (event.m_eventType == wxEVT_SCROLL_TOP)
2268 wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
2269 else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
2270 wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
2271 else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
2272 wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
2273 else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
2274 wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
2275 else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
2276 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
2277 else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
2278 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
2279 else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
2280 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
2281 else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
2282 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
2283
2284 GetEventHandler()->ProcessEvent(wevent);
2285 }
2286 }
2287
2288 // Get the window with the focus
2289 wxWindowMac *wxWindowBase::FindFocus()
2290 {
2291 ControlRef control ;
2292 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2293 return wxFindControlFromMacControl( control ) ;
2294 }
2295
2296 void wxWindowMac::OnSetFocus(wxFocusEvent& event)
2297 {
2298 // panel wants to track the window which was the last to have focus in it,
2299 // so we want to set ourselves as the window which last had focus
2300 //
2301 // notice that it's also important to do it upwards the tree becaus
2302 // otherwise when the top level panel gets focus, it won't set it back to
2303 // us, but to some other sibling
2304
2305 // CS:don't know if this is still needed:
2306 //wxChildFocusEvent eventFocus(this);
2307 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2308
2309 event.Skip();
2310 }
2311
2312 void wxWindowMac::OnInternalIdle()
2313 {
2314 // This calls the UI-update mechanism (querying windows for
2315 // menu/toolbar/control state information)
2316 if (wxUpdateUIEvent::CanUpdate(this))
2317 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2318 }
2319
2320 // Raise the window to the top of the Z order
2321 void wxWindowMac::Raise()
2322 {
2323 }
2324
2325 // Lower the window to the bottom of the Z order
2326 void wxWindowMac::Lower()
2327 {
2328 }
2329
2330
2331 // static wxWindow *gs_lastWhich = NULL;
2332
2333 bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
2334 {
2335 // first trigger a set cursor event
2336
2337 wxPoint clientorigin = GetClientAreaOrigin() ;
2338 wxSize clientsize = GetClientSize() ;
2339 wxCursor cursor ;
2340 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2341 {
2342 wxSetCursorEvent event( pt.x , pt.y );
2343
2344 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2345 if ( processedEvtSetCursor && event.HasCursor() )
2346 {
2347 cursor = event.GetCursor() ;
2348 }
2349 else
2350 {
2351
2352 // the test for processedEvtSetCursor is here to prevent using m_cursor
2353 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2354 // it - this is a way to say that our cursor shouldn't be used for this
2355 // point
2356 if ( !processedEvtSetCursor && m_cursor.Ok() )
2357 {
2358 cursor = m_cursor ;
2359 }
2360 if ( wxIsBusy() )
2361 {
2362 }
2363 else
2364 {
2365 if ( !GetParent() )
2366 cursor = *wxSTANDARD_CURSOR ;
2367 }
2368 }
2369 if ( cursor.Ok() )
2370 cursor.MacInstall() ;
2371 }
2372 return cursor.Ok() ;
2373 }
2374
2375 wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
2376 {
2377 if ( m_tooltip )
2378 {
2379 return m_tooltip->GetTip() ;
2380 }
2381 return wxEmptyString ;
2382 }
2383
2384 void wxWindowMac::Update()
2385 {
2386 #if TARGET_API_MAC_OSX
2387 HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
2388 #else
2389 ::Draw1Control( (ControlRef) m_macControl ) ;
2390 #endif
2391 }
2392
2393 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2394 {
2395 wxTopLevelWindowMac* win = NULL ;
2396 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2397 if ( window )
2398 {
2399 win = wxFindWinFromMacWindow( window ) ;
2400 }
2401 return win ;
2402 }
2403 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2404 {
2405
2406 Rect r ;
2407 RgnHandle visRgn = NewRgn() ;
2408 RgnHandle tempRgn = NewRgn() ;
2409 if ( IsControlVisible( (ControlRef) m_macControl ) )
2410 {
2411 GetControlBounds( (ControlRef) m_macControl , &r ) ;
2412 if (! MacGetTopLevelWindow()->MacUsesCompositing() )
2413 {
2414 MacRootWindowToWindow( &r.left , & r.top ) ;
2415 MacRootWindowToWindow( &r.right , & r.bottom ) ;
2416 }
2417 else
2418 {
2419 r.right -= r.left ;
2420 r.bottom -= r.top ;
2421 r.left = 0 ;
2422 r.top = 0 ;
2423 }
2424 if ( includeOuterStructures )
2425 InsetRect( &r , -3 , -3 ) ;
2426 RectRgn( visRgn , &r ) ;
2427 if ( !IsTopLevel() )
2428 {
2429 wxWindow* child = this ;
2430 wxWindow* parent = child->GetParent() ;
2431 while( parent )
2432 {
2433 int x , y ;
2434 wxSize size ;
2435 // we have to find a better clipping algorithm here, in order not to clip things
2436 // positioned like status and toolbar
2437 if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
2438 {
2439 size = parent->GetSize() ;
2440 x = y = 0 ;
2441 }
2442 else
2443 {
2444 size = parent->GetClientSize() ;
2445 wxPoint origin = parent->GetClientAreaOrigin() ;
2446 x = origin.x ;
2447 y = origin.y ;
2448 }
2449 parent->MacWindowToRootWindow( &x, &y ) ;
2450 MacRootWindowToWindow( &x , &y ) ;
2451
2452 SetRectRgn( tempRgn ,
2453 x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
2454 x + size.x - parent->MacGetRightBorderSize(),
2455 y + size.y - parent->MacGetBottomBorderSize()) ;
2456
2457 SectRgn( visRgn , tempRgn , visRgn ) ;
2458 if ( parent->IsTopLevel() )
2459 break ;
2460 child = parent ;
2461 parent = child->GetParent() ;
2462 }
2463 }
2464 }
2465
2466 wxRegion vis = visRgn ;
2467 DisposeRgn( visRgn ) ;
2468 DisposeRgn( tempRgn ) ;
2469 return vis ;
2470 }
2471
2472 /*
2473 This function must not change the updatergn !
2474 */
2475 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
2476 {
2477 RgnHandle updatergn = (RgnHandle) updatergnr ;
2478 bool handled = false ;
2479
2480 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2481 {
2482 RgnHandle newupdate = NewRgn() ;
2483 wxSize point = GetClientSize() ;
2484 wxPoint origin = GetClientAreaOrigin() ;
2485 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
2486 SectRgn( newupdate , updatergn , newupdate ) ;
2487 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
2488 m_updateRegion = newupdate ;
2489 DisposeRgn( newupdate ) ;
2490 }
2491
2492 if ( !EmptyRgn(updatergn) )
2493 {
2494 wxWindowDC dc(this);
2495 if (!EmptyRgn(updatergn))
2496 dc.SetClippingRegion(wxRegion(updatergn));
2497
2498 wxEraseEvent eevent( GetId(), &dc );
2499 eevent.SetEventObject( this );
2500 GetEventHandler()->ProcessEvent( eevent );
2501
2502 if ( !m_updateRegion.Empty() )
2503 {
2504 // paint the window itself
2505 wxPaintEvent event;
2506 event.m_timeStamp = time ;
2507 event.SetEventObject(this);
2508 handled = GetEventHandler()->ProcessEvent(event);
2509
2510 // paint custom borders
2511 wxNcPaintEvent eventNc( GetId() );
2512 eventNc.SetEventObject( this );
2513 GetEventHandler()->ProcessEvent( eventNc );
2514 }
2515 }
2516 return handled ;
2517 }
2518
2519 void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
2520 {
2521 RgnHandle updatergn = (RgnHandle) updatergnr ;
2522 // updatergn is always already clipped to our boundaries
2523 // if we are in compositing mode then it is in relative to the upper left of the control
2524 // if we are in non-compositing, then it is relatvie to the uppder left of the content area
2525 // of the toplevel window
2526 // it is in window coordinates, not in client coordinates
2527
2528 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
2529 RgnHandle ownUpdateRgn = NewRgn() ;
2530 CopyRgn( updatergn , ownUpdateRgn ) ;
2531
2532 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2533 {
2534 Rect bounds;
2535 UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds );
2536 RgnHandle controlRgn = NewRgn();
2537 RectRgn( controlRgn, &bounds );
2538 //KO: This sets the ownUpdateRgn to the area of this control that is inside
2539 // the window update region
2540 SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn );
2541 DisposeRgn( controlRgn );
2542
2543 //KO: convert ownUpdateRgn to local coordinates
2544 OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top );
2545 }
2546
2547 MacDoRedraw( ownUpdateRgn , time ) ;
2548 DisposeRgn( ownUpdateRgn ) ;
2549
2550 }
2551
2552 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
2553 {
2554 wxWindowMac *iter = (wxWindowMac*)this ;
2555
2556 while( iter )
2557 {
2558 if ( iter->IsTopLevel() )
2559 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
2560
2561 iter = iter->GetParent() ;
2562 }
2563 wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
2564 return NULL ;
2565 }
2566
2567 void wxWindowMac::MacCreateScrollBars( long style )
2568 {
2569 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
2570
2571 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
2572 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
2573 int width, height ;
2574 GetClientSize( &width , &height ) ;
2575
2576 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2577 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2578 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2579 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2580
2581 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
2582 vSize , wxVERTICAL);
2583
2584 if ( style & wxVSCROLL )
2585 {
2586
2587 }
2588 else
2589 {
2590 m_vScrollBar->Show(false) ;
2591 }
2592 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
2593 hSize , wxHORIZONTAL);
2594 if ( style & wxHSCROLL )
2595 {
2596 }
2597 else
2598 {
2599 m_hScrollBar->Show(false) ;
2600 }
2601
2602 // because the create does not take into account the client area origin
2603 MacRepositionScrollBars() ; // we might have a real position shift
2604 }
2605
2606 void wxWindowMac::MacRepositionScrollBars()
2607 {
2608 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
2609 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
2610
2611 // get real client area
2612
2613 int width ;
2614 int height ;
2615 GetSize( &width , &height ) ;
2616
2617 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2618 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2619
2620 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2621 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2622 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2623 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2624
2625 int x = 0 ;
2626 int y = 0 ;
2627 int w ;
2628 int h ;
2629 GetSize( &w , &h ) ;
2630
2631 MacClientToRootWindow( &x , &y ) ;
2632 MacClientToRootWindow( &w , &h ) ;
2633
2634 wxWindowMac *iter = (wxWindowMac*)this ;
2635
2636 int totW = 10000 , totH = 10000;
2637 while( iter )
2638 {
2639 if ( iter->IsTopLevel() )
2640 {
2641 iter->GetSize( &totW , &totH ) ;
2642 break ;
2643 }
2644
2645 iter = iter->GetParent() ;
2646 }
2647
2648 if ( x == 0 )
2649 {
2650 hPoint.x = -1 ;
2651 hSize.x += 1 ;
2652 }
2653 if ( y == 0 )
2654 {
2655 vPoint.y = -1 ;
2656 vSize.y += 1 ;
2657 }
2658
2659 if ( w-x >= totW )
2660 {
2661 hSize.x += 1 ;
2662 vPoint.x += 1 ;
2663 }
2664
2665 if ( h-y >= totH )
2666 {
2667 vSize.y += 1 ;
2668 hPoint.y += 1 ;
2669 }
2670
2671 if ( m_vScrollBar )
2672 {
2673 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
2674 }
2675 if ( m_hScrollBar )
2676 {
2677 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
2678 }
2679 }
2680
2681 bool wxWindowMac::AcceptsFocus() const
2682 {
2683 return MacCanFocus() && wxWindowBase::AcceptsFocus();
2684 }
2685
2686 void wxWindowMac::MacSuperChangedPosition()
2687 {
2688 // only window-absolute structures have to be moved i.e. controls
2689
2690 wxWindowListNode *node = GetChildren().GetFirst();
2691 while ( node )
2692 {
2693 wxWindowMac *child = node->GetData();
2694 child->MacSuperChangedPosition() ;
2695 node = node->GetNext();
2696 }
2697 }
2698
2699 void wxWindowMac::MacTopLevelWindowChangedPosition()
2700 {
2701 // only screen-absolute structures have to be moved i.e. glcanvas
2702
2703 wxWindowListNode *node = GetChildren().GetFirst();
2704 while ( node )
2705 {
2706 wxWindowMac *child = node->GetData();
2707 child->MacTopLevelWindowChangedPosition() ;
2708 node = node->GetNext();
2709 }
2710 }
2711
2712 long wxWindowMac::MacGetLeftBorderSize( ) const
2713 {
2714 if( IsTopLevel() )
2715 return 0 ;
2716
2717 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
2718 {
2719 SInt32 border = 3 ;
2720 #if wxMAC_USE_THEME_BORDER
2721 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2722 #endif
2723 return border ;
2724 }
2725 else if ( m_windowStyle &wxDOUBLE_BORDER)
2726 {
2727 SInt32 border = 3 ;
2728 #if wxMAC_USE_THEME_BORDER
2729 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2730 #endif
2731 return border ;
2732 }
2733 else if (m_windowStyle &wxSIMPLE_BORDER)
2734 {
2735 return 1 ;
2736 }
2737 return 0 ;
2738 }
2739
2740 long wxWindowMac::MacGetRightBorderSize( ) const
2741 {
2742 // they are all symmetric in mac themes
2743 return MacGetLeftBorderSize() ;
2744 }
2745
2746 long wxWindowMac::MacGetTopBorderSize( ) const
2747 {
2748 // they are all symmetric in mac themes
2749 return MacGetLeftBorderSize() ;
2750 }
2751
2752 long wxWindowMac::MacGetBottomBorderSize( ) const
2753 {
2754 // they are all symmetric in mac themes
2755 return MacGetLeftBorderSize() ;
2756 }
2757
2758 long wxWindowMac::MacRemoveBordersFromStyle( long style )
2759 {
2760 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
2761 }
2762
2763 // Find the wxWindowMac at the current mouse position, returning the mouse
2764 // position.
2765 wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
2766 {
2767 pt = wxGetMousePosition();
2768 wxWindowMac* found = wxFindWindowAtPoint(pt);
2769 return found;
2770 }
2771
2772 // Get the current mouse position.
2773 wxPoint wxGetMousePosition()
2774 {
2775 int x, y;
2776 wxGetMousePosition(& x, & y);
2777 return wxPoint(x, y);
2778 }
2779
2780 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2781 {
2782 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2783 {
2784 // copied from wxGTK : CS
2785 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
2786 // except that:
2787 //
2788 // (a) it's a command event and so is propagated to the parent
2789 // (b) under MSW it can be generated from kbd too
2790 // (c) it uses screen coords (because of (a))
2791 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
2792 this->GetId(),
2793 this->ClientToScreen(event.GetPosition()));
2794 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
2795 event.Skip() ;
2796 }
2797 else
2798 {
2799 event.Skip() ;
2800 }
2801 }
2802
2803 void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
2804 {
2805 }
2806
2807 Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
2808 {
2809 int x ,y , w ,h ;
2810
2811 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin) ;
2812 Rect bounds = { y , x , y+h , x+w };
2813 return bounds ;
2814 }
2815
2816 wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
2817 {
2818 return eventNotHandledErr ;
2819 }
2820
2821