Merge branch 'gtk-spin-width-from-text'
Fixes for wxSpinCtrl::GetSizeFromTextSize() and best size in wxGTK. Closes #18568. See https://github.com/wxWidgets/wxWidgets/pull/1645
This commit is contained in:
@@ -71,7 +71,9 @@ protected:
|
||||
void GtkDisableEvents() const;
|
||||
void GtkEnableEvents() const;
|
||||
|
||||
virtual wxSize DoGetBestSize() const wxOVERRIDE;
|
||||
// Update the number of digits used to match our range (and base).
|
||||
void GtkSetEntryWidth();
|
||||
|
||||
virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const wxOVERRIDE;
|
||||
virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE;
|
||||
|
||||
|
31
include/wx/private/spinctrl.h
Normal file
31
include/wx/private/spinctrl.h
Normal file
@@ -0,0 +1,31 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/spinctrl.h
|
||||
// Purpose: Private functions used in wxSpinCtrl implementation.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2019-11-13
|
||||
// Copyright: (c) 2019 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PRIVATE_SPINCTRL_H_
|
||||
#define _WX_PRIVATE_SPINCTRL_H_
|
||||
|
||||
namespace wxSpinCtrlImpl
|
||||
{
|
||||
|
||||
// This is an internal helper function currently used by all ports: return the
|
||||
// string containing hexadecimal representation of the given number.
|
||||
extern wxString FormatAsHex(long val, long maxVal);
|
||||
|
||||
// Another helper returning the maximum length of a string representing a value
|
||||
// valid in the given control.
|
||||
extern int GetMaxValueLength(int minVal, int maxVal, int base);
|
||||
|
||||
// The helper function to determine the best size for the given control.
|
||||
// We can't implement this function in the wxSpinCtrlBase because MSW implementation
|
||||
// of wxSpinCtrl is derived from wxSpinButton but uses the same algorithm.
|
||||
extern wxSize GetBestSize(const wxControl* spin, int minVal, int maxVal, int base);
|
||||
|
||||
} // namespace wxSpinCtrlImpl
|
||||
|
||||
#endif // _WX_PRIVATE_SPINCTRL_H_
|
@@ -136,19 +136,6 @@ typedef void (wxEvtHandler::*wxSpinDoubleEventFunction)(wxSpinDoubleEvent&);
|
||||
#if !defined(wxHAS_NATIVE_SPINCTRL) || !defined(wxHAS_NATIVE_SPINCTRLDOUBLE)
|
||||
#include "wx/generic/spinctlg.h"
|
||||
#endif
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
// This is an internal helper function currently used by all ports: return the
|
||||
// string containing hexadecimal representation of the given number.
|
||||
extern wxString wxSpinCtrlFormatAsHex(long val, long maxVal);
|
||||
|
||||
// The helper function to determine the best size for the given control.
|
||||
// We can't implement this function in the wxSpinCtrlBase because MSW implementation
|
||||
// of wxSpinCtrl is derived from wxSpinButton but uses the same algorithm.
|
||||
extern wxSize wxSpinCtrlGetBestSize(const wxControl* spin, int minVal, int maxVal, int base);
|
||||
|
||||
} // namespace wxPrivate
|
||||
|
||||
// old wxEVT_COMMAND_* constants
|
||||
#define wxEVT_COMMAND_SPINCTRL_UPDATED wxEVT_SPINCTRL
|
||||
|
@@ -25,6 +25,8 @@
|
||||
#include "wx/spinbutt.h"
|
||||
#include "wx/spinctrl.h"
|
||||
|
||||
#include "wx/private/spinctrl.h"
|
||||
|
||||
#if wxUSE_SPINCTRL
|
||||
|
||||
wxDEFINE_EVENT(wxEVT_SPINCTRL, wxSpinEvent);
|
||||
@@ -102,7 +104,9 @@ wxCONSTRUCTOR_6( wxSpinCtrl, wxWindow*, Parent, wxWindowID, Id, \
|
||||
wxSize, Size, long, WindowStyle )
|
||||
|
||||
|
||||
wxString wxPrivate::wxSpinCtrlFormatAsHex(long val, long maxVal)
|
||||
using namespace wxSpinCtrlImpl;
|
||||
|
||||
wxString wxSpinCtrlImpl::FormatAsHex(long val, long maxVal)
|
||||
{
|
||||
// We format the value like this is for compatibility with (native
|
||||
// behaviour of) wxMSW
|
||||
@@ -115,16 +119,21 @@ wxString wxPrivate::wxSpinCtrlFormatAsHex(long val, long maxVal)
|
||||
return text;
|
||||
}
|
||||
|
||||
wxSize wxPrivate::wxSpinCtrlGetBestSize(const wxControl* spin,
|
||||
int minVal, int maxVal, int base)
|
||||
int wxSpinCtrlImpl::GetMaxValueLength(int minVal, int maxVal, int base)
|
||||
{
|
||||
const int lenMin = (base == 16 ?
|
||||
wxSpinCtrlFormatAsHex(minVal, maxVal) :
|
||||
FormatAsHex(minVal, maxVal) :
|
||||
wxString::Format("%d", minVal)).length();
|
||||
const int lenMax = (base == 16 ?
|
||||
wxSpinCtrlFormatAsHex(maxVal, maxVal) :
|
||||
FormatAsHex(maxVal, maxVal) :
|
||||
wxString::Format("%d", maxVal)).length();
|
||||
const wxString largestString('8', wxMax(lenMin, lenMax));
|
||||
return wxMax(lenMin, lenMax);
|
||||
}
|
||||
|
||||
wxSize wxSpinCtrlImpl::GetBestSize(const wxControl* spin,
|
||||
int minVal, int maxVal, int base)
|
||||
{
|
||||
const wxString largestString('8', GetMaxValueLength(minVal, maxVal, base));
|
||||
return spin->GetSizeFromText(largestString);
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,8 @@
|
||||
|
||||
#if wxUSE_SPINCTRL
|
||||
|
||||
#include "wx/private/spinctrl.h"
|
||||
|
||||
wxIMPLEMENT_DYNAMIC_CLASS(wxSpinDoubleEvent, wxNotifyEvent);
|
||||
|
||||
// There are port-specific versions for the wxSpinCtrl, so exclude the
|
||||
@@ -654,8 +656,7 @@ wxString wxSpinCtrl::DoValueToText(double val)
|
||||
switch ( GetBase() )
|
||||
{
|
||||
case 16:
|
||||
return wxPrivate::wxSpinCtrlFormatAsHex(static_cast<long>(val),
|
||||
GetMax());
|
||||
return wxSpinCtrlImpl::FormatAsHex(static_cast<long>(val), GetMax());
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxS("Unsupported spin control base") );
|
||||
|
@@ -16,10 +16,13 @@
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/textctrl.h" // for wxEVT_TEXT
|
||||
#include "wx/math.h" // wxRound()
|
||||
#include "wx/utils.h"
|
||||
#include "wx/wxcrtvararg.h"
|
||||
#endif
|
||||
|
||||
#include "wx/private/spinctrl.h"
|
||||
|
||||
#include "wx/gtk/private.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -135,6 +138,8 @@ bool wxSpinCtrlGTKBase::Create(wxWindow *parent, wxWindowID id,
|
||||
|
||||
gtk_entry_set_alignment(GTK_ENTRY(m_widget), align);
|
||||
|
||||
GtkSetEntryWidth();
|
||||
|
||||
gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(m_widget),
|
||||
(int)(m_windowStyle & wxSP_WRAP) );
|
||||
|
||||
@@ -269,6 +274,8 @@ void wxSpinCtrlGTKBase::DoSetRange(double minVal, double maxVal)
|
||||
gtk_spin_button_set_range( GTK_SPIN_BUTTON(m_widget), minVal, maxVal);
|
||||
|
||||
InvalidateBestSize();
|
||||
|
||||
GtkSetEntryWidth();
|
||||
}
|
||||
|
||||
void wxSpinCtrlGTKBase::DoSetIncrement(double inc)
|
||||
@@ -353,38 +360,35 @@ GdkWindow *wxSpinCtrlGTKBase::GTKGetWindow(wxArrayGdkWindows& windows) const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxSize wxSpinCtrlGTKBase::DoGetBestSize() const
|
||||
void wxSpinCtrlGTKBase::GtkSetEntryWidth()
|
||||
{
|
||||
const int minVal = static_cast<int>(DoGetMin());
|
||||
const int maxVal = static_cast<int>(DoGetMax());
|
||||
return wxPrivate::wxSpinCtrlGetBestSize(this, minVal, maxVal, GetBase());
|
||||
|
||||
gtk_entry_set_width_chars
|
||||
(
|
||||
GTK_ENTRY(m_widget),
|
||||
wxSpinCtrlImpl::GetMaxValueLength(minVal, maxVal, GetBase())
|
||||
);
|
||||
}
|
||||
|
||||
wxSize wxSpinCtrlGTKBase::DoGetSizeFromTextSize(int xlen, int ylen) const
|
||||
{
|
||||
wxASSERT_MSG( m_widget, wxS("GetSizeFromTextSize called before creation") );
|
||||
|
||||
// This is a bit stupid as we typically compute xlen by measuring some
|
||||
// string of digits in the first place, but there doesn't seem to be
|
||||
// anything better to do (unless we add some GetSizeFromNumberOfDigits()).
|
||||
const double widthDigit = GetTextExtent("0123456789").GetWidth() / 10.0;
|
||||
const int numDigits = wxRound(xlen / widthDigit);
|
||||
|
||||
const gint widthChars = gtk_entry_get_width_chars(GTK_ENTRY(m_widget));
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(m_widget), 0);
|
||||
#if GTK_CHECK_VERSION(3,12,0)
|
||||
gint maxWidthChars = 0;
|
||||
if ( gtk_check_version(3,12,0) == NULL )
|
||||
{
|
||||
maxWidthChars = gtk_entry_get_max_width_chars(GTK_ENTRY(m_widget));
|
||||
gtk_entry_set_max_width_chars(GTK_ENTRY(m_widget), 0);
|
||||
}
|
||||
#endif // GTK+ 3.12+
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(m_widget), numDigits);
|
||||
|
||||
wxSize totalS = GTKGetPreferredSize(m_widget);
|
||||
wxSize tsize = GTKGetPreferredSize(m_widget);
|
||||
|
||||
#if GTK_CHECK_VERSION(3,12,0)
|
||||
if ( gtk_check_version(3,12,0) == NULL )
|
||||
gtk_entry_set_max_width_chars(GTK_ENTRY(m_widget), maxWidthChars);
|
||||
#endif // GTK+ 3.12+
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(m_widget), widthChars);
|
||||
|
||||
wxSize tsize(xlen + totalS.x, totalS.y);
|
||||
|
||||
// Check if the user requested a non-standard height.
|
||||
if ( ylen > 0 )
|
||||
tsize.IncBy(0, ylen - GetCharHeight());
|
||||
@@ -431,7 +435,7 @@ wx_gtk_spin_output(GtkSpinButton* spin, wxSpinCtrl* win)
|
||||
gtk_entry_set_text
|
||||
(
|
||||
GTK_ENTRY(spin),
|
||||
wxPrivate::wxSpinCtrlFormatAsHex(val, win->GetMax()).utf8_str()
|
||||
wxSpinCtrlImpl::FormatAsHex(val, win->GetMax()).utf8_str()
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
@@ -474,6 +478,8 @@ bool wxSpinCtrl::SetBase(int base)
|
||||
|
||||
InvalidateBestSize();
|
||||
|
||||
GtkSetEntryWidth();
|
||||
|
||||
// Update the displayed text after changing the base it uses.
|
||||
SetValue(GetValue());
|
||||
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#include "wx/crt.h"
|
||||
#endif
|
||||
|
||||
#include "wx/private/spinctrl.h"
|
||||
|
||||
#include "wx/gtk1/private.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -69,7 +71,7 @@ wx_gtk_spin_output(GtkSpinButton* spin, wxSpinCtrl* win)
|
||||
gtk_entry_set_text
|
||||
(
|
||||
GTK_ENTRY(spin),
|
||||
wxPrivate::wxSpinCtrlFormatAsHex(val, win->GetMax()).utf8_str()
|
||||
wxSpinCtrlImpl::FormatAsHex(val, win->GetMax()).utf8_str()
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
|
@@ -35,6 +35,8 @@
|
||||
#include "wx/wxcrtvararg.h"
|
||||
#endif
|
||||
|
||||
#include "wx/private/spinctrl.h"
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/private/winstyle.h"
|
||||
|
||||
@@ -474,7 +476,7 @@ void wxSpinCtrl::SetValue(int val)
|
||||
(text[1] != 'x' && text[1] != 'X')) )
|
||||
{
|
||||
::SetWindowText(GetBuddyHwnd(),
|
||||
wxPrivate::wxSpinCtrlFormatAsHex(val, m_max).t_str());
|
||||
wxSpinCtrlImpl::FormatAsHex(val, m_max).t_str());
|
||||
}
|
||||
|
||||
m_oldValue = GetValue();
|
||||
@@ -741,7 +743,7 @@ int wxSpinCtrl::GetOverlap() const
|
||||
|
||||
wxSize wxSpinCtrl::DoGetBestSize() const
|
||||
{
|
||||
return wxPrivate::wxSpinCtrlGetBestSize(this, GetMin(), GetMax(), GetBase());
|
||||
return wxSpinCtrlImpl::GetBestSize(this, GetMin(), GetMax(), GetBase());
|
||||
}
|
||||
|
||||
wxSize wxSpinCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const
|
||||
|
Reference in New Issue
Block a user