diff --git a/TODO b/TODO index a29b8bb5d9..35e2fb8a40 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,10 @@ TODO ---------------------------------------------------------------------------- +samples: + + add SetString button to lboxtest + wxTextCtrl * display corrupted when typing text in quickly @@ -23,6 +27,8 @@ All MSW + scrollbar behaves strangely in log lbox with many strings + GTK * listbox scrolling leaves unpainted areas diff --git a/include/wx/listbox.h b/include/wx/listbox.h index f96cdb95ec..f5e6b7d481 100644 --- a/include/wx/listbox.h +++ b/include/wx/listbox.h @@ -74,11 +74,19 @@ public: // GetSelection which only works for listboxes with single selection) virtual int GetSelections(wxArrayInt& aSelections) const = 0; - // Set the specified item at the first visible item or scroll to max + // set the specified item at the first visible item or scroll to max // range. void SetFirstItem(int n) { DoSetFirstItem(n); } void SetFirstItem(const wxString& s); + // ensures that the given item is visible scrolling the listbox if + // necessary + virtual void EnsureVisible(int n); + + // a combination of Append() and EnsureVisible(): appends the item to the + // listbox and ensures that it is visible i.e. not scrolled out of view + void AppendAndEnsureVisible(const wxString& s); + // return TRUE if the listbox allows multiple selection bool HasMultipleSelection() const { diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index a68a43266b..94cba3b362 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -134,8 +134,8 @@ public: // select or unselect the specified or current (if -1) item void Select(bool sel = TRUE, int item = -1); - // ensure that the current item is visible by scrolling it into view - void EnsureVisible(); + // ensure that the given item is visible by scrolling it into view + virtual void EnsureVisible(int n); // find the first item after the current one which starts with the given // string and make it the current one, return TRUE if the current item @@ -175,7 +175,6 @@ protected: void Init(); // event handlers - void OnChar(wxKeyEvent& event); void OnIdle(wxIdleEvent& event); void OnSize(wxSizeEvent& event); @@ -202,6 +201,9 @@ protected: virtual void DoDrawRange(wxControlRenderer *renderer, int itemFirst, int itemLast); + // update the scrollbars and then ensure that the item is visible + void DoEnsureVisible(int n); + // mark horz scrollbar for updating void RefreshHorzScrollbar(); diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 9d97294885..d7c2c34607 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -262,6 +262,12 @@ protected: const wxSize& sizeArrow); static wxCoord StandardScrollBarSize(const wxScrollBar *scrollbar, const wxSize& sizeArrow); + static void StandardScrollBarThumbSize(wxCoord lenBar, + int thumbPos, + int thumbSize, + int range, + wxCoord *thumbStart, + wxCoord *thumbEnd); }; // ---------------------------------------------------------------------------- diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp index 2258bc4f67..39e70a027c 100644 --- a/src/common/lboxcmn.cpp +++ b/src/common/lboxcmn.cpp @@ -115,6 +115,10 @@ void wxListBoxBase::Command(wxCommandEvent& event) (void)ProcessEvent(event); } +// ---------------------------------------------------------------------------- +// SetFirstItem() and such +// ---------------------------------------------------------------------------- + void wxListBoxBase::SetFirstItem(const wxString& s) { int n = FindString(s); @@ -124,4 +128,16 @@ void wxListBoxBase::SetFirstItem(const wxString& s) DoSetFirstItem(n); } +void wxListBoxBase::AppendAndEnsureVisible(const wxString& s) +{ + Append(s); + EnsureVisible(GetCount() - 1); +} + +void wxListBoxBase::EnsureVisible(int WXUNUSED(n)) +{ + // the base class version does nothing (the only alternative would be to + // call SetFirstItem() but this is probably even more stupid) +} + #endif // wxUSE_LISTBOX diff --git a/src/msw/window.cpp b/src/msw/window.cpp index cbe563acfe..41930ec451 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1507,6 +1507,8 @@ long wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) { + // wxUniversal implements tab traversal itself +#ifndef __WXUNIVERSAL__ if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) { // intercept dialog navigation keys @@ -1672,6 +1674,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) return TRUE; } } +#endif // __WXUNIVERSAL__ #if wxUSE_TOOLTIPS if ( m_tooltip ) @@ -2425,8 +2428,15 @@ bool wxWindowMSW::MSWCreate(int id, if ( style & WS_CHILD ) { controlId = id; - // all child windows should clip their siblings - // style |= /* WS_CLIPSIBLINGS */ ; + +#if 0 // def __WXUNIVERSAL__ + // all child windows should clip their siblings except those which + // contain other controls + if ( !wxDynamicCast(this, wxStaticBox) ) + { + style |= WS_CLIPSIBLINGS; + } +#endif // __WXUNIVERSAL__ } wxString className(wclass); diff --git a/src/univ/button.cpp b/src/univ/button.cpp index c46c934a17..bd2ddb2fb4 100644 --- a/src/univ/button.cpp +++ b/src/univ/button.cpp @@ -97,6 +97,23 @@ wxButton::~wxButton() // size management // ---------------------------------------------------------------------------- +/* static */ +wxSize wxButtonBase::GetDefaultSize() +{ + static wxSize s_sizeBtn; + + if ( s_sizeBtn.x == 0 ) + { + wxScreenDC dc; + + // this corresponds more or less to wxMSW standard + s_sizeBtn.x = (50 * dc.GetCharWidth())/4; + s_sizeBtn.y = (14 * dc.GetCharHeight())/8; + } + + return s_sizeBtn; +} + wxSize wxButton::DoGetBestClientSize() const { wxClientDC dc(wxConstCast(this, wxButton)); diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index dcdf3c75df..6ecf6f2559 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -48,8 +48,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase) - EVT_CHAR(wxListBox::OnChar) - EVT_SIZE(wxListBox::OnSize) EVT_IDLE(wxListBox::OnIdle) @@ -582,7 +580,7 @@ void wxListBox::OnIdle(wxIdleEvent& event) if ( m_currentChanged ) { - EnsureVisible(); + DoEnsureVisible(m_current); m_currentChanged = FALSE; } @@ -808,17 +806,10 @@ bool wxListBox::FindItem(const wxString& prefix) { size_t len = prefix.length(); int count = GetCount(); - for ( int item = m_current + 1; item != m_current; item++ ) + int first = m_current == count - 1 ? 0 : m_current + 1; + int last = m_current == -1 ? count : m_current; + for ( int item = first; item != last; item < count - 1 ? item++ : item = 0 ) { - if ( item == count ) - { - // wrap - item = 0; - - if ( m_current == -1 ) - break; - } - if ( wxStrnicmp(m_strings[item], prefix, len) == 0 ) { SetCurrentItem(item); @@ -840,7 +831,20 @@ bool wxListBox::FindItem(const wxString& prefix) return FALSE; } -void wxListBox::EnsureVisible() +void wxListBox::EnsureVisible(int n) +{ + if ( m_updateScrollbarY ) + { + UpdateScrollbars(); + + m_updateScrollbarX = + m_updateScrollbarY = FALSE; + } + + DoEnsureVisible(n); +} + +void wxListBox::DoEnsureVisible(int n) { if ( !m_showScrollbarY ) { @@ -850,20 +854,20 @@ void wxListBox::EnsureVisible() int first; GetViewStart(0, &first); - if ( first > m_current ) + if ( first > n ) { // we need to scroll upwards, so make the current item appear on top // of the shown range - Scroll(0, m_current); + Scroll(0, n); } else { int last = first + GetClientSize().y / GetLineHeight() - 1; - if ( last < m_current ) + if ( last < n ) { // scroll down: the current item appears at the bottom of the // range - Scroll(0, m_current - (last - first)); + Scroll(0, n - (last - first)); } } } @@ -953,35 +957,6 @@ void wxListBox::Activate(int item) } } -// ---------------------------------------------------------------------------- -// built-in keyboard interface (should it be implemented in the inp handler?) -// ---------------------------------------------------------------------------- - -void wxListBox::OnChar(wxKeyEvent& event) -{ - int keycode = event.GetKeyCode(); - if ( isalnum(keycode) ) - { - // find the next item after this one which starts with this letter - int count = GetCount(); - int last = m_current == -1 ? count : m_current; - for ( int n = m_current + 1; n != last; n++ ) - { - if ( n == count ) - n = 0; - - wxString str = m_strings[n]; - if ( !str.empty() && (str[0u] == (wxChar)keycode) ) - { - SetCurrentItem(n); - return; - } - } - } - - event.Skip(); -} - // ---------------------------------------------------------------------------- // input handling // ---------------------------------------------------------------------------- diff --git a/src/univ/renderer.cpp b/src/univ/renderer.cpp index 56f831b07f..5d1cc31348 100644 --- a/src/univ/renderer.cpp +++ b/src/univ/renderer.cpp @@ -74,6 +74,37 @@ void wxRenderer::StandardDrawFrame(wxDC& dc, // wxRenderer: scrollbar geometry // ---------------------------------------------------------------------------- +/* static */ +void wxRenderer::StandardScrollBarThumbSize(wxCoord length, + int thumbPos, + int thumbSize, + int range, + wxCoord *thumbStart, + wxCoord *thumbEnd) +{ + // the thumb can't be made less than this number of pixels + static const wxCoord thumbMinWidth = 8; // FIXME: should be configurable + + *thumbStart = (length*thumbPos) / range; + *thumbEnd = (length*(thumbPos + thumbSize)) / range; + + if ( *thumbEnd - *thumbStart < thumbMinWidth ) + { + // adjust the end if possible + if ( *thumbStart <= length - thumbMinWidth ) + { + // yes, just make it wider + *thumbEnd = *thumbStart + thumbMinWidth; + } + else // it is at the bottom of the scrollbar + { + // so move it a bit up + *thumbStart = length - thumbMinWidth; + *thumbEnd = length; + } + } +} + /* static */ wxRect wxRenderer::StandardGetScrollbarRect(const wxScrollBar *scrollbar, wxScrollBar::Element elem, @@ -139,10 +170,12 @@ wxRect wxRenderer::StandardGetScrollbarRect(const wxScrollBar *scrollbar, } else { - int thumbSize = scrollbar->GetThumbSize(); - - thumbStart = (length*thumbPos) / range; - thumbEnd = (length*(thumbPos + thumbSize)) / range; + StandardScrollBarThumbSize(length, + thumbPos, + scrollbar->GetThumbSize(), + range, + &thumbStart, + &thumbEnd); } if ( elem == wxScrollBar::Element_Thumb ) @@ -280,11 +313,12 @@ wxHitTest wxRenderer::StandardHitTestScrollbar(const wxScrollBar *scrollbar, } else { - int posThumb = scrollbar->GetThumbPosition(), - sizeThumb = scrollbar->GetThumbSize(); - - thumbStart = (sizeTotal*posThumb) / range; - thumbEnd = (sizeTotal*(posThumb + sizeThumb)) / range; + StandardScrollBarThumbSize(sizeTotal, + scrollbar->GetThumbPosition(), + scrollbar->GetThumbSize(), + range, + &thumbStart, + &thumbEnd); } // now compare with the thumb position diff --git a/src/univ/scrolbar.cpp b/src/univ/scrolbar.cpp index 24f70bb15a..3c49c104a2 100644 --- a/src/univ/scrolbar.cpp +++ b/src/univ/scrolbar.cpp @@ -271,7 +271,6 @@ void wxScrollBar::OnIdle(wxIdleEvent& event) #endif // 0/1 } - // FIXME: rect is client or win (must be client)? Refresh(TRUE, &rect); } diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index f2e9aca87c..d4d9703096 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -1772,6 +1772,10 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window) { // TODO size->x += 3*window->GetCharWidth(); + wxSize sizeDef = wxButton::GetDefaultSize(); + if ( size->x < sizeDef.x ) + size->x = sizeDef.x; + wxCoord heightBtn = (11*(window->GetCharHeight() + 8))/10; if ( size->y < heightBtn - 8 ) size->y = heightBtn; diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index d29f7832ff..72d99d2e97 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -308,7 +308,7 @@ void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient) bool wxWindow::Enable(bool enable) { - if ( !wxWindowBase::Enable(enable) ) + if ( !wxWindowNative::Enable(enable) ) return FALSE; // disabled window can't keep focus