]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/utils.cpp
mac cgcolor changes & cleanup
[wxWidgets.git] / src / mac / carbon / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/utils.cpp
3 // Purpose: Various utilities
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 #include "wx/wxprec.h"
13
14 #include "wx/utils.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19 #if wxUSE_GUI
20 #include "wx/toplevel.h"
21 #include "wx/font.h"
22 #endif
23 #endif
24
25 #include "wx/apptrait.h"
26
27 #if wxUSE_GUI
28 #include "wx/mac/uma.h"
29 #endif
30
31 #include <ctype.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdarg.h>
37
38 #include "MoreFilesX.h"
39
40 #ifndef __DARWIN__
41 #include <Threads.h>
42 #include <Sound.h>
43 #endif
44
45 #if wxUSE_GUI
46 #include <CoreServices/CoreServices.h>
47 #include <Carbon/Carbon.h>
48 #include "wx/mac/private/timer.h"
49 #endif // wxUSE_GUI
50
51 #include "wx/evtloop.h"
52 #include "wx/mac/private.h"
53
54 #if defined(__MWERKS__) && wxUSE_UNICODE
55 #if __MWERKS__ < 0x4100
56 #include <wtime.h>
57 #endif
58 #endif
59
60 #if wxUSE_BASE
61
62 // our OS version is the same in non GUI and GUI cases
63 wxOperatingSystemId wxGetOsVersion(int *majorVsn, int *minorVsn)
64 {
65 SInt32 theSystem;
66 Gestalt(gestaltSystemVersion, &theSystem);
67
68 if ( majorVsn != NULL )
69 *majorVsn = (theSystem >> 8);
70
71 if ( minorVsn != NULL )
72 *minorVsn = (theSystem & 0xFF);
73
74 #if defined( __DARWIN__ )
75 return wxOS_MAC_OSX_DARWIN;
76 #else
77 return wxOS_MAC_OS;
78 #endif
79 }
80
81 extern bool WXDLLEXPORT wxIsDebuggerRunning()
82 {
83 // TODO : try to find out ...
84 return false;
85 }
86
87 // Emit a beeeeeep
88 void wxBell()
89 {
90 #ifndef __LP64__
91 SysBeep(30);
92 #endif
93 }
94
95
96 #endif // wxUSE_BASE
97
98 #if wxUSE_GUI
99
100 wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
101 {
102 // We suppose that toolkit version is the same as OS version under Mac
103 wxGetOsVersion(verMaj, verMin);
104
105 return wxPORT_MAC;
106 }
107
108 wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
109 {
110 return new wxEventLoop;
111 }
112
113 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
114 {
115 return new wxCarbonTimerImpl(timer);
116 }
117
118 int gs_wxBusyCursorCount = 0;
119 extern wxCursor gMacCurrentCursor;
120 wxCursor gMacStoredActiveCursor;
121
122 // Set the cursor to the busy cursor for all windows
123 void wxBeginBusyCursor(const wxCursor *cursor)
124 {
125 if (gs_wxBusyCursorCount++ == 0)
126 {
127 gMacStoredActiveCursor = gMacCurrentCursor;
128 cursor->MacInstall();
129 }
130 //else: nothing to do, already set
131 }
132
133 // Restore cursor to normal
134 void wxEndBusyCursor()
135 {
136 wxCHECK_RET( gs_wxBusyCursorCount > 0,
137 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
138
139 if (--gs_wxBusyCursorCount == 0)
140 {
141 gMacStoredActiveCursor.MacInstall();
142 gMacStoredActiveCursor = wxNullCursor;
143 }
144 }
145
146 // true if we're between the above two calls
147 bool wxIsBusy()
148 {
149 return (gs_wxBusyCursorCount > 0);
150 }
151
152 #endif // wxUSE_GUI
153
154 #if wxUSE_BASE
155
156 wxString wxMacFindFolderNoSeparator( short vol,
157 OSType folderType,
158 Boolean createFolder)
159 {
160 FSRef fsRef;
161 wxString strDir;
162
163 if ( FSFindFolder( vol, folderType, createFolder, &fsRef) == noErr)
164 {
165 strDir = wxMacFSRefToPath( &fsRef );
166 }
167
168 return strDir;
169 }
170
171 wxString wxMacFindFolder( short vol,
172 OSType folderType,
173 Boolean createFolder)
174 {
175 return wxMacFindFolderNoSeparator(vol, folderType, createFolder) + wxFILE_SEP_PATH;
176 }
177
178 #endif // wxUSE_BASE
179
180 #if wxUSE_GUI
181
182 // Check whether this window wants to process messages, e.g. Stop button
183 // in long calculations.
184 bool wxCheckForInterrupt(wxWindow *WXUNUSED(wnd))
185 {
186 // TODO
187 return false;
188 }
189
190 void wxGetMousePosition( int* x, int* y )
191 {
192 Point pt;
193 GetGlobalMouse(&pt);
194 *x = pt.h;
195 *y = pt.v;
196 };
197
198 // Return true if we have a colour display
199 bool wxColourDisplay()
200 {
201 return true;
202 }
203
204 // Returns depth of screen
205 int wxDisplayDepth()
206 {
207 int theDepth = (int) CGDisplayBitsPerPixel(CGMainDisplayID());
208 Rect globRect;
209 SetRect(&globRect, -32760, -32760, 32760, 32760);
210 GDHandle theMaxDevice;
211
212 theMaxDevice = GetMaxDevice(&globRect);
213 if (theMaxDevice != NULL)
214 theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
215
216 return theDepth;
217 }
218
219 // Get size of display
220 void wxDisplaySize(int *width, int *height)
221 {
222 // TODO adapt for multi-displays
223 CGRect bounds = CGDisplayBounds(CGMainDisplayID());
224 if ( width )
225 *width = (int)bounds.size.width ;
226 if ( height )
227 *height = (int)bounds.size.height;
228 }
229
230 void wxDisplaySizeMM(int *width, int *height)
231 {
232 wxDisplaySize(width, height);
233 // on mac 72 is fixed (at least now;-)
234 float cvPt2Mm = 25.4 / 72;
235
236 if (width != NULL)
237 *width = int( *width * cvPt2Mm );
238
239 if (height != NULL)
240 *height = int( *height * cvPt2Mm );
241 }
242
243 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
244 {
245 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
246 HIRect bounds ;
247 HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal,
248 &bounds);
249 if ( x )
250 *x = bounds.origin.x;
251 if ( y )
252 *y = bounds.origin.y;
253 if ( width )
254 *width = bounds.size.width;
255 if ( height )
256 *height = bounds.size.height;
257 #else
258 Rect r;
259 GetAvailableWindowPositioningBounds( GetMainDevice() , &r );
260 if ( x )
261 *x = r.left;
262 if ( y )
263 *y = r.top;
264 if ( width )
265 *width = r.right - r.left;
266 if ( height )
267 *height = r.bottom - r.top;
268 #endif
269 }
270
271 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
272 {
273 return wxGenericFindWindowAtPoint(pt);
274 }
275
276 #endif // wxUSE_GUI
277
278 #if wxUSE_BASE
279
280 wxString wxGetOsDescription()
281 {
282 #ifdef WXWIN_OS_DESCRIPTION
283 // use configure generated description if available
284 return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
285 #else
286 return wxT("MacOS"); //TODO:define further
287 #endif
288 }
289
290 #ifndef __DARWIN__
291 wxString wxGetUserHome (const wxString& user)
292 {
293 // TODO
294 return wxString();
295 }
296
297 bool wxGetDiskSpace(const wxString& path, wxDiskspaceSize_t *pTotal, wxDiskspaceSize_t *pFree)
298 {
299 if ( path.empty() )
300 return false;
301
302 wxString p = path;
303 if (p[0u] == ':' )
304 p = wxGetCwd() + p;
305
306 int pos = p.Find(':');
307 if ( pos != wxNOT_FOUND )
308 p = p.Mid(1,pos);
309
310 p = p + wxT(":");
311
312 OSErr err = noErr;
313
314 FSRef fsRef;
315 err = wxMacPathToFSRef( p , &fsRef );
316 if ( noErr == err )
317 {
318 FSVolumeRefNum vRefNum;
319 err = FSGetVRefNum( &fsRef , &vRefNum );
320 if ( noErr == err )
321 {
322 UInt64 freeBytes , totalBytes;
323 err = FSGetVInfo( vRefNum , NULL , &freeBytes , &totalBytes );
324 if ( noErr == err )
325 {
326 if ( pTotal )
327 *pTotal = wxDiskspaceSize_t( totalBytes );
328 if ( pFree )
329 *pFree = wxDiskspaceSize_t( freeBytes );
330 }
331 }
332 }
333
334 return err == noErr;
335 }
336 #endif // !__DARWIN__
337
338 //---------------------------------------------------------------------------
339 // wxMac Specific utility functions
340 //---------------------------------------------------------------------------
341
342 void wxMacStringToPascal( const wxString&from , StringPtr to )
343 {
344 wxCharBuffer buf = from.mb_str( wxConvLocal );
345 int len = strlen(buf);
346
347 if ( len > 255 )
348 len = 255;
349 to[0] = len;
350 memcpy( (char*) &to[1] , buf , len );
351 }
352
353 wxString wxMacMakeStringFromPascal( ConstStringPtr from )
354 {
355 return wxString( (char*) &from[1] , wxConvLocal , from[0] );
356 }
357
358 // ----------------------------------------------------------------------------
359 // Common Event Support
360 // ----------------------------------------------------------------------------
361
362 extern ProcessSerialNumber gAppProcess;
363
364 void wxMacWakeUp()
365 {
366 ProcessSerialNumber psn;
367 Boolean isSame;
368 psn.highLongOfPSN = 0;
369 psn.lowLongOfPSN = kCurrentProcess;
370 SameProcess( &gAppProcess , &psn , &isSame );
371 if ( isSame )
372 {
373 OSStatus err = noErr;
374
375 #if 0
376 // lead sometimes to race conditions, although all calls used should be thread safe ...
377 static wxMacCarbonEvent s_wakeupEvent;
378 if ( !s_wakeupEvent.IsValid() )
379 {
380 err = s_wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
381 kEventAttributeNone );
382 }
383 if ( err == noErr )
384 {
385
386 if ( IsEventInQueue( GetMainEventQueue() , s_wakeupEvent ) )
387 return;
388 s_wakeupEvent.SetCurrentTime();
389 err = PostEventToQueue(GetMainEventQueue(), s_wakeupEvent,
390 kEventPriorityHigh );
391 }
392 #else
393 wxMacCarbonEvent wakeupEvent;
394 wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
395 kEventAttributeNone );
396 err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
397 kEventPriorityHigh );
398 #endif
399 }
400 else
401 {
402 WakeUpProcess( &gAppProcess );
403 }
404 }
405
406 #endif // wxUSE_BASE
407
408 #if wxUSE_GUI
409
410 // ----------------------------------------------------------------------------
411 // Native Struct Conversions
412 // ----------------------------------------------------------------------------
413
414 void wxMacRectToNative( const wxRect *wx , Rect *n )
415 {
416 n->left = wx->x;
417 n->top = wx->y;
418 n->right = wx->x + wx->width;
419 n->bottom = wx->y + wx->height;
420 }
421
422 void wxMacNativeToRect( const Rect *n , wxRect* wx )
423 {
424 wx->x = n->left;
425 wx->y = n->top;
426 wx->width = n->right - n->left;
427 wx->height = n->bottom - n->top;
428 }
429
430 void wxMacPointToNative( const wxPoint* wx , Point *n )
431 {
432 n->h = wx->x;
433 n->v = wx->y;
434 }
435
436 void wxMacNativeToPoint( const Point *n , wxPoint* wx )
437 {
438 wx->x = n->h;
439 wx->y = n->v;
440 }
441
442 // ----------------------------------------------------------------------------
443 // Carbon Event Support
444 // ----------------------------------------------------------------------------
445
446 OSStatus wxMacCarbonEvent::GetParameter(EventParamName inName, EventParamType inDesiredType, UInt32 inBufferSize, void * outData)
447 {
448 return ::GetEventParameter( m_eventRef , inName , inDesiredType , NULL , inBufferSize , NULL , outData );
449 }
450
451 OSStatus wxMacCarbonEvent::SetParameter(EventParamName inName, EventParamType inType, UInt32 inBufferSize, const void * inData)
452 {
453 return ::SetEventParameter( m_eventRef , inName , inType , inBufferSize , inData );
454 }
455
456 // ----------------------------------------------------------------------------
457 // Control Access Support
458 // ----------------------------------------------------------------------------
459
460 IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxObject )
461
462 wxMacControl::wxMacControl()
463 {
464 Init();
465 }
466
467 wxMacControl::wxMacControl(wxWindow* peer , bool isRootControl )
468 {
469 Init();
470 m_peer = peer;
471 m_isRootControl = isRootControl;
472 }
473
474 wxMacControl::wxMacControl( wxWindow* peer , ControlRef control )
475 {
476 Init();
477 m_peer = peer;
478 m_controlRef = control;
479 }
480
481 wxMacControl::wxMacControl( wxWindow* peer , WXWidget control )
482 {
483 Init();
484 m_peer = peer;
485 m_controlRef = (ControlRef) control;
486 }
487
488 wxMacControl::~wxMacControl()
489 {
490 }
491
492 void wxMacControl::Init()
493 {
494 m_peer = NULL;
495 m_controlRef = NULL;
496 m_needsFocusRect = false;
497 m_isRootControl = false;
498 }
499
500 void wxMacControl::Dispose()
501 {
502 wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") );
503 wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
504
505 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
506 // we can have situations when being embedded, where the control gets deleted behind our back, so only
507 // CFRelease if we are safe
508 if ( IsValidControlHandle(m_controlRef) )
509 CFRelease(m_controlRef);
510 m_controlRef = NULL;
511 }
512
513 void wxMacControl::SetReference( URefCon data )
514 {
515 SetControlReference( m_controlRef , data );
516 }
517
518 OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const
519 {
520 return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize );
521 }
522
523 OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const
524 {
525 return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize );
526 }
527
528 OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData)
529 {
530 return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData );
531 }
532
533 OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions )
534 {
535 return SendEventToEventTargetWithOptions( event,
536 HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions );
537 }
538
539 OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions )
540 {
541 wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
542
543 event.SetParameter<HICommand>(kEventParamDirectObject,command);
544
545 return SendEvent( event , inOptions );
546 }
547
548 OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions )
549 {
550 HICommand command;
551
552 memset( &command, 0 , sizeof(command) );
553 command.commandID = commandID;
554 return SendHICommand( command , inOptions );
555 }
556
557 void wxMacControl::Flash( ControlPartCode part , UInt32 ticks )
558 {
559 unsigned long finalTicks;
560
561 HiliteControl( m_controlRef , part );
562 Delay( ticks , &finalTicks );
563 HiliteControl( m_controlRef , kControlNoPart );
564 }
565
566 SInt32 wxMacControl::GetValue() const
567 {
568 return ::GetControl32BitValue( m_controlRef );
569 }
570
571 SInt32 wxMacControl::GetMaximum() const
572 {
573 return ::GetControl32BitMaximum( m_controlRef );
574 }
575
576 SInt32 wxMacControl::GetMinimum() const
577 {
578 return ::GetControl32BitMinimum( m_controlRef );
579 }
580
581 void wxMacControl::SetValue( SInt32 v )
582 {
583 ::SetControl32BitValue( m_controlRef , v );
584 }
585
586 void wxMacControl::SetMinimum( SInt32 v )
587 {
588 ::SetControl32BitMinimum( m_controlRef , v );
589 }
590
591 void wxMacControl::SetMaximum( SInt32 v )
592 {
593 ::SetControl32BitMaximum( m_controlRef , v );
594 }
595
596 void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum )
597 {
598 ::SetControl32BitMinimum( m_controlRef , minimum );
599 ::SetControl32BitMaximum( m_controlRef , maximum );
600 ::SetControl32BitValue( m_controlRef , value );
601 }
602
603 OSStatus wxMacControl::SetFocus( ControlFocusPart focusPart )
604 {
605 return SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, focusPart );
606 }
607
608 bool wxMacControl::HasFocus() const
609 {
610 ControlRef control;
611 GetKeyboardFocus( GetUserFocusWindow() , &control );
612 return control == m_controlRef;
613 }
614
615 void wxMacControl::SetNeedsFocusRect( bool needs )
616 {
617 m_needsFocusRect = needs;
618 }
619
620 bool wxMacControl::NeedsFocusRect() const
621 {
622 return m_needsFocusRect;
623 }
624
625 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown))
626 {
627 }
628
629 void wxMacControl::SuperChangedPosition()
630 {
631 }
632
633 void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle )
634 {
635 m_font = font;
636 #ifndef __LP64__
637 ControlFontStyleRec fontStyle;
638 if ( font.MacGetThemeFontID() != kThemeCurrentPortFont )
639 {
640 switch ( font.MacGetThemeFontID() )
641 {
642 case kThemeSmallSystemFont :
643 fontStyle.font = kControlFontSmallSystemFont;
644 break;
645
646 case 109 : // mini font
647 fontStyle.font = -5;
648 break;
649
650 case kThemeSystemFont :
651 fontStyle.font = kControlFontBigSystemFont;
652 break;
653
654 default :
655 fontStyle.font = kControlFontBigSystemFont;
656 break;
657 }
658
659 fontStyle.flags = kControlUseFontMask;
660 }
661 else
662 {
663 fontStyle.font = font.MacGetFontNum();
664 fontStyle.style = font.MacGetFontStyle();
665 fontStyle.size = font.MacGetFontSize();
666 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask;
667 }
668
669 fontStyle.just = teJustLeft;
670 fontStyle.flags |= kControlUseJustMask;
671 if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
672 fontStyle.just = teJustCenter;
673 else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT )
674 fontStyle.just = teJustRight;
675
676
677 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
678 // won't get grayed out by the system anymore
679
680 if ( foreground != *wxBLACK )
681 {
682 fontStyle.foreColor = MAC_WXCOLORREF( foreground.GetPixel() );
683 fontStyle.flags |= kControlUseForeColorMask;
684 }
685
686 ::SetControlFontStyle( m_controlRef , &fontStyle );
687 #endif
688 }
689
690 void wxMacControl::SetBackground( const wxBrush &WXUNUSED(brush) )
691 {
692 // TODO
693 // setting up a color proc is not recommended anymore
694 }
695
696 void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum )
697 {
698 ::SetControl32BitMinimum( m_controlRef , minimum );
699 ::SetControl32BitMaximum( m_controlRef , maximum );
700 }
701
702 short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers )
703 {
704 #ifndef __LP64__
705 return HandleControlKey( m_controlRef , keyCode , charCode , modifiers );
706 #else
707 return 0;
708 #endif
709 }
710
711 void wxMacControl::SetActionProc( ControlActionUPP actionProc )
712 {
713 SetControlAction( m_controlRef , actionProc );
714 }
715
716 void wxMacControl::SetViewSize( SInt32 viewSize )
717 {
718 SetControlViewSize(m_controlRef , viewSize );
719 }
720
721 SInt32 wxMacControl::GetViewSize() const
722 {
723 return GetControlViewSize( m_controlRef );
724 }
725
726 bool wxMacControl::IsVisible() const
727 {
728 return IsControlVisible( m_controlRef );
729 }
730
731 void wxMacControl::SetVisibility( bool visible , bool redraw )
732 {
733 SetControlVisibility( m_controlRef , visible , redraw );
734 }
735
736 bool wxMacControl::IsEnabled() const
737 {
738 #if TARGET_API_MAC_OSX
739 return IsControlEnabled( m_controlRef );
740 #else
741 return IsControlActive( m_controlRef );
742 #endif
743 }
744
745 bool wxMacControl::IsActive() const
746 {
747 return IsControlActive( m_controlRef );
748 }
749
750 void wxMacControl::Enable( bool enable )
751 {
752 if ( enable )
753 EnableControl( m_controlRef );
754 else
755 DisableControl( m_controlRef );
756 }
757
758 void wxMacControl::SetDrawingEnabled( bool enable )
759 {
760 HIViewSetDrawingEnabled( m_controlRef , enable );
761 }
762
763 bool wxMacControl::GetNeedsDisplay() const
764 {
765 return HIViewGetNeedsDisplay( m_controlRef );
766 }
767
768 void wxMacControl::SetNeedsDisplay( RgnHandle where )
769 {
770 if ( !IsVisible() )
771 return;
772
773 HIViewSetNeedsDisplayInRegion( m_controlRef , where , true );
774 }
775
776 void wxMacControl::SetNeedsDisplay( Rect* where )
777 {
778 if ( !IsVisible() )
779 return;
780
781 if ( where != NULL )
782 {
783 RgnHandle update = NewRgn();
784 RectRgn( update , where );
785 HIViewSetNeedsDisplayInRegion( m_controlRef , update , true );
786 DisposeRgn( update );
787 }
788 else
789 HIViewSetNeedsDisplay( m_controlRef , true );
790 }
791
792 void wxMacControl::Convert( wxPoint *pt , wxMacControl *from , wxMacControl *to )
793 {
794 HIPoint hiPoint;
795
796 hiPoint.x = pt->x;
797 hiPoint.y = pt->y;
798 HIViewConvertPoint( &hiPoint , from->m_controlRef , to->m_controlRef );
799 pt->x = (int)hiPoint.x;
800 pt->y = (int)hiPoint.y;
801 }
802
803 void wxMacControl::SetRect( Rect *r )
804 {
805 //A HIRect is actually a CGRect on OSX - which consists of two structures -
806 //CGPoint and CGSize, which have two floats each
807 HIRect hir = { { r->left , r->top }, { r->right - r->left , r->bottom - r->top } };
808 HIViewSetFrame ( m_controlRef , &hir );
809 // eventuall we might have to do a SetVisibility( false , true );
810 // before and a SetVisibility( true , true ); after
811 }
812
813 void wxMacControl::GetRect( Rect *r )
814 {
815 GetControlBounds( m_controlRef , r );
816 }
817
818 void wxMacControl::GetRectInWindowCoords( Rect *r )
819 {
820 UMAGetControlBoundsInWindowCoords( m_controlRef , r );
821 }
822
823 void wxMacControl::GetBestRect( Rect *r )
824 {
825 short baselineoffset;
826
827 GetBestControlRect( m_controlRef , r , &baselineoffset );
828 }
829
830 void wxMacControl::SetLabel( const wxString &title )
831 {
832 wxFontEncoding encoding;
833
834 if ( m_font.Ok() )
835 encoding = m_font.GetEncoding();
836 else
837 encoding = wxFont::GetDefaultEncoding();
838
839 UMASetControlTitle( m_controlRef , title , encoding );
840 }
841
842 void wxMacControl::GetFeatures( UInt32 * features )
843 {
844 GetControlFeatures( m_controlRef , features );
845 }
846
847 OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region )
848 {
849 OSStatus err = GetControlRegion( m_controlRef , partCode , region );
850 return err;
851 }
852
853 OSStatus wxMacControl::SetZOrder( bool above , wxMacControl* other )
854 {
855 #if TARGET_API_MAC_OSX
856 return HIViewSetZOrder( m_controlRef,above ? kHIViewZOrderAbove : kHIViewZOrderBelow,
857 (other != NULL) ? other->m_controlRef : NULL);
858 #else
859 return 0;
860 #endif
861 }
862
863 #if TARGET_API_MAC_OSX
864 // SetNeedsDisplay would not invalidate the children
865 static void InvalidateControlAndChildren( HIViewRef control )
866 {
867 HIViewSetNeedsDisplay( control , true );
868 UInt16 childrenCount = 0;
869 OSStatus err = CountSubControls( control , &childrenCount );
870 if ( err == errControlIsNotEmbedder )
871 return;
872
873 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") );
874
875 for ( UInt16 i = childrenCount; i >=1; --i )
876 {
877 HIViewRef child;
878
879 err = GetIndexedSubControl( control , i , & child );
880 if ( err == errControlIsNotEmbedder )
881 return;
882
883 InvalidateControlAndChildren( child );
884 }
885 }
886 #endif
887
888 void wxMacControl::InvalidateWithChildren()
889 {
890 #if TARGET_API_MAC_OSX
891 InvalidateControlAndChildren( m_controlRef );
892 #endif
893 }
894
895 void wxMacControl::ScrollRect( wxRect *r , int dx , int dy )
896 {
897 wxASSERT( r != NULL );
898
899 HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height);
900 HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy );
901 }
902
903 OSType wxMacCreator = 'WXMC';
904 OSType wxMacControlProperty = 'MCCT';
905
906 void wxMacControl::SetReferenceInNativeControl()
907 {
908 void * data = this;
909 verify_noerr( SetControlProperty ( m_controlRef ,
910 wxMacCreator,wxMacControlProperty, sizeof(data), &data ) );
911 }
912
913 wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control)
914 {
915 wxMacControl* ctl = NULL;
916 ByteCount actualSize;
917 if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) ,
918 &actualSize , &ctl ) == noErr )
919 {
920 return ctl;
921 }
922 return NULL;
923 }
924
925 // ============================================================================
926 // DataBrowser Wrapper
927 // ============================================================================
928 //
929 // basing on DataBrowserItemIDs
930 //
931
932 IMPLEMENT_ABSTRACT_CLASS( wxMacDataBrowserControl , wxMacControl )
933
934 pascal void wxMacDataBrowserControl::DataBrowserItemNotificationProc(
935 ControlRef browser,
936 DataBrowserItemID itemID,
937 DataBrowserItemNotification message,
938 DataBrowserItemDataRef itemData )
939 {
940 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
941 if ( ctl != 0 )
942 {
943 ctl->ItemNotification(itemID, message, itemData);
944 }
945 }
946
947 pascal OSStatus wxMacDataBrowserControl::DataBrowserGetSetItemDataProc(
948 ControlRef browser,
949 DataBrowserItemID itemID,
950 DataBrowserPropertyID property,
951 DataBrowserItemDataRef itemData,
952 Boolean changeValue )
953 {
954 OSStatus err = errDataBrowserPropertyNotSupported;
955 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
956 if ( ctl != 0 )
957 {
958 err = ctl->GetSetItemData(itemID, property, itemData, changeValue);
959 }
960 return err;
961 }
962
963 pascal Boolean wxMacDataBrowserControl::DataBrowserCompareProc(
964 ControlRef browser,
965 DataBrowserItemID itemOneID,
966 DataBrowserItemID itemTwoID,
967 DataBrowserPropertyID sortProperty)
968 {
969 wxMacDataBrowserControl* ctl = wxDynamicCast(wxMacControl::GetReferenceFromNativeControl( browser ), wxMacDataBrowserControl);
970 if ( ctl != 0 )
971 {
972 return ctl->CompareItems(itemOneID, itemTwoID, sortProperty);
973 }
974 return false;
975 }
976
977 DataBrowserItemDataUPP gDataBrowserItemDataUPP = NULL;
978 DataBrowserItemNotificationUPP gDataBrowserItemNotificationUPP = NULL;
979 DataBrowserItemCompareUPP gDataBrowserItemCompareUPP = NULL;
980
981 wxMacDataBrowserControl::wxMacDataBrowserControl( wxWindow* peer,
982 const wxPoint& pos,
983 const wxSize& size,
984 long WXUNUSED(style))
985 : wxMacControl( peer )
986 {
987 Rect bounds = wxMacGetBoundsForControl( peer, pos, size );
988 OSStatus err = ::CreateDataBrowserControl(
989 MAC_WXHWND(peer->MacGetTopLevelWindowRef()),
990 &bounds, kDataBrowserListView, &m_controlRef );
991 SetReferenceInNativeControl();
992 verify_noerr( err );
993 if ( gDataBrowserItemCompareUPP == NULL )
994 gDataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(DataBrowserCompareProc);
995 if ( gDataBrowserItemDataUPP == NULL )
996 gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(DataBrowserGetSetItemDataProc);
997 if ( gDataBrowserItemNotificationUPP == NULL )
998 {
999 gDataBrowserItemNotificationUPP =
1000 #if TARGET_API_MAC_OSX
1001 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc);
1002 #else
1003 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc);
1004 #endif
1005 }
1006
1007 DataBrowserCallbacks callbacks;
1008 InitializeDataBrowserCallbacks( &callbacks, kDataBrowserLatestCallbacks );
1009
1010 callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP;
1011 callbacks.u.v1.itemCompareCallback = gDataBrowserItemCompareUPP;
1012 callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP;
1013 SetCallbacks( &callbacks );
1014
1015 }
1016
1017 OSStatus wxMacDataBrowserControl::GetItemCount( DataBrowserItemID container,
1018 Boolean recurse,
1019 DataBrowserItemState state,
1020 ItemCount *numItems) const
1021 {
1022 return GetDataBrowserItemCount( m_controlRef, container, recurse, state, numItems );
1023 }
1024
1025 OSStatus wxMacDataBrowserControl::GetItems( DataBrowserItemID container,
1026 Boolean recurse,
1027 DataBrowserItemState state,
1028 Handle items) const
1029 {
1030 return GetDataBrowserItems( m_controlRef, container, recurse, state, items );
1031 }
1032
1033 OSStatus wxMacDataBrowserControl::SetSelectionFlags( DataBrowserSelectionFlags options )
1034 {
1035 return SetDataBrowserSelectionFlags( m_controlRef, options );
1036 }
1037
1038 OSStatus wxMacDataBrowserControl::AddColumn( DataBrowserListViewColumnDesc *columnDesc,
1039 DataBrowserTableViewColumnIndex position )
1040 {
1041 return AddDataBrowserListViewColumn( m_controlRef, columnDesc, position );
1042 }
1043
1044 OSStatus wxMacDataBrowserControl::GetColumnIDFromIndex( DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id ){
1045 return GetDataBrowserTableViewColumnProperty( m_controlRef, position, id );
1046 }
1047
1048 OSStatus wxMacDataBrowserControl::RemoveColumn( DataBrowserTableViewColumnIndex position )
1049 {
1050 DataBrowserTableViewColumnID id;
1051 GetColumnIDFromIndex( position, &id );
1052 return RemoveDataBrowserTableViewColumn( m_controlRef, id );
1053 }
1054
1055 OSStatus wxMacDataBrowserControl::AutoSizeColumns()
1056 {
1057 return AutoSizeDataBrowserListViewColumns(m_controlRef);
1058 }
1059
1060 OSStatus wxMacDataBrowserControl::SetHasScrollBars( bool horiz, bool vert )
1061 {
1062 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
1063 }
1064
1065 OSStatus wxMacDataBrowserControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
1066 {
1067 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
1068 }
1069
1070 OSStatus wxMacDataBrowserControl::SetHeaderButtonHeight(UInt16 height)
1071 {
1072 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1073 }
1074
1075 OSStatus wxMacDataBrowserControl::GetHeaderButtonHeight(UInt16 *height)
1076 {
1077 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
1078 }
1079
1080 OSStatus wxMacDataBrowserControl::SetCallbacks(const DataBrowserCallbacks *callbacks)
1081 {
1082 return SetDataBrowserCallbacks( m_controlRef, callbacks );
1083 }
1084
1085 OSStatus wxMacDataBrowserControl::UpdateItems(
1086 DataBrowserItemID container,
1087 UInt32 numItems,
1088 const DataBrowserItemID *items,
1089 DataBrowserPropertyID preSortProperty,
1090 DataBrowserPropertyID propertyID ) const
1091 {
1092 return UpdateDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty, propertyID );
1093 }
1094
1095 bool wxMacDataBrowserControl::IsItemSelected( DataBrowserItemID item ) const
1096 {
1097 return IsDataBrowserItemSelected( m_controlRef, item );
1098 }
1099
1100 OSStatus wxMacDataBrowserControl::AddItems(
1101 DataBrowserItemID container,
1102 UInt32 numItems,
1103 const DataBrowserItemID *items,
1104 DataBrowserPropertyID preSortProperty )
1105 {
1106 return AddDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1107 }
1108
1109 OSStatus wxMacDataBrowserControl::RemoveItems(
1110 DataBrowserItemID container,
1111 UInt32 numItems,
1112 const DataBrowserItemID *items,
1113 DataBrowserPropertyID preSortProperty )
1114 {
1115 return RemoveDataBrowserItems( m_controlRef, container, numItems, items, preSortProperty );
1116 }
1117
1118 OSStatus wxMacDataBrowserControl::RevealItem(
1119 DataBrowserItemID item,
1120 DataBrowserPropertyID propertyID,
1121 DataBrowserRevealOptions options ) const
1122 {
1123 return RevealDataBrowserItem( m_controlRef, item, propertyID, options );
1124 }
1125
1126 OSStatus wxMacDataBrowserControl::SetSelectedItems(
1127 UInt32 numItems,
1128 const DataBrowserItemID *items,
1129 DataBrowserSetOption operation )
1130 {
1131 return SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
1132 }
1133
1134 OSStatus wxMacDataBrowserControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
1135 {
1136 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
1137 }
1138
1139 OSStatus wxMacDataBrowserControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
1140 {
1141 return GetDataBrowserTableViewItemID( m_controlRef, row, item );
1142 }
1143
1144 OSStatus wxMacDataBrowserControl::GetItemRow( DataBrowserItemID item, DataBrowserTableViewRowIndex * row ) const
1145 {
1146 return GetDataBrowserTableViewItemRow( m_controlRef, item, row );
1147 }
1148
1149 OSStatus wxMacDataBrowserControl::SetDefaultRowHeight( UInt16 height )
1150 {
1151 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
1152 }
1153
1154 OSStatus wxMacDataBrowserControl::GetDefaultRowHeight( UInt16 * height ) const
1155 {
1156 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
1157 }
1158
1159 OSStatus wxMacDataBrowserControl::SetRowHeight( DataBrowserItemID item , UInt16 height)
1160 {
1161 return SetDataBrowserTableViewItemRowHeight( m_controlRef, item , height );
1162 }
1163
1164 OSStatus wxMacDataBrowserControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
1165 {
1166 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
1167 }
1168
1169 OSStatus wxMacDataBrowserControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
1170 {
1171 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1172 }
1173
1174 OSStatus wxMacDataBrowserControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
1175 {
1176 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
1177 }
1178
1179 OSStatus wxMacDataBrowserControl::GetDefaultColumnWidth( UInt16 *width ) const
1180 {
1181 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
1182 }
1183
1184 OSStatus wxMacDataBrowserControl::SetDefaultColumnWidth( UInt16 width )
1185 {
1186 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
1187 }
1188
1189 OSStatus wxMacDataBrowserControl::GetColumnCount(UInt32* numColumns) const
1190 {
1191 return GetDataBrowserTableViewColumnCount( m_controlRef, numColumns);
1192 }
1193
1194 OSStatus wxMacDataBrowserControl::GetColumnPosition( DataBrowserPropertyID column,
1195 DataBrowserTableViewColumnIndex *position) const
1196 {
1197 return GetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1198 }
1199
1200 OSStatus wxMacDataBrowserControl::SetColumnPosition( DataBrowserPropertyID column, DataBrowserTableViewColumnIndex position)
1201 {
1202 return SetDataBrowserTableViewColumnPosition( m_controlRef , column , position);
1203 }
1204
1205 OSStatus wxMacDataBrowserControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
1206 {
1207 return GetDataBrowserScrollPosition( m_controlRef , top , left );
1208 }
1209
1210 OSStatus wxMacDataBrowserControl::SetScrollPosition( UInt32 top , UInt32 left )
1211 {
1212 return SetDataBrowserScrollPosition( m_controlRef , top , left );
1213 }
1214
1215 OSStatus wxMacDataBrowserControl::GetSortProperty( DataBrowserPropertyID *column ) const
1216 {
1217 return GetDataBrowserSortProperty( m_controlRef , column );
1218 }
1219
1220 OSStatus wxMacDataBrowserControl::SetSortProperty( DataBrowserPropertyID column )
1221 {
1222 return SetDataBrowserSortProperty( m_controlRef , column );
1223 }
1224
1225 OSStatus wxMacDataBrowserControl::GetSortOrder( DataBrowserSortOrder *order ) const
1226 {
1227 return GetDataBrowserSortOrder( m_controlRef , order );
1228 }
1229
1230 OSStatus wxMacDataBrowserControl::SetSortOrder( DataBrowserSortOrder order )
1231 {
1232 return SetDataBrowserSortOrder( m_controlRef , order );
1233 }
1234
1235 OSStatus wxMacDataBrowserControl::GetPropertyFlags( DataBrowserPropertyID property,
1236 DataBrowserPropertyFlags *flags ) const
1237 {
1238 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
1239 }
1240
1241 OSStatus wxMacDataBrowserControl::SetPropertyFlags( DataBrowserPropertyID property,
1242 DataBrowserPropertyFlags flags )
1243 {
1244 return SetDataBrowserPropertyFlags( m_controlRef , property , flags );
1245 }
1246
1247 OSStatus wxMacDataBrowserControl::GetHeaderDesc( DataBrowserPropertyID property,
1248 DataBrowserListViewHeaderDesc *desc ) const
1249 {
1250 return GetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1251 }
1252
1253 OSStatus wxMacDataBrowserControl::SetHeaderDesc( DataBrowserPropertyID property,
1254 DataBrowserListViewHeaderDesc *desc )
1255 {
1256 return SetDataBrowserListViewHeaderDesc( m_controlRef , property , desc );
1257 }
1258
1259 OSStatus wxMacDataBrowserControl::SetDisclosureColumn( DataBrowserPropertyID property ,
1260 Boolean expandableRows )
1261 {
1262 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
1263 }
1264
1265 // ============================================================================
1266 // Higher-level Databrowser
1267 // ============================================================================
1268 //
1269 // basing on data item objects
1270 //
1271
1272 wxMacDataItem::wxMacDataItem()
1273 {
1274 m_data = NULL;
1275
1276 m_order = 0;
1277 m_colId = kTextColumnId; // for compat with existing wx*ListBox impls.
1278 }
1279
1280 wxMacDataItem::~wxMacDataItem()
1281 {
1282 }
1283
1284 void wxMacDataItem::SetOrder( SInt32 order )
1285 {
1286 m_order = order;
1287 }
1288
1289 SInt32 wxMacDataItem::GetOrder() const
1290 {
1291 return m_order;
1292 }
1293
1294 void wxMacDataItem::SetData( void* data)
1295 {
1296 m_data = data;
1297 }
1298
1299 void* wxMacDataItem::GetData() const
1300 {
1301 return m_data;
1302 }
1303
1304 short wxMacDataItem::GetColumn()
1305 {
1306 return m_colId;
1307 }
1308
1309 void wxMacDataItem::SetColumn( short col )
1310 {
1311 m_colId = col;
1312 }
1313
1314 void wxMacDataItem::SetLabel( const wxString& str)
1315 {
1316 m_label = str;
1317 m_cfLabel.Assign( str , wxLocale::GetSystemEncoding());
1318 }
1319
1320 const wxString& wxMacDataItem::GetLabel() const
1321 {
1322 return m_label;
1323 }
1324
1325 bool wxMacDataItem::IsLessThan(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1326 const wxMacDataItem* rhs,
1327 DataBrowserPropertyID sortProperty) const
1328 {
1329 const wxMacDataItem* otherItem = wx_const_cast(wxMacDataItem*,rhs);
1330 bool retval = false;
1331
1332 if ( sortProperty == m_colId ){
1333 retval = m_label.CmpNoCase( otherItem->m_label) < 0;
1334 }
1335
1336 else if ( sortProperty == kNumericOrderColumnId )
1337 retval = m_order < otherItem->m_order;
1338
1339 return retval;
1340 }
1341
1342 OSStatus wxMacDataItem::GetSetData( wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1343 DataBrowserPropertyID property,
1344 DataBrowserItemDataRef itemData,
1345 bool changeValue )
1346 {
1347 OSStatus err = errDataBrowserPropertyNotSupported;
1348 if ( !changeValue )
1349 {
1350 if ( property == m_colId ){
1351 err = ::SetDataBrowserItemDataText( itemData, m_cfLabel );
1352 err = noErr;
1353 }
1354 else if ( property == kNumericOrderColumnId ){
1355 err = ::SetDataBrowserItemDataValue( itemData, m_order );
1356 err = noErr;
1357 }
1358 else{
1359 }
1360 }
1361 else
1362 {
1363 switch (property)
1364 {
1365 // no editable props here
1366 default:
1367 break;
1368 }
1369 }
1370
1371 return err;
1372 }
1373
1374 void wxMacDataItem::Notification(wxMacDataItemBrowserControl *WXUNUSED(owner) ,
1375 DataBrowserItemNotification WXUNUSED(message),
1376 DataBrowserItemDataRef WXUNUSED(itemData) ) const
1377 {
1378 }
1379
1380 IMPLEMENT_DYNAMIC_CLASS( wxMacDataItemBrowserControl , wxMacDataBrowserControl )
1381
1382 wxMacDataItemBrowserControl::wxMacDataItemBrowserControl( wxWindow* peer , const wxPoint& pos, const wxSize& size, long style) :
1383 wxMacDataBrowserControl( peer, pos, size, style )
1384 {
1385 m_suppressSelection = false;
1386 m_sortOrder = SortOrder_None;
1387 m_clientDataItemsType = wxClientData_None;
1388 }
1389
1390 wxMacDataItem* wxMacDataItemBrowserControl::CreateItem()
1391 {
1392 return new wxMacDataItem();
1393 }
1394
1395 wxMacDataItemBrowserSelectionSuppressor::wxMacDataItemBrowserSelectionSuppressor(wxMacDataItemBrowserControl *browser)
1396 {
1397 m_former = browser->SuppressSelection(true);
1398 m_browser = browser;
1399 }
1400
1401 wxMacDataItemBrowserSelectionSuppressor::~wxMacDataItemBrowserSelectionSuppressor()
1402 {
1403 m_browser->SuppressSelection(m_former);
1404 }
1405
1406 bool wxMacDataItemBrowserControl::SuppressSelection( bool suppress )
1407 {
1408 bool former = m_suppressSelection;
1409 m_suppressSelection = suppress;
1410
1411 return former;
1412 }
1413
1414 Boolean wxMacDataItemBrowserControl::CompareItems(DataBrowserItemID itemOneID,
1415 DataBrowserItemID itemTwoID,
1416 DataBrowserPropertyID sortProperty)
1417 {
1418 wxMacDataItem* itemOne = (wxMacDataItem*) itemOneID;
1419 wxMacDataItem* itemTwo = (wxMacDataItem*) itemTwoID;
1420 return CompareItems( itemOne , itemTwo , sortProperty );
1421 }
1422
1423 Boolean wxMacDataItemBrowserControl::CompareItems(const wxMacDataItem* itemOne,
1424 const wxMacDataItem* itemTwo,
1425 DataBrowserPropertyID sortProperty)
1426 {
1427 Boolean retval = false;
1428 if ( itemOne != NULL )
1429 retval = itemOne->IsLessThan( this , itemTwo , sortProperty);
1430 return retval;
1431 }
1432
1433 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1434 DataBrowserItemID itemID,
1435 DataBrowserPropertyID property,
1436 DataBrowserItemDataRef itemData,
1437 Boolean changeValue )
1438 {
1439 wxMacDataItem* item = (wxMacDataItem*) itemID;
1440 return GetSetItemData(item, property, itemData , changeValue );
1441 }
1442
1443 OSStatus wxMacDataItemBrowserControl::GetSetItemData(
1444 wxMacDataItem* item,
1445 DataBrowserPropertyID property,
1446 DataBrowserItemDataRef itemData,
1447 Boolean changeValue )
1448 {
1449 OSStatus err = errDataBrowserPropertyNotSupported;
1450 switch( property )
1451 {
1452 case kDataBrowserContainerIsClosableProperty :
1453 case kDataBrowserContainerIsSortableProperty :
1454 case kDataBrowserContainerIsOpenableProperty :
1455 // right now default behaviour on these
1456 break;
1457 default :
1458
1459 if ( item != NULL ){
1460 err = item->GetSetData( this, property , itemData , changeValue );
1461 }
1462 break;
1463
1464 }
1465 return err;
1466 }
1467
1468 void wxMacDataItemBrowserControl::ItemNotification(
1469 DataBrowserItemID itemID,
1470 DataBrowserItemNotification message,
1471 DataBrowserItemDataRef itemData)
1472 {
1473 wxMacDataItem* item = (wxMacDataItem*) itemID;
1474 ItemNotification( item , message, itemData);
1475 }
1476
1477 void wxMacDataItemBrowserControl::ItemNotification(
1478 const wxMacDataItem* item,
1479 DataBrowserItemNotification message,
1480 DataBrowserItemDataRef itemData)
1481 {
1482 if (item != NULL)
1483 item->Notification( this, message, itemData);
1484 }
1485
1486 unsigned int wxMacDataItemBrowserControl::GetItemCount(const wxMacDataItem* container,
1487 bool recurse , DataBrowserItemState state) const
1488 {
1489 ItemCount numItems = 0;
1490 verify_noerr( wxMacDataBrowserControl::GetItemCount( (DataBrowserItemID)container,
1491 recurse, state, &numItems ) );
1492 return numItems;
1493 }
1494
1495 unsigned int wxMacDataItemBrowserControl::GetSelectedItemCount( const wxMacDataItem* container,
1496 bool recurse ) const
1497 {
1498 return GetItemCount( container, recurse, kDataBrowserItemIsSelected );
1499
1500 }
1501
1502 void wxMacDataItemBrowserControl::GetItems(const wxMacDataItem* container,
1503 bool recurse , DataBrowserItemState state, wxArrayMacDataItemPtr &items) const
1504 {
1505 Handle handle = NewHandle(0);
1506 verify_noerr( wxMacDataBrowserControl::GetItems( (DataBrowserItemID)container ,
1507 recurse , state, handle) );
1508
1509 int itemCount = GetHandleSize(handle)/sizeof(DataBrowserItemID);
1510 HLock( handle );
1511 wxMacDataItemPtr* itemsArray = (wxMacDataItemPtr*) *handle;
1512 for ( int i = 0; i < itemCount; ++i)
1513 {
1514 items.Add(itemsArray[i]);
1515 }
1516 HUnlock( handle );
1517 DisposeHandle( handle );
1518 }
1519
1520 unsigned int wxMacDataItemBrowserControl::GetLineFromItem(const wxMacDataItem* item) const
1521 {
1522 DataBrowserTableViewRowIndex row;
1523 OSStatus err = GetItemRow( (DataBrowserItemID) item , &row);
1524 wxASSERT( err == noErr);
1525 return row;
1526 }
1527
1528 wxMacDataItem* wxMacDataItemBrowserControl::GetItemFromLine(unsigned int n) const
1529 {
1530 DataBrowserItemID id;
1531 OSStatus err = GetItemID( (DataBrowserTableViewRowIndex) n , &id);
1532 wxASSERT( err == noErr);
1533 return (wxMacDataItem*) id;
1534 }
1535
1536 void wxMacDataItemBrowserControl::UpdateItem(const wxMacDataItem *container,
1537 const wxMacDataItem *item , DataBrowserPropertyID property) const
1538 {
1539 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, 1,
1540 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty /* notSorted */, property ) );
1541 }
1542
1543 void wxMacDataItemBrowserControl::UpdateItems(const wxMacDataItem *container,
1544 wxArrayMacDataItemPtr &itemArray , DataBrowserPropertyID property) const
1545 {
1546 unsigned int noItems = itemArray.GetCount();
1547 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1548 for ( unsigned int i = 0; i < noItems; ++i )
1549 items[i] = (DataBrowserItemID) itemArray[i];
1550
1551 verify_noerr( wxMacDataBrowserControl::UpdateItems((DataBrowserItemID)container, noItems,
1552 items, kDataBrowserItemNoProperty /* notSorted */, property ) );
1553 delete [] items;
1554 }
1555
1556 void wxMacDataItemBrowserControl::InsertColumn(int colId, DataBrowserPropertyType colType,
1557 const wxString& title, SInt16 just, int defaultWidth)
1558 {
1559 DataBrowserListViewColumnDesc columnDesc;
1560 columnDesc.headerBtnDesc.titleOffset = 0;
1561 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
1562
1563 columnDesc.headerBtnDesc.btnFontStyle.flags =
1564 kControlUseFontMask | kControlUseJustMask;
1565
1566 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
1567 columnDesc.headerBtnDesc.btnFontStyle.just = just;
1568 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
1569 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
1570
1571 // TODO: Why is m_font not defined when we enter wxLC_LIST mode, but is
1572 // defined for other modes?
1573 wxFontEncoding enc;
1574 if ( m_font.Ok() )
1575 enc = m_font.GetEncoding();
1576 else
1577 enc = wxLocale::GetSystemEncoding();
1578 wxMacCFStringHolder cfTitle;
1579 cfTitle.Assign( title, enc );
1580 columnDesc.headerBtnDesc.titleString = cfTitle;
1581
1582 columnDesc.headerBtnDesc.minimumWidth = 0;
1583 columnDesc.headerBtnDesc.maximumWidth = 30000;
1584
1585 columnDesc.propertyDesc.propertyID = (kMinColumnId + colId);
1586 columnDesc.propertyDesc.propertyType = colType;
1587 columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSortableColumn;
1588 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn;
1589 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton;
1590
1591 verify_noerr( AddColumn( &columnDesc, kDataBrowserListViewAppendColumn ) );
1592
1593 if (defaultWidth > 0){
1594 SetColumnWidth(colId, defaultWidth);
1595 }
1596
1597 }
1598
1599 void wxMacDataItemBrowserControl::SetColumnWidth(int colId, int width)
1600 {
1601 DataBrowserPropertyID id;
1602 GetColumnIDFromIndex(colId, &id);
1603 verify_noerr( wxMacDataBrowserControl::SetColumnWidth(id, width));
1604 }
1605
1606 int wxMacDataItemBrowserControl::GetColumnWidth(int colId)
1607 {
1608 DataBrowserPropertyID id;
1609 GetColumnIDFromIndex(colId, &id);
1610 UInt16 result;
1611 verify_noerr( wxMacDataBrowserControl::GetColumnWidth(id, &result));
1612 return result;
1613 }
1614
1615 void wxMacDataItemBrowserControl::AddItem(wxMacDataItem *container, wxMacDataItem *item)
1616 {
1617 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, 1,
1618 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty ) );
1619 }
1620
1621 void wxMacDataItemBrowserControl::AddItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray )
1622 {
1623 unsigned int noItems = itemArray.GetCount();
1624 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1625 for ( unsigned int i = 0; i < noItems; ++i )
1626 items[i] = (DataBrowserItemID) itemArray[i];
1627
1628 verify_noerr( wxMacDataBrowserControl::AddItems( (DataBrowserItemID)container, noItems,
1629 (DataBrowserItemID*) items, kDataBrowserItemNoProperty ) );
1630 delete [] items;
1631 }
1632
1633 void wxMacDataItemBrowserControl::RemoveItem(wxMacDataItem *container, wxMacDataItem* item)
1634 {
1635 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 1,
1636 (DataBrowserItemID*) &item, kDataBrowserItemNoProperty );
1637 verify_noerr( err );
1638 }
1639
1640 void wxMacDataItemBrowserControl::RemoveItems(wxMacDataItem *container, wxArrayMacDataItemPtr &itemArray)
1641 {
1642 unsigned int noItems = itemArray.GetCount();
1643 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1644 for ( unsigned int i = 0; i < noItems; ++i )
1645 items[i] = (DataBrowserItemID) itemArray[i];
1646
1647 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, noItems,
1648 (DataBrowserItemID*) items, kDataBrowserItemNoProperty );
1649 verify_noerr( err );
1650 delete [] items;
1651 }
1652
1653 void wxMacDataItemBrowserControl::RemoveAllItems(wxMacDataItem *container)
1654 {
1655 OSStatus err = wxMacDataBrowserControl::RemoveItems( (DataBrowserItemID)container, 0 , NULL , kDataBrowserItemNoProperty );
1656 verify_noerr( err );
1657 }
1658
1659 void wxMacDataItemBrowserControl::SetSelectedItem(wxMacDataItem* item , DataBrowserSetOption option)
1660 {
1661 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 1, (DataBrowserItemID*) &item, option ));
1662 }
1663
1664 void wxMacDataItemBrowserControl::SetSelectedAllItems(DataBrowserSetOption option)
1665 {
1666 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( 0 , NULL , option ));
1667 }
1668
1669 void wxMacDataItemBrowserControl::SetSelectedItems(wxArrayMacDataItemPtr &itemArray , DataBrowserSetOption option)
1670 {
1671 unsigned int noItems = itemArray.GetCount();
1672 DataBrowserItemID *items = new DataBrowserItemID[noItems];
1673 for ( unsigned int i = 0; i < noItems; ++i )
1674 items[i] = (DataBrowserItemID) itemArray[i];
1675
1676 verify_noerr(wxMacDataBrowserControl::SetSelectedItems( noItems, (DataBrowserItemID*) items, option ));
1677 delete [] items;
1678 }
1679
1680 Boolean wxMacDataItemBrowserControl::IsItemSelected( const wxMacDataItem* item) const
1681 {
1682 return wxMacDataBrowserControl::IsItemSelected( (DataBrowserItemID) item);
1683 }
1684
1685 void wxMacDataItemBrowserControl::RevealItem( wxMacDataItem* item, DataBrowserRevealOptions options)
1686 {
1687 verify_noerr(wxMacDataBrowserControl::RevealItem( (DataBrowserItemID) item, kDataBrowserNoItem , options ) );
1688 }
1689
1690 void wxMacDataItemBrowserControl::GetSelectionAnchor( wxMacDataItemPtr* first , wxMacDataItemPtr* last) const
1691 {
1692 verify_noerr(wxMacDataBrowserControl::GetSelectionAnchor( (DataBrowserItemID*) first, (DataBrowserItemID*) last) );
1693 }
1694
1695 wxClientDataType wxMacDataItemBrowserControl::GetClientDataType() const
1696 {
1697 return m_clientDataItemsType;
1698 }
1699 void wxMacDataItemBrowserControl::SetClientDataType(wxClientDataType clientDataItemsType)
1700 {
1701 m_clientDataItemsType = clientDataItemsType;
1702 }
1703
1704 unsigned int wxMacDataItemBrowserControl::MacGetCount() const
1705 {
1706 return GetItemCount(wxMacDataBrowserRootContainer,false,kDataBrowserItemAnyState);
1707 }
1708
1709 void wxMacDataItemBrowserControl::MacDelete( unsigned int n )
1710 {
1711 wxMacDataItem* item = (wxMacDataItem*)GetItemFromLine( n );
1712 RemoveItem( wxMacDataBrowserRootContainer, item );
1713 }
1714
1715 void wxMacDataItemBrowserControl::MacInsert( unsigned int n,
1716 const wxArrayStringsAdapter& items,
1717 int column )
1718 {
1719 size_t itemsCount = items.GetCount();
1720 if ( itemsCount == 0 )
1721 return;
1722
1723 SInt32 frontLineOrder = 0;
1724
1725 if ( m_sortOrder == SortOrder_None )
1726 {
1727 // increase the order of the lines to be shifted
1728 unsigned int lines = MacGetCount();
1729 for ( unsigned int i = n; i < lines; ++i)
1730 {
1731 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(i);
1732 iter->SetOrder( iter->GetOrder() + itemsCount );
1733 }
1734 if ( n > 0 )
1735 {
1736 wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(n-1);
1737 frontLineOrder = iter->GetOrder();
1738 }
1739 }
1740
1741 wxArrayMacDataItemPtr ids;
1742 ids.SetCount( itemsCount );
1743
1744 for ( unsigned int i = 0; i < itemsCount; ++i )
1745 {
1746 wxMacDataItem* item = CreateItem();
1747 item->SetLabel( items[i]);
1748 if ( column != -1 )
1749 item->SetColumn( kMinColumnId + column );
1750
1751 if ( m_sortOrder == SortOrder_None )
1752 item->SetOrder( frontLineOrder + 1 + i );
1753
1754 ids[i] = item;
1755 }
1756
1757 AddItems( wxMacDataBrowserRootContainer, ids );
1758 }
1759
1760 int wxMacDataItemBrowserControl::MacAppend( const wxString& text)
1761 {
1762 wxMacDataItem* item = CreateItem();
1763 item->SetLabel( text );
1764 if ( m_sortOrder == SortOrder_None )
1765 {
1766 unsigned int lines = MacGetCount();
1767 if ( lines == 0 )
1768 item->SetOrder( 1 );
1769 else
1770 {
1771 wxMacDataItem* frontItem = (wxMacDataItem*) GetItemFromLine(lines-1);
1772 item->SetOrder( frontItem->GetOrder() + 1 );
1773 }
1774 }
1775 AddItem( wxMacDataBrowserRootContainer, item );
1776
1777 return GetLineFromItem(item);
1778 }
1779
1780 void wxMacDataItemBrowserControl::MacClear()
1781 {
1782 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
1783 RemoveAllItems(wxMacDataBrowserRootContainer);
1784 }
1785
1786 void wxMacDataItemBrowserControl::MacDeselectAll()
1787 {
1788 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
1789 SetSelectedAllItems( kDataBrowserItemsRemove );
1790 }
1791
1792 void wxMacDataItemBrowserControl::MacSetSelection( unsigned int n, bool select, bool multi )
1793 {
1794 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
1795 wxMacDataItemBrowserSelectionSuppressor suppressor(this);
1796
1797 if ( IsItemSelected( item ) != select )
1798 {
1799 if ( select )
1800 SetSelectedItem( item, multi ? kDataBrowserItemsAdd : kDataBrowserItemsAssign );
1801 else
1802 SetSelectedItem( item, kDataBrowserItemsRemove );
1803 }
1804
1805 MacScrollTo( n );
1806 }
1807
1808 bool wxMacDataItemBrowserControl::MacIsSelected( unsigned int n ) const
1809 {
1810 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine(n);
1811 return IsItemSelected( item );
1812 }
1813
1814 int wxMacDataItemBrowserControl::MacGetSelection() const
1815 {
1816 wxMacDataItemPtr first, last;
1817 GetSelectionAnchor( &first, &last );
1818
1819 if ( first != NULL )
1820 {
1821 return GetLineFromItem( first );
1822 }
1823
1824 return -1;
1825 }
1826
1827 int wxMacDataItemBrowserControl::MacGetSelections( wxArrayInt& aSelections ) const
1828 {
1829 aSelections.Empty();
1830 wxArrayMacDataItemPtr selectedItems;
1831 GetItems( wxMacDataBrowserRootContainer, false , kDataBrowserItemIsSelected, selectedItems);
1832
1833 int count = selectedItems.GetCount();
1834
1835 for ( int i = 0; i < count; ++i)
1836 {
1837 aSelections.Add(GetLineFromItem(selectedItems[i]));
1838 }
1839
1840 return count;
1841 }
1842
1843 void wxMacDataItemBrowserControl::MacSetString( unsigned int n, const wxString& text )
1844 {
1845 // as we don't store the strings we only have to issue a redraw
1846 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
1847 item->SetLabel( text );
1848 UpdateItem( wxMacDataBrowserRootContainer, item , kTextColumnId );
1849 }
1850
1851 wxString wxMacDataItemBrowserControl::MacGetString( unsigned int n ) const
1852 {
1853 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
1854 return item->GetLabel();
1855 }
1856
1857 void wxMacDataItemBrowserControl::MacSetClientData( unsigned int n, void * data)
1858 {
1859 wxMacDataItem* item = (wxMacDataItem*) GetItemFromLine( n);
1860 item->SetData( data );
1861 // not displayed, therefore no Update infos to DataBrowser
1862 }
1863
1864 void * wxMacDataItemBrowserControl::MacGetClientData( unsigned int n) const
1865 {
1866 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
1867 return item->GetData();
1868 }
1869
1870 void wxMacDataItemBrowserControl::MacScrollTo( unsigned int n )
1871 {
1872 UInt32 top , left ;
1873 GetScrollPosition( &top , &left ) ;
1874 wxMacDataItem * item = (wxMacDataItem*) GetItemFromLine( n );
1875
1876 UInt16 height ;
1877 GetRowHeight( (DataBrowserItemID) item , &height ) ;
1878 SetScrollPosition( n * ((UInt32)height) , left ) ;
1879
1880 RevealItem( item , kDataBrowserRevealWithoutSelecting );
1881 }
1882
1883
1884
1885 //
1886 // Tab Control
1887 //
1888
1889 OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable )
1890 {
1891 return ::SetTabEnabled( m_controlRef , tabNo , enable );
1892 }
1893
1894 //
1895 // Quartz Support
1896 //
1897
1898 // snippets from Sketch Sample from Apple :
1899
1900 #define kGenericRGBProfilePathStr "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
1901
1902 /*
1903 This function locates, opens, and returns the profile reference for the calibrated
1904 Generic RGB color space. It is up to the caller to call CMCloseProfile when done
1905 with the profile reference this function returns.
1906 */
1907 CMProfileRef wxMacOpenGenericProfile()
1908 {
1909 static CMProfileRef cachedRGBProfileRef = NULL;
1910
1911 // we only create the profile reference once
1912 if (cachedRGBProfileRef == NULL)
1913 {
1914 CMProfileLocation loc;
1915
1916 loc.locType = cmPathBasedProfile;
1917 strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
1918
1919 verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
1920 }
1921
1922 // clone the profile reference so that the caller has their own reference, not our cached one
1923 if (cachedRGBProfileRef)
1924 CMCloneProfileRef(cachedRGBProfileRef);
1925
1926 return cachedRGBProfileRef;
1927 }
1928
1929 /*
1930 Return the generic RGB color space. This is a 'get' function and the caller should
1931 not release the returned value unless the caller retains it first. Usually callers
1932 of this routine will immediately use the returned colorspace with CoreGraphics
1933 so they typically do not need to retain it themselves.
1934
1935 This function creates the generic RGB color space once and hangs onto it so it can
1936 return it whenever this function is called.
1937 */
1938
1939 CGColorSpaceRef wxMacGetGenericRGBColorSpace()
1940 {
1941 static wxMacCFRefHolder<CGColorSpaceRef> genericRGBColorSpace;
1942
1943 if (genericRGBColorSpace == NULL)
1944 {
1945 genericRGBColorSpace.Set( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) );
1946 }
1947
1948 return genericRGBColorSpace;
1949 }
1950
1951 #ifndef __LP64__
1952
1953 wxMacPortSaver::wxMacPortSaver( GrafPtr port )
1954 {
1955 ::GetPort( &m_port );
1956 ::SetPort( port );
1957 }
1958
1959 wxMacPortSaver::~wxMacPortSaver()
1960 {
1961 ::SetPort( m_port );
1962 }
1963 #endif
1964
1965 void wxMacGlobalToLocal( WindowRef window , Point*pt )
1966 {
1967 HIPoint p = CGPointMake( pt->h, pt->v );
1968 HIViewRef contentView ;
1969 // TODO check toolbar offset
1970 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
1971 HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView );
1972 pt->h = p.x;
1973 pt->v = p.y;
1974 }
1975
1976 void wxMacLocalToGlobal( WindowRef window , Point*pt )
1977 {
1978 HIPoint p = CGPointMake( pt->h, pt->v );
1979 HIViewRef contentView ;
1980 // TODO check toolbar offset
1981 HIViewFindByID( HIViewGetRoot( window ), kHIViewWindowContentID , &contentView) ;
1982 HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL );
1983 pt->h = p.x;
1984 pt->v = p.y;
1985 }
1986
1987 #endif // wxUSE_GUI