X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/736fe67c66e0f5a552f3b45e13d288f5c650c46e..d949570b6673dadd764686213afb89bddb6f19da:/src/generic/datavgen.cpp?ds=inline diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 8c9cd03309..adcf1b3582 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -63,7 +63,7 @@ static const int EXPANDER_MARGIN = 4; // wxDataViewHeaderWindow //----------------------------------------------------------------------------- -#define USE_NATIVE_HEADER_WINDOW 0 +#define USE_NATIVE_HEADER_WINDOW 1 //Below is the compare stuff //For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed @@ -138,17 +138,23 @@ public: // the column count virtual void UpdateDisplay(); - // called when the main window gets scrolled + // called Refresh afterwards virtual void ScrollWindow(int dx, int dy, const wxRect *rect = NULL); protected: virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); + virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags); + wxSize DoGetBestSize() const; + unsigned int GetColumnIdxFromHeader(NMHEADER *nmHDR); wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR) { return GetColumn(GetColumnIdxFromHeader(nmHDR)); } + + int m_scrollOffsetX; + int m_buttonHeight; private: DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW) @@ -268,7 +274,7 @@ class wxDataViewTreeNode { public: wxDataViewTreeNode( wxDataViewTreeNode * parent = NULL ) - { + { m_parent = parent; if (!parent) m_open = true; @@ -277,7 +283,7 @@ public: m_hasChildren = false; m_subTreeCount = 0; } - + ~wxDataViewTreeNode() { } @@ -399,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 { @@ -601,6 +607,8 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, m_dc = NULL; m_align = align; m_mode = mode; + m_wantsAttr = false; + m_hasAttr = false; } wxDataViewRenderer::~wxDataViewRenderer() @@ -635,6 +643,16 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, { } +void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state ) +{ + wxDataViewCtrl *view = GetOwner()->GetOwner(); + wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? + wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : + view->GetForegroundColour(); + dc->SetTextForeground(col); + dc->DrawText( text, cell.x + xoffset, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); +} + // --------------------------------------------------------- // wxDataViewTextRenderer // --------------------------------------------------------- @@ -681,15 +699,7 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVarian bool wxDataViewTextRenderer::Render( wxRect cell, wxDC *dc, int state ) { - wxDataViewCtrl *view = GetOwner()->GetOwner(); - wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? - wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : - view->GetForegroundColour(); - - dc->SetTextForeground(col); - dc->DrawText( m_text, cell.x, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); - // dc->DrawText( m_text, cell.x, cell.y ); - + RenderText( m_text, 0, cell, dc, state ); return true; } @@ -705,6 +715,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 // --------------------------------------------------------- @@ -950,12 +1014,10 @@ bool wxDataViewDateRenderer::GetValue( wxVariant &value ) const return true; } -bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) +bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int state ) { - dc->SetFont( GetOwner()->GetOwner()->GetFont() ); wxString tmp = m_date.FormatDate(); - dc->DrawText( tmp, cell.x, cell.y ); - + RenderText( tmp, 0, cell, dc, state ); return true; } @@ -1012,31 +1074,22 @@ bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) return true; } -bool wxDataViewIconTextRenderer::GetValue( wxVariant &value ) const +bool wxDataViewIconTextRenderer::GetValue( wxVariant& WXUNUSED(value) ) const { return false; } bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) { - wxDataViewCtrl *view = GetOwner()->GetOwner(); - - dc->SetFont( view->GetFont() ); - - wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? - wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : - view->GetForegroundColour(); - - dc->SetTextForeground(col); - + int xoffset = 0; const wxIcon &icon = m_value.GetIcon(); if (icon.IsOk()) { - dc->DrawIcon( icon, cell.x, cell.y + ((cell.height - icon.GetHeight()) / 2)); - cell.x += icon.GetWidth()+4; + dc->DrawIcon( icon, cell.x, cell.y + ((cell.height - icon.GetHeight()) / 2)); + xoffset = icon.GetWidth()+4; } - dc->DrawText( m_value.GetText(), cell.x, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); + RenderText( m_value.GetText(), xoffset, cell, dc, state ); return true; } @@ -1048,7 +1101,7 @@ wxSize wxDataViewIconTextRenderer::GetSize() const { int x,y; view->GetTextExtent( m_value.GetText(), &x, &y ); - + if (m_value.GetIcon().IsOk()) x += m_value.GetIcon().GetWidth() + 4; return wxSize( x, y ); @@ -1056,12 +1109,17 @@ wxSize wxDataViewIconTextRenderer::GetSize() const return wxSize(80,20); } -wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ) +wxControl * +wxDataViewIconTextRenderer::CreateEditorCtrl(wxWindow * WXUNUSED(parent), + wxRect WXUNUSED(labelRect), + const wxVariant& WXUNUSED(value)) { return NULL; } -bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( wxControl* editor, wxVariant &value ) +bool +wxDataViewIconTextRenderer::GetValueFromEditorCtrl(wxControl* WXUNUSED(editor), + wxVariant& WXUNUSED(value)) { return false; } @@ -1191,6 +1249,13 @@ 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); @@ -1202,17 +1267,24 @@ bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id, { m_owner = parent; - if ( !CreateControl(parent, id, pos, size, 0, wxDefaultValidator, name) ) - return false; + 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; + m_hWnd = CreateWindowEx(0, WC_HEADER, (LPCTSTR) NULL, @@ -1235,37 +1307,7 @@ bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id, // the following is required to get the default win's font for // header windows and must be done befor sending the HDM_LAYOUT msg SetFont(GetFont()); - - RECT rcParent; - HDLAYOUT hdl; - WINDOWPOS wp; - - // Retrieve the bounding rectangle of the parent window's - // client area, and then request size and position values - // from the header control. - ::GetClientRect((HWND)hwndParent, &rcParent); - - hdl.prc = &rcParent; - hdl.pwpos = ℘ - if (!SendMessage((HWND)m_hWnd, HDM_LAYOUT, 0, (LPARAM) &hdl)) - { - wxLogLastError(_T("SendMessage")); - return false; - } - - // Set the size, position, and visibility of the header control. - SetWindowPos((HWND)m_hWnd, - wp.hwndInsertAfter, - wp.x, wp.y, - wp.cx, wp.cy, - wp.flags | SWP_SHOWWINDOW); - - // set our size hints: wxDataViewCtrl will put this wxWindow inside - // a wxBoxSizer and in order to avoid super-big header windows, - // we need to set our height as fixed - SetMinSize(wxSize(-1, wp.cy)); - SetMaxSize(wxSize(-1, wp.cy)); - + return true; } @@ -1274,6 +1316,11 @@ wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow() UnsubclassWin(); } +wxSize wxDataViewHeaderWindowMSW::DoGetBestSize() const +{ + return wxSize(80, m_buttonHeight ); +} + void wxDataViewHeaderWindowMSW::UpdateDisplay() { // remove old columns @@ -1283,7 +1330,6 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay() // add the updated array of columns to the header control unsigned int cols = GetOwner()->GetColumnCount(); unsigned int added = 0; - wxDataViewModel * model = GetOwner()->GetModel(); for (unsigned int i = 0; i < cols; i++) { wxDataViewColumn *col = GetColumn( i ); @@ -1298,13 +1344,12 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay() hdi.fmt = HDF_LEFT | HDF_STRING; //hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP); - //sorting support - if(model && m_owner->GetSortingColumn() == col) + if (col->IsSortable() && GetOwner()->GetSortingColumn() == col) { //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 - //hdi.fmt |= model->GetSortOrderAscending()? HDF_SORTUP:HDF_SORTDOWN; - ; + // VZ: works with 5.81 + hdi.fmt |= col->IsSortOrderAscending() ? HDF_SORTUP : HDF_SORTDOWN; } // lParam is reserved for application's use: @@ -1334,7 +1379,7 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay() default: // such alignment is not allowed for the column header! - wxFAIL; + break; // wxFAIL; } SendMessage((HWND)m_hWnd, HDM_INSERTITEM, @@ -1509,32 +1554,20 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA return true; } -void wxDataViewHeaderWindowMSW::ScrollWindow(int WXUNUSED(dx), int WXUNUSED(dy), - const wxRect *WXUNUSED(rect)) +void wxDataViewHeaderWindowMSW::ScrollWindow(int dx, int WXUNUSED(dy), + const wxRect * WXUNUSED(rect)) { - wxSize ourSz = GetClientSize(); - wxSize ownerSz = m_owner->GetClientSize(); - - // where should the (logical) origin of this window be placed? - int x1 = 0, y1 = 0; - m_owner->CalcUnscrolledPosition(0, 0, &x1, &y1); - - // put this window on top of our parent and - SetWindowPos((HWND)m_hWnd, HWND_TOP, -x1, 0, - ownerSz.GetWidth() + x1, ourSz.GetHeight(), - SWP_SHOWWINDOW); + m_scrollOffsetX += dx; + + GetParent()->Layout(); } -void wxDataViewHeaderWindowMSW::DoSetSize(int WXUNUSED(x), int WXUNUSED(y), - int WXUNUSED(w), int WXUNUSED(h), - int WXUNUSED(f)) +void wxDataViewHeaderWindowMSW::DoSetSize(int x, int y, + int w, int h, + int f) { - // the wxDataViewCtrl's internal wxBoxSizer will call this function when - // the wxDataViewCtrl window gets resized: the following dummy call - // to ScrollWindow() is required in order to get this header window - // correctly repainted when it's (horizontally) scrolled: - - ScrollWindow(0, 0); + // 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__) @@ -1612,7 +1645,7 @@ void wxGenericDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) else sortArrow = wxHDR_SORT_ICON_DOWN; } - + int state = 0; if (m_parent->IsEnabled()) { @@ -1740,7 +1773,7 @@ void wxGenericDataViewHeaderWindow::OnMouse( wxMouseEvent &event ) m_minX = xpos; } - + int old_hover = m_hover; m_hover = m_column; if (event.Leaving()) @@ -1865,7 +1898,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 ) { @@ -2117,7 +2150,7 @@ bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item) le.SetModel(GetOwner()->GetModel()); le.SetItem(item); parent->GetEventHandler()->ProcessEvent(le); - + return true; } @@ -2380,12 +2413,21 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) continue; wxDataViewItem dataitem = node->GetItem(); - + if ((i > 0) && model->IsContainer(dataitem) && !model->HasContainerColumns(dataitem)) continue; - + 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; @@ -2462,7 +2504,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) item_rect.x += indent; int state = 0; - if (m_selection.Index(item) != wxNOT_FOUND) + if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND)) state |= wxDATAVIEW_CELL_SELECTED; // TODO: it would be much more efficient to create a clipping @@ -3370,12 +3412,12 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (m_underMouse && m_underMouse != node) { //wxLogMessage("Undo the row: %d", GetRowByItem(m_underMouse->GetItem())); - Refresh(GetRowByItem(m_underMouse->GetItem())); + RefreshRow(GetRowByItem(m_underMouse->GetItem())); } if (m_underMouse != node) { //wxLogMessage("Do the row: %d", current); - Refresh(current); + RefreshRow(current); } m_underMouse = node; } @@ -3388,7 +3430,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (m_underMouse != NULL) { //wxLogMessage("Undo the row: %d", GetRowByItem(m_underMouse->GetItem())); - Refresh(GetRowByItem(m_underMouse->GetItem())); + RefreshRow(GetRowByItem(m_underMouse->GetItem())); m_underMouse = NULL; } } @@ -3434,7 +3476,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) ((GetOwner()->GetExpanderColumn() != col) && (model->IsContainer(item)) && (!model->HasContainerColumns(item))); - + if (event.LeftDClick()) { if ( current == m_lineLastClicked ) @@ -3453,7 +3495,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { wxWindow *parent = GetParent(); wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId()); - le.SetItem( GetItemByRow(current) ); + le.SetItem( item ); le.SetEventObject(parent); le.SetModel(GetOwner()->GetModel()); @@ -3647,7 +3689,7 @@ wxDataViewItem wxDataViewMainWindow::GetSelection() const //----------------------------------------------------------------------------- // wxDataViewCtrl //----------------------------------------------------------------------------- -WX_DEFINE_LIST(wxDataViewColumnList); +WX_DEFINE_LIST(wxDataViewColumnList) IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase) @@ -3671,11 +3713,11 @@ 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); - + Init(); #ifdef __WXMAC__ @@ -3696,7 +3738,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, sizer->Add( m_headerArea, 0, wxGROW ); sizer->Add( m_clientArea, 1, wxGROW ); SetSizer( sizer ); - + return true; } @@ -3811,7 +3853,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);