X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ec184e324214ea06f0c056ab626de5f32bcdad3b..04fa04d8067d235ab45b5bc05b65f0679634b541:/src/generic/srchctlg.cpp diff --git a/src/generic/srchctlg.cpp b/src/generic/srchctlg.cpp index d624d7d22e..d0efcd17b3 100644 --- a/src/generic/srchctlg.cpp +++ b/src/generic/srchctlg.cpp @@ -2,21 +2,12 @@ // Name: src/generic/srchctlg.cpp // Purpose: implements wxSearchCtrl as a composite control // Author: Vince Harron -// Modified by: // Created: 2006-02-19 -// RCS-ID: +// RCS-ID: $Id$ // Copyright: Vince Harron -// License: wxWindows licence +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -24,6 +15,10 @@ #pragma hdrstop #endif +#if wxUSE_SEARCHCTRL + +#include "wx/srchctrl.h" + #ifndef WX_PRECOMP #include "wx/button.h" #include "wx/dcclient.h" @@ -31,16 +26,11 @@ #include "wx/dcmemory.h" #endif //WX_PRECOMP -#if wxUSE_SEARCHCTRL - -#include "wx/srchctrl.h" - -#if !USE_NATIVE_SEARCH_CONTROL +#if !wxUSE_NATIVE_SEARCH_CONTROL #include "wx/image.h" -#define WXMIN(a,b) (a)<(b)?(a):(b) -#define WXMAX(a,b) (a)>(b)?(a):(b) +#define WXMAX(a,b) ((a)>(b)?(a):(b)) // ---------------------------------------------------------------------------- // constants @@ -60,6 +50,8 @@ static const wxCoord ICON_MARGIN = 0; static const wxCoord ICON_OFFSET = 0; #endif +#define LIGHT_STEP 160 + // ---------------------------------------------------------------------------- // wxSearchTextCtrl: text control used by search control // ---------------------------------------------------------------------------- @@ -69,14 +61,34 @@ class wxSearchTextCtrl : public wxTextCtrl public: wxSearchTextCtrl(wxSearchCtrl *search, const wxString& value, int style) : wxTextCtrl(search, wxID_ANY, value, wxDefaultPosition, wxDefaultSize, - style | wxNO_BORDER) + (style & ~wxBORDER_MASK) | wxNO_BORDER) { m_search = search; - + + SetHint(_("Search")); + // remove the default minsize, the searchctrl will have one instead SetSizeHints(wxDefaultCoord,wxDefaultCoord); } + + // provide access to the base class protected methods to wxSearchCtrl which + // needs to forward to them + void DoSetValue(const wxString& value, int flags) + { + wxTextCtrl::DoSetValue(value, flags); + } + + bool DoLoadFile(const wxString& file, int fileType) + { + return wxTextCtrl::DoLoadFile(file, fileType); + } + + bool DoSaveFile(const wxString& file, int fileType) + { + return wxTextCtrl::DoSaveFile(file, fileType); + } + protected: void OnText(wxCommandEvent& eventText) { @@ -92,7 +104,7 @@ protected: // copy constructor is disabled for some reason? //wxTextUrlEvent event(eventText); wxTextUrlEvent event( - m_search->GetId(), + m_search->GetId(), eventText.GetMouseEvent(), eventText.GetURLStart(), eventText.GetURLEnd() @@ -131,27 +143,44 @@ public: void SetBitmapLabel(const wxBitmap& label) { m_bmp = label; } - + // The buttons in wxSearchCtrl shouldn't accept focus from keyboard because + // this would interfere with the usual TAB processing: the user expects + // that pressing TAB in the search control should switch focus to the next + // control and not give it to the button inside the same control. Besides, + // the search button can be already activated by pressing "Enter" so there + // is really no reason for it to be able to get focus from keyboard. + virtual bool AcceptsFocusFromKeyboard() const { return false; } + protected: wxSize DoGetBestSize() const { return wxSize(m_bmp.GetWidth(), m_bmp.GetHeight()); } - + void OnLeftUp(wxMouseEvent&) { wxCommandEvent event(m_eventType, m_search->GetId()); event.SetEventObject(m_search); + if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN ) + { + // it's convenient to have the string to search for directly in the + // event instead of having to retrieve it from the control in the + // event handler code later, so provide it here + event.SetString(m_search->GetValue()); + } + GetEventHandler()->ProcessEvent(event); m_search->SetFocus(); - if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH ) +#if wxUSE_MENUS + if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN ) { // this happens automatically, just like on Mac OS X m_search->PopupSearchMenu(); } +#endif // wxUSE_MENUS } void OnPaint(wxPaintEvent&) @@ -160,7 +189,7 @@ protected: dc.DrawBitmap(m_bmp, 0,0, true); } - + private: wxSearchCtrl *m_search; wxEventType m_eventType; @@ -175,8 +204,9 @@ BEGIN_EVENT_TABLE(wxSearchButton, wxControl) END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase) - EVT_SEARCHCTRL_SEARCH(wxID_ANY, wxSearchCtrl::OnSearchButton) + EVT_SEARCHCTRL_SEARCH_BTN(wxID_ANY, wxSearchCtrl::OnSearchButton) EVT_SET_FOCUS(wxSearchCtrl::OnSetFocus) + EVT_SIZE(wxSearchCtrl::OnSize) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase) @@ -193,7 +223,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase) // -------- wxSearchCtrl::wxSearchCtrl() -{ +{ Init(); } @@ -212,17 +242,21 @@ wxSearchCtrl::wxSearchCtrl(wxWindow *parent, wxWindowID id, void wxSearchCtrl::Init() { - m_text = 0; - m_searchButton = 0; - m_cancelButton = 0; - m_menu = 0; + m_text = NULL; + m_searchButton = NULL; + m_cancelButton = NULL; +#if wxUSE_MENUS + m_menu = NULL; +#endif // wxUSE_MENUS m_searchButtonVisible = true; m_cancelButtonVisible = false; - m_searchMenuBitmapUser = false; m_searchBitmapUser = false; m_cancelBitmapUser = false; +#if wxUSE_MENUS + m_searchMenuBitmapUser = false; +#endif // wxUSE_MENUS } bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id, @@ -233,17 +267,33 @@ bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id, const wxValidator& validator, const wxString& name) { - if ( !wxTextCtrlBase::Create(parent, id, pos, size, wxSIMPLE_BORDER | style, validator, name) ) + // force border style for more native appearance + style &= ~wxBORDER_MASK; +#ifdef __WXGTK__ + style |= wxBORDER_SUNKEN; +#elif defined(__WXMSW__) + // Don't set the style explicitly, let GetDefaultBorder() work it out, unless + // we will get a sunken border (e.g. on Windows 200) in which case we must + // override with a simple border. + if (GetDefaultBorder() == wxBORDER_SUNKEN) + style |= wxBORDER_SIMPLE; +#else + style |= wxBORDER_SIMPLE; +#endif + if ( !wxSearchCtrlBaseBaseClass::Create(parent, id, pos, size, + style, validator, name) ) { return false; } - m_text = new wxSearchTextCtrl(this, value, style & ~wxBORDER_MASK); + m_text = new wxSearchTextCtrl(this, value, style); - wxSize sizeText = m_text->GetBestSize(); - - m_searchButton = new wxSearchButton(this,wxEVT_COMMAND_SEARCHCTRL_SEARCH,m_searchBitmap); - m_cancelButton = new wxSearchButton(this,wxEVT_COMMAND_SEARCHCTRL_CANCEL,m_cancelBitmap); + m_searchButton = new wxSearchButton(this, + wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, + m_searchBitmap); + m_cancelButton = new wxSearchButton(this, + wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, + m_cancelBitmap); SetForegroundColour( m_text->GetForegroundColour() ); m_searchButton->SetForegroundColour( m_text->GetForegroundColour() ); @@ -265,11 +315,15 @@ wxSearchCtrl::~wxSearchCtrl() delete m_text; delete m_searchButton; delete m_cancelButton; +#if wxUSE_MENUS delete m_menu; +#endif // wxUSE_MENUS } // search control specific interfaces +#if wxUSE_MENUS + void wxSearchCtrl::SetMenu( wxMenu* menu ) { if ( menu == m_menu ) @@ -277,20 +331,14 @@ void wxSearchCtrl::SetMenu( wxMenu* menu ) // no change return; } + bool hadMenu = (m_menu != NULL); delete m_menu; - bool hadMenu = (m_menu!=0); m_menu = menu; if ( m_menu && !hadMenu ) { m_searchButton->SetBitmapLabel(m_searchMenuBitmap); m_searchButton->Refresh(); - if ( !m_searchButtonVisible ) - { - // adding the menu will force the search button to be visible - wxRect rect = GetRect(); - LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight()); - } } else if ( !m_menu && hadMenu ) { @@ -299,12 +347,9 @@ void wxSearchCtrl::SetMenu( wxMenu* menu ) { m_searchButton->Refresh(); } - else - { - wxRect rect = GetRect(); - LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight()); - } } + wxRect rect = GetRect(); + LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight()); } wxMenu* wxSearchCtrl::GetMenu() @@ -312,6 +357,8 @@ wxMenu* wxSearchCtrl::GetMenu() return m_menu; } +#endif // wxUSE_MENUS + void wxSearchCtrl::ShowSearchButton( bool show ) { if ( m_searchButtonVisible == show ) @@ -353,6 +400,15 @@ bool wxSearchCtrl::IsCancelButtonVisible() const return m_cancelButtonVisible; } +void wxSearchCtrl::SetDescriptiveText(const wxString& text) +{ + m_text->SetHint(text); +} + +wxString wxSearchCtrl::GetDescriptiveText() const +{ + return m_text->GetHint(); +} // ---------------------------------------------------------------------------- // geometry @@ -365,7 +421,7 @@ wxSize wxSearchCtrl::DoGetBestSize() const wxSize sizeCancel(0,0); int searchMargin = 0; int cancelMargin = 0; - if ( m_searchButtonVisible || m_menu ) + if ( m_searchButtonVisible || HasMenu() ) { sizeSearch = m_searchButton->GetBestSize(); searchMargin = MARGIN; @@ -393,19 +449,24 @@ void wxSearchCtrl::DoMoveWindow(int x, int y, int width, int height) void wxSearchCtrl::LayoutControls(int x, int y, int width, int height) { + if ( !m_text ) + return; + wxSize sizeText = m_text->GetBestSize(); // make room for the search menu & clear button - int horizontalBorder = 1 + ( sizeText.y - sizeText.y * 14 / 21 ) / 2; + int horizontalBorder = ( sizeText.y - sizeText.y * 14 / 21 ) / 2; x += horizontalBorder; y += BORDER; width -= horizontalBorder*2; height -= BORDER*2; + if (width < 0) width = 0; + if (height < 0) height = 0; wxSize sizeSearch(0,0); wxSize sizeCancel(0,0); int searchMargin = 0; int cancelMargin = 0; - if ( m_searchButtonVisible || m_menu ) + if ( m_searchButtonVisible || HasMenu() ) { sizeSearch = m_searchButton->GetBestSize(); searchMargin = MARGIN; @@ -415,7 +476,7 @@ void wxSearchCtrl::LayoutControls(int x, int y, int width, int height) sizeCancel = m_cancelButton->GetBestSize(); cancelMargin = MARGIN; } - m_searchButton->Show( m_searchButtonVisible || m_menu ); + m_searchButton->Show( m_searchButtonVisible || HasMenu() ); m_cancelButton->Show( m_cancelButtonVisible ); if ( sizeSearch.x + sizeCancel.x > width ) @@ -425,29 +486,28 @@ void wxSearchCtrl::LayoutControls(int x, int y, int width, int height) searchMargin = 0; cancelMargin = 0; } - wxCoord textWidth = width - sizeSearch.x - sizeCancel.x - searchMargin - cancelMargin; + wxCoord textWidth = width - sizeSearch.x - sizeCancel.x - searchMargin - cancelMargin - 1; + if (textWidth < 0) textWidth = 0; // position the subcontrols inside the client area - m_searchButton->SetSize(x, y + ICON_OFFSET, sizeSearch.x, height); - m_text->SetSize(x + sizeSearch.x + searchMargin, y + ICON_OFFSET, textWidth, height); + m_searchButton->SetSize(x, y + ICON_OFFSET - 1, sizeSearch.x, height); + m_text->SetSize( x + sizeSearch.x + searchMargin, + y + ICON_OFFSET - BORDER, + textWidth, + height); m_cancelButton->SetSize(x + sizeSearch.x + searchMargin + textWidth + cancelMargin, - y + ICON_OFFSET, sizeCancel.x, height); + y + ICON_OFFSET - 1, sizeCancel.x, height); } // accessors // --------- -wxString wxSearchCtrl::GetValue() const +wxString wxSearchCtrl::DoGetValue() const { return m_text->GetValue(); } -void wxSearchCtrl::SetValue(const wxString& value) -{ - m_text->SetValue(value); -} - wxString wxSearchCtrl::GetRange(long from, long to) const { return m_text->GetRange(from, to); @@ -669,7 +729,7 @@ long wxSearchCtrl::GetInsertionPoint() const { return m_text->GetInsertionPoint(); } -wxTextPos wxSearchCtrl::GetLastPosition() const +long wxSearchCtrl::GetLastPosition() const { return m_text->GetLastPosition(); } @@ -693,7 +753,7 @@ bool wxSearchCtrl::SetFont(const wxFont& font) bool result = wxSearchCtrlBase::SetFont(font); if ( result && m_text ) { - result &= m_text->SetFont(font); + result = m_text->SetFont(font); } RecalcBitmaps(); return result; @@ -703,10 +763,10 @@ bool wxSearchCtrl::SetFont(const wxFont& font) void wxSearchCtrl::SetSearchBitmap( const wxBitmap& bitmap ) { m_searchBitmap = bitmap; - m_searchBitmapUser = bitmap.Ok(); + m_searchBitmapUser = bitmap.IsOk(); if ( m_searchBitmapUser ) { - if ( m_searchButton && !m_menu ) + if ( m_searchButton && !HasMenu() ) { m_searchButton->SetBitmapLabel( m_searchBitmap ); } @@ -718,10 +778,12 @@ void wxSearchCtrl::SetSearchBitmap( const wxBitmap& bitmap ) } } +#if wxUSE_MENUS + void wxSearchCtrl::SetSearchMenuBitmap( const wxBitmap& bitmap ) { m_searchMenuBitmap = bitmap; - m_searchMenuBitmapUser = bitmap.Ok(); + m_searchMenuBitmapUser = bitmap.IsOk(); if ( m_searchMenuBitmapUser ) { if ( m_searchButton && m_menu ) @@ -736,10 +798,12 @@ void wxSearchCtrl::SetSearchMenuBitmap( const wxBitmap& bitmap ) } } +#endif // wxUSE_MENUS + void wxSearchCtrl::SetCancelBitmap( const wxBitmap& bitmap ) { m_cancelBitmap = bitmap; - m_cancelBitmapUser = bitmap.Ok(); + m_cancelBitmapUser = bitmap.IsOk(); if ( m_cancelBitmapUser ) { if ( m_cancelButton ) @@ -773,9 +837,17 @@ wxTextCtrl& operator<<(const wxChar c); void wxSearchCtrl::DoSetValue(const wxString& value, int flags) { - m_text->ChangeValue( value ); - if ( flags & SetValue_SendEvent ) - SendTextUpdatedEvent(); + m_text->DoSetValue(value, flags); +} + +bool wxSearchCtrl::DoLoadFile(const wxString& file, int fileType) +{ + return m_text->DoLoadFile(file, fileType); +} + +bool wxSearchCtrl::DoSaveFile(const wxString& file, int fileType) +{ + return m_text->DoSaveFile(file, fileType); } // do the window-specific processing after processing the update event @@ -810,7 +882,7 @@ static int GetMultiplier() wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) { wxColour bg = GetBackgroundColour(); - wxColour fg = GetForegroundColour(); + wxColour fg = GetForegroundColour().ChangeLightness(LIGHT_STEP-20); //=============================================================================== // begin drawing code @@ -891,6 +963,7 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) }; mem.DrawPolygon(WXSIZEOF(dropPolygon),dropPolygon,multiplier*triangleX,multiplier*triangleY); } + mem.SelectObject(wxNullBitmap); //=============================================================================== // end drawing code @@ -902,6 +975,11 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) image.Rescale(x,y); bitmap = wxBitmap( image ); } + if ( !renderDrop ) + { + // Trim the edge where the arrow would have gone + bitmap = bitmap.GetSubBitmap(wxRect(0,0, y,y)); + } return bitmap; } @@ -909,7 +987,7 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) wxBitmap wxSearchCtrl::RenderCancelBitmap( int x, int y ) { wxColour bg = GetBackgroundColour(); - wxColour fg = GetForegroundColour(); + wxColour fg = GetForegroundColour().ChangeLightness(LIGHT_STEP); //=============================================================================== // begin drawing code @@ -1004,14 +1082,14 @@ void wxSearchCtrl::RecalcBitmaps() if ( !m_searchBitmapUser ) { - if ( - !m_searchBitmap.Ok() || - m_searchBitmap.GetHeight() != bitmapHeight || + if ( + !m_searchBitmap.IsOk() || + m_searchBitmap.GetHeight() != bitmapHeight || m_searchBitmap.GetWidth() != bitmapWidth ) { m_searchBitmap = RenderSearchBitmap(bitmapWidth,bitmapHeight,false); - if ( !m_menu ) + if ( !HasMenu() ) { m_searchButton->SetBitmapLabel(m_searchBitmap); } @@ -1019,11 +1097,12 @@ void wxSearchCtrl::RecalcBitmaps() // else this bitmap was set by user, don't alter } +#if wxUSE_MENUS if ( !m_searchMenuBitmapUser ) { - if ( - !m_searchMenuBitmap.Ok() || - m_searchMenuBitmap.GetHeight() != bitmapHeight || + if ( + !m_searchMenuBitmap.IsOk() || + m_searchMenuBitmap.GetHeight() != bitmapHeight || m_searchMenuBitmap.GetWidth() != bitmapWidth ) { @@ -1035,16 +1114,17 @@ void wxSearchCtrl::RecalcBitmaps() } // else this bitmap was set by user, don't alter } +#endif // wxUSE_MENUS if ( !m_cancelBitmapUser ) { - if ( - !m_cancelBitmap.Ok() || - m_cancelBitmap.GetHeight() != bitmapHeight || + if ( + !m_cancelBitmap.IsOk() || + m_cancelBitmap.GetHeight() != bitmapHeight || m_cancelBitmap.GetWidth() != bitmapHeight ) { - m_cancelBitmap = RenderCancelBitmap(bitmapHeight-BORDER,bitmapHeight-BORDER); // square + m_cancelBitmap = RenderCancelBitmap(bitmapHeight-BORDER-1,bitmapHeight-BORDER-1); // square m_cancelButton->SetBitmapLabel(m_cancelBitmap); } // else this bitmap was set by user, don't alter @@ -1064,6 +1144,15 @@ void wxSearchCtrl::OnSetFocus( wxFocusEvent& /*event*/ ) } } +void wxSearchCtrl::OnSize( wxSizeEvent& WXUNUSED(event) ) +{ + int width, height; + GetSize(&width, &height); + LayoutControls(0, 0, width, height); +} + +#if wxUSE_MENUS + void wxSearchCtrl::PopupSearchMenu() { if ( m_menu ) @@ -1073,6 +1162,8 @@ void wxSearchCtrl::PopupSearchMenu() } } -#endif // !USE_NATIVE_SEARCH_CONTROL +#endif // wxUSE_MENUS + +#endif // !wxUSE_NATIVE_SEARCH_CONTROL #endif // wxUSE_SEARCHCTRL