- HDITEM item;
- item.mask = HDI_LPARAM;
- Header_GetItem((HWND)m_hWnd, nmHDR->iItem, &item);
-
- return (unsigned int)item.lParam;
-}
-
-bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
-{
- NMHDR *nmhdr = (NMHDR *)lParam;
-
- // is it a message from the header?
- if ( nmhdr->hwndFrom != (HWND)m_hWnd )
- return wxWindow::MSWOnNotify(idCtrl, lParam, result);
-
- NMHEADER *nmHDR = (NMHEADER *)nmhdr;
- switch ( nmhdr->code )
- {
- case HDN_BEGINTRACK:
- // user has started to resize a column:
- // do we need to veto it?
- if (!GetColumn(nmHDR->iItem)->IsResizeable())
- {
- // veto it!
- *result = TRUE;
- }
- break;
-
- case HDN_BEGINDRAG:
- // user has started to reorder a column
- if ((nmHDR->iItem != -1) && (!GetColumn(nmHDR->iItem)->IsReorderable()))
- {
- // veto it!
- *result = TRUE;
- }
- break;
-
- case HDN_ENDDRAG: // user has finished reordering a column
- {
- wxDataViewColumn *col = GetColumn(nmHDR->iItem);
- unsigned int new_pos = nmHDR->pitem->iOrder;
- m_owner->ColumnMoved( col, new_pos );
- m_delayedUpdate = true;
- }
- break;
-
- case HDN_ITEMCHANGING:
- if (nmHDR->pitem != NULL &&
- (nmHDR->pitem->mask & HDI_WIDTH) != 0)
- {
- int minWidth = GetColumnFromHeader(nmHDR)->GetMinWidth();
- if (nmHDR->pitem->cxy < minWidth)
- {
- // do not allow the user to resize this column under
- // its minimal width:
- *result = TRUE;
- }
- }
- break;
-
- case HDN_ITEMCHANGED: // user is resizing a column
- case HDN_ENDTRACK: // user has finished resizing a column
-
- // update the width of the modified column:
- if (nmHDR->pitem != NULL &&
- (nmHDR->pitem->mask & HDI_WIDTH) != 0)
- {
- unsigned int idx = GetColumnIdxFromHeader(nmHDR);
- unsigned int w = nmHDR->pitem->cxy;
- wxDataViewColumn *col = GetColumn(idx);
-
- // see UpdateDisplay() for more info about COLUMN_WIDTH_OFFSET
- if (idx == 0 && w > COLUMN_WIDTH_OFFSET)
- w -= COLUMN_WIDTH_OFFSET;
-
- if (w >= (unsigned)col->GetMinWidth())
- col->SetInternalWidth(w);
- }
- break;
-
- case HDN_ITEMCLICK:
- {
- unsigned int idx = GetColumnIdxFromHeader(nmHDR);
- wxDataViewModel * model = GetOwner()->GetModel();
-
- if(nmHDR->iButton == 0)
- {
- wxDataViewColumn *col = GetColumn(idx);
- if(col->IsSortable())
- {
- if(model && m_owner->GetSortingColumn() == col)
- {
- bool order = col->IsSortOrderAscending();
- col->SetSortOrder(!order);
- }
- else if(model)
- {
- m_owner->SetSortingColumn(col);
- }
- }
- UpdateDisplay();
- if(model)
- model->Resort();
- }
-
- wxEventType evt = nmHDR->iButton == 0 ?
- wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK :
- wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK;
- SendEvent(evt, idx);
- }
- break;
-
- case NM_RCLICK:
- {
- // NOTE: for some reason (i.e. for a bug in Windows)
- // the HDN_ITEMCLICK notification is not sent on
- // right clicks, so we need to handle NM_RCLICK
-
- POINT ptClick;
- int column = wxMSWGetColumnClicked(nmhdr, &ptClick);
- if (column != wxNOT_FOUND)
- {
- HDITEM item;
- item.mask = HDI_LPARAM;
- Header_GetItem((HWND)m_hWnd, column, &item);
-
- // 'idx' may be different from 'column' if there are
- // hidden columns...
- unsigned int idx = (unsigned int)item.lParam;
- SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK,
- idx);
- }
- }
- break;
-
- case HDN_GETDISPINFOW:
- // see wxListCtrl::MSWOnNotify for more info!
- break;
-
- case HDN_ITEMDBLCLICK:
- {
- unsigned int idx = GetColumnIdxFromHeader(nmHDR);
- int w = GetOwner()->GetBestColumnWidth(idx);
-
- // update the native control:
- HDITEM hd;
- ZeroMemory(&hd, sizeof(hd));
- hd.mask = HDI_WIDTH;
- hd.cxy = w;
- Header_SetItem(GetHwnd(),
- nmHDR->iItem, // NOTE: we don't want 'idx' here!
- &hd);
-
- // update the wxDataViewColumn class:
- GetColumn(idx)->SetInternalWidth(w);
- }
- break;
-
- default:
- return wxWindow::MSWOnNotify(idCtrl, lParam, result);
- }
-
- return true;
-}
-
-void wxDataViewHeaderWindowMSW::ScrollWindow(int dx, int WXUNUSED(dy),
- const wxRect * WXUNUSED(rect))
-{
- m_scrollOffsetX += dx;
-
- GetParent()->Layout();
-}
-
-void wxDataViewHeaderWindowMSW::DoSetSize(int x, int y,
- int w, int h,
- int 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__)
-
-IMPLEMENT_ABSTRACT_CLASS(wxGenericDataViewHeaderWindow, wxWindow)
-BEGIN_EVENT_TABLE(wxGenericDataViewHeaderWindow, wxWindow)
- EVT_PAINT (wxGenericDataViewHeaderWindow::OnPaint)
- EVT_MOUSE_EVENTS (wxGenericDataViewHeaderWindow::OnMouse)
- EVT_SET_FOCUS (wxGenericDataViewHeaderWindow::OnSetFocus)
-END_EVENT_TABLE()
-
-bool wxGenericDataViewHeaderWindow::Create(wxDataViewCtrl *parent, wxWindowID id,
- const wxPoint &pos, const wxSize &size,
- const wxString &name )
-{
- m_owner = parent;
-
- if (!wxDataViewHeaderWindowBase::Create(parent, id, pos, size, name))
- return false;
-
- wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
- SetBackgroundStyle( wxBG_STYLE_CUSTOM );
- SetOwnForegroundColour( attr.colFg );
- SetOwnBackgroundColour( attr.colBg );
- if (!m_hasFont)
- SetOwnFont( attr.font );
-
- // 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, HEADER_WINDOW_HEIGHT));
- SetMaxSize(wxSize(-1, HEADER_WINDOW_HEIGHT));
-
- return true;
-}
-
-void wxGenericDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
-{
- int w, h;
- GetClientSize( &w, &h );
-
- wxAutoBufferedPaintDC dc( this );
-
- dc.SetBackground(GetBackgroundColour());
- dc.Clear();
-
- int xpix;
- m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
-
- int x;
- m_owner->GetViewStart( &x, NULL );
-
- // account for the horz scrollbar offset
- dc.SetDeviceOrigin( -x * xpix, 0 );
-
- dc.SetFont( GetFont() );
-
- unsigned int cols = GetOwner()->GetColumnCount();
- unsigned int i;
- int xpos = 0;
- for (i = 0; i < cols; i++)
- {
- wxDataViewColumn *col = GetColumn( i );
- if (col->IsHidden())
- continue; // skip it!
-
- int cw = col->GetWidth();
- int ch = h;
-
- wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE;
- if (col->IsSortable() && GetOwner()->GetSortingColumn() == col)
- {
- if (col->IsSortOrderAscending())
- sortArrow = wxHDR_SORT_ICON_UP;
- else
- sortArrow = wxHDR_SORT_ICON_DOWN;
- }
-
- int state = 0;
- if (m_parent->IsEnabled())
- {
- if ((int) i == m_hover)
- state = wxCONTROL_CURRENT;
- }
- else
- {
- state = (int) wxCONTROL_DISABLED;
- }
-
- wxRendererNative::Get().DrawHeaderButton
- (
- this,
- dc,
- wxRect(xpos, 0, cw, ch-1),
- state,
- sortArrow
- );
-
- // align as required the column title:
- int x = xpos;
- wxSize titleSz = dc.GetTextExtent(col->GetTitle());
- switch (col->GetAlignment())
- {
- case wxALIGN_LEFT:
- x += HEADER_HORIZ_BORDER;
- break;
- case wxALIGN_RIGHT:
- x += cw - titleSz.GetWidth() - HEADER_HORIZ_BORDER;
- break;
- default:
- case wxALIGN_CENTER:
- case wxALIGN_CENTER_HORIZONTAL:
- x += (cw - titleSz.GetWidth() - 2 * HEADER_HORIZ_BORDER)/2;
- break;
- }
-
- // always center the title vertically:
- int y = wxMax((ch - titleSz.GetHeight()) / 2, HEADER_VERT_BORDER);
-
- dc.SetClippingRegion( xpos+HEADER_HORIZ_BORDER,
- HEADER_VERT_BORDER,
- wxMax(cw - 2 * HEADER_HORIZ_BORDER, 1), // width
- wxMax(ch - 2 * HEADER_VERT_BORDER, 1)); // height
- dc.DrawText( col->GetTitle(), x, y );
- dc.DestroyClippingRegion();
-
- xpos += cw;
- }
-}
-
-void wxGenericDataViewHeaderWindow::OnSetFocus( wxFocusEvent &event )
-{
- GetParent()->SetFocus();
- event.Skip();
-}