]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/listbox.cpp
fixed background drawing for opaque controls
[wxWidgets.git] / src / mac / carbon / listbox.cpp
index f9199630c4759f181b785cb327232dc592b2f73b..70035a81c2453d8edb6c032bef9fe3ec44959ea0 100644 (file)
@@ -27,8 +27,8 @@
 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
 
 BEGIN_EVENT_TABLE(wxListBox, wxControl)
-#if !__WXMAC_OSX__
-    EVT_SIZE( wxListBox::OnSize )
+#ifndef __WXMAC_OSX__
+//    EVT_SIZE( wxListBox::OnSize )
     EVT_CHAR( wxListBox::OnChar )
 #endif
 END_EVENT_TABLE()
@@ -44,28 +44,6 @@ const short kTextColumnId = 1024 ;
 // we just introduce id s corresponding
 // to the line number
 
-// Listbox item
-wxListBox::wxListBox()
-{
-  m_noItems = 0;
-  m_selected = 0;
-  m_macList = NULL ;
-}
-
-bool wxListBox::Create(wxWindow *parent, wxWindowID id,
-                       const wxPoint& pos,
-                       const wxSize& size,
-                       const wxArrayString& choices,
-                       long style,
-                       const wxValidator& validator,
-                       const wxString& name)
-{
-    wxCArrayString chs(choices);
-
-    return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
-                  style, validator, name);
-}
-
 #if TARGET_API_MAC_OSX
 static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, 
     DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
