X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7ead384579f416a16c8bc3e132cbbd9211238690..64ea838d8f4d1853b7d850db93ee565e901d099a:/src/common/lboxcmn.cpp diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp index 9b114d7c1b..0e1d050193 100644 --- a/src/common/lboxcmn.cpp +++ b/src/common/lboxcmn.cpp @@ -31,9 +31,10 @@ #ifndef WX_PRECOMP #include "wx/dynarray.h" #include "wx/arrstr.h" + #include "wx/log.h" #endif -#include "wx/log.h" +extern WXDLLEXPORT_DATA(const char) wxListBoxNameStr[] = "listBox"; // ============================================================================ // implementation @@ -44,6 +45,78 @@ wxListBoxBase::~wxListBoxBase() // this destructor is required for Darwin } +// ---------------------------------------------------------------------------- +// XTI +// ---------------------------------------------------------------------------- + +wxDEFINE_FLAGS( wxListBoxStyle ) +wxBEGIN_FLAGS( wxListBoxStyle ) +// new style border flags, we put them first to +// use them for streaming out +wxFLAGS_MEMBER(wxBORDER_SIMPLE) +wxFLAGS_MEMBER(wxBORDER_SUNKEN) +wxFLAGS_MEMBER(wxBORDER_DOUBLE) +wxFLAGS_MEMBER(wxBORDER_RAISED) +wxFLAGS_MEMBER(wxBORDER_STATIC) +wxFLAGS_MEMBER(wxBORDER_NONE) + +// old style border flags +wxFLAGS_MEMBER(wxSIMPLE_BORDER) +wxFLAGS_MEMBER(wxSUNKEN_BORDER) +wxFLAGS_MEMBER(wxDOUBLE_BORDER) +wxFLAGS_MEMBER(wxRAISED_BORDER) +wxFLAGS_MEMBER(wxSTATIC_BORDER) +wxFLAGS_MEMBER(wxBORDER) + +// standard window styles +wxFLAGS_MEMBER(wxTAB_TRAVERSAL) +wxFLAGS_MEMBER(wxCLIP_CHILDREN) +wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW) +wxFLAGS_MEMBER(wxWANTS_CHARS) +wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE) +wxFLAGS_MEMBER(wxALWAYS_SHOW_SB ) +wxFLAGS_MEMBER(wxVSCROLL) +wxFLAGS_MEMBER(wxHSCROLL) + +wxFLAGS_MEMBER(wxLB_SINGLE) +wxFLAGS_MEMBER(wxLB_MULTIPLE) +wxFLAGS_MEMBER(wxLB_EXTENDED) +wxFLAGS_MEMBER(wxLB_HSCROLL) +wxFLAGS_MEMBER(wxLB_ALWAYS_SB) +wxFLAGS_MEMBER(wxLB_NEEDED_SB) +wxFLAGS_MEMBER(wxLB_SORT) +wxEND_FLAGS( wxListBoxStyle ) + +wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxListBox, wxControl, "wx/listbox.h") + +wxBEGIN_PROPERTIES_TABLE(wxListBox) +wxEVENT_PROPERTY( Select, wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEvent ) +wxEVENT_PROPERTY( DoubleClick, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEvent ) + +wxPROPERTY( Font, wxFont, SetFont, GetFont , wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \ + wxT("Helpstring"), wxT("group")) +wxPROPERTY_COLLECTION( Choices, wxArrayString, wxString, AppendString, \ + GetStrings, 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Selection, int, SetSelection, GetSelection, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) + +wxPROPERTY_FLAGS( WindowStyle, wxListBoxStyle, long, SetWindowStyleFlag, \ + GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \ + wxT("Helpstring"), wxT("group")) // style +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxListBox) + +wxCONSTRUCTOR_4( wxListBox, wxWindow*, Parent, wxWindowID, Id, \ + wxPoint, Position, wxSize, Size ) + +/* + TODO PROPERTIES + selection + content + item + */ + // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- @@ -59,6 +132,14 @@ bool wxListBoxBase::SetStringSelection(const wxString& s, bool select) return true; } +void wxListBoxBase::SetSelection(int n) +{ + if ( !HasMultipleSelection() ) + DoChangeSingleSelection(n); + + DoSetSelection(n, true); +} + void wxListBoxBase::DeselectAll(int itemToLeaveSelected) { if ( HasMultipleSelection() ) @@ -86,33 +167,70 @@ void wxListBoxBase::DeselectAll(int itemToLeaveSelected) void wxListBoxBase::UpdateOldSelections() { + // When the control becomes empty, any previously remembered selections are + // invalid anyhow, so just forget them. + if ( IsEmpty() ) + { + m_oldSelections.clear(); + return; + } + + // We need to remember the selection even in single-selection case on + // Windows, so that we don't send an event when the user clicks on an + // already selected item. +#ifndef __WXMSW__ if (HasFlag(wxLB_MULTIPLE) || HasFlag(wxLB_EXTENDED)) +#endif + { GetSelections( m_oldSelections ); + } } -static void LBSendEvent( wxCommandEvent &event, wxListBoxBase *listbox, int item ) +bool wxListBoxBase::SendEvent(wxEventType evtType, int item, bool selected) { - event.SetInt( item ); - event.SetString( listbox->GetString( item ) ); - if ( listbox->HasClientObjectData() ) - event.SetClientObject( listbox->GetClientObject(item) ); - else if ( listbox->HasClientUntypedData() ) - event.SetClientData( listbox->GetClientData(item) ); - listbox->HandleWindowEvent( event ); + wxCommandEvent event(evtType, GetId()); + event.SetEventObject(this); + + event.SetInt(item); + event.SetString(GetString(item)); + event.SetExtraLong(selected); + + if ( HasClientObjectData() ) + event.SetClientObject(GetClientObject(item)); + else if ( HasClientUntypedData() ) + event.SetClientData(GetClientData(item)); + + return HandleWindowEvent(event); } -void wxListBoxBase::CalcAndSendEvent() +bool wxListBoxBase::DoChangeSingleSelection(int item) { - wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId()); - event.SetEventObject( this ); + // As we don't use m_oldSelections in single selection mode, we store the + // last item that we notified the user about in it in this case because we + // need to remember it to be able to filter out the dummy selection changes + // that we get when the user clicks on an already selected item. + if ( !m_oldSelections.empty() && *m_oldSelections.begin() == item ) + { + // Same item as the last time. + return false; + } + m_oldSelections.clear(); + m_oldSelections.push_back(item); + + return true; +} + +bool wxListBoxBase::CalcAndSendEvent() +{ wxArrayInt selections; GetSelections(selections); + bool selected = true; if ( selections.empty() && m_oldSelections.empty() ) { // nothing changed, just leave - return; + return false; } const size_t countSel = selections.size(), @@ -131,14 +249,13 @@ void wxListBoxBase::CalcAndSendEvent() // nothing changed, just leave if ( !changed ) - return; + return false; } int item = wxNOT_FOUND; if ( selections.empty() ) { - // indicate that this is a deselection - event.SetExtraLong(0); + selected = false; item = m_oldSelections[0]; } else // we [still] have some selections @@ -155,14 +272,9 @@ void wxListBoxBase::CalcAndSendEvent() } } - if ( any_new_selected ) - { - // indicate that this is a selection - event.SetExtraLong(1); - } - else // no new items selected + if ( !any_new_selected ) { - // Now test if any new item is deselected + // No new items selected, now test if any new item is deselected bool any_new_deselected = false; for ( size_t idx = 0; idx < countSelOld; idx++ ) { @@ -177,7 +289,7 @@ void wxListBoxBase::CalcAndSendEvent() if ( any_new_deselected ) { // indicate that this is a selection - event.SetExtraLong(0); + selected = false; } else { @@ -191,7 +303,7 @@ void wxListBoxBase::CalcAndSendEvent() m_oldSelections = selections; - LBSendEvent(event, this, item); + return SendEvent(wxEVT_COMMAND_LISTBOX_SELECTED, item, selected); } // ---------------------------------------------------------------------------- @@ -201,7 +313,7 @@ void wxListBoxBase::CalcAndSendEvent() void wxListBoxBase::Command(wxCommandEvent& event) { SetSelection(event.GetInt(), event.GetExtraLong() != 0); - (void)ProcessEvent(event); + (void)GetEventHandler()->ProcessEvent(event); } // ----------------------------------------------------------------------------