]> git.saurik.com Git - wxWidgets.git/commitdiff
Implemended column header mouse clicks.
authorRobert Roebling <robert@roebling.de>
Fri, 6 Oct 2006 09:50:45 +0000 (09:50 +0000)
committerRobert Roebling <robert@roebling.de>
Fri, 6 Oct 2006 09:50:45 +0000 (09:50 +0000)
  Ascending/descending sorting.
  Setting the little arrow indicator for ascending
    and desceding sorting.
  Generic stubs.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41659 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index af2905c47b7933447b3a57b4a12b7fb2e3d6de58..2eb0882ae599a09ce18986388f91be149800d243 100644 (file)
@@ -24,7 +24,7 @@
 
 #if defined(__WXGTK20__)
     // for testing
-    #define wxUSE_GENERICDATAVIEWCTRL 1
+    // #define wxUSE_GENERICDATAVIEWCTRL 1
 #elif defined(__WXMAC__)
     #define wxUSE_GENERICDATAVIEWCTRL 1
 #else
@@ -159,6 +159,9 @@ public:
     wxDataViewSortedListModel( wxDataViewListModel *child );
     virtual ~wxDataViewSortedListModel();
 
+    void SetAscending( bool ascending ) { m_ascending = ascending; }
+    bool GetAscending() { return m_ascending; }
+
     virtual unsigned int GetNumberOfRows();
     virtual unsigned int GetNumberOfCols();
     // return type as reported by wxVariant
@@ -191,9 +194,12 @@ public:
     virtual void Resort();
 
 private:
+    bool                             m_ascending;
     wxDataViewListModel             *m_child;
     wxDataViewSortedIndexArray       m_array;
     wxDataViewListModelNotifier     *m_notifierOnChild;
+    
+    void InitStatics(); // BAD
 
 protected:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewSortedListModel)
@@ -269,7 +275,11 @@ public:
     virtual const wxBitmap &GetBitmap();
     
     virtual void SetAlignment( wxAlignment align ) = 0;
+    
+    virtual void SetSortable( bool sortable ) = 0;
+    virtual bool GetSortable() = 0;
     virtual void SetSortOrder( bool ascending ) = 0;
+    virtual bool IsSortOrderAscending() = 0;
 
     wxDataViewRenderer* GetRenderer()       { return m_renderer; }
 
@@ -359,7 +369,8 @@ public:
         m_row(-1),
         m_model(NULL),
         m_value(wxNullVariant),
-        m_editCancelled(false)
+        m_editCancelled(false),
+        m_column(NULL)
         { }
 
     wxDataViewEvent(const wxDataViewEvent& event)
@@ -368,7 +379,8 @@ public:
         m_row(event.m_col),
         m_model(event.m_model),
         m_value(event.m_value),
-        m_editCancelled(event.m_editCancelled)
+        m_editCancelled(event.m_editCancelled),
+        m_column(event.m_column)
         { }
 
     int GetColumn() const { return m_col; }
@@ -380,6 +392,10 @@ public:
     const wxVariant &GetValue() const { return m_value; }
     void SetValue( const wxVariant &value ) { m_value = value; }
 
+    // for wxEVT_DATAVIEW_COLUMN_HEADER_CLICKED only
+    void SetDataViewColumn( wxDataViewColumn *col ) { m_column = col; }
+    wxDataViewColumn *GetDataViewColumn() { return m_column; }
+
     // was label editing canceled? (for wxEVT_COMMAND_DATVIEW_END_LABEL_EDIT only)
     bool IsEditCancelled() const { return m_editCancelled; }
     void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; }
@@ -392,6 +408,7 @@ protected:
     wxDataViewModel    *m_model;
     wxVariant           m_value;
     bool                m_editCancelled;
+    wxDataViewColumn   *m_column;
 
 private:
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewEvent)
@@ -400,6 +417,8 @@ private:
 BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED, -1)
     DECLARE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED, -1)
+    DECLARE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, -1)
+    DECLARE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, -1)
 END_DECLARE_EVENT_TYPES()
 
 typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&);
@@ -412,6 +431,8 @@ typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&);
 
 #define EVT_DATAVIEW_ROW_SELECTED(id, fn) wx__DECLARE_DATAVIEWEVT(ROW_SELECTED, id, fn)
 #define EVT_DATAVIEW_ROW_ACTIVATED(id, fn) wx__DECLARE_DATAVIEWEVT(ROW_ACTIVATED, id, fn)
+#define EVT_DATAVIEW_COLUMN_HEADER_CLICK(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_HEADER_CLICK, id, fn)
+#define EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICKED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_HEADER_RIGHT_CLICK, id, fn)
 
 
 #if defined(wxUSE_GENERICDATAVIEWCTRL)
index 5d6097d7079c29e367016c2d3a0eedc9e0ef3551..a8800e37aa73e291d9c83f0bb1add01390b2bea6 100644 (file)
@@ -224,7 +224,11 @@ public:
     virtual void SetBitmap( const wxBitmap &bitmap );
     
     virtual void SetAlignment( wxAlignment align );
+    
+    virtual void SetSortable( bool sortable );
+    virtual bool GetSortable();
     virtual void SetSortOrder( bool ascending );
+    virtual bool IsSortOrderAscending();
 
     virtual int GetWidth();
 
index dbb3d78e119e5d62f45b49668bab1892ffd6eb14..6965502b28dd901b5f753fbb2103259a09c63dee 100644 (file)
@@ -198,7 +198,11 @@ public:
     virtual void SetBitmap( const wxBitmap &bitmap );
 
     virtual void SetAlignment( wxAlignment align );
+    
+    virtual void SetSortable( bool sortable );
+    virtual bool GetSortable();
     virtual void SetSortOrder( bool ascending );
+    virtual bool IsSortOrderAscending();
 
     virtual int GetWidth();
     
@@ -211,7 +215,12 @@ public:
 private:
     // holds the GTK handle
     void*   m_column;
-
+    
+    // delayed connection to mouse events
+    friend class wxDataViewCtrl;
+    void OnInternalIdle();
+    bool    m_isConnected;  
+    
 protected:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewColumn)
 };
@@ -257,13 +266,15 @@ public:
     virtual int GetSelection() const;
     virtual int GetSelections(wxArrayInt& aSelections) const;
     
-    
 private:
     friend class wxDataViewCtrlDC;
+    friend class wxDataViewColumn;
     friend class wxGtkDataViewListModelNotifier;
     GtkWidget                   *m_treeview;
     wxDataViewListModelNotifier *m_notifier;
     
+    virtual void OnInternalIdle();
+    
 private:
     DECLARE_DYNAMIC_CLASS(wxDataViewCtrl)
     DECLARE_NO_COPY_CLASS(wxDataViewCtrl)
index cea6827c421b0deacd2bb96fd622f33866f9d225..be70dd56be48e8565ed998014756901b7c22577d 100644 (file)
@@ -338,6 +338,9 @@ public:
     void OnSelectedSorted(wxDataViewEvent &event);
     void OnActivatedUnsorted(wxDataViewEvent &event);
 
+    void OnHeaderClickSorted(wxDataViewEvent &event);
+    void OnHeaderClickUnsorted(wxDataViewEvent &event);
+
 private:
     wxDataViewCtrl* dataview_left;
     wxDataViewCtrl* dataview_right;
@@ -345,7 +348,8 @@ private:
     wxLog          *m_logOld;
     wxTextCtrl     *m_logWindow;
 
-    MyUnsortedTextModel *m_unsorted_model;
+    MyUnsortedTextModel        *m_unsorted_model;
+    wxDataViewSortedListModel  *m_sorted_model;
 
     DECLARE_EVENT_TABLE()
 };
@@ -474,6 +478,8 @@ BEGIN_EVENT_TABLE(MySortingFrame,wxFrame)
     EVT_DATAVIEW_ROW_SELECTED( ID_SORTED, MySortingFrame::OnSelectedSorted )
     EVT_DATAVIEW_ROW_SELECTED( ID_UNSORTED, MySortingFrame::OnSelectedUnsorted )
     EVT_DATAVIEW_ROW_ACTIVATED( ID_UNSORTED, MySortingFrame::OnActivatedUnsorted )
+    EVT_DATAVIEW_COLUMN_HEADER_CLICK( ID_SORTED, MySortingFrame::OnHeaderClickSorted )
+    EVT_DATAVIEW_COLUMN_HEADER_CLICK( ID_UNSORTED, MySortingFrame::OnHeaderClickUnsorted )
 END_EVENT_TABLE()
 
 MySortingFrame::MySortingFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
@@ -515,9 +521,8 @@ MySortingFrame::MySortingFrame(wxFrame *frame, wxChar *title, int x, int y, int
     // Right wxDataViewCtrl using the sorting model
     dataview_right = new wxDataViewCtrl( this, ID_SORTED );
     
-    wxDataViewSortedListModel *sorted_model =
-        new wxDataViewSortedListModel( m_unsorted_model );
-    dataview_right->AssociateModel( sorted_model );
+    m_sorted_model = new wxDataViewSortedListModel( m_unsorted_model );
+    dataview_right->AssociateModel( m_sorted_model );
     text_renderer = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_EDITABLE );
     column = new wxDataViewColumn( wxT("editable"), text_renderer, 0, -1, wxDATAVIEW_COL_SORTABLE|wxDATAVIEW_COL_RESIZABLE );
     dataview_right->AppendColumn( column );
@@ -592,6 +597,34 @@ void MySortingFrame::OnActivatedUnsorted(wxDataViewEvent &event)
     wxLogMessage( wxT("OnActivated from unsorted list, activated %d"), (int) event.GetRow() );
 }
 
+void MySortingFrame::OnHeaderClickSorted(wxDataViewEvent &event)
+{
+    wxDataViewColumn *col = event.GetDataViewColumn();
+    wxLogMessage( wxT("OnHeaderClick from sorted list, column %s"), col->GetTitle().c_str() );
+    
+    if (col->GetTitle() == wxT("editable"))
+    {
+        // this is the sorting column
+        if (col->IsSortOrderAscending())
+        {
+            col->SetSortOrder( false );
+            m_sorted_model->SetAscending( false );
+            m_sorted_model->Resort();
+        }
+        else
+        {
+            col->SetSortOrder( true );
+            m_sorted_model->SetAscending( true );
+            m_sorted_model->Resort();
+        }
+    }
+}
+
+void MySortingFrame::OnHeaderClickUnsorted(wxDataViewEvent &event)
+{
+    wxLogMessage( wxT("OnHeaderClick from unsorted list, column %s"), event.GetDataViewColumn()->GetTitle().c_str() );
+}
+
 void MySortingFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
 {
     Close(true);
index 976723b2f4249a10144cb9956052af12d2c6bf49..26d78c6b4d2800001a65ec3cdd040673daa73858 100644 (file)
@@ -287,9 +287,15 @@ int wxCALLBACK wxDataViewListModelSortedDefaultCompare
     return 0;
 }
 
+int wxCALLBACK wxDataViewListModelSortedDefaultCompareDescending
+      (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model )
+{
+    return wxDataViewListModelSortedDefaultCompare( row2, row1, col, model );
+}
+
 static wxDataViewListModelCompare   s_CmpFunc;
 static wxDataViewListModel         *s_CmpModel;
