]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
Fixed bug [ 754596 ] wxUSE_CONSTRAINTS 0 breaks AutoLayout() with sizers
[wxWidgets.git] / src / generic / listctrl.cpp
index 5bed03921da555c67400ff8911c4414dc0aedb0e..dc42f4b08a74566a506a4533f99721ca75a0565d 100644 (file)
@@ -282,6 +282,18 @@ public:
 
         // the part to be highlighted
         wxRect m_rectHighlight;
+
+        // extend all our rects to be centered inside theo ne of given width
+        void ExtendWidth(wxCoord w)
+        {
+            wxASSERT_MSG( m_rectAll.width <= w,
+                            _T("width can only be increased") );
+
+            m_rectAll.width = w;
+            m_rectLabel.x = m_rectAll.x + (w - m_rectLabel.width)/2;
+            m_rectIcon.x = m_rectAll.x + (w - m_rectIcon.width)/2;
+            m_rectHighlight.x = m_rectAll.x + (w - m_rectHighlight.width)/2;
+        }
     } *m_gi;
 
     // is this item selected? [NB: not used in virtual mode]
@@ -1115,96 +1127,93 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
 
     wxListItemData *item = node->GetData();
 
+    wxString s;
+    wxCoord lw, lh;
+
     switch ( GetMode() )
     {
         case wxLC_ICON:
         case wxLC_SMALL_ICON:
-            {
-                m_gi->m_rectAll.width = spacing;
-
-                wxString s = item->GetText();
-
-                wxCoord lw, lh;
-                if ( s.empty() )
-                {
-                    lh =
-                    m_gi->m_rectLabel.width =
-                    m_gi->m_rectLabel.height = 0;
-                }
-                else // has label
-                {
-                    dc->GetTextExtent( s, &lw, &lh );
-                    if (lh < SCROLL_UNIT_Y)
-                        lh = SCROLL_UNIT_Y;
-                    lw += EXTRA_WIDTH;
-                    lh += EXTRA_HEIGHT;
-
-                    m_gi->m_rectAll.height = spacing + lh;
-                    if (lw > spacing)
-                        m_gi->m_rectAll.width = lw;
-
-                    m_gi->m_rectLabel.width = lw;
-                    m_gi->m_rectLabel.height = lh;
-                }
+            m_gi->m_rectAll.width = spacing;
 
-                if (item->HasImage())
-                {
-                    int w, h;
-                    m_owner->GetImageSize( item->GetImage(), w, h );
-                    m_gi->m_rectIcon.width = w + 8;
-                    m_gi->m_rectIcon.height = h + 8;
-
-                    if ( m_gi->m_rectIcon.width > m_gi->m_rectAll.width )
-                        m_gi->m_rectAll.width = m_gi->m_rectIcon.width;
-                    if ( m_gi->m_rectIcon.height + lh > m_gi->m_rectAll.height - 4 )
-                        m_gi->m_rectAll.height = m_gi->m_rectIcon.height + lh + 4;
-                }
+            s = item->GetText();
 
-                if ( item->HasText() )
-                {
-                    m_gi->m_rectHighlight.width = m_gi->m_rectLabel.width;
-                    m_gi->m_rectHighlight.height = m_gi->m_rectLabel.height;
-                }
-                else // no text, highlight the icon
-                {
-                    m_gi->m_rectHighlight.width = m_gi->m_rectIcon.width;
-                    m_gi->m_rectHighlight.height = m_gi->m_rectIcon.height;
-                }
+            if ( s.empty() )
+            {
+                lh =
+                m_gi->m_rectLabel.width =
+                m_gi->m_rectLabel.height = 0;
             }
-            break;
-
-        case wxLC_LIST:
+            else // has label
             {
-                wxString s = item->GetTextForMeasuring();
-
-                wxCoord lw,lh;
                 dc->GetTextExtent( s, &lw, &lh );
                 if (lh < SCROLL_UNIT_Y)
                     lh = SCROLL_UNIT_Y;
                 lw += EXTRA_WIDTH;
                 lh += EXTRA_HEIGHT;
 
+                m_gi->m_rectAll.height = spacing + lh;
+                if (lw > spacing)
+                    m_gi->m_rectAll.width = lw;
+
                 m_gi->m_rectLabel.width = lw;
                 m_gi->m_rectLabel.height = lh;
+            }
 
-                m_gi->m_rectAll.width = lw;
-                m_gi->m_rectAll.height = lh;
+            if (item->HasImage())
+            {
+                int w, h;
+                m_owner->GetImageSize( item->GetImage(), w, h );
+                m_gi->m_rectIcon.width = w + 8;
+                m_gi->m_rectIcon.height = h + 8;
+
+                if ( m_gi->m_rectIcon.width > m_gi->m_rectAll.width )
+                    m_gi->m_rectAll.width = m_gi->m_rectIcon.width;
+                if ( m_gi->m_rectIcon.height + lh > m_gi->m_rectAll.height - 4 )
+                    m_gi->m_rectAll.height = m_gi->m_rectIcon.height + lh + 4;
+            }
 
-                if (item->HasImage())
-                {
-                    int w, h;
-                    m_owner->GetImageSize( item->GetImage(), w, h );
-                    m_gi->m_rectIcon.width = w;
-                    m_gi->m_rectIcon.height = h;
-
-                    m_gi->m_rectAll.width += 4 + w;
-                    if (h > m_gi->m_rectAll.height)
-                        m_gi->m_rectAll.height = h;
-                }
+            if ( item->HasText() )
+            {
+                m_gi->m_rectHighlight.width = m_gi->m_rectLabel.width;
+                m_gi->m_rectHighlight.height = m_gi->m_rectLabel.height;
+            }
+            else // no text, highlight the icon
+            {
+                m_gi->m_rectHighlight.width = m_gi->m_rectIcon.width;
+                m_gi->m_rectHighlight.height = m_gi->m_rectIcon.height;
+            }
+            break;
+
+        case wxLC_LIST:
+            s = item->GetTextForMeasuring();
+
+            dc->GetTextExtent( s, &lw, &lh );
+            if (lh < SCROLL_UNIT_Y)
+                lh = SCROLL_UNIT_Y;
+            lw += EXTRA_WIDTH;
+            lh += EXTRA_HEIGHT;
+
+            m_gi->m_rectLabel.width = lw;
+            m_gi->m_rectLabel.height = lh;
 
-                m_gi->m_rectHighlight.width = m_gi->m_rectAll.width;
-                m_gi->m_rectHighlight.height = m_gi->m_rectAll.height;
+            m_gi->m_rectAll.width = lw;
+            m_gi->m_rectAll.height = lh;
+
+            if (item->HasImage())
+            {
+                int w, h;
+                m_owner->GetImageSize( item->GetImage(), w, h );
+                m_gi->m_rectIcon.width = w;
+                m_gi->m_rectIcon.height = h;
+
+                m_gi->m_rectAll.width += 4 + w;
+                if (h > m_gi->m_rectAll.height)
+                    m_gi->m_rectAll.height = h;
             }
+
+            m_gi->m_rectHighlight.width = m_gi->m_rectAll.width;
+            m_gi->m_rectHighlight.height = m_gi->m_rectAll.height;
             break;
 
         case wxLC_REPORT:
@@ -1446,20 +1455,31 @@ void wxListLineData::Draw( wxDC *dc )
         dc->DrawRectangle( m_gi->m_rectHighlight );
     }
 
+    // just for debugging to better see where the items are
+#if 0
+    dc->SetPen(*wxRED_PEN);
+    dc->SetBrush(*wxTRANSPARENT_BRUSH);
+    dc->DrawRectangle( m_gi->m_rectAll );
+    dc->SetPen(*wxGREEN_PEN);
+    dc->DrawRectangle( m_gi->m_rectIcon );
+#endif // 0
+
     wxListItemData *item = node->GetData();
     if (item->HasImage())
     {
-        wxRect rectIcon = m_gi->m_rectIcon;
-        m_owner->DrawImage( item->GetImage(), dc,
-                            rectIcon.x, rectIcon.y );
+        // centre the image inside our rectangle, this looks nicer when items
+        // ae aligned in a row
+        const wxRect& rectIcon = m_gi->m_rectIcon;
+
+        m_owner->DrawImage(item->GetImage(), dc, rectIcon.x, rectIcon.y);
     }
 
     if (item->HasText())
     {
-        wxRect rectLabel = m_gi->m_rectLabel;
+        const wxRect& rectLabel = m_gi->m_rectLabel;
 
         wxDCClipper clipper(*dc, rectLabel);
-        dc->DrawText( item->GetText(), rectLabel.x, rectLabel.y );
+        dc->DrawText(item->GetText(), rectLabel.x, rectLabel.y);
     }
 }
 
