]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/toplevel.cpp
CarbonEvents Added
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mac/toplevel.cpp
3 // Purpose: implements wxTopLevelWindow for MSW
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 24.09.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
34 #include "wx/frame.h"
35 #include "wx/string.h"
36 #include "wx/log.h"
37 #include "wx/intl.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/mac/uma.h"
41 #include "wx/mac/aga.h"
42 #include "wx/app.h"
43 #include "wx/tooltip.h"
44 #include "wx/dnd.h"
45
46 #define wxMAC_DEBUG_REDRAW 0
47 #ifndef wxMAC_DEBUG_REDRAW
48 #define wxMAC_DEBUG_REDRAW 0
49 #endif
50
51 // ----------------------------------------------------------------------------
52 // globals
53 // ----------------------------------------------------------------------------
54
55 // list of all frames and modeless dialogs
56 wxWindowList wxModelessWindows;
57
58 // double click testing
59 static Point gs_lastWhere;
60 static long gs_lastWhen = 0;
61
62 // ============================================================================
63 // wxTopLevelWindowMac implementation
64 // ============================================================================
65
66 // ---------------------------------------------------------------------------
67 // Carbon Events
68 // ---------------------------------------------------------------------------
69
70 #if TARGET_CARBON
71
72 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
73
74 static const EventTypeSpec eventList[] =
75 {
76 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
77 /*
78 { kEventClassKeyboard, kEventRawKeyDown } ,
79 { kEventClassKeyboard, kEventRawKeyRepeat } ,
80 { kEventClassKeyboard, kEventRawKeyUp } ,
81 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
82 */
83 { kEventClassWindow , kEventWindowUpdate } ,
84 { kEventClassWindow , kEventWindowActivated } ,
85 { kEventClassWindow , kEventWindowDeactivated } ,
86 { kEventClassWindow , kEventWindowBoundsChanging } ,
87 { kEventClassWindow , kEventWindowBoundsChanged } ,
88 { kEventClassWindow , kEventWindowClose } ,
89
90 { kEventClassMouse , kEventMouseDown } ,
91 { kEventClassMouse , kEventMouseUp } ,
92 { kEventClassMouse , kEventMouseMoved } ,
93 { kEventClassMouse , kEventMouseDragged } ,
94
95 } ;
96
97 static pascal OSStatus TextInputEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
98 {
99 OSStatus result = eventNotHandledErr ;
100 EventRecord rec ;
101
102 if ( wxMacConvertEventToRecord( event , &rec ) )
103 {
104 wxTheApp->m_macCurrentEvent = &rec ;
105 wxWindow* focus = wxWindow::FindFocus() ;
106 if ( (focus != NULL) && !UMAMenuEvent(&rec) && wxTheApp->MacSendKeyDownEvent( focus , rec.message , rec.modifiers , rec.when , rec.where.h , rec.where.v ) )
107 {
108 // was handled internally
109 result = noErr ;
110 }
111 }
112
113 return result ;
114 }
115
116 static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
117 {
118 OSStatus result = eventNotHandledErr ;
119
120 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
121 Point point ;
122 UInt32 modifiers = 0;
123 EventMouseButton button = 0 ;
124 UInt32 click = 0 ;
125
126 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
127 sizeof( Point ), NULL, &point );
128 GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
129 sizeof( UInt32 ), NULL, &modifiers );
130 GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
131 sizeof( EventMouseButton ), NULL, &button );
132 GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
133 sizeof( UInt32 ), NULL, &click );
134
135 if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
136 modifiers += btnState ;
137
138 WindowRef window ;
139 short windowPart = ::FindWindow(point, &window);
140 if ( windowPart == inContent )
141 {
142 switch ( GetEventKind( event ) )
143 {
144 case kEventMouseDown :
145 toplevelWindow->MacFireMouseEvent( mouseDown , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
146 result = noErr ;
147 break ;
148 case kEventMouseUp :
149 toplevelWindow->MacFireMouseEvent( mouseUp , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
150 result = noErr ;
151 break ;
152 case kEventMouseMoved :
153 toplevelWindow->MacFireMouseEvent( nullEvent , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
154 result = noErr ;
155 break ;
156 case kEventMouseDragged :
157 toplevelWindow->MacFireMouseEvent( nullEvent , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
158 result = noErr ;
159 break ;
160 default :
161 break ;
162 }
163 }
164
165 return result ;
166
167
168 }
169 static pascal OSStatus WindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
170 {
171 OSStatus result = eventNotHandledErr ;
172 OSStatus err = noErr ;
173
174 UInt32 attributes;
175 WindowRef windowRef ;
176 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
177
178 GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL,
179 sizeof( WindowRef ), NULL, &windowRef );
180
181 switch( GetEventKind( event ) )
182 {
183 case kEventWindowUpdate :
184 if ( !wxPendingDelete.Member(toplevelWindow) )
185 toplevelWindow->MacUpdate( EventTimeToTicks( GetEventTime( event ) ) ) ;
186 result = noErr ;
187 break ;
188 case kEventWindowActivated :
189 toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , true) ;
190 result = noErr ;
191 break ;
192 case kEventWindowDeactivated :
193 toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , false) ;
194 result = noErr ;
195 break ;
196 case kEventWindowClose :
197 toplevelWindow->Close() ;
198 result = noErr ;
199 break ;
200 case kEventWindowBoundsChanged :
201 err = GetEventParameter( event, kEventParamAttributes, typeUInt32,
202 NULL, sizeof( UInt32 ), NULL, &attributes );
203 if ( err == noErr )
204 {
205 Rect newContentRect ;
206
207 GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL,
208 sizeof( newContentRect ), NULL, &newContentRect );
209
210 toplevelWindow->SetSize( newContentRect.left , newContentRect.top ,
211 newContentRect.right - newContentRect.left ,
212 newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
213
214 result = noErr;
215 }
216 break ;
217 default :
218 break ;
219 }
220 return result ;
221 }
222
223 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
224 {
225 OSStatus result = eventNotHandledErr ;
226
227 switch ( GetEventClass( event ) )
228 {
229 case kEventClassTextInput :
230 result = TextInputEventHandler( handler, event , data ) ;
231 break ;
232 case kEventClassWindow :
233 result = WindowEventHandler( handler, event , data ) ;
234 break ;
235 case kEventClassMouse :
236 result = MouseEventHandler( handler, event , data ) ;
237 break ;
238 default :
239 break ;
240 }
241 return result ;
242 }
243
244 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
245
246 #endif
247
248 // ---------------------------------------------------------------------------
249 // wxWindowMac utility functions
250 // ---------------------------------------------------------------------------
251
252 // Find an item given the Macintosh Window Reference
253
254 wxList *wxWinMacWindowList = NULL;
255 wxTopLevelWindowMac *wxFindWinFromMacWindow(WXWindow inWindowRef)
256 {
257 wxNode *node = wxWinMacWindowList->Find((long)inWindowRef);
258 if (!node)
259 return NULL;
260 return (wxTopLevelWindowMac *)node->GetData();
261 }
262
263 void wxAssociateWinWithMacWindow(WXWindow inWindowRef, wxTopLevelWindowMac *win)
264 {
265 // adding NULL WindowRef is (first) surely a result of an error and
266 // (secondly) breaks menu command processing
267 wxCHECK_RET( inWindowRef != (WindowRef) NULL, "attempt to add a NULL WindowRef to window list" );
268
269 if ( !wxWinMacWindowList->Find((long)inWindowRef) )
270 wxWinMacWindowList->Append((long)inWindowRef, win);
271 }
272
273 void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
274 {
275 wxWinMacWindowList->DeleteObject(win);
276 }
277
278
279 // ----------------------------------------------------------------------------
280 // wxTopLevelWindowMac creation
281 // ----------------------------------------------------------------------------
282
283 WXHWND wxTopLevelWindowMac::s_macWindowInUpdate = NULL;
284
285 void wxTopLevelWindowMac::Init()
286 {
287 m_iconized =
288 m_maximizeOnShow = FALSE;
289 m_macNoEraseUpdateRgn = NewRgn() ;
290 m_macNeedsErasing = false ;
291 m_macWindow = NULL ;
292 #if TARGET_CARBON
293 m_macEventHandler = NULL ;
294 #endif
295 }
296
297 class wxMacDeferredWindowDeleter : public wxObject
298 {
299 public :
300 wxMacDeferredWindowDeleter( WindowRef windowRef )
301 {
302 m_macWindow = windowRef ;
303 }
304 virtual ~wxMacDeferredWindowDeleter()
305 {
306 UMADisposeWindow( (WindowRef) m_macWindow ) ;
307 }
308 protected :
309 WindowRef m_macWindow ;
310 } ;
311
312 bool wxTopLevelWindowMac::Create(wxWindow *parent,
313 wxWindowID id,
314 const wxString& title,
315 const wxPoint& pos,
316 const wxSize& size,
317 long style,
318 const wxString& name)
319 {
320 // init our fields
321 Init();
322
323 m_windowStyle = style;
324
325 SetName(name);
326
327 m_windowId = id == -1 ? NewControlId() : id;
328
329 wxTopLevelWindows.Append(this);
330
331 if ( parent )
332 parent->AddChild(this);
333
334 return TRUE;
335 }
336
337 wxTopLevelWindowMac::~wxTopLevelWindowMac()
338 {
339 if ( m_macWindow )
340 {
341 wxToolTip::NotifyWindowDelete(m_macWindow) ;
342 wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
343 }
344
345 #if TARGET_CARBON
346 if ( m_macEventHandler )
347 {
348 ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
349 m_macEventHandler = NULL ;
350 }
351 #endif
352
353 wxRemoveMacWindowAssociation( this ) ;
354
355 if ( wxModelessWindows.Find(this) )
356 wxModelessWindows.DeleteObject(this);
357
358 DisposeRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
359 }
360
361
362 // ----------------------------------------------------------------------------
363 // wxTopLevelWindowMac maximize/minimize
364 // ----------------------------------------------------------------------------
365
366 void wxTopLevelWindowMac::Maximize(bool maximize)
367 {
368 // not available on mac
369 }
370
371 bool wxTopLevelWindowMac::IsMaximized() const
372 {
373 return false ;
374 }
375
376 void wxTopLevelWindowMac::Iconize(bool iconize)
377 {
378 // not available on mac
379 }
380
381 bool wxTopLevelWindowMac::IsIconized() const
382 {
383 // mac dialogs cannot be iconized
384 return FALSE;
385 }
386
387 void wxTopLevelWindowMac::Restore()
388 {
389 // not available on mac
390 }
391
392 // ----------------------------------------------------------------------------
393 // wxTopLevelWindowMac misc
394 // ----------------------------------------------------------------------------
395
396 void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
397 {
398 // this sets m_icon
399 wxTopLevelWindowBase::SetIcon(icon);
400 }
401
402 void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
403 const wxPoint& pos,
404 const wxSize& size,
405 long style,
406 const wxString& name )
407 {
408 SetName(name);
409 m_windowStyle = style;
410 m_isShown = FALSE;
411
412 // create frame.
413
414 Rect theBoundsRect;
415
416 m_x = (int)pos.x;
417 m_y = (int)pos.y;
418 if ( m_y < 50 )
419 m_y = 50 ;
420 if ( m_x < 20 )
421 m_x = 20 ;
422
423 m_width = size.x;
424 if (m_width == -1)
425 m_width = 20;
426 m_height = size.y;
427 if (m_height == -1)
428 m_height = 20;
429
430 ::SetRect(&theBoundsRect, m_x, m_y , m_x + m_width, m_y + m_height);
431
432 // translate the window attributes in the appropriate window class and attributes
433
434 WindowClass wclass = 0;
435 WindowAttributes attr = kWindowNoAttributes ;
436
437 if ( HasFlag( wxFRAME_TOOL_WINDOW) )
438 {
439 if (
440 HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
441 HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
442 HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT)
443 )
444 {
445 wclass = kFloatingWindowClass ;
446 if ( HasFlag(wxTINY_CAPTION_VERT) )
447 {
448 attr |= kWindowSideTitlebarAttribute ;
449 }
450 }
451 else
452 {
453 #if TARGET_CARBON
454 wclass = kPlainWindowClass ;
455 #else
456 wclass = kFloatingWindowClass ;
457 #endif
458 }
459 }
460 else if ( HasFlag( wxCAPTION ) )
461 {
462 if ( HasFlag( wxDIALOG_MODAL ) )
463 {
464 wclass = kDocumentWindowClass ; // kMovableModalWindowClass ;
465 }
466 else
467 {
468 wclass = kDocumentWindowClass ;
469 }
470 }
471 else
472 {
473 if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
474 HasFlag( wxSYSTEM_MENU ) )
475 {
476 wclass = kDocumentWindowClass ;
477 }
478 else
479 {
480 #if TARGET_CARBON
481 wclass = kPlainWindowClass ;
482 #else
483 wclass = kModalWindowClass ;
484 #endif
485 }
486 }
487
488 if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) )
489 {
490 attr |= kWindowFullZoomAttribute ;
491 attr |= kWindowCollapseBoxAttribute ;
492 }
493 if ( HasFlag( wxRESIZE_BORDER ) )
494 {
495 attr |= kWindowResizableAttribute ;
496 }
497 if ( HasFlag( wxSYSTEM_MENU ) )
498 {
499 attr |= kWindowCloseBoxAttribute ;
500 }
501
502 ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
503 wxAssociateWinWithMacWindow( m_macWindow , this ) ;
504 wxString label ;
505 if( wxApp::s_macDefaultEncodingIsPC )
506 label = wxMacMakeMacStringFromPC( title ) ;
507 else
508 label = title ;
509 UMASetWTitleC( (WindowRef)m_macWindow , label ) ;
510 ::CreateRootControl( (WindowRef)m_macWindow , (ControlHandle*)&m_macRootControl ) ;
511 #if TARGET_CARBON
512 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
513 InstallWindowEventHandler(MAC_WXHWND(m_macWindow), GetwxMacWindowEventHandlerUPP(),
514 GetEventTypeCount(eventList), eventList, this, &((EventHandlerRef)m_macEventHandler));
515 #endif
516 m_macFocus = NULL ;
517 }
518
519 void wxTopLevelWindowMac::MacGetPortParams(WXPOINTPTR localOrigin, WXRECTPTR clipRect, WXHWND *window , wxWindowMac** rootwin)
520 {
521 ((Point*)localOrigin)->h = 0;
522 ((Point*)localOrigin)->v = 0;
523 ((Rect*)clipRect)->left = 0;
524 ((Rect*)clipRect)->top = 0;
525 ((Rect*)clipRect)->right = m_width;
526 ((Rect*)clipRect)->bottom = m_height;
527 *window = m_macWindow ;
528 *rootwin = this ;
529 }
530
531 void wxTopLevelWindowMac::Clear()
532 {
533 wxWindow::Clear() ;
534 }
535
536 WXWidget wxTopLevelWindowMac::MacGetContainerForEmbedding()
537 {
538 return m_macRootControl ;
539 }
540
541
542 void wxTopLevelWindowMac::MacUpdate( long timestamp)
543 {
544
545 wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
546
547 BeginUpdate( (WindowRef)m_macWindow ) ;
548
549 RgnHandle updateRgn = NewRgn();
550 RgnHandle diffRgn = NewRgn() ;
551 if ( updateRgn && diffRgn )
552 {
553 GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn );
554 DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
555 if ( !EmptyRgn( updateRgn ) )
556 {
557 MacRedraw( updateRgn , timestamp , m_macNeedsErasing || !EmptyRgn( diffRgn ) ) ;
558 }
559 }
560 if ( updateRgn )
561 DisposeRgn( updateRgn );
562 if ( diffRgn )
563 DisposeRgn( diffRgn );
564 EndUpdate( (WindowRef)m_macWindow ) ;
565 SetEmptyRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
566 m_macNeedsErasing = false ;
567 }
568
569
570 // Raise the window to the top of the Z order
571 void wxTopLevelWindowMac::Raise()
572 {
573 ::BringToFront( (WindowRef)m_macWindow ) ;
574 }
575
576 // Lower the window to the bottom of the Z order
577 void wxTopLevelWindowMac::Lower()
578 {
579 ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
580 }
581
582 void wxTopLevelWindowMac::MacFireMouseEvent(
583 wxUint16 kind , wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp )
584 {
585 wxMouseEvent event(wxEVT_LEFT_DOWN);
586 bool isDown = !(modifiers & btnState) ; // 1 is for up
587 bool controlDown = modifiers & controlKey ; // for simulating right mouse
588
589 event.m_leftDown = isDown && !controlDown;
590
591 event.m_middleDown = FALSE;
592 event.m_rightDown = isDown && controlDown;
593
594 if ( kind == mouseDown )
595 {
596 if ( controlDown )
597 event.SetEventType(wxEVT_RIGHT_DOWN ) ;
598 else
599 event.SetEventType(wxEVT_LEFT_DOWN ) ;
600 }
601 else if ( kind == mouseUp )
602 {
603 if ( controlDown )
604 event.SetEventType(wxEVT_RIGHT_UP ) ;
605 else
606 event.SetEventType(wxEVT_LEFT_UP ) ;
607 }
608 else
609 {
610 event.SetEventType(wxEVT_MOTION ) ;
611 }
612
613 event.m_shiftDown = modifiers & shiftKey;
614 event.m_controlDown = modifiers & controlKey;
615 event.m_altDown = modifiers & optionKey;
616 event.m_metaDown = modifiers & cmdKey;
617
618 Point localwhere ;
619 localwhere.h = x ;
620 localwhere.v = y ;
621
622 GrafPtr port ;
623 ::GetPort( &port ) ;
624 ::SetPort( UMAGetWindowPort( (WindowRef)m_macWindow ) ) ;
625 ::GlobalToLocal( &localwhere ) ;
626 ::SetPort( port ) ;
627
628 if ( kind == mouseDown )
629 {
630 if ( timestamp - gs_lastWhen <= GetDblTime() )
631 {
632 if ( abs( localwhere.h - gs_lastWhere.h ) < 3 && abs( localwhere.v - gs_lastWhere.v ) < 3 )
633 {
634 // This is not right if the second mouse down
635 // event occured in a differen window. We
636 // correct this in MacDispatchMouseEvent.
637 if ( controlDown )
638 event.SetEventType(wxEVT_RIGHT_DCLICK ) ;
639 else
640 event.SetEventType(wxEVT_LEFT_DCLICK ) ;
641 }
642 gs_lastWhen = 0 ;
643 }
644 else
645 {
646 gs_lastWhen = timestamp ;
647 }
648 gs_lastWhere = localwhere ;
649 }
650
651 event.m_x = localwhere.h;
652 event.m_y = localwhere.v;
653 event.m_x += m_x;
654 event.m_y += m_y;
655
656 event.m_timeStamp = timestamp;
657 event.SetEventObject(this);
658 if ( wxTheApp->s_captureWindow )
659 {
660 int x = event.m_x ;
661 int y = event.m_y ;
662 wxTheApp->s_captureWindow->ScreenToClient( &x , &y ) ;
663 event.m_x = x ;
664 event.m_y = y ;
665 event.SetEventObject( wxTheApp->s_captureWindow ) ;
666 wxTheApp->s_captureWindow->GetEventHandler()->ProcessEvent( event ) ;
667
668 if ( kind == mouseUp )
669 {
670 wxTheApp->s_captureWindow = NULL ;
671 if ( !wxIsBusy() )
672 {
673 m_cursor.MacInstall() ;
674 }
675 }
676 }
677 else
678 {
679 MacDispatchMouseEvent( event ) ;
680 }
681 }
682 #if !TARGET_CARBON
683
684 void wxTopLevelWindowMac::MacMouseDown( WXEVENTREF ev , short part)
685 {
686 MacFireMouseEvent( mouseDown , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
687 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
688 }
689
690 void wxTopLevelWindowMac::MacMouseUp( WXEVENTREF ev , short part)
691 {
692 switch (part)
693 {
694 case inContent:
695 {
696 MacFireMouseEvent( mouseUp , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
697 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
698 }
699 break ;
700 }
701 }
702
703 void wxTopLevelWindowMac::MacMouseMoved( WXEVENTREF ev , short part)
704 {
705 switch (part)
706 {
707 case inContent:
708 {
709 MacFireMouseEvent( nullEvent /*moved*/ , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
710 ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
711 }
712 break ;
713 }
714 }
715
716 #endif
717
718 void wxTopLevelWindowMac::MacActivate( long timestamp , bool inIsActivating )
719 {
720 wxActivateEvent event(wxEVT_ACTIVATE, inIsActivating , m_windowId);
721 event.m_timeStamp = timestamp ;
722 event.SetEventObject(this);
723
724 GetEventHandler()->ProcessEvent(event);
725
726 UMAHighlightAndActivateWindow( (WindowRef)m_macWindow , inIsActivating ) ;
727
728 // Early versions of MacOS X don't refresh backgrounds properly,
729 // so refresh the whole window on activation and deactivation.
730 long osVersion = UMAGetSystemVersion();
731 if (osVersion >= 0x1000 && osVersion < 0x1020)
732 Refresh(TRUE);
733 else
734 MacSuperEnabled( inIsActivating ) ;
735 }
736
737 #if !TARGET_CARBON
738
739 void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev )
740 {
741 }
742
743 #endif
744
745 void wxTopLevelWindowMac::SetTitle(const wxString& title)
746 {
747 wxWindow::SetTitle( title ) ;
748
749 wxString label ;
750
751 if( wxApp::s_macDefaultEncodingIsPC )
752 label = wxMacMakeMacStringFromPC( m_label ) ;
753 else
754 label = m_label ;
755
756 UMASetWTitleC( (WindowRef)m_macWindow , label ) ;
757 }
758
759 bool wxTopLevelWindowMac::Show(bool show)
760 {
761 if ( !wxWindow::Show(show) )
762 return FALSE;
763
764 if (show)
765 {
766 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil);
767 ::SelectWindow( (WindowRef)m_macWindow ) ;
768 // no need to generate events here, they will get them triggered by macos
769 // actually they should be , but apparently they are not
770 wxSize size(m_width, m_height);
771 wxSizeEvent event(size, m_windowId);
772 event.SetEventObject(this);
773 GetEventHandler()->ProcessEvent(event);
774 }
775 else
776 {
777 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil);
778 }
779
780 if ( !show )
781 {
782 }
783 else
784 {
785 Refresh() ;
786 }
787
788 return TRUE;
789 }
790
791 void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
792 {
793 int former_x = m_x ;
794 int former_y = m_y ;
795 int former_w = m_width ;
796 int former_h = m_height ;
797
798 int actualWidth = width;
799 int actualHeight = height;
800 int actualX = x;
801 int actualY = y;
802
803 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
804 actualWidth = m_minWidth;
805 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
806 actualHeight = m_minHeight;
807 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
808 actualWidth = m_maxWidth;
809 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
810 actualHeight = m_maxHeight;
811
812 bool doMove = false ;
813 bool doResize = false ;
814
815 if ( actualX != former_x || actualY != former_y )
816 {
817 doMove = true ;
818 }
819 if ( actualWidth != former_w || actualHeight != former_h )
820 {
821 doResize = true ;
822 }
823
824 if ( doMove || doResize )
825 {
826 m_x = actualX ;
827 m_y = actualY ;
828 m_width = actualWidth ;
829 m_height = actualHeight ;
830
831 if ( doMove )
832 ::MoveWindow((WindowRef)m_macWindow, m_x, m_y , false); // don't make frontmost
833
834 if ( doResize )
835 ::SizeWindow((WindowRef)m_macWindow, m_width, m_height , true);
836
837 // the OS takes care of invalidating and erasing the new area so we only have to
838 // take care of refreshing for full repaints
839
840 if ( doResize && !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) )
841 Refresh() ;
842
843
844 if ( IsKindOf( CLASSINFO( wxFrame ) ) )
845 {
846 wxFrame* frame = (wxFrame*) this ;
847 frame->PositionStatusBar();
848 frame->PositionToolBar();
849 }
850 if ( doMove )
851 wxWindowMac::MacTopLevelWindowChangedPosition() ; // like this only children will be notified
852
853 MacRepositionScrollBars() ;
854 if ( doMove )
855 {
856 wxPoint point(m_x, m_y);
857 wxMoveEvent event(point, m_windowId);
858 event.SetEventObject(this);
859 GetEventHandler()->ProcessEvent(event) ;
860 }
861 if ( doResize )
862 {
863 MacRepositionScrollBars() ;
864 wxSize size(m_width, m_height);
865 wxSizeEvent event(size, m_windowId);
866 event.SetEventObject(this);
867 GetEventHandler()->ProcessEvent(event);
868 }
869 }
870
871 }
872
873 /*
874 * Invalidation Mechanism
875 *
876 * The update mechanism reflects exactely the windows mechanism
877 * the rect gets added to the window invalidate region, if the eraseBackground flag
878 * has been true for any part of the update rgn the background is erased in the entire region
879 * not just in the specified rect.
880 *
881 * In order to achive this, we also have an internal m_macNoEraseUpdateRgn, all rects that have
882 * the eraseBackground flag set to false are also added to this rgn. upon receiving an update event
883 * the update rgn is compared to the m_macNoEraseUpdateRgn and in case they differ, every window
884 * will get the eraseBackground event first
885 */
886
887 void wxTopLevelWindowMac::MacInvalidate( const WXRECTPTR rect, bool eraseBackground )
888 {
889 GrafPtr formerPort ;
890 GetPort( &formerPort ) ;
891 SetPortWindowPort( (WindowRef)m_macWindow ) ;
892
893 m_macNeedsErasing |= eraseBackground ;
894
895 // if we already know that we will have to erase, there's no need to track the rest
896 if ( !m_macNeedsErasing)
897 {
898 // we end only here if eraseBackground is false
899 // if we already have a difference between m_macNoEraseUpdateRgn and UpdateRgn
900 // we will have to erase anyway
901
902 RgnHandle updateRgn = NewRgn();
903 RgnHandle diffRgn = NewRgn() ;
904 if ( updateRgn && diffRgn )
905 {
906 GetWindowUpdateRgn( (WindowRef)m_macWindow , updateRgn );
907 Point pt = {0,0} ;
908 LocalToGlobal( &pt ) ;
909 OffsetRgn( updateRgn , -pt.h , -pt.v ) ;
910 DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
911 if ( !EmptyRgn( diffRgn ) )
912 {
913 m_macNeedsErasing = true ;
914 }
915 }
916 if ( updateRgn )
917 DisposeRgn( updateRgn );
918 if ( diffRgn )
919 DisposeRgn( diffRgn );
920
921 if ( !m_macNeedsErasing )
922 {
923 RgnHandle rectRgn = NewRgn() ;
924 SetRectRgn( rectRgn , ((Rect*)rect)->left , ((Rect*)rect)->top , ((Rect*)rect)->right , ((Rect*)rect)->bottom ) ;
925 UnionRgn( (RgnHandle) m_macNoEraseUpdateRgn , rectRgn , (RgnHandle) m_macNoEraseUpdateRgn ) ;
926 DisposeRgn( rectRgn ) ;
927 }
928 }
929 InvalWindowRect( (WindowRef)m_macWindow , (Rect*)rect ) ;
930 // turn this on to debug the refreshing cycle
931 #if wxMAC_DEBUG_REDRAW
932 PaintRect( rect ) ;
933 #endif
934 SetPort( formerPort ) ;
935 }
936