📄 window.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: src/mac/carbon/window.cpp
// Purpose: wxWindowMac
// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
// RCS-ID: $Id: window.cpp,v 1.309 2006/06/19 07:12:37 ABX Exp $
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#include "wx/window.h"
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/app.h"
#include "wx/utils.h"
#include "wx/panel.h"
#include "wx/frame.h"
#include "wx/dc.h"
#include "wx/dcclient.h"
#include "wx/button.h"
#include "wx/menu.h"
#include "wx/dialog.h"
#include "wx/settings.h"
#include "wx/msgdlg.h"
#include "wx/scrolbar.h"
#include "wx/statbox.h"
#include "wx/textctrl.h"
#include "wx/toolbar.h"
#include "wx/layout.h"
#include "wx/statusbr.h"
#include "wx/menuitem.h"
#endif
#include "wx/tooltip.h"
#include "wx/spinctrl.h"
#include "wx/geometry.h"
#if wxUSE_CARET
#include "wx/caret.h"
#endif
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#endif
#include "wx/mac/uma.h"
#define MAC_SCROLLBAR_SIZE 15
#define MAC_SMALL_SCROLLBAR_SIZE 11
#ifndef __DARWIN__
#include <Windows.h>
#include <ToolUtils.h>
#include <Scrap.h>
#include <MacTextEditor.h>
#endif
#if TARGET_API_MAC_OSX
#ifndef __HIVIEW__
#include <HIToolbox/HIView.h>
#endif
#endif
#include <string.h>
#ifdef __WXUNIVERSAL__
IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
#else
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
#endif
BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
EVT_NC_PAINT(wxWindowMac::OnNcPaint)
EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
#if TARGET_API_MAC_OSX
EVT_PAINT(wxWindowMac::OnPaint)
#endif
EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
END_EVENT_TABLE()
#define wxMAC_DEBUG_REDRAW 0
#ifndef wxMAC_DEBUG_REDRAW
#define wxMAC_DEBUG_REDRAW 0
#endif
#define wxMAC_USE_THEME_BORDER 1
// ---------------------------------------------------------------------------
// Utility Routines to move between different coordinate systems
// ---------------------------------------------------------------------------
/*
* Right now we have the following setup :
* a border that is not part of the native control is always outside the
* control's border (otherwise we loose all native intelligence, future ways
* may be to have a second embedding control responsible for drawing borders
* and backgrounds eventually)
* so all this border calculations have to be taken into account when calling
* native methods or getting native oriented data
* so we have three coordinate systems here
* wx client coordinates
* wx window coordinates (including window frames)
* native coordinates
*/
//
// originating from native control
//
void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
{
OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
}
void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
{
OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
}
//
// directed towards native control
//
void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
{
OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
}
void wxMacWindowToNative( const wxWindow* window , Rect *rect )
{
OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
}
// ---------------------------------------------------------------------------
// Carbon Events
// ---------------------------------------------------------------------------
extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
#if TARGET_API_MAC_OSX
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
enum
{
kEventControlVisibilityChanged = 157
};
#endif
#endif
static const EventTypeSpec eventList[] =
{
{ kEventClassCommand, kEventProcessCommand } ,
{ kEventClassCommand, kEventCommandUpdateStatus } ,
{ kEventClassControl , kEventControlHit } ,
{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
{ kEventClassControl , kEventControlDraw } ,
#if TARGET_API_MAC_OSX
{ kEventClassControl , kEventControlVisibilityChanged } ,
{ kEventClassControl , kEventControlEnabledStateChanged } ,
{ kEventClassControl , kEventControlHiliteChanged } ,
#endif
{ kEventClassControl , kEventControlSetFocusPart } ,
{ kEventClassService , kEventServiceGetTypes },
{ kEventClassService , kEventServiceCopy },
{ kEventClassService , kEventServicePaste },
// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
// { kEventClassControl , kEventControlBoundsChanged } ,
} ;
static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
wxMacCarbonEvent cEvent( event ) ;
ControlRef controlRef ;
wxWindowMac* thisWindow = (wxWindowMac*) data ;
cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
switch ( GetEventKind( event ) )
{
#if TARGET_API_MAC_OSX
case kEventControlDraw :
{
RgnHandle updateRgn = NULL ;
RgnHandle allocatedRgn = NULL ;
wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
Rect controlBounds ;
if ( ! thisWindow->GetPeer()->IsCompositing() )
{
if ( thisWindow->GetPeer()->IsRootControl() )
thisWindow->GetPeer()->GetRect( &controlBounds ) ;
else
GetControlBounds( thisWindow->GetPeer()->GetControlRef() , &controlBounds ) ;
}
if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
{
updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
}
else
{
if ( ! thisWindow->GetPeer()->IsCompositing() )
{
allocatedRgn = NewRgn() ;
CopyRgn( updateRgn , allocatedRgn ) ;
OffsetRgn( allocatedRgn , -controlBounds.left , -controlBounds.top ) ;
// hide the given region by the new region that must be shifted
wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
updateRgn = allocatedRgn ;
}
else
{
if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
{
// as this update region is in native window locals we must adapt it to wx window local
allocatedRgn = NewRgn() ;
CopyRgn( updateRgn , allocatedRgn ) ;
// hide the given region by the new region that must be shifted
wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
updateRgn = allocatedRgn ;
}
}
}
Rect rgnBounds ;
GetRegionBounds( updateRgn , &rgnBounds ) ;
#if wxMAC_DEBUG_REDRAW
if ( thisWindow->MacIsUserPane() )
{
static float color = 0.5 ;
static channel = 0 ;
HIRect bounds;
CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
HIViewGetBounds( controlRef, &bounds );
CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
CGContextFillRect( cgContext, bounds );
color += 0.1 ;
if ( color > 0.9 )
{
color = 0.5 ;
channel++ ;
if ( channel == 3 )
channel = 0 ;
}
}
#endif
{
#if wxMAC_USE_CORE_GRAPHICS
bool created = false ;
CGContextRef cgContext = NULL ;
if ( cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) != noErr )
{
wxASSERT( thisWindow->GetPeer()->IsCompositing() == false ) ;
// this parameter is not provided on non-composited windows
created = true ;
// rest of the code expects this to be already transformed and clipped for local
CGrafPtr port = GetWindowPort( (WindowRef) thisWindow->MacGetTopLevelWindowRef() ) ;
Rect bounds ;
GetPortBounds( port , &bounds ) ;
CreateCGContextForPort( port , &cgContext ) ;
wxMacWindowToNative( thisWindow , updateRgn ) ;
OffsetRgn( updateRgn , controlBounds.left , controlBounds.top ) ;
ClipCGContextToRegion( cgContext , &bounds , updateRgn ) ;
wxMacNativeToWindow( thisWindow , updateRgn ) ;
OffsetRgn( updateRgn , -controlBounds.left , -controlBounds.top ) ;
CGContextTranslateCTM( cgContext , 0 , bounds.bottom - bounds.top ) ;
CGContextScaleCTM( cgContext , 1 , -1 ) ;
CGContextTranslateCTM( cgContext , controlBounds.left , controlBounds.top ) ;
#if 0
CGContextSetRGBFillColor( cgContext , 1.0 , 1.0 , 1.0 , 1.0 ) ;
CGContextFillRect( cgContext ,
CGRectMake( 0 , 0 ,
controlBounds.right - controlBounds.left ,
controlBounds.bottom - controlBounds.top ) );
#endif
}
thisWindow->MacSetCGContextRef( cgContext ) ;
{
wxMacCGContextStateSaver sg( cgContext ) ;
#endif
if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
result = noErr ;
#if wxMAC_USE_CORE_GRAPHICS
thisWindow->MacSetCGContextRef( NULL ) ;
}
if ( created )
CGContextRelease( cgContext ) ;
#endif
}
if ( allocatedRgn )
DisposeRgn( allocatedRgn ) ;
}
break ;
case kEventControlVisibilityChanged :
thisWindow->MacVisibilityChanged() ;
break ;
case kEventControlEnabledStateChanged :
thisWindow->MacEnabledStateChanged() ;
break ;
case kEventControlHiliteChanged :
thisWindow->MacHiliteChanged() ;
break ;
#endif
// we emulate this event under Carbon CFM
case kEventControlSetFocusPart :
{
Boolean focusEverything = false ;
ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
#ifdef __WXMAC_OSX__
if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
{
}
#endif
if ( controlPart == kControlFocusNoPart )
{
#if wxUSE_CARET
if ( thisWindow->GetCaret() )
thisWindow->GetCaret()->OnKillFocus();
#endif
static bool inKillFocusEvent = false ;
if ( !inKillFocusEvent )
{
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
thisWindow->GetEventHandler()->ProcessEvent(event) ;
inKillFocusEvent = false ;
}
}
else
{
// panel wants to track the window which was the last to have focus in it
wxChildFocusEvent eventFocus(thisWindow);
thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
#if wxUSE_CARET
if ( thisWindow->GetCaret() )
thisWindow->GetCaret()->OnSetFocus();
#endif
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
thisWindow->GetEventHandler()->ProcessEvent(event) ;
}
if ( thisWindow->MacIsUserPane() )
result = noErr ;
}
break ;
case kEventControlHit :
result = thisWindow->MacControlHit( handler , event ) ;
break ;
default :
break ;
}
return result ;
}
static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
wxMacCarbonEvent cEvent( event ) ;
ControlRef controlRef ;
wxWindowMac* thisWindow = (wxWindowMac*) data ;
wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -