]> git.saurik.com Git - wxWidgets.git/commitdiff
Patch from Bo, adapt generic code to new API, add GetItemRect and HitTest
authorRobert Roebling <robert@roebling.de>
Mon, 20 Aug 2007 17:26:11 +0000 (17:26 +0000)
committerRobert Roebling <robert@roebling.de>
Mon, 20 Aug 2007 17:26:11 +0000 (17:26 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48223 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/dataview.h
include/wx/generic/dataview.h
include/wx/gtk/dataview.h
src/common/datavcmn.cpp
src/generic/datavgen.cpp
src/gtk/dataview.cpp

index 051447a2f19575be1040e810803c2a1484a5fecc..76b98fcf144d3b91a65e553426478f8e9c93fb9c 100644 (file)
@@ -25,7 +25,7 @@
 
 #if defined(__WXGTK20__)
     // for testing
-    // #define wxUSE_GENERICDATAVIEWCTRL 1
+    #define wxUSE_GENERICDATAVIEWCTRL 1
 #elif defined(__WXMAC__)
 #else
     #define wxUSE_GENERICDATAVIEWCTRL 1
@@ -154,7 +154,7 @@ public:
     // default compare function
     virtual int Compare( const wxDataViewItem &item1, const wxDataViewItem &item2, 
                          unsigned int column, bool ascending );
-    
+
 protected:
     // the user should not delete this class directly: he should use DecRef() instead!
     virtual ~wxDataViewModel() { }
@@ -487,6 +487,11 @@ public:
 
     virtual void EnsureVisible( const wxDataViewItem & item,
                                 wxDataViewColumn *column = NULL ) = 0;
+                                
+    virtual void HitTest( const wxPoint &point, 
+                          wxDataViewItem &item, unsigned int &column ) const = 0;
+    virtual wxRect GetItemRect( const wxDataViewItem &item, 
+                          unsigned int column ) const = 0;
 
 protected:
     virtual void DoSetExpanderColumn() = 0 ;
index 083d4b1cfb1478ccea9c3a45c563a798e21b1ec7..4207e50ef655483ac3488bf18a388815e2f9885d 100644 (file)
@@ -326,6 +326,7 @@ class WXDLLIMPEXP_ADV wxDataViewCtrl: public wxDataViewCtrlBase,
 public:
     wxDataViewCtrl() : wxScrollHelperNative(this)
     {
+        m_sortingColumn = 0;
         Init();
     }
 
@@ -353,12 +354,22 @@ public:
     virtual void DoSetExpanderColumn();
     virtual void DoSetIndent();
 
+    virtual wxDataViewItem GetSelection();
     virtual int GetSelections( wxDataViewItemArray & sel ) const;
     virtual void SetSelections( const wxDataViewItemArray & sel );
     virtual void Select( const wxDataViewItem & item );
     virtual void Unselect( const wxDataViewItem & item );
     virtual bool IsSelected( const wxDataViewItem & item ) const;
 
+    virtual void SelectAll();
+    virtual void UnselectAll();
+
+    virtual void EnsureVisible( const wxDataViewItem & item,
+                                wxDataViewColumn *column = NULL );
+    virtual void HitTest( const wxPoint & point, wxDataViewItem & item, unsigned int & column ) const;
+    virtual wxRect GetItemRect( const wxDataViewItem & item, unsigned int column ) const;
+
+protected:
     virtual int GetSelections( wxArrayInt & sel ) const; 
     virtual void SetSelections( const wxArrayInt & sel );
     virtual void Select( int row );
@@ -367,15 +378,13 @@ public:
     virtual void SelectRange( int from, int to );
     virtual void UnselectRange( int from, int to );
 
-    virtual void SelectAll();
-    virtual void UnselectAll();
-
     virtual void EnsureVisible( int row );
-    virtual void EnsureVisible( const wxDataViewItem & item, wxDataViewColumn *column = NULL );
 
     virtual wxDataViewItem GetItemByRow( unsigned int row ) const;
     virtual int GetRowByItem( const wxDataViewItem & item ) const;
 
+    unsigned int GetSortingColumn() { return m_sortingColumn; }
+    void SetSortingColumn( unsigned int column ) { m_sortingColumn = column; }
 
 public:     // utility functions not part of the API
 
@@ -394,6 +403,7 @@ private:
     wxDataViewModelNotifier *m_notifier;
     wxDataViewMainWindow        *m_clientArea;
     wxDataViewHeaderWindow      *m_headerArea;
+    unsigned int m_sortingColumn;
 
 private:
     void OnSize( wxSizeEvent &event );
index d98ec0fb1063dc9c1a406ac2bee7c0e27138875c..6a94076629a356d0b235bc9c20aae417984fd290 100644 (file)
@@ -317,6 +317,12 @@ public:
 
     virtual void EnsureVisible( const wxDataViewItem & item, wxDataViewColumn *column = NULL );
 
+    virtual void HitTest( const wxPoint &point, 
+                          wxDataViewItem &item, unsigned int &column ) const;
+    virtual wxRect GetItemRect( const wxDataViewItem &item, 
+                          unsigned int column ) const;
+
+
     static wxVisualAttributes
     GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
     
index 1572f8c75f8ef4d9d6e07b6b64b98c5a40e6352e..87e5d3b807229c7512a9907d7c88d219051a6d30 100644 (file)
@@ -683,6 +683,9 @@ bool wxDataViewCtrlBase::ClearColumns()
 
 wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos )
 {
+    if( pos >= m_cols.GetCount() )
+        return NULL;
+
     return (wxDataViewColumn*) m_cols[ pos ];
 }
 
index 0f609572ed50d7a28fa4f08e0e9b02a27ef1a1f4..5caf300891a9074323c8d3092a6512b06745a3ad 100644 (file)
@@ -385,15 +385,17 @@ private:
 //Below is the compare stuff
 //For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
 static wxDataViewModel * g_model;
+static unsigned int g_column;
+static bool g_asending;
 
 int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode * node1, wxDataViewTreeNode * node2)
 {
-    return g_model->Compare( node1->GetItem(), node2->GetItem() );
+    return g_model->Compare( node1->GetItem(), node2->GetItem(), g_column, g_asending );
 }
 
 int LINKAGEMODE wxGenericTreeModelItemCmp( void * id1, void * id2)
 {
-    return g_model->Compare( id1, id2 );
+    return g_model->Compare( id1, id2, g_column, g_asending );
 }
 
 
@@ -425,8 +427,25 @@ public:
     bool ValueChanged( const wxDataViewItem &item, unsigned int col );
     bool Cleared();
     void Resort()
-        { g_model = GetOwner()->GetModel(); m_root->Resort(); UpdateDisplay(); }
+    { 
+        SortPrepare();
+        m_root->Resort(); 
+        UpdateDisplay(); 
+    }
 
+    void SortPrepare()
+    {
+        g_model = GetOwner()->GetModel(); 
+        g_column = GetOwner()->GetSortingColumn();
+        wxDataViewColumn * col = GetOwner()->GetColumn(g_column);
+        if( !col )
+        {
+            g_asending = true;
+            return;
+        }
+        g_asending = col->IsSortOrderAscending();    
+    }
+       
     void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
     wxDataViewCtrl *GetOwner() { return m_owner; }
     const wxDataViewCtrl *GetOwner() const { return m_owner; }
@@ -490,6 +509,8 @@ public:
     //Methods for building the mapping tree
     void BuildTree( wxDataViewModel  * model );
     void DestroyTree();
+    void HitTest( const wxPoint & point, wxDataViewItem & item, unsigned int & column );
+    wxRect GetItemRect( const wxDataViewItem & item, unsigned int column );
 private:
     wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row );
     //We did not need this temporarily
@@ -497,6 +518,7 @@ private:
 
     int RecalculateCount() ;
 
+    wxDataViewEvent SendExpanderEvent( wxEventType type, const wxDataViewItem & item );
     void OnExpanding( unsigned int row );
     void OnCollapsing( unsigned int row );
 
@@ -1197,7 +1219,7 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
         //hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
 
         //sorting support
-        if(model && model->GetSortingColumn() == i)
+        if(model && m_owner->GetSortingColumn() == i)
         {
             //The Microsoft Comctrl32.dll 6.0 support SORTUP/SORTDOWN, but they are not default
             //see http://msdn2.microsoft.com/en-us/library/ms649534.aspx for more detail
@@ -1332,16 +1354,14 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA
                     wxDataViewColumn *col = GetColumn(idx);
                     if(col->IsSortable())
                     {
-                        if(model && model->GetSortingColumn() == idx)
+                        if(model && m_owner->GetSortingColumn() == idx)
                         {
                             bool order = col->IsSortOrderAscending();
                             col->SetSortOrder(!order);
-                            model->SetSortOrderAscending(!order);
                         }
                         else if(model)
                         {
-                            model->SetSortingColumn(idx);
-                            model->SetSortOrderAscending(col->IsSortOrderAscending());
+                            m_owner->SetSortingColumn(idx);
                         }
                     }
                     UpdateDisplay();
@@ -1505,7 +1525,7 @@ void wxGenericDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         int ch = h;
 
         wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE;
-        if (col->IsSortable() && GetOwner()->GetModel()->GetSortingColumn() == i)
+        if (col->IsSortable() && GetOwner()->GetSortingColumn() == i)
         {
             if (col->IsSortOrderAscending())
                 sortArrow = wxHDR_SORT_ICON_UP;
@@ -1670,17 +1690,15 @@ void wxGenericDataViewHeaderWindow::OnMouse( wxMouseEvent &event )
                     wxDataViewColumn *col = GetColumn(m_column);
                     if(col->IsSortable())
                     {
-                        unsigned int colnum = model->GetSortingColumn();
+                        unsigned int colnum = m_owner->GetSortingColumn();
                         if(model && static_cast<int>(colnum) == m_column)
                         {
                             bool order = col->IsSortOrderAscending();
                             col->SetSortOrder(!order);
-                            model->SetSortOrderAscending(!order);
                         }
                         else if(model)
                         {
-                            model->SetSortingColumn(m_column);
-                            model->SetSortOrderAscending(col->IsSortOrderAscending());
+                            m_owner->SetSortingColumn(m_column);
                         }
                     }
                     UpdateDisplay();
@@ -1944,7 +1962,7 @@ void wxDataViewMainWindow::SendModelEvent( wxEventType type, const wxDataViewIte
 
 bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
 {
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
 
     wxDataViewTreeNode * node;
     node = FindNode(parent);
@@ -1978,7 +1996,7 @@ void DestroyTreeHelper( wxDataViewTreeNode * node);
 bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
                                        const wxDataViewItem& item)
 {
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
 
     wxDataViewTreeNode * node;
     node = FindNode(parent);
@@ -2029,7 +2047,7 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
 
 bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item)
 {
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
     g_model->Resort();
 
     SendModelEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED,item);
@@ -2048,7 +2066,7 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
 
     return true;
 */
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
     g_model->Resort();
 
     //Send event
@@ -2066,7 +2084,7 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
 
 bool wxDataViewMainWindow::Cleared()
 {
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
 
     DestroyTree();
     UpdateDisplay();
@@ -2757,20 +2775,41 @@ wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row)
     return job.GetResult();
 }
 
+wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item )
+{
+    wxWindow *parent = GetParent();
+    wxDataViewEvent le(type, parent->GetId());
+
+    le.SetEventObject(parent);
+    le.SetModel(GetOwner()->GetModel());
+    le.SetItem( item );
+
+    parent->GetEventHandler()->ProcessEvent(le);
+    return le;
+}
+
 void wxDataViewMainWindow::OnExpanding( unsigned int row )
 {
     wxDataViewTreeNode * node = GetTreeNodeByRow(row);
     if( node != NULL )
     {
         if( node->HasChildren())
+        {
             if( !node->IsOpen())
             {
+               wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,node->GetItem());
+               //Check if the user prevent expanding
+               if( e.GetSkipped() )
+                    return;
+               
                node->ToggleOpen();
                //Here I build the children of current node
                if( node->GetChildrenNumber() == 0 )
                    BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
                m_count = -1;
                UpdateDisplay();
+               //Send the expanded event
+               SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,node->GetItem());
             }
             else
             {
@@ -2778,6 +2817,7 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row )
                 SelectRow( row + 1, true );
                 ChangeCurrentRow( row + 1 );
             }
+        }
         else
             delete node;
     }
@@ -2792,27 +2832,30 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
 
         if( node->HasChildren() && node->IsOpen() )
         {
+            wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,node->GetItem());
+            if( e.GetSkipped() )
+                return;
             node->ToggleOpen();
             m_count = -1;
             UpdateDisplay();