-static unsigned int                       s_CmpCol;
+static unsigned int                 s_CmpCol;
 
 int LINKAGEMODE wxDataViewIntermediateCmp( unsigned int row1, unsigned int row2 )
 {
@@ -306,9 +312,8 @@ wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child
   m_array( wxDataViewIntermediateCmp )
 {
     m_child = child;
-    s_CmpCol = 0;
-    s_CmpModel = child;
-    s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
+    
+    m_ascending = true;
 
     m_notifierOnChild = new wxDataViewSortedListModelNotifier( this );
     m_child->AddNotifier( m_notifierOnChild );
@@ -321,8 +326,21 @@ wxDataViewSortedListModel::~wxDataViewSortedListModel()
     m_child->RemoveNotifier( m_notifierOnChild );
 }
 
+// FIXME
+void wxDataViewSortedListModel::InitStatics()
+{
+    s_CmpCol = 0;
+    s_CmpModel = m_child;
+    if (m_ascending)
+        s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
+    else
+        s_CmpFunc = wxDataViewListModelSortedDefaultCompareDescending;
+}
+
 void wxDataViewSortedListModel::Resort()
 {
+    InitStatics();
+    
     m_array.Clear();
     unsigned int n = m_child->GetNumberOfRows();
     unsigned int i;
@@ -866,6 +884,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
 
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
 
 
 #endif
index d3564748c10079afd9438516147b49908e697b3f..e3886ffcf4dc7573928f0b17ab66eaddc114cbab 100644 (file)
@@ -617,11 +617,29 @@ void wxDataViewColumn::SetAlignment( wxAlignment WXUNUSED(align) )
     // TODO
 }
 
+void wxDataViewColumn::SetSortable( bool WXUNUSED(sortable) )
+{
+    // TODO
+}
+
+bool wxDataViewColumn::GetSortable()
+{   
+    // TODO
+    return false;
+}
+
 void wxDataViewColumn::SetSortOrder( bool WXUNUSED(ascending) )
 {
     // TODO
 }
 
+bool wxDataViewColumn::IsSortOrderAscending()
+{
+    // TODO
+    return true;
+}
+
+
 wxDataViewColumn::~wxDataViewColumn()
 {
 }
index 752e3e69a8b1ad8e068121e71d3df62e50303168..7d4d4eafb09437b20f4c141b93e9f2cc31e89c26 100644 (file)
@@ -1384,6 +1384,27 @@ bool wxDataViewDateRenderer::Activate( wxRect cell, wxDataViewListModel *model,
 // wxDataViewColumn
 // ---------------------------------------------------------
 
+
+static gboolean
+gtk_dataview_header_button_press_callback( GtkWidget *widget,
+                                           GdkEventButton *gdk_event,
+                                           wxDataViewColumn *column )
+{
+    if (gdk_event->type != GDK_BUTTON_PRESS)
+        return TRUE;
+        
+    if (gdk_event->button == 1)
+    {
+        wxDataViewCtrl *dv = column->GetOwner();
+        wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, dv->GetId() );
+        event.SetDataViewColumn( column );
+        event.SetModel( dv->GetModel() );
+        dv->GetEventHandler()->ProcessEvent( event );
+    }
+    
+    return TRUE;
+}
+
 extern "C" {
 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column,
                             GtkCellRenderer *cell,
@@ -1423,11 +1444,16 @@ wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewRenderer *c
     int width, int flags ) :
     wxDataViewColumnBase( title, cell, model_column, width, flags )
 {
+    m_isConnected = false;
+
     GtkCellRenderer *renderer = (GtkCellRenderer *) cell->GetGtkHandle();
 
     GtkTreeViewColumn *column = gtk_tree_view_column_new();
-
-    gtk_tree_view_column_set_title( column, wxGTK_CONV(title) );
+    m_column = (void*) column;
+    
+    gtk_tree_view_column_set_clickable( column, true );
+    
+    SetTitle( title );
 
     if (flags & wxDATAVIEW_COL_RESIZABLE)
         gtk_tree_view_column_set_resizable( column, true );
@@ -1447,13 +1473,14 @@ wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewRenderer *c
     gtk_tree_view_column_set_cell_data_func( column, renderer,
         wxGtkTreeCellDataFunc, (gpointer) cell, NULL );
 
-    m_column = (void*) column;
 }
 
 wxDataViewColumn::wxDataViewColumn( const wxBitmap &bitmap, wxDataViewRenderer *cell, unsigned int model_column,
     int width, int flags ) :
     wxDataViewColumnBase( bitmap, cell, model_column, width, flags )
 {
+    m_isConnected = false;
+    
     GtkCellRenderer *renderer = (GtkCellRenderer *) cell->GetGtkHandle();
 
     GtkTreeViewColumn *column = gtk_tree_view_column_new();
@@ -1484,13 +1511,41 @@ wxDataViewColumn::~wxDataViewColumn()
 {
 }
 
+void wxDataViewColumn::OnInternalIdle()
+{
+    if (m_isConnected)
+        return;
+        
+    if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview))
+    {
+        GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
+        if (column->button)
+        {
+            g_signal_connect(column->button, "button_press_event",
+                      G_CALLBACK (gtk_dataview_header_button_press_callback), this);
+    
+            m_isConnected = true;
+        }
+    }
+}
+
 void wxDataViewColumn::SetTitle( const wxString &title )
 {
     wxDataViewColumnBase::SetTitle( title );
 
     GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
-    gtk_tree_view_column_set_title( column, wxGTK_CONV(title) );
     
+    if (m_isConnected)
+    {
+        // disconnect before column->button gets recreated
+        g_signal_handlers_disconnect_by_func( column->button, 
+                      (void*) gtk_dataview_header_button_press_callback, this);
+                      
+        m_isConnected = false;
+    }
+
+    gtk_tree_view_column_set_title( column, wxGTK_CONV(title) );
+
     gtk_tree_view_column_set_widget( column, NULL );
 }
 
@@ -1540,6 +1595,18 @@ void wxDataViewColumn::SetAlignment( wxAlignment align )
     gtk_tree_view_column_set_alignment( column, xalign );    
 }
 
+void wxDataViewColumn::SetSortable( bool sortable )
+{
+    GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
+    gtk_tree_view_column_set_sort_indicator( column, sortable );
+}
+
+bool wxDataViewColumn::GetSortable()
+{
+    GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
+    return gtk_tree_view_column_get_sort_indicator( column );
+}
+
 void wxDataViewColumn::SetSortOrder( bool ascending )
 {
     GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
@@ -1550,6 +1617,13 @@ void wxDataViewColumn::SetSortOrder( bool ascending )
         gtk_tree_view_column_set_sort_order( column, GTK_SORT_DESCENDING );
 }
 
+bool wxDataViewColumn::IsSortOrderAscending()
+{
+    GtkTreeViewColumn *column = (GtkTreeViewColumn *)m_column;
+    
+    return (gtk_tree_view_column_get_sort_order( column ) != GTK_SORT_DESCENDING);
+}
+
 int wxDataViewColumn::GetWidth()
 {
     return gtk_tree_view_column_get_width( (GtkTreeViewColumn *)m_column );
@@ -1652,6 +1726,19 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
     return true;
 }
 
+void wxDataViewCtrl::OnInternalIdle()
+{
+    wxWindow::OnInternalIdle();
+    
+    unsigned int cols = GetNumberOfColumns();
+    unsigned int i;
+    for (i = 0; i < cols; i++)
+    {
+        wxDataViewColumn *col = GetColumn( i );
+        col->OnInternalIdle();
+    }
+}
+
 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
 {
     if (!wxDataViewCtrlBase::AssociateModel( model ))