#endif
#include "wx/stockitem.h"
-#include "wx/calctrl.h"
#include "wx/popupwin.h"
#include "wx/renderer.h"
#include "wx/dcbuffer.h"
m_branchData->children.Remove(node);
}
+ // returns position of child node for given item in children list or wxNOT_FOUND
+ int FindChildByItem(const wxDataViewItem& item) const
+ {
+ if ( !m_branchData )
+ return wxNOT_FOUND;
+
+ const wxDataViewTreeNodes& nodes = m_branchData->children;
+ const int len = nodes.size();
+ for ( int i = 0; i < len; i++ )
+ {
+ if ( nodes[i]->m_item == item )
+ return i;
+ }
+ return wxNOT_FOUND;
+ }
+
const wxDataViewItem & GetItem() const { return m_item; }
void SetItem( const wxDataViewItem & item ) { m_item = item; }
return true;
}
-bool wxDataViewToggleRenderer::WXOnLeftClick(const wxPoint& cursor,
- const wxRect& cell,
- wxDataViewModel *model,
- const wxDataViewItem& item,
- unsigned int col)
+bool wxDataViewToggleRenderer::WXActivateCell(const wxRect& WXUNUSED(cell),
+ wxDataViewModel *model,
+ const wxDataViewItem& item,
+ unsigned int col,
+ const wxMouseEvent *mouseEvent)
{
- // only react to clicks directly on the checkbox, not elsewhere in the same cell:
- if (!wxRect(GetSize()).Contains(cursor))
+ if ( !model->IsEnabled(item, col) )
return false;
- return WXOnActivate(cell, model, item, col);
-}
-
-bool wxDataViewToggleRenderer::WXOnActivate(const wxRect& WXUNUSED(cell),
- wxDataViewModel *model,
- const wxDataViewItem& item,
- unsigned int col)
-{
- if (model->IsEnabled(item, col))
+ if ( mouseEvent )
{
- model->ChangeValue(!m_toggle, item, col);
- return true;
+ // only react to clicks directly on the checkbox, not elsewhere in the same cell:
+ if ( !wxRect(GetSize()).Contains(mouseEvent->GetPosition()) )
+ return false;
}
- return false;
+ model->ChangeValue(!m_toggle, item, col);
+ return true;
}
wxSize wxDataViewToggleRenderer::GetSize() const
return wxSize(40,12);
}
-// ---------------------------------------------------------
-// wxDataViewDateRenderer
-// ---------------------------------------------------------
-
-#define wxUSE_DATE_RENDERER_POPUP (wxUSE_CALENDARCTRL && wxUSE_POPUPWIN)
-
-#if wxUSE_DATE_RENDERER_POPUP
-
-class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow
-{
-public:
- wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value,
- wxDataViewModel *model, const wxDataViewItem & item, unsigned int col) :
- wxPopupTransientWindow( parent, wxBORDER_SIMPLE ),
- m_item( item )
- {
- m_model = model;
- m_col = col;
- m_cal = new wxCalendarCtrl( this, wxID_ANY, *value );
- wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
- sizer->Add( m_cal, 1, wxGROW );
- SetSizer( sizer );
- sizer->Fit( this );
- }
-
- void OnCalendar( wxCalendarEvent &event );
-
- wxCalendarCtrl *m_cal;
- wxDataViewModel *m_model;
- unsigned int m_col;
- const wxDataViewItem & m_item;
-
-protected:
- virtual void OnDismiss()
- {
- }
-
-private:
- DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient,wxPopupTransientWindow)
- EVT_CALENDAR( wxID_ANY, wxDataViewDateRendererPopupTransient::OnCalendar )
-END_EVENT_TABLE()
-
-void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event )
-{
- m_model->ChangeValue( event.GetDate(), m_item, m_col );
- DismissAndNotify();
-}
-
-#endif // wxUSE_DATE_RENDERER_POPUP
-
-IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer, wxDataViewRenderer)
-
-wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype,
- wxDataViewCellMode mode, int align ) :
- wxDataViewRenderer( varianttype, mode, align )
-{
-}
-
-bool wxDataViewDateRenderer::SetValue( const wxVariant &value )
-{
- m_date = value.GetDateTime();
-
- return true;
-}
-
-bool wxDataViewDateRenderer::GetValue( wxVariant &value ) const
-{
- value = m_date;
- return true;
-}
-
-bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int state )
-{
- wxString tmp = m_date.FormatDate();
- RenderText( tmp, 0, cell, dc, state );
- return true;
-}
-
-wxSize wxDataViewDateRenderer::GetSize() const
-{
- return GetTextExtent(m_date.FormatDate());
-}
-
-bool wxDataViewDateRenderer::WXOnActivate(const wxRect& WXUNUSED(cell),
- wxDataViewModel *model,
- const wxDataViewItem& item,
- unsigned int col)
-{
- wxDateTime dtOld = m_date;
-
-#if wxUSE_DATE_RENDERER_POPUP
- wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient(
- GetOwner()->GetOwner()->GetParent(), &dtOld, model, item, col);
- wxPoint pos = wxGetMousePosition();
- popup->Move( pos );
- popup->Layout();
- popup->Popup( popup->m_cal );
-#else // !wxUSE_DATE_RENDERER_POPUP
- wxMessageBox(dtOld.Format());
-#endif // wxUSE_DATE_RENDERER_POPUP/!wxUSE_DATE_RENDERER_POPUP
-
- return true;
-}
-
// ---------------------------------------------------------
// wxDataViewIconTextRenderer
// ---------------------------------------------------------
if ( !parentNode )
return false;
- wxDataViewItemArray siblings;
- GetModel()->GetChildren(parent, siblings);
- int itemPos = siblings.Index(item, /*fromEnd=*/true);
- wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" );
+ wxDataViewItemArray modelSiblings;
+ GetModel()->GetChildren(parent, modelSiblings);
+ const int modelSiblingsSize = modelSiblings.size();
+
+ int posInModel = modelSiblings.Index(item, /*fromEnd=*/true);
+ wxCHECK_MSG( posInModel != wxNOT_FOUND, false, "adding non-existent item?" );
wxDataViewTreeNode *itemNode = new wxDataViewTreeNode(parentNode, item);
itemNode->SetHasChildren(GetModel()->IsContainer(item));
parentNode->SetHasChildren(true);
- parentNode->InsertChild(itemNode, itemPos);
+
+ const wxDataViewTreeNodes& nodeSiblings = parentNode->GetChildNodes();
+ const int nodeSiblingsSize = nodeSiblings.size();
+
+ int nodePos = 0;
+
+ if ( posInModel == modelSiblingsSize - 1 )
+ {
+ nodePos = nodeSiblingsSize;
+ }
+ else if ( modelSiblingsSize == nodeSiblingsSize + 1 )
+ {
+ // This is the simple case when our node tree already matches the
+ // model and only this one item is missing.
+ nodePos = posInModel;
+ }
+ else
+ {
+ // It's possible that a larger discrepancy between the model and
+ // our realization exists. This can happen e.g. when adding a bunch
+ // of items to the model and then calling ItemsAdded() just once
+ // afterwards. In this case, we must find the right position by
+ // looking at sibling items.
+
+ // append to the end if we won't find a better position:
+ nodePos = nodeSiblingsSize;
+
+ for ( int nextItemPos = posInModel + 1;
+ nextItemPos < modelSiblingsSize;
+ nextItemPos++ )
+ {
+ int nextNodePos = parentNode->FindChildByItem(modelSiblings[nextItemPos]);
+ if ( nextNodePos != wxNOT_FOUND )
+ {
+ nodePos = nextNodePos;
+ break;
+ }
+ }
+ }
+
parentNode->ChangeSubTreeCount(+1);
+ parentNode->InsertChild(itemNode, nodePos);
m_count = -1;
}
// collapsed) item in a tree model. So it's not an error if we don't know
// about this item, just return without doing anything then.
if ( !parentNode )
- return false;
+ return true;
wxCHECK_MSG( parentNode->HasChildren(), false, "parent node doesn't have children?" );
const wxDataViewTreeNodes& parentsChildren = parentNode->GetChildNodes();
if ( parentNode->GetChildNodes().empty() )
parentNode->SetHasChildren(GetModel()->IsContainer(parent));
- return false;
+ return true;
}
// Delete the item from wxDataViewTreeNode representation:
wxDataViewRenderer *cell = activatableCol->GetRenderer();
cell->PrepareForItem(GetModel(), item, colIdx);
- cell->WXOnActivate(cell_rect, GetModel(), item, colIdx);
+ cell->WXActivateCell(cell_rect, GetModel(), item, colIdx, NULL);
}
}
break;
}
else if ( current == m_lineLastClicked )
{
- bool activated = false;
-
- if ((!ignore_other_columns) && (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE))
- {
- const unsigned colIdx = col->GetModelColumn();
-
- cell->PrepareForItem(model, item, colIdx);
-
- wxRect cell_rect( xpos, GetLineStart( current ),
- col->GetWidth(), GetLineHeight( current ) );
- activated = cell->WXOnActivate( cell_rect, model, item, colIdx );
- }
-
- if ( !activated )
- {
- wxWindow *parent = GetParent();
- wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId());
- le.SetItem( item );
- le.SetColumn( col->GetModelColumn() );
- le.SetDataViewColumn( col );
- le.SetEventObject(parent);
- le.SetModel(GetModel());
+ wxWindow *parent = GetParent();
+ wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId());
+ le.SetItem( item );
+ le.SetColumn( col->GetModelColumn() );
+ le.SetDataViewColumn( col );
+ le.SetEventObject(parent);
+ le.SetModel(GetModel());
- parent->ProcessWindowEvent(le);
- }
+ parent->ProcessWindowEvent(le);
return;
}
else
m_lastOnSame = !simulateClick && ((col == oldCurrentCol) &&
(current == oldCurrentRow)) && oldWasSelected;
- // Call LeftClick after everything else as under GTK+
+ // Call ActivateCell() after everything else as under GTK+
if (cell->GetMode() & wxDATAVIEW_CELL_ACTIVATABLE)
{
// notify cell about click
}
}
- wxPoint pos( event.GetPosition() );
- pos.x -= rectItem.x;
- pos.y -= rectItem.y;
+ wxMouseEvent event2(event);
+ event2.m_x -= rectItem.x;
+ event2.m_y -= rectItem.y;
+ m_owner->CalcUnscrolledPosition(event2.m_x, event2.m_y, &event2.m_x, &event2.m_y);
- m_owner->CalcUnscrolledPosition( pos.x, pos.y, &pos.x, &pos.y );
-
- /* ignore ret */ cell->WXOnLeftClick( pos, cell_rect,
- model, item, col->GetModelColumn());
+ /* ignore ret */ cell->WXActivateCell
+ (
+ cell_rect,
+ model,
+ item,
+ col->GetModelColumn(),
+ &event2
+ );
}
}
}