📄 textctrl.cpp
字号:
}
} else {
/* if it's in our bounds, set the cursor */
GetControlBounds(theControl, &bounds);
if (PtInRect(mousep, &bounds))
{
// SetThemeCursor(kThemeArrowCursor);
}
}
HSetState((Handle) tpvars, state);
}
}
}
/* TPPaneKeyDownProc is called whenever a keydown event is directed
at our control. Here, we direct the keydown event to the text
edit record and redraw the scroll bar and text field as appropriate. */
static pascal ControlPartCode TPPaneKeyDownProc(ControlHandle theControl,
SInt16 keyCode, SInt16 charCode, SInt16 modifiers) {
STPTextPaneVars **tpvars;
tpvars = (STPTextPaneVars **) GetControlReference(theControl);
if (tpvars != NULL) {
if ((**tpvars).fInFocus) {
/* turn autoscrolling on and send the key event to text edit */
SetPort((**tpvars).fDrawingEnvironment);
wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
EventRecord ev ;
memset( &ev , 0 , sizeof( ev ) ) ;
ev.what = keyDown ;
ev.modifiers = modifiers ;
ev.message = (( keyCode << 8 ) & keyCodeMask ) + ( charCode & charCodeMask ) ;
TXNKeyDown( (**tpvars).fTXNRec, &ev);
}
}
return kControlEntireControl;
}
/* TPPaneActivateProc is called when the window containing
the user pane control receives activate events. Here, we redraw
the control and it's text as necessary for the activation state. */
static pascal void TPPaneActivateProc(ControlHandle theControl, Boolean activating) {
Rect bounds;
STPTextPaneVars **tpvars, *varsp;
char state;
/* set up locals */
tpvars = (STPTextPaneVars **) GetControlReference(theControl);
if (tpvars != NULL) {
state = HGetState((Handle) tpvars);
HLock((Handle) tpvars);
varsp = *tpvars;
/* de/activate the text edit record */
SetPort((**tpvars).fDrawingEnvironment);
wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
GetControlBounds(theControl, &bounds);
varsp->fIsActive = activating;
TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
/* redraw the frame */
if ( IsControlVisible( theControl ) )
{
DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
if (varsp->fInFocus)
DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive);
}
HSetState((Handle) tpvars, state);
}
}
/* TPPaneFocusProc is called when every the focus changes to or
from our control. Herein, switch the focus appropriately
according to the parameters and redraw the control as
necessary. */
static pascal ControlPartCode TPPaneFocusProc(ControlHandle theControl, ControlFocusPart action) {
ControlPartCode focusResult;
STPTextPaneVars **tpvars, *varsp;
char state;
/* set up locals */
focusResult = kControlFocusNoPart;
tpvars = (STPTextPaneVars **) GetControlReference(theControl);
if (tpvars != NULL ) {
state = HGetState((Handle) tpvars);
HLock((Handle) tpvars);
varsp = *tpvars;
/* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
tabbing forwards (or shift tabbing backwards) through the items in the dialog,
and kControlFocusNextPart will be received. When the user clicks in our field
and it is not the current focus, then the constant kUserClickedToFocusPart will
be received. The constant kControlFocusNoPart will be received when our control
is the current focus and the user clicks in another control. In your focus routine,
you should respond to these codes as follows:
kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
the control and the focus rectangle as necessary.
kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
depending on its current state. redraw the control and the focus rectangle
as appropriate for the new focus state. If the focus state is 'off', return the constant
kControlFocusNoPart, otherwise return a non-zero part code.
kUserClickedToFocusPart - is a constant defined for this example. You should
define your own value for handling click-to-focus type events. */
/* calculate the next highlight state */
switch (action) {
default:
case kControlFocusNoPart:
TPFocusPaneText(tpvars, false);
focusResult = kControlFocusNoPart;
break;
case kUserClickedToFocusPart:
TPFocusPaneText(tpvars, true);
focusResult = 1;
break;
case kControlFocusPrevPart:
case kControlFocusNextPart:
TPFocusPaneText(tpvars, ( ! varsp->fInFocus));
focusResult = varsp->fInFocus ? 1 : kControlFocusNoPart;
break;
}
TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
/* redraw the text fram and focus rectangle to indicate the
new focus state */
if ( IsControlVisible( theControl ) )
{
/* save the drawing state */
SetPort((**tpvars).fDrawingEnvironment);
wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive && varsp->fInFocus);
}
/* done */
HSetState((Handle) tpvars, state);
}
return focusResult;
}
/* mUPOpenControl initializes a user pane control so it will be drawn
and will behave as a scrolling text edit field inside of a window.
This routine performs all of the initialization steps necessary,
except it does not create the user pane control itself. theControl
should refer to a user pane control that you have either created
yourself or extracted from a dialog's control heirarchy using
the GetDialogItemAsControl routine. */
OSStatus mUPOpenControl(ControlHandle theControl, long wxStyle )
{
Rect bounds;
WindowRef theWindow;
STPTextPaneVars **tpvars, *varsp;
OSStatus err = noErr ;
RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
TXNBackground tback;
/* set up our globals */
if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(TPPaneDrawProc);
if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(TPPaneHitTestProc);
if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(TPPaneTrackingProc);
if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(TPPaneIdleProc);
if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc);
if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(TPPaneActivateProc);
if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(TPPaneFocusProc);
/* allocate our private storage */
tpvars = (STPTextPaneVars **) NewHandleClear(sizeof(STPTextPaneVars));
SetControlReference(theControl, (long) tpvars);
HLock((Handle) tpvars);
varsp = *tpvars;
/* set the initial settings for our private data */
varsp->fMultiline = wxStyle & wxTE_MULTILINE ;
varsp->fInFocus = false;
varsp->fIsActive = true;
varsp->fTEActive = true; // in order to get a deactivate
varsp->fUserPaneRec = theControl;
theWindow = varsp->fOwner = GetControlOwner(theControl);
varsp->fDrawingEnvironment = (GrafPtr) GetWindowPort(theWindow);
varsp->fInDialogWindow = ( GetWindowKind(varsp->fOwner) == kDialogWindowKind );
/* set up the user pane procedures */
SetControlData(theControl, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
/* calculate the rectangles used by the control */
GetControlBounds(theControl, &bounds);
SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
/* calculate the background region for the text. In this case, it's kindof
and irregular region because we're setting the scroll bar a little ways inside
of the text area. */
RectRgn((varsp->fTextBackgroundRgn = NewRgn()), &varsp->fRTextOutline);
/* set up the drawing environment */
SetPort(varsp->fDrawingEnvironment);
/* create the new edit field */
TXNFrameOptions frameOptions =
kTXNDontDrawCaretWhenInactiveMask ;
if ( ! ( wxStyle & wxTE_NOHIDESEL ) )
frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
if ( wxStyle & wxTE_MULTILINE )
{
if ( ! ( wxStyle & wxTE_DONTWRAP ) )
frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
else
{
frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
frameOptions |= kTXNWantHScrollBarMask ;
}
if ( !(wxStyle & wxTE_NO_VSCROLL ) )
frameOptions |= kTXNWantVScrollBarMask ;
}
else
frameOptions |= kTXNSingleLineOnlyMask ;
if ( wxStyle & wxTE_READONLY )
frameOptions |= kTXNReadOnlyMask ;
TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea,
frameOptions ,
kTXNTextEditStyleFrameType,
kTXNTextensionFile,
kTXNSystemDefaultEncoding,
&varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) tpvars);
if ( !IsControlVisible( theControl ) )
TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top + 30000 , varsp->fRTextArea.left + 30000 ,
varsp->fRTextArea.bottom + 30000 , varsp->fRTextArea.right + 30000 , varsp->fTXNFrame);
if ( (wxStyle & wxTE_MULTILINE) && (wxStyle & wxTE_DONTWRAP) )
{
TXNControlTag tag = kTXNWordWrapStateTag ;
TXNControlData dat ;
dat.uValue = kTXNNoAutoWrap ;
TXNSetTXNObjectControls( varsp->fTXNRec , false , 1 , &tag , &dat ) ;
}
Str255 fontName ;
SInt16 fontSize ;
Style fontStyle ;
GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
TXNTypeAttributes typeAttr[] =
{
{ kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
{ kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
{ kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
} ;
err = TXNSetTypeAttributes (varsp->fTXNRec, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr,
kTXNStartOffset,
kTXNEndOffset);
/* set the field's background */
tback.bgType = kTXNBackgroundTypeRGB;
tback.bg.color = rgbWhite;
TXNSetBackground( varsp->fTXNRec, &tback);
/* unlock our storage */
HUnlock((Handle) tpvars);
/* perform final activations and setup for our text field. Here,
we assume that the window is going to be the 'active' window. */
TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
/* all done */
return err;
}
IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
EVT_CHAR(wxTextCtrl::OnChar)
EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
END_EVENT_TABLE()
static void SetTXNData( TXNObject txn , const wxString& st , TXNOffset start , TXNOffset end )
{
#if wxUSE_UNICODE
#if SIZEOF_WCHAR_T == 2
size_t len = st.length() ;
TXNSetData( txn , kTXNUnicodeTextData, (void*)st.wc_str(), len * 2,
start, end);
#else
wxMBConvUTF16BE converter ;
ByteCount byteBufferLen = converter.WC2MB( NULL , st.wc_str() , 0 ) ;
UniChar *unibuf = (UniChar*) malloc(byteBufferLen) ;
converter.WC2MB( (char*) unibuf , st.wc_str() , byteBufferLen ) ;
TXNSetData( txn , kTXNUnicodeTextData, (void*)unibuf, byteBufferLen ,
start, end);
free( unibuf ) ;
#endif
#else
wxCharBuffer text = st.mb_str(wxConvLocal) ;
TXNSetData( txn , kTXNTextData, (void*)text.data(), strlen( text ) ,
start, end);
#endif
}
// Text item
void wxTextCtrl::Init()
{
m_macTE = NULL ;
m_macTXN = NULL ;
m_macTXNvars = NULL ;
m_macUsesTXN = false ;
m_editable = true ;
m_dirty = false;
m_maxLength = TE_UNLIMITED_LENGTH ;
}
wxTextCtrl::~wxTextCtrl()
{
if ( m_macUsesTXN )
{
SetControlReference((ControlHandle)m_macControl, 0) ;
TXNDeleteObject((TXNObject)m_macTXN);
/* delete our private storage */
DisposeHandle((Handle) m_macTXNvars);
/* zero the control reference */
}
}
const short kVerticalMargin = 2 ;
const short kHorizontalMargin = 2 ;
bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
const wxString& str,
const wxPoint& pos,
const wxSize& size, long style,
const wxValidator& validator,
const wxString& name)
{
m_macTE = NULL ;
m_macTXN = NULL ;
m_macTXNvars = NULL ;
m_macUsesTXN = false ;
m_editable = true ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -