X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/327788acc5e4915df4e9e97db7fb08a4c4a00cdd..4813bb8d72d4e6821e031f2b19baaa338b714d39:/src/mac/carbon/spinctrl.cpp diff --git a/src/mac/carbon/spinctrl.cpp b/src/mac/carbon/spinctrl.cpp index a083c8a3c5..47c2332911 100644 --- a/src/mac/carbon/spinctrl.cpp +++ b/src/mac/carbon/spinctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: spinbutt.cpp +// Name: src/mac/carbon/spinbutt.cpp // Purpose: wxSpinCtrl // Author: Robert // Modified by: Mark Newsam (Based on GTK file) @@ -8,30 +8,28 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "spinctlg.h" -#endif - -#include "wx/defs.h" - -#ifndef WX_PRECOMP - #include "wx/textctrl.h" -#endif //WX_PRECOMP +#include "wx/wxprec.h" #if wxUSE_SPINCTRL -#include "wx/spinbutt.h" #include "wx/spinctrl.h" +#ifndef WX_PRECOMP + #include "wx/textctrl.h" + #include "wx/containr.h" +#endif -#include "wx/spinctrl.h" +#include "wx/spinbutt.h" // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- +// the focus rect around a text may have 4 pixels in each direction +// we handle these problems right now in an extended vis region of a window +static const wxCoord TEXTBORDER = 4 ; // the margin between the text control and the spin -static const wxCoord MARGIN = 2; +static const wxCoord MARGIN = 8 - TEXTBORDER; // ---------------------------------------------------------------------------- // wxSpinCtrlText: text control used by spin control @@ -41,32 +39,89 @@ class wxSpinCtrlText : public wxTextCtrl { public: wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value) - : wxTextCtrl(spin , -1, value) + : wxTextCtrl(spin , wxID_ANY, value, wxDefaultPosition, wxSize(40, wxDefaultCoord)) { m_spin = spin; + + // remove the default minsize, the spinctrl will have one instead + SetMinSize(wxDefaultSize); + } + + bool ProcessEvent(wxEvent &event) + { + // Hand button down events to wxSpinCtrl. Doesn't work. + if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event )) + return true; + + return wxTextCtrl::ProcessEvent( event ); } protected: + void OnKillFocus(wxFocusEvent& WXUNUSED(event)) + { + long l; + if ( !GetValue().ToLong(&l) ) + { + // not a number at all + return; + } + + // is within range + if (l < m_spin->GetMin()) + l = m_spin->GetMin(); + if (l > m_spin->GetMax()) + l = m_spin->GetMax(); + + // Update text control + wxString str; + str.Printf( wxT("%d"), (int)l ); + if (str != GetValue()) + SetValue( str ); + + if (l != m_spin->m_oldValue) + { + // set value in spin button + // does that trigger an event? + m_spin->m_btn->SetValue( l ); + + // if not + wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId()); + event.SetEventObject(m_spin); + event.SetInt(l); + m_spin->HandleWindowEvent(event); + + m_spin->m_oldValue = l; + } + } + void OnTextChange(wxCommandEvent& event) { int val; if ( m_spin->GetTextValue(&val) ) { m_spin->GetSpinButton()->SetValue(val); + + // If we're already processing a text update from m_spin, + // don't send it again, since we could end up recursing + // infinitely. + if (event.GetId() == m_spin->GetId()) + { + event.Skip(); + return; + } + + // Send event that the text was manually changed + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_spin->GetId()); + event.SetEventObject(m_spin); + event.SetString(m_spin->GetText()->GetValue()); + event.SetInt(val); + + m_spin->HandleWindowEvent(event); } event.Skip(); } - bool ProcessEvent(wxEvent &event) - { - // Hand button down events to wxSpinCtrl. Doesn't work. - if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event )) - return TRUE; - - return wxTextCtrl::ProcessEvent( event ); - } - private: wxSpinCtrl *m_spin; @@ -74,7 +129,8 @@ private: }; BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl) - EVT_TEXT(-1, wxSpinCtrlText::OnTextChange) + EVT_TEXT(wxID_ANY, wxSpinCtrlText::OnTextChange) + EVT_KILL_FOCUS( wxSpinCtrlText::OnKillFocus) END_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -88,25 +144,31 @@ public: : wxSpinButton(spin ) { m_spin = spin; - SetWindowStyle(style | wxSP_VERTICAL); + + // TODO: The spin button gets truncated a little bit due to size + // differences so change it's default size a bit. SMALL still gets a + // bit truncated, but MINI seems to be too small... Readdress this + // when the textctrl issues are all sorted out. + //SetWindowVariant(wxWINDOW_VARIANT_SMALL); + + // remove the default minsize, the spinctrl will have one instead + SetMinSize(wxDefaultSize); } protected: void OnSpinButton(wxSpinEvent& eventSpin) { -#if defined(__WXMAC__) || defined(__WXMOTIF__) - m_spin->SetTextValue(eventSpin.GetPosition()); + int pos = eventSpin.GetPosition(); + m_spin->SetTextValue(pos); - wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId()); - event.SetEventObject(m_spin); - event.SetInt(eventSpin.GetPosition()); + wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId()); + event.SetEventObject(m_spin); + event.SetInt(pos); - m_spin->GetEventHandler()->ProcessEvent(event); -#else - m_spin->SetTextValue(eventSpin.GetPosition()); - eventSpin.Skip(); -#endif + m_spin->HandleWindowEvent(event); + + m_spin->m_oldValue = pos; } private: @@ -116,11 +178,18 @@ private: }; BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton) - EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton) + EVT_SPIN(wxID_ANY, wxSpinCtrlButton::OnSpinButton) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl) - + +BEGIN_EVENT_TABLE(wxSpinCtrl, wxControl) + WX_EVENT_TABLE_CONTROL_CONTAINER(wxSpinCtrl) +END_EVENT_TABLE() + +WX_DELEGATE_TO_CONTROL_CONTAINER(wxSpinCtrl, wxControl) + + // ============================================================================ // implementation // ============================================================================ @@ -133,6 +202,7 @@ void wxSpinCtrl::Init() { m_text = NULL; m_btn = NULL; + WX_INIT_CONTROL_CONTAINER(); } bool wxSpinCtrl::Create(wxWindow *parent, @@ -146,10 +216,11 @@ bool wxSpinCtrl::Create(wxWindow *parent, int initial, const wxString& name) { - if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style, + m_macIsUserPane = true; + if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) { - return FALSE; + return false; } // the string value overrides the numeric one (for backwards compatibility @@ -169,13 +240,25 @@ bool wxSpinCtrl::Create(wxWindow *parent, m_btn->SetRange(min, max); m_btn->SetValue(initial); + // make it different + m_oldValue = GetMin()-1; - if ( size.y == -1 ) { - csize.y = m_text->GetSize().y ; + if ( size.x == wxDefaultCoord ){ + csize.x = m_text->GetSize().x + MARGIN + m_btn->GetSize().x ; } - DoSetSize(pos.x , pos.y , csize.x, csize.y); - return TRUE; + if ( size.y == wxDefaultCoord ) { + csize.y = m_text->GetSize().y + 2 * TEXTBORDER ; //allow for text border highlights + if ( m_btn->GetSize().y > csize.y ) + csize.y = m_btn->GetSize().y ; + } + + //SetSize(csize); + + //MacPostControlCreate(pos, csize); + SetInitialSize(csize); + + return true; } wxSpinCtrl::~wxSpinCtrl() @@ -195,22 +278,36 @@ wxSpinCtrl::~wxSpinCtrl() wxSize wxSpinCtrl::DoGetBestSize() const { + if (!m_btn || !m_text) + return GetSize(); + wxSize sizeBtn = m_btn->GetBestSize(), sizeText = m_text->GetBestSize(); - return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y); + sizeText.y += 2 * TEXTBORDER ; + sizeText.x += 2 * TEXTBORDER ; + + int height; + if (sizeText.y > sizeBtn.y) + height = sizeText.y; + else + height = sizeBtn.y; + + return wxSize(sizeBtn.x + sizeText.x + MARGIN, height ); } void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height) { - wxControl::DoMoveWindow(x, y, width, height); - // position the subcontrols inside the client area wxSize sizeBtn = m_btn->GetSize(); + wxSize sizeText = m_text->GetSize(); + + wxControl::DoMoveWindow(x, y, width, height); + + wxCoord wText = width - sizeBtn.x - MARGIN - 2 * TEXTBORDER; - wxCoord wText = width - sizeBtn.x; - m_text->SetSize(0, 0, wText, height); - m_btn->SetSize(0 + wText + MARGIN, 0, -1, -1); + m_text->SetSize(TEXTBORDER, (height - sizeText.y) / 2, wText, -1); + m_btn->SetSize(0 + wText + MARGIN + 2 * TEXTBORDER , (height - sizeBtn.y) / 2 , -1, -1 ); } // ---------------------------------------------------------------------------- @@ -220,15 +317,15 @@ void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height) bool wxSpinCtrl::Enable(bool enable) { if ( !wxControl::Enable(enable) ) - return FALSE; - return TRUE; + return false; + return true; } bool wxSpinCtrl::Show(bool show) { if ( !wxControl::Show(show) ) - return FALSE; - return TRUE; + return false; + return true; } // ---------------------------------------------------------------------------- @@ -241,18 +338,18 @@ bool wxSpinCtrl::GetTextValue(int *val) const if ( !m_text->GetValue().ToLong(&l) ) { // not a number at all - return FALSE; + return false; } if ( l < GetMin() || l > GetMax() ) { // out of range - return FALSE; + return false; } *val = l; - return TRUE; + return true; } int wxSpinCtrl::GetValue() const @@ -294,6 +391,7 @@ void wxSpinCtrl::SetValue(int val) SetTextValue(val); m_btn->SetValue(val); + m_oldValue = val; } void wxSpinCtrl::SetValue(const wxString& text) @@ -319,4 +417,15 @@ void wxSpinCtrl::SetRange(int min, int max) m_btn->SetRange(min, max); } +void wxSpinCtrl::SetSelection(long from, long to) +{ + // if from and to are both -1, it means (in wxWidgets) that all text should + // be selected + if ( (from == -1) && (to == -1) ) + { + from = 0; + } + m_text->SetSelection(from, to); +} + #endif // wxUSE_SPINCTRL