📄 listbox.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: src/mac/classic/listbox.cpp// Purpose: wxListBox// Author: Stefan Csomor// Modified by:// Created: 1998-01-01// RCS-ID: $Id: listbox.cpp,v 1.20 2006/07/25 01:31:08 VZ Exp $// Copyright: (c) Stefan Csomor// Licence: wxWindows licence///////////////////////////////////////////////////////////////////////////////#include "wx/wxprec.h"#if wxUSE_LISTBOX#include "wx/listbox.h"#ifndef WX_PRECOMP #include "wx/dynarray.h" #include "wx/log.h" #include "wx/app.h" #include "wx/utils.h" #include "wx/button.h" #include "wx/settings.h" #include "wx/toplevel.h"#endifIMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)BEGIN_EVENT_TABLE(wxListBox, wxControl) EVT_SIZE( wxListBox::OnSize ) EVT_CHAR( wxListBox::OnChar )END_EVENT_TABLE()#include "wx/mac/uma.h"#if PRAGMA_STRUCT_ALIGN #pragma options align=mac68k#elif PRAGMA_STRUCT_PACKPUSH #pragma pack(push, 2)#elif PRAGMA_STRUCT_PACK #pragma pack(2)#endiftypedef struct { unsigned short instruction; void (*function)();} ldefRec, *ldefPtr, **ldefHandle;#if PRAGMA_STRUCT_ALIGN #pragma options align=reset#elif PRAGMA_STRUCT_PACKPUSH #pragma pack(pop)#elif PRAGMA_STRUCT_PACK #pragma pack()#endif#if TARGET_CARBONconst short kwxMacListItemHeight = 19 ;#elseconst short kwxMacListItemHeight = 14 ;#endifextern "C"{static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect, Cell cell, short dataOffset, short dataLength, ListHandle listHandle ) ;}static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect, Cell cell, short dataOffset, short dataLength, ListHandle listHandle ){ wxListBox* list; list = (wxListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) ); if ( list == NULL ) return ; GrafPtr savePort; GrafPtr grafPtr; RgnHandle savedClipRegion; SInt32 savedPenMode; GetPort(&savePort); SetPort((**listHandle).port); grafPtr = (**listHandle).port ; // typecast our refCon // Calculate the cell rect. switch( message ) { case lInitMsg: break; case lCloseMsg: break; case lDrawMsg: { const wxString linetext = list->m_stringArray[cell.v] ; // Save the current clip region, and set the clip region to the area we are about // to draw. savedClipRegion = NewRgn(); GetClip( savedClipRegion ); ClipRect( drawRect ); EraseRect( drawRect ); const wxFont& font = list->GetFont(); if ( font.Ok() ) { ::TextFont( font.GetMacFontNum() ) ; ::TextSize( font.GetMacFontSize() ) ; ::TextFace( font.GetMacFontStyle() ) ; } else { ::TextFont( kFontIDMonaco ) ; ::TextSize( 9 ); ::TextFace( 0 ) ; }#if TARGET_CARBON { Rect frame = { drawRect->top, drawRect->left + 4, drawRect->top + kwxMacListItemHeight, drawRect->right + 10000 } ; CFMutableStringRef mString = CFStringCreateMutableCopy( NULL , 0 , wxMacCFStringHolder(linetext , list->GetFont().GetEncoding()) ) ; ::TruncateThemeText( mString , kThemeCurrentPortFont, kThemeStateActive, drawRect->right - drawRect->left , truncEnd , NULL ) ; ::DrawThemeTextBox( mString, kThemeCurrentPortFont, kThemeStateActive, false, &frame, teJustLeft, nil ); CFRelease( mString ) ; }#else { wxCharBuffer text = linetext.mb_str( wxConvLocal) ; MoveTo(drawRect->left + 4 , drawRect->top + 10 ); DrawText(text, 0 , strlen(text) ); }#endif // If the cell is hilited, do the hilite now. Paint the cell contents with the // appropriate QuickDraw transform mode. if( isSelected ) { savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr ); SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode ); PaintRect( drawRect ); SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode ); } // Restore the saved clip region. SetClip( savedClipRegion ); DisposeRgn( savedClipRegion ); } break; case lHiliteMsg: // Hilite or unhilite the cell. Paint the cell contents with the // appropriate QuickDraw transform mode. GetPort( &grafPtr ); savedPenMode = GetPortPenMode( (CGrafPtr)grafPtr ); SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode ); PaintRect( drawRect ); SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode ); break; default : break ; } SetPort(savePort);}extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;// resources ldef idsconst short kwxMacListWithVerticalScrollbar = 128 ;const short kwxMacListWithVerticalAndHorizontalScrollbar = 129 ;// ============================================================================// list box control implementation// ============================================================================// Listbox itemwxListBox::wxListBox(){ m_noItems = 0; m_selected = 0; m_macList = NULL ;}static ListDefUPP macListDefUPP = NULL ;bool wxListBox::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, const wxArrayString& choices, long style, const wxValidator& validator, const wxString& name){ wxCArrayString chs(choices); return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(), style, validator, name);}bool wxListBox::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, int n, const wxString choices[], long style, const wxValidator& validator, const wxString& name){ if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) ) return false; m_noItems = 0 ; // this will be increased by our append command m_selected = 0; Rect bounds ; Str255 title ; MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ; ListDefSpec listDef; listDef.defType = kListDefUserProcType; if ( macListDefUPP == NULL ) { macListDefUPP = NewListDefUPP( wxMacListDefinition ); } listDef.u.userProc = macListDefUPP ; Str255 fontName ; SInt16 fontSize ; Style fontStyle ;#if TARGET_CARBON GetThemeFont(kThemeViewsFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;#else GetFontName( kFontIDMonaco , fontName ) ; fontSize = 9 ; fontStyle = normal ;#endif SetFont( wxFont (fontSize, wxSWISS, wxNORMAL, wxNORMAL , false , wxMacMakeStringFromPascal( fontName ) ) ) ;#if TARGET_CARBON Size asize; CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, (style & wxLB_HSCROLL), true, kwxMacListItemHeight, kwxMacListItemHeight, false, &listDef, (ControlRef *)&m_macControl ); GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag, sizeof(ListHandle), (Ptr) &m_macList, &asize); SetControlReference( (ControlHandle) m_macControl, (long) this); SetControlVisibility( (ControlHandle) m_macControl, false, false);#else long result ; wxStAppResource resload ; m_macControl = (WXWidget) ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , (style & wxLB_HSCROLL) ? kwxMacListWithVerticalAndHorizontalScrollbar : kwxMacListWithVerticalScrollbar , 0 , 0, kControlListBoxProc , (long) this ) ; ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &m_macList , &result ) ; HLock( (Handle) m_macList ) ; ldefHandle ldef ; ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ; if ( (**(ListHandle)m_macList).listDefProc != NULL ) { (**ldef).instruction = 0x4EF9; /* JMP instruction */ (**ldef).function = (void(*)()) listDef.u.userProc; (**(ListHandle)m_macList).listDefProc = (Handle) ldef ; } Point pt = (**(ListHandle)m_macList).cellSize ; pt.v = kwxMacListItemHeight ; LCellSize( pt , (ListHandle)m_macList ) ; LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;#endif OptionBits options = 0; if ( style & wxLB_MULTIPLE ) { options += lExtendDrag + lUseSense ; } else if ( style & wxLB_EXTENDED ) { // default behaviour } else { options = (OptionBits) lOnlyOne ; } SetListSelectionFlags((ListHandle)m_macList, options); for ( int i = 0 ; i < n ; i++ ) { Append( choices[i] ) ; } MacPostControlCreate() ; LSetDrawingMode( true , (ListHandle)m_macList ) ; return true;}wxListBox::~wxListBox(){ FreeData() ; // avoid access during destruction SetControlReference( (ControlHandle) m_macControl , NULL ) ; if ( m_macList ) {#if !TARGET_CARBON DisposeHandle( (**(ListHandle)m_macList).listDefProc ) ; (**(ListHandle)m_macList).listDefProc = NULL ;#endif m_macList = NULL ; }}void wxListBox::FreeData(){#if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { size_t uiCount = m_aItems.Count(); while ( uiCount-- != 0 ) { delete m_aItems[uiCount]; m_aItems[uiCount] = NULL; } m_aItems.Clear(); } else#endif // wxUSE_OWNER_DRAWN if ( HasClientObjectData() ) { for ( unsigned int n = 0; n < m_noItems; n++ ) { delete GetClientObject(n); } }}void wxListBox::DoSetSize(int x, int y, int width, int height, int sizeFlags ){ wxControl::DoSetSize( x , y , width , height , sizeFlags ) ;#if TARGET_CARBON Rect bounds ; GetControlBounds( (ControlHandle) m_macControl , &bounds ) ; ControlRef control = GetListVerticalScrollBar( (ListHandle)m_macList ) ; if ( control ) { Rect scrollbounds ; GetControlBounds( control , &scrollbounds ) ; if( scrollbounds.right != bounds.right + 1 ) { UMAMoveControl( control , bounds.right - (scrollbounds.right - scrollbounds.left) + 1 , scrollbounds.top ) ; } }#endif}void wxListBox::DoSetFirstItem(int N){ MacScrollTo( N ) ;}void wxListBox::Delete(unsigned int n){ wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") );#if wxUSE_OWNER_DRAWN delete m_aItems[n]; m_aItems.RemoveAt(n);#else // !wxUSE_OWNER_DRAWN if ( HasClientObjectData() ) { delete GetClientObject(n); }#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN m_stringArray.RemoveAt(n) ; m_dataArray.RemoveAt(n) ; m_noItems--; MacDelete(n) ;}int wxListBox::DoAppend(const wxString& item){ InvalidateBestSize(); unsigned int index = m_noItems ; m_stringArray.Add( item ) ; m_dataArray.Add( NULL ); m_noItems ++; DoSetItemClientData( index , NULL ) ; MacAppend( item ) ; return index ;}void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData){ MacSetRedraw( false ) ; Clear() ; int n = choices.GetCount(); for( int i = 0 ; i < n ; ++i ) { if ( clientData ) {#if wxUSE_OWNER_DRAWN wxASSERT_MSG(clientData[i] == NULL, wxT("Can't use client data with owner-drawn listboxes"));#else // !wxUSE_OWNER_DRAWN Append( choices[i] , clientData[i] ) ;#endif } else Append( choices[i] ) ; }#if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { // first delete old items unsigned int ui = m_aItems.Count(); while ( ui-- != 0 ) { delete m_aItems[ui]; m_aItems[ui] = NULL; } m_aItems.Empty(); // then create new ones for ( ui = 0; ui < m_noItems; ui++ ) { wxOwnerDrawn *pNewItem = CreateItem(ui); pNewItem->SetName(choices[ui]); m_aItems.Add(pNewItem); } }#endif // wxUSE_OWNER_DRAWN MacSetRedraw( true ) ;}bool wxListBox::HasMultipleSelection() const{ return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);}int wxListBox::FindString(const wxString& s, bool bCase) const{ if ( s.Right(1) == wxT("*") ) { wxString search = s.Left( s.length() - 1 ) ; int len = search.length() ; Str255 s1 , s2 ; wxMacStringToPascal( search , s2 ) ; for ( unsigned int i = 0 ; i < m_noItems ; ++ i ) { wxMacStringToPascal( m_stringArray[i].Left( len ) , s1 ) ; if ( EqualString( s1 , s2 , bCase , false ) ) return (int)i ; } if ( s.Left(1) == wxT("*") && s.length() > 1 ) { wxString st = s ; st.MakeLower() ; for ( unsigned int i = 0 ; i < m_noItems ; ++i ) { if (GetString(i).Lower().Matches(st)) return (int)i ; } } } else { Str255 s1 , s2 ; wxMacStringToPascal( s , s2 ) ; for ( unsigned int i = 0 ; i < m_noItems ; ++ i ) { wxMacStringToPascal( m_stringArray[i] , s1 ) ; if ( EqualString( s1 , s2 , bCase , false ) ) return (int)i ; } } return wxNOT_FOUND;}void wxListBox::Clear(){ FreeData(); m_noItems = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -