~wxDataViewHeaderWindowMSW();
- void OnPaint(wxPaintEvent &event);
-
// called when any column setting is changed and/or changed
// the column count
virtual void UpdateDisplay();
{ return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
int m_scrollOffsetX;
+ int m_buttonHeight;
private:
- DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
};
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
{
bool Cleared();
void Resort()
{
- SortPrepare();
- m_root->Resort();
+ if (m_root)
+ {
+ SortPrepare();
+ m_root->Resort();
+ }
UpdateDisplay();
}
m_dc = NULL;
m_align = align;
m_mode = mode;
+ m_wantsAttr = false;
+ m_hasAttr = false;
}
wxDataViewRenderer::~wxDataViewRenderer()
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
// ---------------------------------------------------------
#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;
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()
{
//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:
default:
// such alignment is not allowed for the column header!
- wxFAIL;
+ break; // wxFAIL;
}
SendMessage((HWND)m_hWnd, HDM_INSERTITEM,
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;
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__)
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 )
{
{
// 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;
}
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
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
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 )
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
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)
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();
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 )
//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() )
//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() )
//-----------------------------------------------------------------------------
// wxDataViewCtrl
//-----------------------------------------------------------------------------
-WX_DEFINE_LIST(wxDataViewColumnList);
+WX_DEFINE_LIST(wxDataViewColumnList)
IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
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);
model->AddNotifier( m_notifier );
+ m_clientArea->DestroyTree();
+
m_clientArea->BuildTree(model);
m_clientArea->UpdateDisplay();
bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
{
wxDataViewColumnList::compatibility_iterator ret = m_cols.Find( column );
- if (ret == NULL)
+ if (!ret)
return false;
m_cols.Erase(ret);