X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6f011faaf00692d0b6e96bc98627e301ea6f8a25..f262b25c93c89d2f2bd0b388bac293c8969a2d72:/src/generic/srchctlg.cpp diff --git a/src/generic/srchctlg.cpp b/src/generic/srchctlg.cpp index 956edb3f83..75f9391892 100644 --- a/src/generic/srchctlg.cpp +++ b/src/generic/srchctlg.cpp @@ -2,25 +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 /////////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "srchctlg.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,6 +15,10 @@ #pragma hdrstop #endif +#if wxUSE_SEARCHCTRL + +#include "wx/srchctrl.h" + #ifndef WX_PRECOMP #include "wx/button.h" #include "wx/dcclient.h" @@ -35,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 @@ -64,6 +50,57 @@ static const wxCoord ICON_MARGIN = 0; static const wxCoord ICON_OFFSET = 0; #endif +// ---------------------------------------------------------------------------- +// TODO: These functions or something like them should probably be made +// public. There are similar functions in src/aui/dockart.cpp... + +static double wxBlendColour(double fg, double bg, double alpha) +{ + double result = bg + (alpha * (fg - bg)); + if (result < 0.0) + result = 0.0; + if (result > 255) + result = 255; + return result; +} + +static wxColor wxStepColour(const wxColor& c, int ialpha) +{ + if (ialpha == 100) + return c; + + double r = c.Red(), g = c.Green(), b = c.Blue(); + double bg; + + // ialpha is 0..200 where 0 is completely black + // and 200 is completely white and 100 is the same + // convert that to normal alpha 0.0 - 1.0 + ialpha = wxMin(ialpha, 200); + ialpha = wxMax(ialpha, 0); + double alpha = ((double)(ialpha - 100.0))/100.0; + + if (ialpha > 100) + { + // blend with white + bg = 255.0; + alpha = 1.0 - alpha; // 0 = transparent fg; 1 = opaque fg + } + else + { + // blend with black + bg = 0.0; + alpha = 1.0 + alpha; // 0 = transparent fg; 1 = opaque fg + } + + r = wxBlendColour(r, bg, alpha); + g = wxBlendColour(g, bg, alpha); + b = wxBlendColour(b, bg, alpha); + + return wxColour((unsigned char)r, (unsigned char)g, (unsigned char)b); +} + +#define LIGHT_STEP 160 + // ---------------------------------------------------------------------------- // wxSearchTextCtrl: text control used by search control // ---------------------------------------------------------------------------- @@ -76,11 +113,27 @@ public: style | wxNO_BORDER) { m_search = search; + m_defaultFG = GetForegroundColour(); // remove the default minsize, the searchctrl will have one instead SetSizeHints(wxDefaultCoord,wxDefaultCoord); } + void SetDescriptiveText(const wxString& text) + { + if ( GetValue() == m_descriptiveText ) + { + SetValue(wxEmptyString); + } + + m_descriptiveText = text; + } + + wxString GetDescriptiveText() const + { + return m_descriptiveText; + } + protected: void OnText(wxCommandEvent& eventText) { @@ -96,7 +149,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() @@ -106,9 +159,31 @@ protected: m_search->GetEventHandler()->ProcessEvent(event); } + void OnIdle(wxIdleEvent& WXUNUSED(event)) + { + if ( IsEmpty() && !(wxWindow::FindFocus() == this) ) + { + SetValue(m_descriptiveText); + SetInsertionPoint(0); + SetForegroundColour(wxStepColour(m_defaultFG, LIGHT_STEP)); + } + } + + void OnFocus(wxFocusEvent& event) + { + event.Skip(); + if ( GetValue() == m_descriptiveText ) + { + SetValue(wxEmptyString); + SetForegroundColour(m_defaultFG); + } + } + private: wxSearchCtrl* m_search; - + wxString m_descriptiveText; + wxColour m_defaultFG; + DECLARE_EVENT_TABLE() }; @@ -117,6 +192,8 @@ BEGIN_EVENT_TABLE(wxSearchTextCtrl, wxTextCtrl) EVT_TEXT_ENTER(wxID_ANY, wxSearchTextCtrl::OnText) EVT_TEXT_URL(wxID_ANY, wxSearchTextCtrl::OnTextUrl) EVT_TEXT_MAXLEN(wxID_ANY, wxSearchTextCtrl::OnText) + EVT_IDLE(wxSearchTextCtrl::OnIdle) + EVT_SET_FOCUS(wxSearchTextCtrl::OnFocus) END_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -135,13 +212,13 @@ public: void SetBitmapLabel(const wxBitmap& label) { m_bmp = label; } - + protected: wxSize DoGetBestSize() const { return wxSize(m_bmp.GetWidth(), m_bmp.GetHeight()); } - + void OnLeftUp(wxMouseEvent&) { wxCommandEvent event(m_eventType, m_search->GetId()); @@ -151,7 +228,7 @@ protected: m_search->SetFocus(); - if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH ) + if ( m_eventType == wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN ) { // this happens automatically, just like on Mac OS X m_search->PopupSearchMenu(); @@ -164,7 +241,7 @@ protected: dc.DrawBitmap(m_bmp, 0,0, true); } - + private: wxSearchCtrl *m_search; wxEventType m_eventType; @@ -179,8 +256,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) @@ -197,7 +275,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase) // -------- wxSearchCtrl::wxSearchCtrl() -{ +{ Init(); } @@ -237,17 +315,22 @@ bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id, const wxValidator& validator, const wxString& name) { +#ifdef __WXGTK__ + if ( !wxTextCtrlBase::Create(parent, id, pos, size, wxSUNKEN_BORDER | style, validator, name) ) +#else if ( !wxTextCtrlBase::Create(parent, id, pos, size, wxSIMPLE_BORDER | style, validator, name) ) +#endif { return false; } m_text = new wxSearchTextCtrl(this, value, style & ~wxBORDER_MASK); - + m_text->SetDescriptiveText(_("Search")); + 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() ); @@ -281,20 +364,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 ) { @@ -303,12 +380,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() @@ -316,7 +390,7 @@ wxMenu* wxSearchCtrl::GetMenu() return m_menu; } -void wxSearchCtrl::SetSearchButtonVisible( bool show ) +void wxSearchCtrl::ShowSearchButton( bool show ) { if ( m_searchButtonVisible == show ) { @@ -333,13 +407,13 @@ void wxSearchCtrl::SetSearchButtonVisible( bool show ) LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight()); } -bool wxSearchCtrl::GetSearchButtonVisible() const +bool wxSearchCtrl::IsSearchButtonVisible() const { return m_searchButtonVisible; } -void wxSearchCtrl::SetCancelButtonVisible( bool show ) +void wxSearchCtrl::ShowCancelButton( bool show ) { if ( m_cancelButtonVisible == show ) { @@ -352,11 +426,20 @@ void wxSearchCtrl::SetCancelButtonVisible( bool show ) LayoutControls(0, 0, rect.GetWidth(), rect.GetHeight()); } -bool wxSearchCtrl::GetCancelButtonVisible() const +bool wxSearchCtrl::IsCancelButtonVisible() const { return m_cancelButtonVisible; } +void wxSearchCtrl::SetDescriptiveText(const wxString& text) +{ + m_text->SetDescriptiveText(text); +} + +wxString wxSearchCtrl::GetDescriptiveText() const +{ + return m_text->GetDescriptiveText(); +} // ---------------------------------------------------------------------------- // geometry @@ -397,9 +480,12 @@ 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; @@ -433,10 +519,13 @@ void wxSearchCtrl::LayoutControls(int x, int y, int width, int height) // 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); } @@ -445,7 +534,11 @@ void wxSearchCtrl::LayoutControls(int x, int y, int width, int height) wxString wxSearchCtrl::GetValue() const { - return m_text->GetValue(); + wxString value = m_text->GetValue(); + if (value == m_text->GetDescriptiveText()) + return wxEmptyString; + else + return value; } void wxSearchCtrl::SetValue(const wxString& value) { @@ -697,7 +790,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; @@ -814,7 +907,7 @@ static int GetMultiplier() wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) { wxColour bg = GetBackgroundColour(); - wxColour fg = GetForegroundColour(); + wxColour fg = wxStepColour(GetForegroundColour(), LIGHT_STEP-20); //=============================================================================== // begin drawing code @@ -895,7 +988,8 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) }; mem.DrawPolygon(WXSIZEOF(dropPolygon),dropPolygon,multiplier*triangleX,multiplier*triangleY); } - + mem.SelectObject(wxNullBitmap); + //=============================================================================== // end drawing code //=============================================================================== @@ -906,6 +1000,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; } @@ -913,7 +1012,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 = wxStepColour(GetForegroundColour(), LIGHT_STEP); //=============================================================================== // begin drawing code @@ -1008,9 +1107,9 @@ void wxSearchCtrl::RecalcBitmaps() if ( !m_searchBitmapUser ) { - if ( + if ( !m_searchBitmap.Ok() || - m_searchBitmap.GetHeight() != bitmapHeight || + m_searchBitmap.GetHeight() != bitmapHeight || m_searchBitmap.GetWidth() != bitmapWidth ) { @@ -1025,9 +1124,9 @@ void wxSearchCtrl::RecalcBitmaps() if ( !m_searchMenuBitmapUser ) { - if ( + if ( !m_searchMenuBitmap.Ok() || - m_searchMenuBitmap.GetHeight() != bitmapHeight || + m_searchMenuBitmap.GetHeight() != bitmapHeight || m_searchMenuBitmap.GetWidth() != bitmapWidth ) { @@ -1042,9 +1141,9 @@ void wxSearchCtrl::RecalcBitmaps() if ( !m_cancelBitmapUser ) { - if ( + if ( !m_cancelBitmap.Ok() || - m_cancelBitmap.GetHeight() != bitmapHeight || + m_cancelBitmap.GetHeight() != bitmapHeight || m_cancelBitmap.GetWidth() != bitmapHeight ) { @@ -1068,6 +1167,13 @@ void wxSearchCtrl::OnSetFocus( wxFocusEvent& /*event*/ ) } } +void wxSearchCtrl::OnSize( wxSizeEvent& WXUNUSED(event) ) +{ + int width, height; + GetSize(&width, &height); + LayoutControls(0, 0, width, height); +} + void wxSearchCtrl::PopupSearchMenu() { if ( m_menu ) @@ -1077,6 +1183,6 @@ void wxSearchCtrl::PopupSearchMenu() } } -#endif // !USE_NATIVE_SEARCH_CONTROL +#endif // !wxUSE_NATIVE_SEARCH_CONTROL #endif // wxUSE_SEARCHCTRL