@@ -78,7 +56,7 @@ static pascal  void DataBrowserItemNotificationProc(ControlRef browser, DataBrow
     if ( ref )
     {
         wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ;
-        size_t i = itemID - 1 ;
+        int i = itemID - 1 ;
         if (i >= 0 && i < list->GetCount() )
         {
             bool trigger = false ;
@@ -88,10 +66,10 @@ static pascal  void DataBrowserItemNotificationProc(ControlRef browser, DataBrow
             {
                 case kDataBrowserItemDeselected :
                     if ( list->HasMultipleSelection() )
-                        trigger = true ;
+                        trigger = !list->MacIsSelectionSuppressed() ;
                     break ;
                 case kDataBrowserItemSelected :
-                    trigger = true ;
+                    trigger = !list->MacIsSelectionSuppressed() ;
                     break ;
                 case kDataBrowserItemDoubleClicked :
                     event.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ;
@@ -118,7 +96,6 @@ static pascal  void DataBrowserItemNotificationProc(ControlRef browser, DataBrow
     }
 }
 
-
 static pascal OSStatus ListBoxGetSetItemData(ControlRef browser, 
     DataBrowserItemID itemID, DataBrowserPropertyID property, 
     DataBrowserItemDataRef itemData, Boolean changeValue)
@@ -136,7 +113,7 @@ static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
                    if ( ref )
                    {
                        wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ;
-                    size_t i = itemID - 1 ;
+                    int i = itemID - 1 ;
                     if (i >= 0 && i < list->GetCount() )
                            {
                                wxMacCFStringHolder cf( list->GetString(i) , list->GetFont().GetEncoding() ) ;
@@ -155,6 +132,31 @@ static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
        
        return err;
 }
+
+
+// Listbox item
+wxListBox::wxListBox()
+{
+  m_noItems = 0;
+  m_selected = 0;
+  m_macList = NULL ;
+  m_suppressSelection = false ;
+}
+
+bool wxListBox::Create(wxWindow *parent, wxWindowID id,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       const wxArrayString& choices,
+                       long style,
+                       const wxValidator& validator,
+                       const wxString& name)
+{
+    wxCArrayString chs(choices);
+
+    return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+                  style, validator, name);
+}
+
 bool wxListBox::Create(wxWindow *parent, wxWindowID id,
                        const wxPoint& pos,
                        const wxSize& size,
@@ -247,7 +249,6 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id,
     if ( UMAGetSystemVersion() < 0x1030 )
         m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ;
 #endif
-
     MacPostControlCreate(pos,size) ;
 
     for ( int i = 0 ; i < n ; i++ )
@@ -439,10 +440,13 @@ void wxListBox::Clear()
 
 void wxListBox::SetSelection(int N, bool select)
 {
-    wxCHECK_RET( N >= 0 && N < m_noItems,
+    wxCHECK_RET( N == wxNOT_FOUND || (N >= 0 && N < m_noItems) ,
         wxT("invalid index in wxListBox::SetSelection") );
-    MacSetSelection( N , select ) ;
-    GetSelections( m_selectionPreImage ) ;
+        
+    if ( N == wxNOT_FOUND )
+        MacDeselectAll() ;
+    else
+        MacSetSelection( N , select ) ;
 }
 
 bool wxListBox::IsSelected(int N) const
@@ -643,17 +647,51 @@ wxListBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 // list box control implementation
 // ============================================================================
 
-void wxListBox::MacDelete( int N )
+void wxListBox::MacDelete( int n )
 {
+    wxArrayInt selectionBefore ;
+    MacGetSelections( selectionBefore ) ;
+
     UInt32 id = m_noItems+1 ;
     verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
+    for ( size_t i = 0 ; i < selectionBefore.GetCount() ; ++i )
+    {
+        int current = selectionBefore[i] ;
+        if ( current == n )
+        {
+            // selection was deleted
+            MacSetSelection( current , false ) ;
+        }
+        else if ( current > n )
+        {
+            // something behind the deleted item was selected -> move up
+            MacSetSelection( current - 1 , true ) ;            
+            MacSetSelection( current , false ) ;
+        }
+    }
+    // refresh all
     verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
 }
 
 void wxListBox::MacInsert( int n , const wxString& text)
 {
+    wxArrayInt selectionBefore ;
+    MacGetSelections( selectionBefore ) ;
+
     UInt32 id = m_noItems ; // this has already been increased
     verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 ,  (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
+
+    for ( int i = selectionBefore.GetCount()-1 ; i >= 0 ; --i )
+    {
+        int current = selectionBefore[i] ;
+        if ( current >= n )
+        {
+            MacSetSelection( current + 1 , true ) ;            
+            MacSetSelection( current , false ) ;
+        }
+    }
+
+    // refresh all
     verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
 }
 
@@ -661,6 +699,7 @@ void wxListBox::MacAppend( const wxString& text)
 {
     UInt32 id = m_noItems ; // this has already been increased
     verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 ,  (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
+    // no need to deal with selections nor refreshed, as we have appended
 }
 
 void wxListBox::MacClear()
@@ -668,23 +707,34 @@ void wxListBox::MacClear()
     verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 0 , NULL , kDataBrowserItemNoProperty ) ) ;
 }
 
+void wxListBox::MacDeselectAll() 
+{
+    bool former = MacSuppressSelection( true ) ;
+    verify_noerr(m_peer->SetSelectedItems( 0 , NULL , kDataBrowserItemsRemove ) ) ;
+    MacSuppressSelection( former ) ;
+}
+
 void wxListBox::MacSetSelection( int n , bool select )
 {
+    bool former = MacSuppressSelection( true ) ;
     UInt32 id = n + 1 ;
-    if ( !(GetWindowStyle() & (wxLB_MULTIPLE|wxLB_EXTENDED) ) )
-    {
-        int n = MacGetSelection() ;
-        if ( n >= 0 )
-        {
-            UInt32 idOld = n + 1 ;
-            m_peer->SetSelectedItems( 1 , & idOld , kDataBrowserItemsRemove ) ;
-        }
-    }
+
     if ( m_peer->IsItemSelected( id ) != select )
     {
-        verify_noerr(m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsToggle ) ) ;
+        if ( select )
+            verify_noerr(m_peer->SetSelectedItems( 1 , & id , HasMultipleSelection() ? kDataBrowserItemsAdd : kDataBrowserItemsAssign ) ) ;
+        else
+            verify_noerr(m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsRemove ) ) ;
     }
     MacScrollTo( n ) ;
+    MacSuppressSelection( former ) ;
+}
+
+bool  wxListBox::MacSuppressSelection( bool suppress ) 
+{
+       bool former = m_suppressSelection ;
+       m_suppressSelection = suppress ;
+       return former ;
 }
 
 bool wxListBox::MacIsSelected( int n ) const
@@ -694,14 +744,14 @@ bool wxListBox::MacIsSelected( int n ) const
 
 int wxListBox::MacGetSelection() const
 {
-    for ( size_t i = 0 ; i < GetCount() ; ++i )
+    for ( int i = 0 ; i < GetCount() ; ++i )
     {
         if ( m_peer->IsItemSelected( i + 1 ) )
         {
             return i ;
         }
     }
-        return -1 ;
+    return -1 ;
 }
 
 int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
@@ -709,12 +759,18 @@ int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
     int no_sel = 0 ;
     
     aSelections.Empty();
-    for ( size_t i = 0 ; i < GetCount() ; ++i )
+    
+    UInt32 first , last ;
+    m_peer->GetSelectionAnchor( &first , &last ) ;
+    if ( first != kDataBrowserNoItem )
     {
-        if ( m_peer->IsItemSelected( i + 1 ) )
+        for ( size_t i = first ; i <= last ; ++i )
         {
-            aSelections.Add( i ) ;
-            no_sel++ ;
+            if ( m_peer->IsItemSelected( i ) )
+            {
+                aSelections.Add( i - 1 ) ;
+                no_sel++ ;
+            }
         }
     }
     return no_sel ;
@@ -733,74 +789,6 @@ void wxListBox::MacScrollTo( int n )
     verify_noerr(  m_peer->RevealItem( id , kTextColumnId , kDataBrowserRevealWithoutSelecting ) ) ;
 }
 
-#if !TARGET_API_MAC_OSX
-void wxListBox::OnSize( wxSizeEvent &event)
-{
-}
-#endif
-
-void wxListBox::MacSetRedraw( bool doDraw )
-{
-    // nothing to do in compositing mode
-}
-
-void wxListBox::MacDoClick()
-{/*
-    wxArrayInt aSelections;
-    int n ;
-    size_t count = GetSelections(aSelections);
-    
-    if ( count == m_selectionPreImage.GetCount() )
-    {
-        bool hasChanged = false ;
-        for ( size_t i = 0 ; i < count ; ++i )
-        {
-            if ( aSelections[i] != m_selectionPreImage[i] )
-            {
-                hasChanged = true ;
-                break ;
-            }
-        }
-        if ( !hasChanged )
-        {
-            return ;
-        }
-    }
-    
-    m_selectionPreImage = aSelections;
-    
-    wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
-    event.SetEventObject( this );
-    
-    if ( count > 0 )
-    {
-        n = aSelections[0];
-        if ( HasClientObjectData() )
-            event.SetClientObject( GetClientObject(n) );
-        else if ( HasClientUntypedData() )
-            event.SetClientData( GetClientData(n) );
-        event.SetString( GetString(n) );
-    }
-    else
-    {
-        n = -1;
-    }
-    
-    event.m_commandInt = n;
-    
-    GetEventHandler()->ProcessEvent(event);
-*/
-}
-
-void wxListBox::MacDoDoubleClick()
-{
-/*
-    wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
-    event.SetEventObject( this );
-    GetEventHandler()->ProcessEvent(event) ;
-*/
-}
-
 #if !TARGET_API_MAC_OSX
 
 void wxListBox::OnChar(wxKeyEvent& event)