X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/70a9e561dfbcfc43f7f0f8efe0acd56024d4cb06..3cd25cff50f35741c8f5327865068593e214e4ca:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index fa031653a4..57d8ae6d58 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -134,8 +134,6 @@ public: ~wxDataViewHeaderWindowMSW(); - void OnPaint(wxPaintEvent &event); - // called when any column setting is changed and/or changed // the column count virtual void UpdateDisplay(); @@ -156,9 +154,9 @@ protected: { return GetColumn(GetColumnIdxFromHeader(nmHDR)); } int m_scrollOffsetX; + int m_buttonHeight; private: - DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW) }; @@ -407,7 +405,7 @@ int LINKAGEMODE wxGenericTreeModelItemCmp( void ** id1, void ** id2) WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection, WXDLLIMPEXP_ADV); WX_DECLARE_LIST(wxDataViewItem, ItemList); -WX_DEFINE_LIST(ItemList); +WX_DEFINE_LIST(ItemList) class wxDataViewMainWindow: public wxWindow { @@ -427,8 +425,11 @@ public: bool Cleared(); void Resort() { - SortPrepare(); - m_root->Resort(); + if (m_root) + { + SortPrepare(); + m_root->Resort(); + } UpdateDisplay(); } @@ -609,6 +610,8 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, m_dc = NULL; m_align = align; m_mode = mode; + m_wantsAttr = false; + m_hasAttr = false; } wxDataViewRenderer::~wxDataViewRenderer() @@ -715,6 +718,60 @@ wxSize wxDataViewTextRenderer::GetSize() const return wxSize(80,20); } +// --------------------------------------------------------- +// wxDataViewTextRendererAttr +// --------------------------------------------------------- + +IMPLEMENT_CLASS(wxDataViewTextRendererAttr, wxDataViewTextRenderer) + +wxDataViewTextRendererAttr::wxDataViewTextRendererAttr( const wxString &varianttype, + wxDataViewCellMode mode, int align ) : + wxDataViewTextRenderer( varianttype, mode, align ) +{ + m_wantsAttr = true; +} + +bool wxDataViewTextRendererAttr::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) +{ + wxFont font; + wxColour colour; + + if (m_hasAttr) + { + if (m_attr.HasColour()) + { + colour = dc->GetTextForeground(); + dc->SetTextForeground( m_attr.GetColour() ); + } + + if (m_attr.GetBold() || m_attr.GetItalic()) + { + font = dc->GetFont(); + wxFont myfont = font; + if (m_attr.GetBold()) + myfont.SetWeight( wxFONTWEIGHT_BOLD ); + if (m_attr.GetItalic()) + myfont.SetStyle( wxFONTSTYLE_ITALIC ); + dc->SetFont( myfont ); + } + } + + dc->DrawText( m_text, cell.x, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); + + // restore dc + if (m_hasAttr) + { + if (m_attr.HasColour()) + dc->SetTextForeground( colour ); + + if (m_attr.GetBold() || m_attr.GetItalic()) + dc->SetFont( font ); + } + + return true; +} + + // --------------------------------------------------------- // wxDataViewBitmapRenderer // --------------------------------------------------------- @@ -1195,34 +1252,38 @@ void wxDataViewHeaderWindowBase::SendEvent(wxEventType type, unsigned int n) #if defined(__WXMSW__) && USE_NATIVE_HEADER_WINDOW +#ifndef HDS_DRAGDROP + #define HDS_DRAGDROP 0x0040 +#endif +#ifndef HDS_FULLDRAG + #define HDS_FULLDRAG 0x0080 +#endif + // implemented in msw/listctrl.cpp: int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick); IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindowMSW, wxWindow) -BEGIN_EVENT_TABLE(wxDataViewHeaderWindowMSW, wxDataViewHeaderWindowBase) - // EVT_PAINT (wxDataViewHeaderWindowMSW::OnPaint) -END_EVENT_TABLE() - bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, const wxString &name ) { m_owner = parent; - m_scrollOffsetX = 0;; + m_scrollOffsetX = 0; + m_buttonHeight = wxRendererNative::Get().GetHeaderButtonHeight( this ) + 10; int x = pos.x == wxDefaultCoord ? 0 : pos.x, y = pos.y == wxDefaultCoord ? 0 : pos.y, w = size.x == wxDefaultCoord ? 1 : size.x, - h = size.y == wxDefaultCoord ? 22 : size.y; + h = size.y == wxDefaultCoord ? m_buttonHeight : size.y; if ( !CreateControl(parent, id, pos, size, 0, wxDefaultValidator, name) ) return false; // create the native WC_HEADER window: WXHWND hwndParent = (HWND)parent->GetHandle(); - WXDWORD msStyle = WS_CHILD | HDS_BUTTONS | HDS_HORZ | HDS_HOTTRACK | HDS_FULLDRAG; + WXDWORD msStyle = WS_CHILD | HDS_DRAGDROP | HDS_BUTTONS | HDS_HORZ | HDS_HOTTRACK | HDS_FULLDRAG; if ( m_isShown ) msStyle |= WS_VISIBLE; @@ -1260,57 +1321,7 @@ wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow() wxSize wxDataViewHeaderWindowMSW::DoGetBestSize() const { - return wxSize(80, 22); -} - -void wxDataViewHeaderWindowMSW::OnPaint(wxPaintEvent &event) -{ - wxClientDC dc(this); - - int sortArrow = wxHDR_SORT_ICON_UP; - - wxRect rect(0,0,80,22); - - // Draw an up or down arrow - int arrowSpace = 0; - if (sortArrow != wxHDR_SORT_ICON_NONE ) - { - wxRect ar = rect; - - // make a rect for the arrow - ar.height = 4; - ar.width = 8; - ar.y += (rect.height - ar.height)/2; - ar.x = ar.x + rect.width - 3*ar.width/2; - arrowSpace = 3*ar.width/2; // space to preserve when drawing the label - - wxPoint triPt[3]; - if ( sortArrow & wxHDR_SORT_ICON_UP ) - { - triPt[0].x = ar.width / 2; - triPt[0].y = 0; - triPt[1].x = ar.width; - triPt[1].y = ar.height; - triPt[2].x = 0; - triPt[2].y = ar.height; - } - else - { - triPt[0].x = 0; - triPt[0].y = 0; - triPt[1].x = ar.width; - triPt[1].y = 0; - triPt[2].x = ar.width / 2; - triPt[2].y = ar.height; - } - - wxColour c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW); - dc.SetPen(wxPen(c)); - dc.SetBrush(wxBrush(c)); - dc.DrawPolygon( 3, triPt, ar.x, ar.y); - } - - event.Skip(); + return wxSize(80, m_buttonHeight ); } void wxDataViewHeaderWindowMSW::UpdateDisplay() @@ -1340,10 +1351,8 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay() { //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 - - // if (col->IsSortOrderAscending()) - // hdi.fmt |= col->IsSortOrderAscending() ? HDF_SORTUP : HDF_SORTDOWN; - // ; + // VZ: works with 5.81 + hdi.fmt |= col->IsSortOrderAscending() ? HDF_SORTUP : HDF_SORTDOWN; } // lParam is reserved for application's use: @@ -1373,7 +1382,7 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay() default: // such alignment is not allowed for the column header! - wxFAIL; + break; // wxFAIL; } SendMessage((HWND)m_hWnd, HDM_INSERTITEM, @@ -1548,7 +1557,8 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA return true; } -void wxDataViewHeaderWindowMSW::ScrollWindow(int dx, int dy, const wxRect *rect ) +void wxDataViewHeaderWindowMSW::ScrollWindow(int dx, int WXUNUSED(dy), + const wxRect * WXUNUSED(rect)) { m_scrollOffsetX += dx; @@ -1559,7 +1569,8 @@ void wxDataViewHeaderWindowMSW::DoSetSize(int x, int y, int w, int h, int f) { - wxControl::DoSetSize( x+m_scrollOffsetX, y, w-m_scrollOffsetX, h, f ); + // TODO: why is there a border + 2px around it? + wxControl::DoSetSize( x+m_scrollOffsetX+1, y+1, w-m_scrollOffsetX-2, h-2, f ); } #else // !defined(__WXMSW__) @@ -1890,7 +1901,7 @@ END_EVENT_TABLE() wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, const wxString &name ) : - wxWindow( parent, id, pos, size, wxWANTS_CHARS, name ), + wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE, name ), m_selection( wxDataViewSelectionCmp ) { @@ -2400,25 +2411,46 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { // get the cell value and set it into the renderer wxVariant value; - wxDataViewTreeNode * node = GetTreeNodeByRow(item); - if( node == NULL ) - continue; + wxDataViewTreeNode *node = NULL; + wxDataViewItem dataitem; + + if (m_root) + { + node = GetTreeNodeByRow(item); + if( node == NULL ) + continue; - wxDataViewItem dataitem = node->GetItem(); + dataitem = node->GetItem(); - if ((i > 0) && model->IsContainer(dataitem) && !model->HasContainerColumns(dataitem)) - continue; + if ((i > 0) && model->IsContainer(dataitem) && !model->HasContainerColumns(dataitem)) + continue; + } + else + { + dataitem = wxDataViewItem( (void*) item ); + } model->GetValue( value, dataitem, col->GetModelColumn()); cell->SetValue( value ); + + if (cell->GetWantsAttr()) + { + wxDataViewItemAttr attr; + bool ret = model->GetAttr( dataitem, col->GetModelColumn(), attr ); + if (ret) + cell->SetAttr( attr ); + cell->SetHasAttr( ret ); + } // update the y offset cell_rect.y = item * m_lineHeight; //Draw the expander here. - int indent = node->GetIndentLevel(); - if( col == expander ) + int indent = 0; + if ((m_root) && (col == expander)) { + indent = node->GetIndentLevel(); + //Calculate the indent first indent = cell_rect.x + GetOwner()->GetIndent() * indent; @@ -2443,9 +2475,11 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) } else { - // I am wandering whether we should draw dot lines between tree nodes - delete node; - //Yes, if the node does not have any child, it must be a leaf which mean that it is a temporarily created by GetTreeNodeByRow + // I am wondering whether we should draw dot lines between tree nodes + if (node) + delete node; + // Yes, if the node does not have any child, it must be a leaf which + // mean that it is a temporarily created by GetTreeNodeByRow } //force the expander column to left-center align @@ -2842,9 +2876,16 @@ private: wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row) const { - RowToItemJob job( row, -2 ); - Walker( m_root , job ); - return job.GetResult(); + if (!m_root) + { + return wxDataViewItem( (void*) row ); + } + else + { + RowToItemJob job( row, -2 ); + Walker( m_root , job ); + return job.GetResult(); + } } class RowToTreeNodeJob: public DoJob @@ -2917,9 +2958,16 @@ private: wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) { - RowToTreeNodeJob job( row , -2, m_root ); - Walker( m_root , job ); - return job.GetResult(); + if (!m_root) + { + return NULL; + } + else + { + RowToTreeNodeJob job( row , -2, m_root ); + Walker( m_root , job ); + return job.GetResult(); + } } wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item ) @@ -3106,7 +3154,15 @@ wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxD int wxDataViewMainWindow::RecalculateCount() { - return m_root->GetSubTreeCount(); + if (!m_root) + { + wxDataViewIndexListModel *list_model = (wxDataViewIndexListModel*) GetOwner()->GetModel(); + return list_model->GetLastIndex(); + } + else + { + return m_root->GetSubTreeCount(); + } } class ItemToRowJob : public DoJob @@ -3160,26 +3216,33 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) if( model == NULL ) return -1; - if( !item.IsOk() ) - return -1; - - //Compose the a parent-chain of the finding item - ItemList list; - wxDataViewItem * pItem = NULL; - list.DeleteContents( true ); - wxDataViewItem it( item ); - while( it.IsOk() ) + if (!m_root) { - pItem = new wxDataViewItem( it ); - list.Insert( pItem ); - it = model->GetParent( it ); + return wxPtrToUInt( item.GetID() ); } - pItem = new wxDataViewItem( ); - list.Insert( pItem ); + else + { + if( !item.IsOk() ) + return -1; + + //Compose the a parent-chain of the finding item + ItemList list; + wxDataViewItem * pItem = NULL; + list.DeleteContents( true ); + wxDataViewItem it( item ); + while( it.IsOk() ) + { + pItem = new wxDataViewItem( it ); + list.Insert( pItem ); + it = model->GetParent( it ); + } + pItem = new wxDataViewItem( ); + list.Insert( pItem ); - ItemToRowJob job( item, list.begin() ); - Walker(m_root , job ); - return job.GetResult(); + ItemToRowJob job( item, list.begin() ); + Walker(m_root , job ); + return job.GetResult(); + } } void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node) @@ -3214,6 +3277,17 @@ void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataVie void wxDataViewMainWindow::BuildTree(wxDataViewModel * model) { + DestroyTree(); + + if (GetOwner()->GetModel()->IsIndexListModel()) + { + m_count = -1 ; + return; + } + + m_root = new wxDataViewTreeNode( NULL ); + m_root->SetHasChildren(true); + //First we define a invalid item to fetch the top-level elements wxDataViewItem item; SortPrepare(); @@ -3238,9 +3312,12 @@ void DestroyTreeHelper( wxDataViewTreeNode * node ) void wxDataViewMainWindow::DestroyTree() { - DestroyTreeHelper(m_root); - m_root->SetSubTreeCount(0); - m_count = 0 ; + if (m_root) + { + DestroyTreeHelper(m_root); + m_count = 0; + m_root = NULL; + } } void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) @@ -3380,7 +3457,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) //Test whether the mouse is hovered on the tree item button bool hover = false; - if (GetOwner()->GetExpanderColumn() == col) + if ((m_root) && (GetOwner()->GetExpanderColumn() == col)) { wxDataViewTreeNode * node = GetTreeNodeByRow(current); if( node!=NULL && node->HasChildren() ) @@ -3505,7 +3582,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) //Process the event of user clicking the expander bool expander = false; - if (GetOwner()->GetExpanderColumn() == col) + if ((m_root) && (GetOwner()->GetExpanderColumn() == col)) { wxDataViewTreeNode * node = GetTreeNodeByRow(current); if( node!=NULL && node->HasChildren() ) @@ -3672,7 +3749,7 @@ wxDataViewItem wxDataViewMainWindow::GetSelection() const //----------------------------------------------------------------------------- // wxDataViewCtrl //----------------------------------------------------------------------------- -WX_DEFINE_LIST(wxDataViewColumnList); +WX_DEFINE_LIST(wxDataViewColumnList) IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase) @@ -3696,7 +3773,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, long style, const wxValidator& validator ) { if (!wxControl::Create( parent, id, pos, size, - style | wxScrolledWindowStyle|wxSUNKEN_BORDER, validator)) + style | wxScrolledWindowStyle|wxBORDER_SUNKEN, validator)) return false; SetInitialSize(size); @@ -3767,6 +3844,8 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) model->AddNotifier( m_notifier ); + m_clientArea->DestroyTree(); + m_clientArea->BuildTree(model); m_clientArea->UpdateDisplay(); @@ -3836,7 +3915,7 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column ) { wxDataViewColumnList::compatibility_iterator ret = m_cols.Find( column ); - if (ret == NULL) + if (!ret) return false; m_cols.Erase(ret);