#endif
#include "wx/stockitem.h"
-#include "wx/calctrl.h"
#include "wx/popupwin.h"
#include "wx/listimpl.cpp"
#include "wx/gtk/private/gdkconv.h"
#include "wx/gtk/private/list.h"
+#include "wx/gtk/private/event.h"
using namespace wxGTKImpl;
class wxGtkDataViewModelNotifier;
}
}
+ // returns position of child node for given item in children list or wxNOT_FOUND
+ int FindChildByItem(const wxDataViewItem& item) const
+ {
+ const void* itemId = item.GetID();
+ const wxGtkTreeModelChildren& nodes = m_children;
+ const int len = nodes.size();
+ for ( int i = 0; i < len; i++ )
+ {
+ if ( nodes[i] == itemId )
+ return i;
+ }
+ return wxNOT_FOUND;
+ }
+
wxGtkTreeModelNode* GetParent()
{ return m_parent; }
wxGtkTreeModelNodes &GetNodes()
/*< private >*/
wxDataViewCustomRenderer *cell;
- guint32 last_click;
};
struct _GtkWxCellRendererClass
gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell)
{
cell->cell = NULL;
- cell->last_click = 0;
}
static void
unsigned int model_col = cell->GetOwner()->GetModelColumn();
- if (!event)
+ if ( !event )
{
- bool ret = false;
-
// activated by <ENTER>
- if (cell->Activate( renderrect, model, item, model_col ))
- ret = true;
-
- return ret;
+ return cell->ActivateCell(renderrect, model, item, model_col, NULL);
}
- else if (event->type == GDK_BUTTON_PRESS)
+ else if ( event->type == GDK_BUTTON_PRESS )
{
- GdkEventButton *button_event = (GdkEventButton*) event;
- wxPoint pt( ((int) button_event->x) - renderrect.x,
- ((int) button_event->y) - renderrect.y );
-
- bool ret = false;
- if (button_event->button == 1)
+ GdkEventButton *button_event = (GdkEventButton*)event;
+ if ( button_event->button == 1 )
{
- if (cell->LeftClick( pt, renderrect, model, item, model_col ))
- ret = true;
- // TODO: query system double-click time
- if (button_event->time - wxrenderer->last_click < 400)
- if (cell->Activate( renderrect, model, item, model_col ))
- ret = true;
- }
- wxrenderer->last_click = button_event->time;
+ wxMouseEvent mouse_event(wxEVT_LEFT_DOWN);
+ InitMouseEvent(ctrl, mouse_event, button_event);
- return ret;
+ mouse_event.m_x -= renderrect.x;
+ mouse_event.m_y -= renderrect.y;
+
+ return cell->ActivateCell(renderrect, model, item, model_col, &mouse_event);
+ }
}
+ wxLogDebug("unexpected event type in gtk_wx_cell_renderer_activate()");
return false;
}
// Take care to not use GetOwner() here if the label is empty, we can be
// called from ctor when GetOwner() is still NULL in this case.
- g_value_set_string( &gvalue,
- m_label.empty() ? ""
- : wxGTK_CONV_FONT(m_label,
- GetOwner()->GetOwner()->GetFont())
- );
+ wxScopedCharBuffer buf;
+ if ( m_label.empty() )
+ buf = wxScopedCharBuffer::CreateNonOwned("");
+ else
+ buf = wxGTK_CONV_FONT(m_label, GetOwner()->GetOwner()->GetFont());
+
+ g_value_set_string( &gvalue, buf);
g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
g_value_unset( &gvalue );
return true;
}
-// ---------------------------------------------------------
-// wxDataViewDateRenderer
-// ---------------------------------------------------------
-
-class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow
-{
-public:
- wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value,
- wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) :
- wxPopupTransientWindow( parent, wxBORDER_SIMPLE )
- {
- m_model = model;
- m_item = item;
- m_col = col;
- m_cal = new wxCalendarCtrl( this, -1, *value );
- wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
- sizer->Add( m_cal, 1, wxGROW );
- SetSizer( sizer );
- sizer->Fit( this );
- }
-
- virtual void OnDismiss()
- {
- }
-
- void OnCalendar( wxCalendarEvent &event );
-
- wxCalendarCtrl *m_cal;
- wxDataViewModel *m_model;
- wxDataViewItem m_item;
- unsigned int m_col;
-
-private:
- DECLARE_EVENT_TABLE()
-};
-
-BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient,wxPopupTransientWindow)
- EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar )
-END_EVENT_TABLE()
-
-void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event )
-{
- m_model->ChangeValue( event.GetDate(), m_item, m_col );
- DismissAndNotify();
-}
-
-IMPLEMENT_CLASS(wxDataViewDateRenderer, wxDataViewCustomRenderer)
-
-wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype,
- wxDataViewCellMode mode, int align ) :
- wxDataViewCustomRenderer( varianttype, mode, align )
-{
- SetMode(mode);
- SetAlignment(align);
-}
-
-bool wxDataViewDateRenderer::SetValue( const wxVariant &value )
-{
- m_date = value.GetDateTime();
-
- return true;
-}
-
-bool wxDataViewDateRenderer::GetValue( wxVariant &WXUNUSED(value) ) const
-{
- return false;
-}
-
-bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int state )
-{
- dc->SetFont( GetOwner()->GetOwner()->GetFont() );
- wxString tmp = m_date.FormatDate();
- RenderText( tmp, 0, cell, dc, state );
- return true;
-}
-
-wxSize wxDataViewDateRenderer::GetSize() const
-{
- wxString tmp = m_date.FormatDate();
- wxCoord x,y,d;
- GetView()->GetTextExtent( tmp, &x, &y, &d );
- return wxSize(x,y+d);
-}
-
-bool wxDataViewDateRenderer::Activate( const wxRect& WXUNUSED(cell), wxDataViewModel *model,
- const wxDataViewItem &item, unsigned int col )
-{
- wxVariant variant;
- model->GetValue( variant, item, col );
- wxDateTime value = variant.GetDateTime();
-
- wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient(
- GetOwner()->GetOwner()->GetParent(), &value, model, item, col );
- wxPoint pos = wxGetMousePosition();
- popup->Move( pos );
- popup->Layout();
- popup->Popup( popup->m_cal );
-
- return true;
-}
-
-
// ---------------------------------------------------------
// wxDataViewIconTextRenderer
// ---------------------------------------------------------
wxCHECK_MSG(parent_node, false,
"Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
- wxDataViewItemArray siblings;
- m_wx_model->GetChildren(parent, siblings);
- int itemPos = siblings.Index(item, /*fromEnd=*/true);
- wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" );
+ wxDataViewItemArray modelSiblings;
+ m_wx_model->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?" );
+
+ const wxGtkTreeModelChildren& nodeSiblings = parent_node->GetChildren();
+ 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 = parent_node->FindChildByItem(modelSiblings[nextItemPos]);
+ if ( nextNodePos != wxNOT_FOUND )
+ {
+ nodePos = nextNodePos;
+ break;
+ }
+ }
+ }
if (m_wx_model->IsContainer( item ))
- parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), itemPos );
+ parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), nodePos );
else
- parent_node->InsertLeaf( item.GetID(), itemPos );
+ parent_node->InsertLeaf( item.GetID(), nodePos );
}
ScheduleRefresh();
GtkTreeViewColumn *column = NULL;
gint cell_x = 0;
gint cell_y = 0;
- if (gtk_tree_view_get_path_at_pos(
+ gtk_tree_view_get_path_at_pos
+ (
GTK_TREE_VIEW(dv->GtkGetTreeView()),
(int) gdk_event->x, (int) gdk_event->y,
path.ByRef(),
&column,
&cell_x,
- &cell_y))
- {
- if (path)
- {
- wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() );
- event.SetItem(dv->GTKPathToItem(path));
- event.SetModel( dv->GetModel() );
- return dv->HandleWindowEvent( event );
- }
- }
+ &cell_y
+ );
+
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() );
+ if (path)
+ event.SetItem(dv->GTKPathToItem(path));
+ event.SetModel( dv->GetModel() );
+ return dv->HandleWindowEvent( event );
}
return FALSE;
m_treeview = gtk_tree_view_new();
gtk_container_add (GTK_CONTAINER (m_widget), m_treeview);
+ m_focusWidget = GTK_WIDGET(m_treeview);
+
g_signal_connect (m_treeview, "size_allocate",
G_CALLBACK (gtk_dataviewctrl_size_callback), this);