1. listbox sample fixed, now seems to work more or less (except for wxSizer problem)

2. wxRadioBox lays out items correctly
3. wxListBox::DoInsertItems() refreshes correctly
4. list box scrollbars are now refreshed correctly too


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8482 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-10-06 16:24:25 +00:00
parent ea8259f286
commit 943240b264
5 changed files with 170 additions and 106 deletions

View File

@@ -200,6 +200,12 @@ protected:
virtual void DoDrawRange(wxControlRenderer *renderer,
int itemFirst, int itemLast);
// update (show/hide/adjust) the scrollbars
void UpdateScrollbars();
// refresh the items specified by m_updateCount and m_updateFrom
void UpdateItems();
// the array containing all items (it is sorted if the listbox has
// wxLB_SORT style)
wxArrayString m_strings;
@@ -228,6 +234,10 @@ private:
// the maximal width of a listbox item
wxCoord m_maxWidth;
// the extents of horz and vert scrollbars
int m_scrollRangeX,
m_scrollRangeY;
// the number of items per page
size_t m_itemsPerPage;

View File

@@ -94,11 +94,16 @@ protected:
// event handlers
void OnButtonReset(wxCommandEvent& event);
void OnButtonCreate(wxCommandEvent& event);
void OnButtonDelete(wxCommandEvent& event);
void OnButtonClear(wxCommandEvent& event);
void OnButtonAdd(wxCommandEvent& event);
void OnButtonAddSeveral(wxCommandEvent& event);
void OnCheckOrRadioBox(wxCommandEvent& event);
void OnUpdateUIButtons(wxUpdateUIEvent& event);
void OnUpdateUICreateButton(wxUpdateUIEvent& event);
void OnUpdateUIClearButton(wxUpdateUIEvent& event);
void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
// reset the listbox parameters
void Reset();
@@ -169,12 +174,16 @@ IMPLEMENT_APP(LboxTestApp)
BEGIN_EVENT_TABLE(LboxTestFrame, wxFrame)
EVT_BUTTON(LboxTest_Reset, LboxTestFrame::OnButtonReset)
EVT_BUTTON(LboxTest_Create, LboxTestFrame::OnButtonCreate)
EVT_BUTTON(LboxTest_Delete, LboxTestFrame::OnButtonDelete)
EVT_BUTTON(LboxTest_Clear, LboxTestFrame::OnButtonClear)
EVT_BUTTON(LboxTest_Add, LboxTestFrame::OnButtonAdd)
EVT_BUTTON(LboxTest_AddSeveral, LboxTestFrame::OnButtonAddSeveral)
EVT_UPDATE_UI_RANGE(LboxTest_Reset, LboxTest_Create,
LboxTestFrame::OnUpdateUIButtons)
LboxTestFrame::OnUpdateUICreateButton)
EVT_UPDATE_UI(LboxTest_Clear, LboxTestFrame::OnUpdateUIClearButton)
EVT_UPDATE_UI(LboxTest_Delete, LboxTestFrame::OnUpdateUIDeleteButton)
EVT_CHECKBOX(-1, LboxTestFrame::OnCheckOrRadioBox)
EVT_RADIOBOX(-1, LboxTestFrame::OnCheckOrRadioBox)
@@ -203,7 +212,7 @@ bool LboxTestApp::OnInit()
// ----------------------------------------------------------------------------
LboxTestFrame::LboxTestFrame(const wxString& title)
: wxFrame(NULL, -1, title)
: wxFrame(NULL, -1, title, wxPoint(100, 100))
{
// init everything
m_dirty = FALSE;
@@ -217,16 +226,13 @@ LboxTestFrame::LboxTestFrame(const wxString& title)
m_sizerLbox = (wxSizer *)NULL;
/*
What we create here is a frame having 2 panes: the explanatory pane to
the left allowing to set the listbox styles and recreate the control
and the pane containing the listbox itself and the control used for log
output to the right.
The left pane is divided, itself, in 2 parts with the upper one
allowing to recreate the listbox and the lower one to add/change/delete
strings to/from it.
What we create here is a frame having 3 panes: the explanatory pane to
the left allowing to set the listbox styles and recreate the control,
the pane containing the listbox itself and the lower pane containing
the buttons which allow to add/change/delete strings to/from it.
*/
wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL),
wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL),
*sizerUp = new wxBoxSizer(wxHORIZONTAL),
*sizerLeft = new wxBoxSizer(wxVERTICAL),
*sizerRight = new wxBoxSizer(wxVERTICAL);
@@ -238,6 +244,7 @@ LboxTestFrame::LboxTestFrame(const wxString& title)
_T("multiple"),
};
wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set listbox parameters"));
m_radioSelMode = new wxRadioBox(this, -1, _T("Selection &mode:"),
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(modes), modes,
@@ -247,44 +254,46 @@ LboxTestFrame::LboxTestFrame(const wxString& title)
m_chkHScroll = new wxCheckBox(this, -1, _T("Show &horizontal scrollbar"));
m_chkSort = new wxCheckBox(this, -1, _T("&Sort items"));
wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set listbox parameters"));
wxSizer *sizerUp = new wxStaticBoxSizer(box, wxVERTICAL);
sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
sizerUp->Add(m_chkVScroll, 0, wxLEFT | wxRIGHT, 5);
sizerUp->Add(m_chkHScroll, 0, wxLEFT | wxRIGHT, 5);
sizerUp->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
sizerUp->Add(m_radioSelMode, 0, wxALL, 5);
sizerUp->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
sizerUp->Add(m_chkSort, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkVScroll, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkHScroll, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkSort, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5);
wxSizer *sizerBtn = new wxBoxSizer(wxHORIZONTAL);
wxButton *btn = new wxButton(this, LboxTest_Reset, _T("&Reset"));
sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
btn = new wxButton(this, LboxTest_Create, _T("&Create"));
sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
sizerUp->Add(sizerBtn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 5);
sizerLeft->Add(sizerBtn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
// lower left pane
// right pane
m_lbox = new wxListBox(this, -1);
sizerRight->Add(m_lbox, 1, wxGROW | wxALL, 5);
sizerRight->SetMinSize(250, 0);
m_sizerLbox = sizerRight; // save it to modify it later
// left + right panes compose the upper one
sizerUp->Add(sizerLeft, 0, wxGROW | wxALL, 10);
sizerUp->Add(sizerRight, 1, wxGROW | wxALL, 10);
// lower pane
wxStaticBox *box2 = new wxStaticBox(this, -1, _T("&Change listbox contents"));
wxSizer *sizerDown = new wxStaticBoxSizer(box2, wxVERTICAL);
btn = new wxButton(this, LboxTest_Add, _T("&Add string..."));
sizerDown->Add(btn, 0, wxALL | wxGROW, 5);
btn = new wxButton(this, LboxTest_AddSeveral, _T("Add a &few string"));
btn = new wxButton(this, LboxTest_AddSeveral, _T("Add a &few strings"));
sizerDown->Add(btn, 0, wxALL | wxGROW, 5);
btn = new wxButton(this, LboxTest_Delete, _T("&Delete"));
sizerDown->Add(btn, 0, wxALL | wxGROW, 5);
btn = new wxButton(this, LboxTest_Clear, _T("&Clear"));
sizerDown->Add(btn, 0, wxALL | wxGROW, 5);
sizerLeft->Add(sizerUp, 0, wxGROW | wxTOP | wxBOTTOM, 5);
sizerLeft->Add(sizerDown, 0, wxGROW | wxTOP | wxBOTTOM, 5);
// right pane
m_lbox = new wxListBox(this, -1);
sizerRight->Add(m_lbox, 1, wxGROW | wxALL, 5);
m_sizerLbox = sizerRight;
sizerTop->Add(sizerLeft, 0, wxGROW | wxALL, 10);
sizerTop->Add(sizerRight, 1, wxGROW | wxALL, 10);
sizerTop->Add(sizerUp, 1, wxGROW | wxALL, 10);
sizerTop->Add(sizerDown, 0, wxGROW | wxALL, 10);
// final initialization
Reset();
@@ -369,6 +378,16 @@ void LboxTestFrame::OnButtonCreate(wxCommandEvent& event)
CreateLbox();
}
void LboxTestFrame::OnButtonDelete(wxCommandEvent& event)
{
wxArrayInt selections;
int n = m_lbox->GetSelections(selections);
while ( n > 0 )
{
m_lbox->Delete(selections[--n]);
}
}
void LboxTestFrame::OnButtonClear(wxCommandEvent& event)
{
m_lbox->Clear();
@@ -385,15 +404,26 @@ void LboxTestFrame::OnButtonAddSeveral(wxCommandEvent& event)
wxArrayString items;
items.Add(_T("First"));
items.Add(_T("another one"));
items.Add(_T("and the last (very long) one"));
items.Add(_T("and the last (very very very very very long) one"));
m_lbox->InsertItems(items, 0);
}
void LboxTestFrame::OnUpdateUIButtons(wxUpdateUIEvent& event)
void LboxTestFrame::OnUpdateUICreateButton(wxUpdateUIEvent& event)
{
event.Enable(m_dirty);
}
void LboxTestFrame::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
{
wxArrayInt selections;
event.Enable(m_lbox->GetSelections(selections) != 0);
}
void LboxTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
{
event.Enable(m_lbox->GetCount() != 0);
}
void LboxTestFrame::OnCheckOrRadioBox(wxCommandEvent& event)
{
m_dirty = TRUE;

View File

@@ -63,6 +63,7 @@ void wxListBox::Init()
m_lineHeight = 0;
m_itemsPerPage = 0;
m_maxWidth = 0;
m_scrollRangeY = 0;
// no items hence no current item
m_current = -1;
@@ -159,7 +160,7 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
m_itemsClientData.Insert(NULL, pos + n);
}
// the number of items has changed
// the number of items has changed so we might have to show the scrollbar
m_updateScrollbarY = TRUE;
// the max width also might have changed - just recalculate it instead of
@@ -168,7 +169,9 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
m_maxWidth = 0;
m_updateScrollbarX = TRUE;
RefreshItems(pos, count);
// note that we have to refresh all the items after the ones we inserted,
// not just these items
RefreshItems(pos, GetCount() - pos);
}
void wxListBox::DoSetItems(const wxArrayString& items, void **clientData)
@@ -424,9 +427,7 @@ void wxListBox::RefreshAll()
m_updateCount = -1;
}
void wxListBox::OnIdle(wxIdleEvent& event)
{
if ( m_updateScrollbarY || m_updateScrollbarX )
void wxListBox::UpdateScrollbars()
{
wxSize size = GetClientSize();
@@ -450,37 +451,34 @@ void wxListBox::OnIdle(wxIdleEvent& event)
showScrollbarX = FALSE;
}
// reset scrollbars if something changed
// what should be the scrollbar range now?
int scrollRangeX = showScrollbarX
? (maxWidth + 2*charWidth - 1) / charWidth
: 0;
int scrollRangeY = showScrollbarY ? nLines : 0;
// reset scrollbars if something changed: either the visibility status
// or the range of a scrollbar which is shown
if ( (showScrollbarY != m_showScrollbarY) ||
(showScrollbarX != m_showScrollbarX) )
(showScrollbarX != m_showScrollbarX) ||
(showScrollbarY && (scrollRangeY != m_scrollRangeY)) ||
(showScrollbarX && (scrollRangeX != m_scrollRangeX)) )
{
int x, y;
GetViewStart(&x, &y);
SetScrollbars(charWidth, lineHeight,
showScrollbarX
? (maxWidth + 2*charWidth - 1) / charWidth
: 0,
showScrollbarY
? nLines
: 0,
scrollRangeX, scrollRangeY,
x, y);
m_showScrollbarX = showScrollbarX;
m_showScrollbarY = showScrollbarY;
m_scrollRangeX = scrollRangeX;
m_scrollRangeY = scrollRangeY;
}
}
m_updateScrollbarX = FALSE;
m_updateScrollbarY = FALSE;
}
if ( m_currentChanged )
{
EnsureVisible();
m_currentChanged = FALSE;
}
if ( m_updateCount )
void wxListBox::UpdateItems()
{
// only refresh the items which must be refreshed
if ( m_updateCount == -1 )
@@ -506,6 +504,28 @@ void wxListBox::OnIdle(wxIdleEvent& event)
Refresh(TRUE, &rect);
}
}
void wxListBox::OnIdle(wxIdleEvent& event)
{
if ( m_updateScrollbarY || m_updateScrollbarX )
{
UpdateScrollbars();
m_updateScrollbarX = FALSE;
m_updateScrollbarY = FALSE;
}
if ( m_currentChanged )
{
EnsureVisible();
m_currentChanged = FALSE;
}
if ( m_updateCount )
{
UpdateItems();
m_updateCount = 0;
}

View File

@@ -140,7 +140,9 @@ void wxRadioBox::SetSelection(int n)
{
wxCHECK_RET( IsValid(n), _T("invalid index in wxRadioBox::SetSelection") );
// this will unselect the previously selected button in our group
m_selection = n;
// this will also unselect the previously selected button in our group
m_buttons[n]->SetValue(TRUE);
}
@@ -278,9 +280,9 @@ void wxRadioBox::DoMoveWindow(int x0, int y0, int width, int height)
if ( GetWindowStyle() & wxRA_SPECIFY_COLS )
{
// from to to bottom
if ( n % m_numRows )
if ( (n == 0) || (n % m_numRows) )
{
// continue in this column
// continue (or start if n == 0) in this column
y += sizeBtn.y;
}
else
@@ -293,7 +295,7 @@ void wxRadioBox::DoMoveWindow(int x0, int y0, int width, int height)
else // wxRA_SPECIFY_ROWS: mirror the code above
{
// from left to right
if ( n % m_numCols )
if ( (n == 0) || (n % m_numCols) )
{
// continue in this row
x += sizeBtn.x;

View File

@@ -1649,7 +1649,9 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window)
{
// TODO: this is ad hoc...
size->x += 3*window->GetCharWidth();
wxCoord minBtnHeight = (11*(window->GetCharHeight() + 8))/10;
if ( size->x < 80 )
size->x = 80;
wxCoord minBtnHeight = 22;
if ( size->y < minBtnHeight )
size->y = minBtnHeight;