-            //RefreshRows(row,GetLastVisibleRow());
-         }
-         else
-         {
-             node = node->GetParent();
-             if( node != NULL )
-             {
-                 int  parent = GetRowByItem( node->GetItem() ) ;
-                 if( parent >= 0 )
-                 {
-                     SelectRow( row, false);
-                     SelectRow(parent , true );
-                     ChangeCurrentRow( parent );
-                 }
-             }
-         }
-         if( !nd->HasChildren())
-             delete nd;
+            SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,nd->GetItem());
+        }
+        else
+        {
+            node = node->GetParent();
+            if( node != NULL )
+            {
+                int  parent = GetRowByItem( node->GetItem() ) ;
+                if( parent >= 0 )
+                {
+                    SelectRow( row, false);
+                    SelectRow(parent , true );
+                    ChangeCurrentRow( parent );
+                }
+            }
+        }
+        if( !nd->HasChildren())
+            delete nd;
     }
 }
 
@@ -2858,6 +2901,49 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
     return node;
 }
 
+void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, unsigned int & column )
+{
+    unsigned int cols = GetOwner()->GetColumnCount();
+    unsigned int colnum = 0;
+    unsigned int x_start = 0;
+    int x, y;
+    m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
+    for (x_start = 0; colnum < cols; colnum++)
+    {
+        wxDataViewColumn *col = GetOwner()->GetColumn(colnum);
+        if (col->IsHidden())
+            continue;      // skip it!
+
+        unsigned int w = col->GetWidth();
+        if (x_start+w >= (unsigned int)x)
+            break;
+
+        x_start += w;
+    }
+
+    column = colnum;
+    item = GetItemByRow( y/m_lineHeight );
+}
+
+wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, unsigned int column )
+{
+    int row = GetRowByItem(item);
+    int y = row*m_lineHeight;
+    int h = m_lineHeight;
+    int x = 0;
+    wxDataViewColumn *col = NULL;
+    for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
+    {
+       col = GetOwner()->GetColumn( i );
+       x += col->GetWidth();
+       if( i == column - 1 )
+           break;
+    }
+    int w = col->GetWidth();
+    m_owner->CalcScrolledPosition( x, y, &x, &y );
+    return wxRect(x, y, w, h);
+}
+
 int wxDataViewMainWindow::RecalculateCount()
 {
     return m_root->GetSubTreeCount();
@@ -2970,7 +3056,7 @@ void wxDataViewMainWindow::BuildTree(wxDataViewModel * model)
 {
     //First we define a invalid item to fetch the top-level elements
     wxDataViewItem item;
-    g_model = GetOwner()->GetModel();
+    SortPrepare();
     BuildTreeHelper( model, item, m_root);
     m_count = -1 ;
 }
@@ -3494,6 +3580,11 @@ void wxDataViewCtrl::DoSetIndent()
 }
 
 //Selection code with wxDataViewItem as parameters
+wxDataViewItem wxDataViewCtrl::GetSelection()
+{
+    return m_clientArea->GetSelection();
+}
+
 int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
 {
     sel.Empty();
@@ -3622,13 +3713,23 @@ void wxDataViewCtrl::EnsureVisible( int row )
     m_clientArea->ScrollTo( row );
 }
 
-void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, wxDataViewColumn *column )
+void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, wxDataViewColumn * column )
 {
     int row = m_clientArea->GetRowByItem(item);
     if( row >= 0 )
         EnsureVisible(row);
 }
 
+void wxDataViewCtrl::HitTest( const wxPoint & point, wxDataViewItem & item, unsigned int & column ) const
+{
+    m_clientArea->HitTest(point, item, column);
+}
+
+wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem & item, unsigned int column ) const
+{
+    return m_clientArea->GetItemRect(item, column);
+}
+
 wxDataViewItem wxDataViewCtrl::GetItemByRow( unsigned int row ) const
 {
     return m_clientArea->GetItemByRow( row );
index c74207cd42464426eea0a1d9b67566afeb78a4d3..b27fb05cc9ebd5e5e59cbdd4d68e9c7844140b03 100644 (file)
@@ -3156,6 +3156,19 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, wxDataViewColum
     gtk_tree_path_free( path );
 }
 
+void wxDataViewCtrl::HitTest( const wxPoint &point, 
+                          wxDataViewItem &item, unsigned int &column ) const
+{
+    item = wxDataViewItem(0);
+    column = 0;
+}
+
+wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, 
+                          unsigned int column ) const
+{
+    return wxRect();
+}
+
 void wxDataViewCtrl::DoSetExpanderColumn()
 {
 }