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