Merge branch 'searchctrl-improve'

Closes https://github.com/wxWidgets/wxWidgets/pull/851
This commit is contained in:
Vadim Zeitlin
2018-07-10 14:40:58 +02:00
7 changed files with 82 additions and 103 deletions

View File

@@ -172,26 +172,6 @@ public:
virtual bool DoAutoCompleteFileNames(int flags) wxOVERRIDE; virtual bool DoAutoCompleteFileNames(int flags) wxOVERRIDE;
virtual bool DoAutoCompleteCustom(wxTextCompleter *completer) wxOVERRIDE; virtual bool DoAutoCompleteCustom(wxTextCompleter *completer) wxOVERRIDE;
#if 0
// override streambuf method
#if wxHAS_TEXT_WINDOW_STREAM
int overflow(int i);
#endif // wxHAS_TEXT_WINDOW_STREAM
// stream-like insertion operators: these are always available, whether we
// were, or not, compiled with streambuf support
wxTextCtrl& operator<<(const wxString& s);
wxTextCtrl& operator<<(int i);
wxTextCtrl& operator<<(long i);
wxTextCtrl& operator<<(float f);
wxTextCtrl& operator<<(double d);
wxTextCtrl& operator<<(wxChar c);
#endif
// do the window-specific processing after processing the update event
virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) wxOVERRIDE;
virtual bool ShouldInheritColours() const wxOVERRIDE; virtual bool ShouldInheritColours() const wxOVERRIDE;
// wxWindow overrides // wxWindow overrides
@@ -214,7 +194,6 @@ protected:
// override the base class virtuals involved into geometry calculations // override the base class virtuals involved into geometry calculations
virtual wxSize DoGetBestClientSize() const wxOVERRIDE; virtual wxSize DoGetBestClientSize() const wxOVERRIDE;
virtual void DoMoveWindow(int x, int y, int width, int height) wxOVERRIDE;
virtual void RecalcBitmaps(); virtual void RecalcBitmaps();
@@ -257,9 +236,6 @@ private:
wxMenu *m_menu; wxMenu *m_menu;
#endif // wxUSE_MENUS #endif // wxUSE_MENUS
bool m_searchButtonVisible;
bool m_cancelButtonVisible;
bool m_searchBitmapUser; bool m_searchBitmapUser;
bool m_cancelBitmapUser; bool m_cancelBitmapUser;
#if wxUSE_MENUS #if wxUSE_MENUS

View File

