#include "wx/icon.h"
#include "wx/list.h"
#include "wx/listimpl.cpp"
+#include "wx/imaglist.h"
//-----------------------------------------------------------------------------
// classes
// wxDataViewHeaderWindow
//-----------------------------------------------------------------------------
-#define USE_NATIVE_HEADER_WINDOW !defined(__WXUNIVERSAL__)
+// on wxMSW the header window (only that part however) can be made native!
+#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
+ #define USE_NATIVE_HEADER_WINDOW
+#endif
//Below is the compare stuff
//For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
void SendEvent(wxEventType type, unsigned int n);
};
-// on wxMSW the header window (only that part however) can be made native!
-#if defined(__WXMSW__) && USE_NATIVE_HEADER_WINDOW
+#ifdef USE_NATIVE_HEADER_WINDOW
#define COLUMN_WIDTH_OFFSET 2
#define wxDataViewHeaderWindowMSW wxDataViewHeaderWindow
wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR)
{ return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
- int m_scrollOffsetX;
- int m_buttonHeight;
- bool m_delayedUpdate;
+ int m_scrollOffsetX;
+ int m_buttonHeight;
+ bool m_delayedUpdate;
+ wxImageList *m_imageList;
private:
DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
return m_dc;
}
+void wxDataViewRenderer::SetAlignment( int align )
+{
+ m_align=align;
+}
+
+int wxDataViewRenderer::GetAlignment() const
+{
+ return m_align;
+}
+
+int wxDataViewRenderer::CalculateAlignment() const
+{
+ if (m_align == wxDVR_DEFAULT_ALIGNMENT)
+ {
+ if (GetOwner() == NULL)
+ return wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL;
+
+ return GetOwner()->GetAlignment() | wxALIGN_CENTRE_VERTICAL;
+ }
+
+ return m_align;
+}
+
// ---------------------------------------------------------
// wxDataViewCustomRenderer
// ---------------------------------------------------------
SetAlignment(align);
SetFlags(flags);
- Init(width < 0 ? wxDVC_TOGGLE_DEFAULT_WIDTH : width);
+ Init(width < 0 ? wxDVC_DEFAULT_WIDTH : width);
}
wxDataViewColumn::~wxDataViewColumn()
parent->GetEventHandler()->ProcessEvent(le);
}
-#if defined(__WXMSW__) && USE_NATIVE_HEADER_WINDOW
+#ifdef USE_NATIVE_HEADER_WINDOW
#ifndef HDS_DRAGDROP
#define HDS_DRAGDROP 0x0040
return false;
}
+ m_imageList = new wxImageList( 16, 16 );
+ Header_SetImageList( (HWND) m_hWnd, m_imageList->GetHIMAGELIST() );
+
// we need to subclass the m_hWnd to force wxWindow::HandleNotify
// to call wxDataViewHeaderWindow::MSWOnNotify
SubclassWin(m_hWnd);
wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow()
{
+ delete m_imageList;
UnsubclassWin();
}
// remove old columns
for (int j=0, max=Header_GetItemCount((HWND)m_hWnd); j < max; j++)
Header_DeleteItem((HWND)m_hWnd, 0);
+
+ m_imageList->RemoveAll();
// add the updated array of columns to the header control
unsigned int cols = GetOwner()->GetColumnCount();
HDITEM hdi;
hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
+ if (col->GetBitmap().IsOk())
+ {
+ m_imageList->Add( col->GetBitmap() );
+ hdi.mask |= HDI_IMAGE;
+ hdi.iImage = m_imageList->GetImageCount()-1;
+ }
hdi.pszText = (wxChar *) col->GetTitle().wx_str();
hdi.cxy = col->GetWidth();
hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]);
hdi.fmt = HDF_LEFT | HDF_STRING;
+ if (col->GetBitmap().IsOk())
+ hdi.fmt |= HDF_IMAGE;
+
//hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
if (col->IsSortable() && GetOwner()->GetSortingColumn() == col)
case HDN_BEGINDRAG:
// user has started to reorder a column
- if (!GetColumn(nmHDR->iItem)->IsReorderable())
+ if ((nmHDR->iItem != -1) && (!GetColumn(nmHDR->iItem)->IsReorderable()))
{
// veto it!
*result = TRUE;
//-----------------------------------------------------------------------------
//The tree building helper, declared firstly
-void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node);
+static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node);
int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
{
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
- m_penRule = wxPen(GetRuleColour(), 1, wxSOLID);
+ m_penRule = wxPen(GetRuleColour());
//Here I compose a pen can draw black lines, maybe there are something system colour to use
- m_penExpander = wxPen( wxColour(0,0,0), 1, wxSOLID );
+ m_penExpander = wxPen(wxColour(0,0,0));
//Some new added code to deal with the tree structure
m_root = new wxDataViewTreeNode( NULL );
m_root->SetHasChildren(true);
else
wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
}
- else
- {
- // 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
cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
}
-
+ if (node && !node->HasChildren())
+ {
+ // Yes, if the node does not have any child, it must be a leaf which
+ // mean that it is a temporarily created by GetTreeNodeByRow
+ wxDELETE(node)
+ }
// cannot be bigger than allocated space
wxSize size = cell->GetSize();
size.y = cell_rect.height;
wxRect item_rect(cell_rect.GetTopLeft(), size);
- int align = cell->GetAlignment();
+ int align = cell->CalculateAlignment();
// horizontal alignment:
item_rect.x = cell_rect.x;
return true;
}
-void DestroyTreeHelper( wxDataViewTreeNode * node);
+static void DestroyTreeHelper( wxDataViewTreeNode * node);
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
const wxDataViewItem& item)
node->GetNodes().Remove( n );
sub -= n->GetSubTreeCount();
- DestroyTreeHelper(n);
+ ::DestroyTreeHelper(n);
}
//Make the row number invalid and get a new valid one when user call GetRowCount
m_count = -1;
node->ChangeSubTreeCount(sub);
- if( node->GetChildrenNumber() == 0)
- {
- node->GetParent()->GetNodes().Remove( node );
- delete node;
- }
//Change the current row to the last row if the current exceed the max row number
if( m_currentRow > GetRowCount() )
if( node->GetChildrenNumber() == 0 )
{
SortPrepare();
- BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
+ ::BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
}
m_count = -1;
UpdateDisplay();
if( node->GetChildrenNumber() == 0 )
{
SortPrepare();
- BuildTreeHelper(model, node->GetItem(), node);
+ ::BuildTreeHelper(model, node->GetItem(), node);
}
wxDataViewTreeNodes nodes = node->GetNodes();
- unsigned int i = 0;
- for (; i < nodes.GetCount(); i ++)
+ unsigned int i;
+ bool found = false;
+
+ for (i = 0; i < nodes.GetCount(); i ++)
{
if (nodes[i]->GetItem() == (**iter))
{
+ if (nodes[i]->GetItem() == item)
+ return nodes[i];
+
node = nodes[i];
+ found = true;
break;
}
}
- if (i == nodes.GetCount())
+ if (!found)
return NULL;
}
else
return NULL;
}
- return node;
+ return NULL;
}
void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column )
}
}
-void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node)
+static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node)
{
if( !model->IsContainer( item ) )
return ;
{
DestroyTree();
- if (GetOwner()->GetModel()->IsIndexListModel())
+ if (GetOwner()->GetModel()->IsVirtualListModel())
{
m_count = -1 ;
return;
m_count = -1 ;
}
-void DestroyTreeHelper( wxDataViewTreeNode * node )
+static void DestroyTreeHelper( wxDataViewTreeNode * node )
{
if( node->GetNodeNumber() != 0 )
{
int len = node->GetNodeNumber();
int i = 0 ;
- wxDataViewTreeNodes nodes = node->GetNodes();
+ wxDataViewTreeNodes& nodes = node->GetNodes();
for( ; i < len; i ++ )
{
DestroyTreeHelper(nodes[i]);
{
if (m_root)
{
- DestroyTreeHelper(m_root);
+ ::DestroyTreeHelper(m_root);
m_count = 0;
m_root = NULL;
}
OnExpanding( current );
}
}
+ if (node && !node->HasChildren())
+ delete node;
}
//If the user click the expander, we do not do editing even if the column with expander are editable
if (m_lastOnSame && !expander && !ignore_other_columns)
{
if ((col == m_currentCol) && (current == m_currentRow) &&
- (cell->GetMode() == wxDATAVIEW_CELL_EDITABLE) )
+ (cell->GetMode() & wxDATAVIEW_CELL_EDITABLE) )
{
m_renameTimer->Start( 100, true );
}
SendSelectionChangedEvent(GetItemByRow( m_currentRow ) );
}
- // notify cell about right click
wxVariant value;
model->GetValue( value, item, col->GetModelColumn() );
- cell->SetValue( value );
- wxRect cell_rect( xpos, current * m_lineHeight,
- col->GetWidth(), m_lineHeight );
- if (!cell->RightClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn()))
- {
- wxWindow *parent = GetParent();
- wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, parent->GetId());
- le.SetItem( item );
- le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
- le.SetValue(value);
-
- parent->GetEventHandler()->ProcessEvent(le);
- }
+ wxWindow *parent = GetParent();
+ wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, parent->GetId());
+ le.SetItem( item );
+ le.SetEventObject(parent);
+ le.SetModel(GetOwner()->GetModel());
+ le.SetValue(value);
+ parent->GetEventHandler()->ProcessEvent(le);
}
else if (event.MiddleDown())
{
- // notify cell about middle click
- // cell->...
}
if (event.LeftDown() || forceClick)
{
wxFAIL_MSG( _T("how did we get here?") );
}
}
-
+
if (m_currentRow != oldCurrentRow)
RefreshRow( oldCurrentRow );
m_lastOnSame = !forceClick && ((col == oldCurrentCol) &&
(current == oldCurrentRow)) && oldWasSelected;
+
+ // Call LeftClick after everything else as under GTK+
+ if (cell->GetMode() & wxDATAVIEW_CELL_ACTIVATABLE)
+ {
+ // notify cell about right click
+ wxVariant value;
+ model->GetValue( value, item, col->GetModelColumn() );
+ cell->SetValue( value );
+ wxRect cell_rect( xpos, current * m_lineHeight,
+ col->GetWidth(), m_lineHeight );
+ /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn());
+ }
}
}
{
if (m_notifier)
GetModel()->RemoveNotifier( m_notifier );
+
+ wxDataViewColumnList::const_iterator iter;
+ for (iter = m_cols.begin(); iter!=m_cols.end(); iter++)
+ {
+ delete *iter;
+ }
}
void wxDataViewCtrl::Init()
const wxPoint& pos, const wxSize& size,
long style, const wxValidator& validator )
{
+ if ( (style & wxBORDER_MASK) == 0)
+ style |= wxBORDER_SUNKEN;
+
if (!wxControl::Create( parent, id, pos, size,
- style | wxScrolledWindowStyle|wxBORDER_SUNKEN, validator))
+ style | wxScrolledWindowStyle, validator))
return false;
SetInitialSize(size);