]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/listbox.cpp
only work on the focus if the control is shown
[wxWidgets.git] / src / univ / listbox.cpp
index 541fa506b49ef77d38c1137102f8fae22a48cfe7..33ba2ea3a3be78055803a791c131716c8b147ebf 100644 (file)
@@ -17,8 +17,8 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "listbox.h"
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+    #pragma implementation "univlistbox.h"
 #endif
 
 #include "wx/wxprec.h"
@@ -49,8 +49,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
 
 BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
     EVT_SIZE(wxListBox::OnSize)
-
-    EVT_IDLE(wxListBox::OnIdle)
 END_EVENT_TABLE()
 
 // ----------------------------------------------------------------------------
@@ -101,7 +99,14 @@ bool wxListBox::Create(wxWindow *parent,
     if ( !(style & (wxLB_MULTIPLE | wxLB_EXTENDED)) )
         style |= wxLB_SINGLE;
 
-    if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) )
+#if wxUSE_TWO_WINDOWS
+    style |=  wxVSCROLL|wxHSCROLL;
+    if ((style & wxBORDER_MASK) == 0)
+        style |= wxBORDER_SUNKEN;
+#endif
+
+    if ( !wxControl::Create(parent, id, pos, size, style, 
+                            validator, name) )
         return FALSE;
 
     SetWindow(this);
@@ -120,6 +125,8 @@ bool wxListBox::Create(wxWindow *parent,
 
 wxListBox::~wxListBox()
 {
+    // call this just to free the client data -- and avoid leaking memory
+    DoClear();
 }
 
 // ----------------------------------------------------------------------------
@@ -265,7 +272,8 @@ void wxListBox::Clear()
 
 void wxListBox::Delete(int n)
 {
-    wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
+    wxCHECK_RET( n >= 0 && n < GetCount(),
+                 _T("invalid index in wxListBox::Delete") );
 
     // do it before removing the index as otherwise the last item will not be
     // refreshed (as GetCount() will be decremented)
@@ -591,7 +599,7 @@ void wxListBox::UpdateItems()
     }
 }
 
-void wxListBox::OnIdle(wxIdleEvent& event)
+void wxListBox::OnInternalIdle()
 {
     if ( m_updateScrollbarY || m_updateScrollbarX )
     {
@@ -614,8 +622,7 @@ void wxListBox::OnIdle(wxIdleEvent& event)
 
         m_updateCount = 0;
     }
-
-    event.Skip();
+    wxListBoxBase::OnInternalIdle();
 }
 
 // ----------------------------------------------------------------------------
@@ -763,7 +770,7 @@ void wxListBox::DoSetSize(int x, int y,
         height = ((height - hBorders + hLine - 1) / hLine)*hLine + hBorders;
     }
 
-    wxListBoxBase::DoSetSize(x, y, width, height);
+    wxListBoxBase::DoSetSize(x, y, width, height, sizeFlags);
 }
 
 wxSize wxListBox::DoGetBestClientSize() const
@@ -805,11 +812,6 @@ wxSize wxListBox::DoGetBestClientSize() const
 
 bool wxListBox::SendEvent(wxEventType type, int item)
 {
-    // don't generate select events while the mouse is captured, we will only
-    // send them once it is released
-    if ( (type == wxEVT_COMMAND_LISTBOX_SELECTED) && (GetCapture() == this) )
-        return FALSE;
-
     wxCommandEvent event(type, m_windowId);
     event.SetEventObject(this);
 
@@ -1005,7 +1007,7 @@ void wxListBox::ExtendSelection(int itemTo)
     }
 }
 
