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