@@ -82,19 +82,35 @@ WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
// misc macros // misc macros
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if wxUSE_GUI
#define MEANING_CHARACTER '0' #define MEANING_CHARACTER '0'
#define DEFAULT_ITEM_WIDTH 100 #define DEFAULT_ITEM_WIDTH 100
#define DEFAULT_ITEM_HEIGHT 80 #define DEFAULT_ITEM_HEIGHT 80
// Scale font to get edit control height // Return the height of a native text control corresponding to the given
//#define EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) (3*(cy)/2) // character height (as returned by GetCharHeight() or wxGetCharSize()).
#define EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) (cy+8) //
// The wxWindow parameter must be valid and used for getting the DPI.
inline int wxGetEditHeightFromCharHeight(int cy, const wxWindow* w)
{
// The value 8 here is empiric, i.e. it's not necessarily correct, but
// seems to work relatively well.
return cy + w->FromDIP(8);
}
// Compatibility macro used in the existing code. It assumes that it's called
// from a method of wxWindow-derived object.
#define EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) \
wxGetEditHeightFromCharHeight((cy), this)
// Generic subclass proc, for panel item moving/sizing and intercept // Generic subclass proc, for panel item moving/sizing and intercept
// EDIT control VK_RETURN messages // EDIT control VK_RETURN messages
extern LONG APIENTRY extern LONG APIENTRY
wxSubclassedGenericControlProc(WXHWND hWnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam); wxSubclassedGenericControlProc(WXHWND hWnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
#endif // wxUSE_GUI
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// useful macros and functions // useful macros and functions
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -178,7 +178,7 @@ void SearchCtrlWidgetsPage::CreateControl()
long style = GetAttrs().m_defaultFlags; long style = GetAttrs().m_defaultFlags;
m_srchCtrl = new wxSearchCtrl(this, -1, wxEmptyString, wxDefaultPosition, m_srchCtrl = new wxSearchCtrl(this, -1, wxEmptyString, wxDefaultPosition,
wxSize(150, -1), style); FromDIP(wxSize(150, -1)), style);
m_srchCtrl->Bind(wxEVT_SET_FOCUS, &SearchCtrlWidgetsPage::OnSetFocus, this); m_srchCtrl->Bind(wxEVT_SET_FOCUS, &SearchCtrlWidgetsPage::OnSetFocus, this);
m_srchCtrl->Bind(wxEVT_KILL_FOCUS, &SearchCtrlWidgetsPage::OnKillFocus, this); m_srchCtrl->Bind(wxEVT_KILL_FOCUS, &SearchCtrlWidgetsPage::OnKillFocus, this);

View File

@@ -28,8 +28,7 @@
#if !wxUSE_NATIVE_SEARCH_CONTROL #if !wxUSE_NATIVE_SEARCH_CONTROL
#include "wx/image.h" #include "wx/image.h"
#include "wx/utils.h"
#define WXMAX(a,b) ((a)>(b)?(a):(b))
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// constants // constants
@@ -38,7 +37,10 @@
// the margin between the text control and the search/cancel buttons // the margin between the text control and the search/cancel buttons
static const wxCoord MARGIN = 2; static const wxCoord MARGIN = 2;
#define LIGHT_STEP 160 // arguments to wxColour::ChangeLightness() for making the search/cancel
// bitmaps foreground colour, respectively
static const int SEARCH_BITMAP_LIGHTNESS = 140; // slightly lighter
static const int CANCEL_BITMAP_LIGHTNESS = 160; // a bit more lighter
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxSearchTextCtrl: text control used by search control // wxSearchTextCtrl: text control used by search control
@@ -130,7 +132,7 @@ protected:
// can't use wxBORDER_NONE to calculate a good height, in which case we just have to // can't use wxBORDER_NONE to calculate a good height, in which case we just have to
// assume a border in the code above and then subtract the space that would be taken up // assume a border in the code above and then subtract the space that would be taken up
// by a themed border (the thin blue border and the white internal border). // by a themed border (the thin blue border and the white internal border).
size.y -= 4; size.y -= FromDIP(4);
self->SetWindowStyleFlag(flags); self->SetWindowStyleFlag(flags);
@@ -282,9 +284,6 @@ void wxSearchCtrl::Init()
m_menu = NULL; m_menu = NULL;
#endif // wxUSE_MENUS #endif // wxUSE_MENUS
m_searchButtonVisible = true;
m_cancelButtonVisible = false;
m_searchBitmapUser = false; m_searchBitmapUser = false;
m_cancelBitmapUser = false; m_cancelBitmapUser = false;
#if wxUSE_MENUS #if wxUSE_MENUS
@@ -311,9 +310,6 @@ bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id,
m_searchButton = new wxSearchButton(this, m_searchButton = new wxSearchButton(this,
wxEVT_SEARCH, wxEVT_SEARCH,
m_searchBitmap); m_searchBitmap);
m_cancelButton = new wxSearchButton(this,
wxEVT_SEARCH_CANCEL,
m_cancelBitmap);
SetBackgroundColour( m_text->GetBackgroundColour() ); SetBackgroundColour( m_text->GetBackgroundColour() );
m_text->SetBackgroundColour(wxColour()); m_text->SetBackgroundColour(wxColour());
@@ -352,13 +348,14 @@ void wxSearchCtrl::SetMenu( wxMenu* menu )
if ( m_menu && !hadMenu ) if ( m_menu && !hadMenu )
{ {
m_searchButton->Show();
m_searchButton->SetBitmapLabel(m_searchMenuBitmap); m_searchButton->SetBitmapLabel(m_searchMenuBitmap);
m_searchButton->Refresh(); m_searchButton->Refresh();
} }
else if ( !m_menu && hadMenu ) else if ( !m_menu && hadMenu )
{ {
m_searchButton->SetBitmapLabel(m_searchBitmap); m_searchButton->SetBitmapLabel(m_searchBitmap);
if ( m_searchButtonVisible ) if ( m_searchButton->IsShown() )
{ {
m_searchButton->Refresh(); m_searchButton->Refresh();
} }
@@ -375,15 +372,23 @@ wxMenu* wxSearchCtrl::GetMenu()
void wxSearchCtrl::ShowSearchButton( bool show ) void wxSearchCtrl::ShowSearchButton( bool show )
{ {
if ( m_searchButtonVisible == show ) if ( show == IsSearchButtonVisible() )
{ {
// no change // no change
return; return;
} }
m_searchButtonVisible = show; if ( show )
if ( m_searchButtonVisible )
{ {
RecalcBitmaps(); RecalcBitmaps();
m_searchButton->Show();
}
else // Requested to hide it.
{
// Only hide the button if we don't need it for the menu, otherwise it
// needs to remain shown.
if ( !HasMenu() )
m_searchButton->Hide();
} }
LayoutControls(); LayoutControls();
@@ -391,25 +396,36 @@ void wxSearchCtrl::ShowSearchButton( bool show )
bool wxSearchCtrl::IsSearchButtonVisible() const bool wxSearchCtrl::IsSearchButtonVisible() const
{ {
return m_searchButtonVisible; return m_searchButton->IsShown() || HasMenu();
} }
void wxSearchCtrl::ShowCancelButton( bool show ) void wxSearchCtrl::ShowCancelButton( bool show )
{ {
if ( m_cancelButtonVisible == show ) if ( show == IsCancelButtonVisible() )
{ {
// no change // no change
return; return;
} }
m_cancelButtonVisible = show;
// This button is not shown initially, so create it on demand if necessary,
// i.e. if it's the first time we show it.
if ( !m_cancelButton )
{
m_cancelButton = new wxSearchButton(this,
wxEVT_SEARCH_CANCEL,
m_cancelBitmap);
RecalcBitmaps();
}
m_cancelButton->Show(show);
LayoutControls(); LayoutControls();
} }
bool wxSearchCtrl::IsCancelButtonVisible() const bool wxSearchCtrl::IsCancelButtonVisible() const
{ {
return m_cancelButtonVisible; return m_cancelButton && m_cancelButton->IsShown();
} }
void wxSearchCtrl::SetDescriptiveText(const wxString& text) void wxSearchCtrl::SetDescriptiveText(const wxString& text)
@@ -433,18 +449,18 @@ wxSize wxSearchCtrl::DoGetBestClientSize() const
wxSize sizeCancel(0,0); wxSize sizeCancel(0,0);
int searchMargin = 0; int searchMargin = 0;
int cancelMargin = 0; int cancelMargin = 0;
if ( m_searchButtonVisible || HasMenu() ) if ( IsSearchButtonVisible() )
{ {
sizeSearch = m_searchButton->GetBestSize(); sizeSearch = m_searchButton->GetBestSize();
searchMargin = MARGIN; searchMargin = FromDIP(MARGIN);
} }
if ( m_cancelButtonVisible ) if ( IsCancelButtonVisible() )
{ {
sizeCancel = m_cancelButton->GetBestSize(); sizeCancel = m_cancelButton->GetBestSize();
cancelMargin = MARGIN; cancelMargin = FromDIP(MARGIN);
} }
int horizontalBorder = 1 + ( sizeText.y - sizeText.y * 14 / 21 ) / 2; int horizontalBorder = FromDIP(1) + ( sizeText.y - sizeText.y * 14 / 21 ) / 2;
// buttons are square and equal to the height of the text control // buttons are square and equal to the height of the text control
int height = sizeText.y; int height = sizeText.y;
@@ -452,13 +468,6 @@ wxSize wxSearchCtrl::DoGetBestClientSize() const
height); height);
} }
void wxSearchCtrl::DoMoveWindow(int x, int y, int width, int height)
{
wxSearchCtrlBase::DoMoveWindow(x, y, width, height);
LayoutControls();
}
void wxSearchCtrl::LayoutControls() void wxSearchCtrl::LayoutControls()
{ {
if ( !m_text ) if ( !m_text )
@@ -470,7 +479,7 @@ void wxSearchCtrl::LayoutControls()
wxSize sizeText = m_text->GetBestSize(); wxSize sizeText = m_text->GetBestSize();
// make room for the search menu & clear button // make room for the search menu & clear button
int horizontalBorder = 1 + ( sizeText.y - sizeText.y * 14 / 21 ) / 2; int horizontalBorder = FromDIP(1) + ( sizeText.y - sizeText.y * 14 / 21 ) / 2;
int x = horizontalBorder; int x = horizontalBorder;
width -= horizontalBorder*2; width -= horizontalBorder*2;
if (width < 0) width = 0; if (width < 0) width = 0;
@@ -479,18 +488,16 @@ void wxSearchCtrl::LayoutControls()
wxSize sizeCancel(0,0); wxSize sizeCancel(0,0);
int searchMargin = 0; int searchMargin = 0;
int cancelMargin = 0; int cancelMargin = 0;
if ( m_searchButtonVisible || HasMenu() ) if ( IsSearchButtonVisible() )
{ {
sizeSearch = m_searchButton->GetBestSize(); sizeSearch = m_searchButton->GetBestSize();
searchMargin = MARGIN; searchMargin = FromDIP(MARGIN);
} }
if ( m_cancelButtonVisible ) if ( IsCancelButtonVisible() )
{ {
sizeCancel = m_cancelButton->GetBestSize(); sizeCancel = m_cancelButton->GetBestSize();
cancelMargin = MARGIN; cancelMargin = FromDIP(MARGIN);
} }
m_searchButton->Show( m_searchButtonVisible || HasMenu() );
m_cancelButton->Show( m_cancelButtonVisible );
if ( sizeSearch.x + sizeCancel.x > width ) if ( sizeSearch.x + sizeCancel.x > width )
{ {
@@ -499,13 +506,13 @@ void wxSearchCtrl::LayoutControls()
searchMargin = 0; searchMargin = 0;
cancelMargin = 0; cancelMargin = 0;
} }
wxCoord textWidth = width - sizeSearch.x - sizeCancel.x - searchMargin - cancelMargin - 1; wxCoord textWidth = width - sizeSearch.x - sizeCancel.x - searchMargin - cancelMargin - FromDIP(1);
if (textWidth < 0) textWidth = 0; if (textWidth < 0) textWidth = 0;
// position the subcontrols inside the client area // position the subcontrols inside the client area
m_searchButton->SetSize(x, (height - sizeSearch.y) / 2, m_searchButton->SetSize(x, (height - sizeSearch.y) / 2,
sizeSearch.x, height); sizeSearch.x, sizeSearch.y);
x += sizeSearch.x; x += sizeSearch.x;
x += searchMargin; x += searchMargin;
@@ -514,7 +521,7 @@ void wxSearchCtrl::LayoutControls()
// of the white border that's part of the theme border. We can also remove a pixel from // of the white border that's part of the theme border. We can also remove a pixel from
// the height to fit the text control in, because the padding in EDIT_HEIGHT_FROM_CHAR_HEIGHT // the height to fit the text control in, because the padding in EDIT_HEIGHT_FROM_CHAR_HEIGHT
// is already generous. // is already generous.
int textY = 1; int textY = FromDIP(2);
#else #else
int textY = 0; int textY = 0;
#endif #endif
@@ -523,8 +530,11 @@ void wxSearchCtrl::LayoutControls()
x += textWidth; x += textWidth;
x += cancelMargin; x += cancelMargin;
m_cancelButton->SetSize(x, (height - sizeCancel.y) / 2, if ( m_cancelButton )
sizeCancel.x, height); {
m_cancelButton->SetSize(x, (height - sizeCancel.y) / 2,
sizeCancel.x, height);
}
} }
wxWindowList wxSearchCtrl::GetCompositeWindowParts() const wxWindowList wxSearchCtrl::GetCompositeWindowParts() const
@@ -883,23 +893,6 @@ void wxSearchCtrl::SetCancelBitmap( const wxBitmap& bitmap )
} }
} }
#if 0
// override streambuf method
#if wxHAS_TEXT_WINDOW_STREAM
int overflow(int i);
#endif // wxHAS_TEXT_WINDOW_STREAM
// stream-like insertion operators: these are always available, whether we
// were, or not, compiled with streambuf support
wxTextCtrl& operator<<(const wxString& s);
wxTextCtrl& operator<<(int i);
wxTextCtrl& operator<<(long i);
wxTextCtrl& operator<<(float f);
wxTextCtrl& operator<<(double d);
wxTextCtrl& operator<<(const wxChar c);
#endif
// Note that overriding DoSetValue() is currently insufficient because the base // Note that overriding DoSetValue() is currently insufficient because the base
// class ChangeValue() only updates m_hintData of this object (which is null // class ChangeValue() only updates m_hintData of this object (which is null
// anyhow), instead of updating m_text->m_hintData, see #16998. // anyhow), instead of updating m_text->m_hintData, see #16998.
@@ -923,12 +916,6 @@ bool wxSearchCtrl::DoSaveFile(const wxString& file, int fileType)
return m_text->DoSaveFile(file, fileType); return m_text->DoSaveFile(file, fileType);
} }
// do the window-specific processing after processing the update event
void wxSearchCtrl::DoUpdateWindowUI(wxUpdateUIEvent& event)
{
wxSearchCtrlBase::DoUpdateWindowUI(event);
}
bool wxSearchCtrl::ShouldInheritColours() const bool wxSearchCtrl::ShouldInheritColours() const
{ {
return true; return true;
@@ -976,7 +963,7 @@ static void RescaleBitmap(wxBitmap& bmp, const wxSize& sizeNeeded)
wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop ) wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop )
{ {
wxColour bg = GetBackgroundColour(); wxColour bg = GetBackgroundColour();
wxColour fg = GetForegroundColour().ChangeLightness(LIGHT_STEP-20); wxColour fg = GetForegroundColour().ChangeLightness(SEARCH_BITMAP_LIGHTNESS);
//=============================================================================== //===============================================================================
// begin drawing code // begin drawing code
@@ -1030,7 +1017,7 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop )
mem.SetPen( wxPen(fg) ); mem.SetPen( wxPen(fg) );
mem.SetBrush( wxBrush(fg) ); mem.SetBrush( wxBrush(fg) );
int handleCornerShift = penWidth * 707 / 1000 / 2; // 707 / 1000 = 0.707 = 1/sqrt(2); int handleCornerShift = penWidth * 707 / 1000 / 2; // 707 / 1000 = 0.707 = 1/sqrt(2);
handleCornerShift = WXMAX( handleCornerShift, 1 ); handleCornerShift = wxMax( handleCornerShift, 1 );
int handleBase = 4 * x / 20; int handleBase = 4 * x / 20;
int handleLength = 2*handleBase+1; int handleLength = 2*handleBase+1;
wxPoint handlePolygon[] = wxPoint handlePolygon[] =
@@ -1079,7 +1066,7 @@ wxBitmap wxSearchCtrl::RenderSearchBitmap( int x, int y, bool renderDrop )
wxBitmap wxSearchCtrl::RenderCancelBitmap( int x, int y ) wxBitmap wxSearchCtrl::RenderCancelBitmap( int x, int y )
{ {
wxColour bg = GetBackgroundColour(); wxColour bg = GetBackgroundColour();
wxColour fg = GetForegroundColour().ChangeLightness(LIGHT_STEP); wxColour fg = GetForegroundColour().ChangeLightness(CANCEL_BITMAP_LIGHTNESS);
//=============================================================================== //===============================================================================
// begin drawing code // begin drawing code
@@ -1129,7 +1116,7 @@ wxBitmap wxSearchCtrl::RenderCancelBitmap( int x, int y )
mem.SetPen( wxPen(bg) ); mem.SetPen( wxPen(bg) );
mem.SetBrush( wxBrush(bg) ); mem.SetBrush( wxBrush(bg) );
int handleCornerShift = penWidth/2; int handleCornerShift = penWidth/2;
handleCornerShift = WXMAX( handleCornerShift, 1 ); handleCornerShift = wxMax( handleCornerShift, 1 );
wxPoint handlePolygon[] = wxPoint handlePolygon[] =
{ {
wxPoint(-handleCornerShift,+handleCornerShift), wxPoint(-handleCornerShift,+handleCornerShift),
@@ -1167,7 +1154,7 @@ void wxSearchCtrl::RecalcBitmaps()
} }
wxSize sizeText = m_text->GetBestSize(); wxSize sizeText = m_text->GetBestSize();
int bitmapHeight = sizeText.y - 4; int bitmapHeight = sizeText.y - FromDIP(4);
int bitmapWidth = sizeText.y * 20 / 14; int bitmapWidth = sizeText.y * 20 / 14;
if ( !m_searchBitmapUser ) if ( !m_searchBitmapUser )
@@ -1206,7 +1193,7 @@ void wxSearchCtrl::RecalcBitmaps()
} }
#endif // wxUSE_MENUS #endif // wxUSE_MENUS
if ( !m_cancelBitmapUser ) if ( m_cancelButton && !m_cancelBitmapUser )
{ {
if ( if (
!m_cancelBitmap.IsOk() || !m_cancelBitmap.IsOk() ||

View File

@@ -441,7 +441,7 @@ wxSize wxMSWButton::IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size
// so make them as high as it. // so make them as high as it.
int yText; int yText;
wxGetCharSize(GetHwndOf(btn), NULL, &yText, btn->GetFont()); wxGetCharSize(GetHwndOf(btn), NULL, &yText, btn->GetFont());
yText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(yText); yText = wxGetEditHeightFromCharHeight(yText, btn);
sizeBtn.IncTo(wxSize(-1, yText)); sizeBtn.IncTo(wxSize(-1, yText));
} }

View File

@@ -726,7 +726,7 @@ int wxSpinCtrl::GetOverlap() const
wxSize wxSpinCtrl::DoGetBestSize() const wxSize wxSpinCtrl::DoGetBestSize() const
{ {
return DoGetSizeFromTextSize(DEFAULT_ITEM_WIDTH); return DoGetSizeFromTextSize(FromDIP(DEFAULT_ITEM_WIDTH));
} }
wxSize wxSpinCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const wxSize wxSpinCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const

View File

@@ -2429,7 +2429,7 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
int cx, cy; int cx, cy;
wxGetCharSize(GetHWND(), &cx, &cy, GetFont()); wxGetCharSize(GetHWND(), &cx, &cy, GetFont());
DWORD wText = 1; DWORD wText = FromDIP(1);
::SystemParametersInfo(SPI_GETCARETWIDTH, 0, &wText, 0); ::SystemParametersInfo(SPI_GETCARETWIDTH, 0, &wText, 0);
wText += xlen; wText += xlen;
@@ -2464,7 +2464,7 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
// stand out). // stand out).
if ( !HasFlag(wxBORDER_NONE) ) if ( !HasFlag(wxBORDER_NONE) )
{ {
wText += 9; // borders and inner margins wText += FromDIP(9); // borders and inner margins
// we have to add the adjustments for the control height only once, not // we have to add the adjustments for the control height only once, not
// once per line, so do it after multiplication above // once per line, so do it after multiplication above