-void wxListBox::Select(bool sel, int item)
+void wxListBox::DoSelect(int item, bool sel)
 {
     if ( item != -1 )
     {
@@ -1025,7 +1027,7 @@ void wxListBox::Select(bool sel, int item)
 
 void wxListBox::SelectAndNotify(int item)
 {
-    Select(TRUE, item);
+    DoSelect(item);
 
     SendEvent(wxEVT_COMMAND_LISTBOX_SELECTED);
 }
@@ -1044,7 +1046,7 @@ void wxListBox::Activate(int item)
 
     if ( item != -1 )
     {
-        Select(TRUE, item);
+        DoSelect(item);
 
         SendEvent(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED);
     }
@@ -1054,6 +1056,19 @@ void wxListBox::Activate(int item)
 // input handling
 // ----------------------------------------------------------------------------
 
+/*
+   The numArg here is the listbox item index while the strArg is used
+   differently for the different actions:
+
+   a) for wxACTION_LISTBOX_FIND it has the natural meaning: this is the string
+      to find
+
+   b) for wxACTION_LISTBOX_SELECT and wxACTION_LISTBOX_EXTENDSEL it is used
+      to decide if the listbox should send the notification event (it is empty)
+      or not (it is not): this allows us to reuse the same action for when the
+      user is dragging the mouse when it has been released although in the
+      first case no notification is sent while in the second it is sent.
+ */
 bool wxListBox::PerformAction(const wxControlAction& action,
                               long numArg,
                               const wxString& strArg)
@@ -1061,28 +1076,36 @@ bool wxListBox::PerformAction(const wxControlAction& action,
     int item = (int)numArg;
 
     if ( action == wxACTION_LISTBOX_SETFOCUS )
+    {
         SetCurrentItem(item);
+    }
     else if ( action == wxACTION_LISTBOX_ACTIVATE )
+    {
         Activate(item);
+    }
     else if ( action == wxACTION_LISTBOX_TOGGLE )
     {
         if ( item == -1 )
             item = m_current;
 
         if ( IsSelected(item) )
-            Unselect(item);
+            DoUnselect(item);
         else
             SelectAndNotify(item);
     }
     else if ( action == wxACTION_LISTBOX_SELECT )
     {
         DeselectAll(item);
-        SelectAndNotify(item);
+
+        if ( strArg.empty() )
+            SelectAndNotify(item);
+        else
+            DoSelect(item);
     }
     else if ( action == wxACTION_LISTBOX_SELECTADD )
-        Select(TRUE, item);
+        DoSelect(item);
     else if ( action == wxACTION_LISTBOX_UNSELECT )
-        Select(FALSE, item);
+        DoUnselect(item);
     else if ( action == wxACTION_LISTBOX_MOVEDOWN )
         ChangeCurrent(1);
     else if ( action == wxACTION_LISTBOX_MOVEUP )
@@ -1236,7 +1259,7 @@ wxStdListboxInputHandler::SetupCapture(wxListBox *lbox,
     return action;
 }
 
-bool wxStdListboxInputHandler::HandleKey(wxControl *control,
+bool wxStdListboxInputHandler::HandleKey(wxInputConsumer *consumer,
                                          const wxKeyEvent& event,
                                          bool pressed)
 {
@@ -1244,7 +1267,7 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control,
     if ( pressed && !event.AltDown() )
     {
         bool isMoveCmd = TRUE;
-        int style = control->GetWindowStyle();
+        int style = consumer->GetInputWindow()->GetWindowStyle();
 
         wxControlAction action;
         wxString strArg;
@@ -1253,12 +1276,33 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control,
         switch ( keycode )
         {
             // movement
-            case WXK_UP:    action = wxACTION_LISTBOX_MOVEUP; break;
-            case WXK_DOWN:  action = wxACTION_LISTBOX_MOVEDOWN; break;
-            case WXK_PRIOR: action = wxACTION_LISTBOX_PAGEUP; break;
-            case WXK_NEXT:  action = wxACTION_LISTBOX_PAGEDOWN; break;
-            case WXK_HOME:  action = wxACTION_LISTBOX_START; break;
-            case WXK_END:   action = wxACTION_LISTBOX_END; break;
+            case WXK_UP:
+                action = wxACTION_LISTBOX_MOVEUP;
+                break;
+
+            case WXK_DOWN:
+                action = wxACTION_LISTBOX_MOVEDOWN;
+                break;
+
+            case WXK_PAGEUP:
+
+            case WXK_PRIOR:
+                action = wxACTION_LISTBOX_PAGEUP;
+                break;
+
+            case WXK_PAGEDOWN:
+
+            case WXK_NEXT:
+                action = wxACTION_LISTBOX_PAGEDOWN;
+                break;
+
+            case WXK_HOME:
+                action = wxACTION_LISTBOX_START;
+                break;
+
+            case WXK_END:
+                action = wxACTION_LISTBOX_END;
+                break;
 
             // selection
             case WXK_SPACE:
@@ -1284,24 +1328,24 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control,
 
         if ( !!action )
         {
-            control->PerformAction(action, -1, strArg);
+            consumer->PerformAction(action, -1, strArg);
 
             if ( isMoveCmd )
             {
                 if ( style & wxLB_SINGLE )
                 {
                     // the current item is always the one selected
-                    control->PerformAction(wxACTION_LISTBOX_SELECT);
+                    consumer->PerformAction(wxACTION_LISTBOX_SELECT);
                 }
                 else if ( style & wxLB_EXTENDED )
                 {
                     if ( event.ShiftDown() )
-                        control->PerformAction(wxACTION_LISTBOX_EXTENDSEL);
+                        consumer->PerformAction(wxACTION_LISTBOX_EXTENDSEL);
                     else
                     {
                         // select the item and make it the new selection anchor
-                        control->PerformAction(wxACTION_LISTBOX_SELECT);
-                        control->PerformAction(wxACTION_LISTBOX_ANCHOR);
+                        consumer->PerformAction(wxACTION_LISTBOX_SELECT);
+                        consumer->PerformAction(wxACTION_LISTBOX_ANCHOR);
                     }
                 }
                 //else: nothing to do for multiple selection listboxes
@@ -1311,13 +1355,13 @@ bool wxStdListboxInputHandler::HandleKey(wxControl *control,
         }
     }
 
-    return wxStdInputHandler::HandleKey(control, event, pressed);
+    return wxStdInputHandler::HandleKey(consumer, event, pressed);
 }
 
-bool wxStdListboxInputHandler::HandleMouse(wxControl *control,
+bool wxStdListboxInputHandler::HandleMouse(wxInputConsumer *consumer,
                                            const wxMouseEvent& event)
 {
-    wxListBox *lbox = wxStaticCast(control, wxListBox);
+    wxListBox *lbox = wxStaticCast(consumer->GetInputWindow(), wxListBox);
     int item = HitTest(lbox, event);
     wxControlAction action;
 
@@ -1340,7 +1384,6 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control,
             winCapture->ReleaseMouse();
             m_btnCapture = 0;
 
-            // generate the last event to triiger sending the selection event
             action = m_actionMouse;
         }
         //else: the mouse wasn't presed over the listbox, only released here
@@ -1357,16 +1400,16 @@ bool wxStdListboxInputHandler::HandleMouse(wxControl *control,
         return TRUE;
     }
 
-    return wxStdInputHandler::HandleMouse(control, event);
+    return wxStdInputHandler::HandleMouse(consumer, event);
 }
 
-bool wxStdListboxInputHandler::HandleMouseMove(wxControl *control,
+bool wxStdListboxInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                                                const wxMouseEvent& event)
 {
     wxWindow *winCapture = wxWindow::GetCapture();
     if ( winCapture && (event.GetEventObject() == winCapture) )
     {
-        wxListBox *lbox = wxStaticCast(control, wxListBox);
+        wxListBox *lbox = wxStaticCast(consumer->GetInputWindow(), wxListBox);
 
         if ( !m_btnCapture || !m_trackMouseOutside )
         {
@@ -1390,7 +1433,9 @@ bool wxStdListboxInputHandler::HandleMouseMove(wxControl *control,
 
         if ( IsValidIndex(lbox, item) )
         {
-            lbox->PerformAction(m_actionMouse, item);
+            // pass something into strArg to tell the listbox that it shouldn't
+            // send the notification message: see PerformAction() above
+            lbox->PerformAction(m_actionMouse, item, _T("no"));
         }
         // else: don't pass invalid index to the listbox
     }
@@ -1404,7 +1449,7 @@ bool wxStdListboxInputHandler::HandleMouseMove(wxControl *control,
         }
     }
 
-    return wxStdInputHandler::HandleMouseMove(control, event);
+    return wxStdInputHandler::HandleMouseMove(consumer, event);
 }
 
 #endif // wxUSE_LISTBOX