@@ -2084,11 +2104,11 @@ void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
     {
         // We must finish regardless of success, otherwise we'll get focus problems
         Finish();
-    
+
         if ( !AcceptChanges() )
             m_owner->OnRenameCancelled( m_itemEdited );
     }
-        
+
     event.Skip();
 }
 
@@ -2818,19 +2838,22 @@ bool wxListMainWindow::OnRenameAccept(size_t itemEdit, const wxString& value)
 # pragma message disable initnotreach
 #endif
 
-void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
+void wxListMainWindow::OnRenameCancelled(size_t WXUNUSED(itemEdit))
 {
     // wxMSW seems not to notify the program about
     // cancelled label edits.
     return;
 
+  #if 0
+    // above unconditional return cause warning about not reachable code
+
     // let owner know that the edit was cancelled
     wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() );
-    
+
     // These only exist for wxTreeCtrl, which should probably be changed
     // le.m_editCancelled = TRUE;
     // le.m_label = wxEmptyString;
-    
+
     le.SetEventObject( GetParent() );
     le.m_itemIndex = itemEdit;
 
@@ -2840,6 +2863,7 @@ void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
     data->GetItem( 0, le.m_item );
 
     GetEventHandler()->ProcessEvent( le );
+  #endif
 }
 #ifdef __VMS__
 # pragma message enable initnotreach
