136
139
// directed towards native control
139
void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
142
void wxMacWindowToNative( const wxWindowMac* window , RgnHandle handle )
141
144
OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
144
void wxMacWindowToNative( const wxWindow* window , Rect *rect )
147
void wxMacWindowToNative( const wxWindowMac* window , Rect *rect )
146
149
OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
448
451
textCtrl->GetSelection( &from , &to ) ;
449
452
wxString val = textCtrl->GetValue() ;
450
453
val = val.Mid( from , to - from ) ;
451
ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
452
verify_noerr( ClearScrap( &scrapRef ) ) ;
453
verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.length() , val.c_str() ) ) ;
454
PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
455
verify_noerr( PasteboardClear( pasteboard ) ) ;
456
PasteboardSynchronize( pasteboard );
457
CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)val.c_str(), val.length() );
458
PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0);
458
464
case kEventServicePaste :
461
ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
462
Size textSize, pastedSize ;
463
verify_noerr( GetScrapFlavorSize(scrapRef, kTXNTextData, &textSize) ) ;
465
char *content = new char[textSize] ;
466
GetScrapFlavorData(scrapRef, kTXNTextData, &pastedSize, content );
467
content[textSize - 1] = 0 ;
467
PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
468
PasteboardSynchronize( pasteboard );
470
verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) );
471
for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ )
473
PasteboardItemID itemID;
474
if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr )
476
CFDataRef flavorData = NULL;
477
if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr )
479
CFIndex flavorDataSize = CFDataGetLength( flavorData );
480
char *content = new char[flavorDataSize+1] ;
481
memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize );
482
content[flavorDataSize]=0;
483
CFRelease( flavorData );
469
484
#if wxUSE_UNICODE
470
textCtrl->WriteText( wxString( content , wxConvLocal ) );
485
textCtrl->WriteText( wxString( content , wxConvLocal ) );
472
textCtrl->WriteText( wxString( content ) ) ;
487
textCtrl->WriteText( wxString( content ) ) ;
534
552
UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
536
NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
537
multiple times to update the active range during inline input, so this handler will often receive
538
uncommited text, which should usually not trigger side effects. It might be a good idea to check the
539
kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
540
On the other hand, it can be useful for some applications to react to uncommitted text (for example,
541
to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
542
should add new event types to support advanced text input. For now, I would keep things as they are.
544
However, the code that was being used caused additional problems:
554
NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
555
multiple times to update the active range during inline input, so this handler will often receive
556
uncommited text, which should usually not trigger side effects. It might be a good idea to check the
557
kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
558
On the other hand, it can be useful for some applications to react to uncommitted text (for example,
559
to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
560
should add new event types to support advanced text input. For now, I would keep things as they are.
562
However, the code that was being used caused additional problems:
545
563
UInt32 message = (0 << 8) + ((char)uniChars[pos] );
546
Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
547
input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
548
for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
549
(still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
550
(the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
551
Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
552
overlap with Unicode within the (7-bit) ASCII range.
553
But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
554
for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
555
characters as they are and replaces the rest with '?', ensuring that update events are triggered.
556
It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
557
I don't have time to look into that right now.
564
Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
565
input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
566
for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
567
(still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
568
(the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
569
Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
570
overlap with Unicode within the (7-bit) ASCII range.
571
But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
572
for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
573
characters as they are and replaces the rest with '?', ensuring that update events are triggered.
574
It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
575
I don't have time to look into that right now.
560
if ( wxTheApp->MacSendCharEvent(
578
if ( wxTheApp->MacSendCharEvent((wxWindow*)
561
579
focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
893
912
// implementation
894
913
// ===========================================================================
896
WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap);
915
WX_DECLARE_HASH_MAP(ControlRef, wxWindowMac*, wxPointerHash, wxPointerEqual, MacControlMap);
898
917
static MacControlMap wxWinMacControlList;
900
wxWindow *wxFindControlFromMacControl(ControlRef inControl )
919
wxWindowMac *wxFindControlFromMacControl(ControlRef inControl )
902
921
MacControlMap::iterator node = wxWinMacControlList.find(inControl);
904
923
return (node == wxWinMacControlList.end()) ? NULL : node->second;
907
void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
926
void wxAssociateControlWithMacControl(ControlRef inControl, wxWindowMac *control)
909
928
// adding NULL ControlRef is (first) surely a result of an error and
910
929
// (secondly) breaks native event processing
2473
2503
// our own window origin is at leftOrigin/rightOrigin
2506
void wxWindowMac::MacPaintGrowBox()
2511
#if wxMAC_USE_CORE_GRAPHICS
2512
if ( MacHasScrollBarCorner() )
2516
CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
2517
wxASSERT( cgContext ) ;
2519
m_peer->GetRect( &rect ) ;
2521
int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2522
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2523
CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2524
CGContextSaveGState( cgContext );
2526
wxMacCoreGraphicsColour bkgnd( m_macBackgroundBrush ) ;
2527
bkgnd.Apply( cgContext );
2528
CGContextFillRect( cgContext, cgrect );
2529
CGContextRestoreGState( cgContext );
2476
2535
void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin )
2478
2537
if ( IsTopLevel() )
2482
2541
bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
2483
bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ;
2485
2543
// back to the surrounding frame rectangle
2486
2544
m_peer->GetRect( &rect ) ;
2487
2545
InsetRect( &rect, -1 , -1 ) ;
2489
#if wxMAC_USE_CORE_GRAPHICS
2547
#if wxMAC_USE_CORE_GRAPHICS
2491
2549
CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2492
2550
rect.bottom - rect.top ) ;
2517
2575
HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2577
#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2520
2578
m_peer->GetRect( &rect ) ;
2521
if ( hasBothScrollbars )
2579
if ( MacHasScrollBarCorner() )
2523
int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ;
2581
int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant();
2582
int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2524
2583
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2525
2584
CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2526
2585
HIThemeGrowBoxDrawInfo info ;
2683
2745
wxRect rc( x, y, w, h );
2684
2746
if (rect->Intersects( rc ))
2685
child->SetSize( x + dx, y + dy, w, h );
2747
child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
2689
child->SetSize( x + dx, y + dy, w, h );
2751
child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
3118
3184
if ( iter->IsTopLevel() )
3119
return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
3186
wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
3188
return toplevel->MacGetWindowRef();
3190
wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
3192
return popupwin->MacGetPopupWindowRef();
3121
3195
iter = iter->GetParent() ;
3201
bool wxWindowMac::MacHasScrollBarCorner() const
3203
/* Returns whether the scroll bars in a wxScrolledWindow should be
3204
* shortened. Scroll bars should be shortened if either:
3206
* - both scroll bars are visible, or
3208
* - there is a resize box in the parent frame's corner and this
3209
* window shares the bottom and right edge with the parent
3213
if ( m_hScrollBar == NULL && m_vScrollBar == NULL )
3216
if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
3217
&& ( m_vScrollBar && m_vScrollBar->IsShown() ) )
3219
// Both scroll bars visible
3224
wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight();
3226
for ( const wxWindow *win = this; win; win = win->GetParent() )
3228
const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
3231
if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
3233
// Parent frame has resize handle
3234
wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
3236
// Note: allow for some wiggle room here as wxMac's
3237
// window rect calculations seem to be imprecise
3238
if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2
3239
&& abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 )
3241
// Parent frame has resize handle and shares
3242
// right bottom corner
3247
// Parent frame has resize handle but doesn't
3248
// share right bottom corner
3254
// Parent frame doesn't have resize handle
3260
// No parent frame found
3127
3265
void wxWindowMac::MacCreateScrollBars( long style )
3129
3267
wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
3131
3269
if ( style & ( wxVSCROLL | wxHSCROLL ) )
3133
bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
3134
3271
int scrlsize = MAC_SCROLLBAR_SIZE ;
3135
3272
if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
3137
3274
scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
3140
int adjust = hasBoth ? scrlsize - 1: 0 ;
3277
int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
3141
3278
int width, height ;
3142
3279
GetClientSize( &width , &height ) ;
3146
3283
wxPoint hPoint(0, height - scrlsize) ;
3147
3284
wxSize hSize(width - adjust, scrlsize) ;
3286
// we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3149
3287
if ( style & wxVSCROLL )
3150
m_vScrollBar = new wxScrollBar(this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3289
m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3290
m_vScrollBar->SetMinSize( wxDefaultSize );
3152
if ( style & wxHSCROLL )
3153
m_hScrollBar = new wxScrollBar(this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3293
if ( style & wxHSCROLL )
3295
m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3296
m_hScrollBar->SetMinSize( wxDefaultSize );
3156
3300
// because the create does not take into account the client area origin