@@ -3892,7 +3916,10 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
             int x = EXTRA_BORDER_X;
             int y = EXTRA_BORDER_Y;
 
-            for ( size_t i = 0; i < count; i++ )
+            wxCoord widthMax = 0;
+
+            size_t i;
+            for ( i = 0; i < count; i++ )
             {
                 wxListLineData *line = GetLine(i);
                 line->CalculateSize( &dc, iconSpacing );
@@ -3902,6 +3929,9 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
 
                 if ( HasFlag(wxLC_ALIGN_TOP) )
                 {
+                    if ( sizeLine.x > widthMax )
+                        widthMax = sizeLine.x;
+
                     y += sizeLine.y;
                 }
                 else // wxLC_ALIGN_LEFT
@@ -3910,6 +3940,18 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
                 }
             }
 
+            if ( HasFlag(wxLC_ALIGN_TOP) )
+            {
+                // traverse the items again and tweak their sizes so that they are
+                // all the same in a row
+                for ( i = 0; i < count; i++ )
+                {
+                    wxListLineData *line = GetLine(i);
+                    line->m_gi->ExtendWidth(widthMax);
+                }
+            }
+
+
             SetScrollbars
             (
                 SCROLL_UNIT_X,
@@ -3927,13 +3969,19 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh)
             // the window, we recalculate after subtracting the space taken by the
             // scrollbar
 
-            int entireWidth = 0,
-                entireHeight = 0;
+            int entireWidth = 0;
+            #if 0
+            // entireHeight is not used so no need to define it
+            int entireHeight = 0;
+            #endif
 
             for (int tries = 0; tries < 2; tries++)
             {
                 entireWidth = 2*EXTRA_BORDER_X;
+                #if 0
+                // entireHeight is not used so no need to define it
                 entireHeight = 2*EXTRA_BORDER_Y;
+                #endif
 
                 if (tries == 1)
                 {
@@ -4302,18 +4350,39 @@ void wxListMainWindow::InsertItem( wxListItem &item )
 
     m_dirty = TRUE;
 
+    #if 0
+    // this is unused variable
     int mode = 0;
+    #endif
     if ( HasFlag(wxLC_REPORT) )
     {
+        #if 0
+        // this is unused variable
         mode = wxLC_REPORT;
+        #endif
         ResetVisibleLinesRange();
     }
     else if ( HasFlag(wxLC_LIST) )
+        #if 0
+        // this is unused variable
         mode = wxLC_LIST;
+        #else
+        {}
+        #endif
     else if ( HasFlag(wxLC_ICON) )
+        #if 0
+        // this is unused variable
         mode = wxLC_ICON;
+        #else
+        {}
+        #endif
     else if ( HasFlag(wxLC_SMALL_ICON) )
+        #if 0
+        // this is unused variable
         mode = wxLC_ICON;  // no typo
+        #else
+        {}
+        #endif
     else
     {
         wxFAIL_MSG( _T("unknown mode") );
@@ -4327,6 +4396,14 @@ void wxListMainWindow::InsertItem( wxListItem &item )
 
     m_dirty = TRUE;
 
+    // If an item is selected at or below the point of insertion, we need to
+    // increment the member variables because the current row's index has gone
+    // up by one
+    if ( HasCurrent() && m_current >= id )
+    {
+        m_current++;
+    }
+
     SendNotify(id, wxEVT_COMMAND_LIST_INSERT_ITEM);
 
     RefreshLines(id, GetItemCount() - 1);
@@ -4511,11 +4588,24 @@ wxGenericListCtrl::~wxGenericListCtrl()
 
 void wxGenericListCtrl::CalculateAndSetHeaderHeight()
 {
-    // we use the letter "H" for calculating the needed space, basing on the current font
-    int w, h;
-    m_headerWin->GetTextExtent(wxT("H"), &w, &h);
-    m_headerHeight = h + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
-    m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
+    if ( m_headerWin )
+    {
+        // we use 'g' to get the descent, too
+        int w, h, d;
+        m_headerWin->GetTextExtent(wxT("Hg"), &w, &h, &d);
+        h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT;
+
+        // only update if there is not enough space
+        if ( h > m_headerHeight )
+        {
+            m_headerHeight = h;
+
+            m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight);
+
+            if ( HasFlag(wxLC_REPORT) && !HasFlag(wxLC_NO_HEADER) )
+                ResizeReportView(TRUE);
+        }
+    }
 }
 
 void wxGenericListCtrl::CreateHeaderWindow()
@@ -5110,7 +5200,7 @@ void wxGenericListCtrl::ResizeReportView(bool showHeader)
 void wxGenericListCtrl::OnInternalIdle()
 {
     wxWindow::OnInternalIdle();
-    
+
     // do it only if needed
     if ( !m_mainWin->m_dirty )
         return;