Implemented the same simple API for creating customized

in-place editing controls for GTK+ and the generic
   version and demonstrate its use in the sample using
   a wxSpinCtrl.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45518 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-04-17 12:08:10 +00:00
parent 29825f5fc4
commit 1e510b1e2d
7 changed files with 335 additions and 143 deletions
+100
View File
@@ -706,6 +706,8 @@ wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype,
int WXUNUSED(align) )
{
m_variantType = varianttype;
m_editorCtrl = NULL;
m_row = (unsigned int) -1;
}
const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
@@ -713,6 +715,104 @@ const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner();
}
bool wxDataViewRendererBase::StartEditing( unsigned int row, wxRect labelRect )
{
m_row = row; // remember for later
unsigned int col = GetOwner()->GetModelColumn();
wxVariant value;
GetOwner()->GetOwner()->GetModel()->GetValue( value, col, row );
m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
m_editorCtrl->PushEventHandler(
new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this ) );
m_editorCtrl->SetFocus();
return true;
}
void wxDataViewRendererBase::CancelEditing()
{
// m_editorCtrl->PopEventHandler( true );
delete m_editorCtrl;
GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
}
bool wxDataViewRendererBase::FinishEditing()
{
// m_editorCtrl->PopEventHandler( true );
wxVariant value;
GetValueFromEditorCtrl( m_editorCtrl, value );
delete m_editorCtrl;
GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
if (!Validate(value))
return false;
unsigned int col = GetOwner()->GetModelColumn();
GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row );
GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row );
return true;
}
//-----------------------------------------------------------------------------
// wxDataViewEditorCtrlEvtHandler
//-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
END_EVENT_TABLE()
wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
wxControl *editorCtrl,
wxDataViewRenderer *owner )
{
m_owner = owner;
m_editorCtrl = editorCtrl;
m_finished = false;
}
void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
case WXK_RETURN:
m_finished = true;
m_owner->FinishEditing();
break;
case WXK_ESCAPE:
m_finished = true;
m_owner->CancelEditing();
break;
default:
event.Skip();
}
}
void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
{
if (!m_finished)
{
m_finished = true;
m_owner->FinishEditing();
}
// We must let the native text control handle focus
event.Skip();
}
// ---------------------------------------------------------
// wxDataViewColumnBase
// ---------------------------------------------------------
+3 -101
View File
@@ -418,106 +418,6 @@ wxDC *wxDataViewRenderer::GetDC()
return m_dc;
}
bool wxDataViewRenderer::StartEditing( unsigned int row, wxRect labelRect )
{
GetView()->CalcScrolledPosition( labelRect.x, labelRect.y,
&labelRect.x, &labelRect.y);
m_row = row; // remember for later
unsigned int col = GetOwner()->GetModelColumn();
wxVariant value;
GetOwner()->GetOwner()->GetModel()->GetValue( value, col, row );
m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
m_editorCtrl->PushEventHandler( new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, this ) );
m_editorCtrl->SetFocus();
return true;
}
void wxDataViewRenderer::CancelEditing()
{
// m_editorCtrl->PopEventHandler( true );
delete m_editorCtrl;
GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
}
bool wxDataViewRenderer::FinishEditing()
{
// m_editorCtrl->PopEventHandler( true );
wxVariant value;
GetValueFromEditorCtrl( m_editorCtrl, value );
delete m_editorCtrl;
GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
if (!Validate(value))
return false;
unsigned int col = GetOwner()->GetModelColumn();
GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row );
GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row );
return true;
}
//-----------------------------------------------------------------------------
// wxDataViewEditorCtrlEvtHandler
//-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
END_EVENT_TABLE()
wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
wxControl *editorCtrl,
wxDataViewRenderer *owner )
{
m_owner = owner;
m_editorCtrl = editorCtrl;
m_finished = false;
}
void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
{
switch ( event.m_keyCode )
{
case WXK_RETURN:
m_finished = true;
m_owner->FinishEditing();
break;
case WXK_ESCAPE:
m_finished = true;
m_owner->CancelEditing();
break;
default:
event.Skip();
}
}
void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
{
if (!m_finished)
{
m_finished = true;
m_owner->FinishEditing();
}
// We must let the native text control handle focus
event.Skip();
}
// ---------------------------------------------------------
// wxDataViewCustomRenderer
// ---------------------------------------------------------
@@ -1665,7 +1565,6 @@ void wxDataViewMainWindow::OnRenameTimer()
if ( m_dirty )
wxSafeYield();
int xpos = 0;
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int i;
@@ -1682,6 +1581,9 @@ void wxDataViewMainWindow::OnRenameTimer()
wxRect labelRect( xpos, m_currentRow * m_lineHeight,
m_currentCol->GetWidth(), m_lineHeight );
GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y,
&labelRect.x, &labelRect.y);
m_currentCol->GetRenderer()->StartEditing( m_currentRow, labelRect );
}
+100
View File
@@ -480,6 +480,15 @@ static gboolean gtk_wx_cell_renderer_activate(
GdkRectangle *background_area,
GdkRectangle *cell_area,
GtkCellRendererState flags );
static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GtkCellRendererState flags );
static GObjectClass *cell_parent_class = NULL;
@@ -532,6 +541,7 @@ gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass)
cell_class->get_size = gtk_wx_cell_renderer_get_size;
cell_class->render = gtk_wx_cell_renderer_render;
cell_class->activate = gtk_wx_cell_renderer_activate;
cell_class->start_editing = gtk_wx_cell_renderer_start_editing;
}
static void
@@ -547,6 +557,48 @@ gtk_wx_cell_renderer_new (void)
return (GtkCellRenderer*) g_object_new (GTK_TYPE_WX_CELL_RENDERER, NULL);
}
static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
GtkCellRenderer *renderer,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GtkCellRendererState flags )
{
GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer;
wxDataViewCustomRenderer *cell = wxrenderer->cell;
if (!cell->HasEditorCtrl())
return NULL;
GdkRectangle rect;
gtk_wx_cell_renderer_get_size (renderer, widget, cell_area,
&rect.x,
&rect.y,
&rect.width,
&rect.height);
rect.x += cell_area->x;
rect.y += cell_area->y;
// rect.width -= renderer->xpad * 2;
// rect.height -= renderer->ypad * 2;
// wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
wxRect renderrect( cell_area->x, cell_area->y, cell_area->width, cell_area->height );
wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel();
GtkTreePath *treepath = gtk_tree_path_new_from_string( path );
unsigned int model_row = (unsigned int)gtk_tree_path_get_indices (treepath)[0];
gtk_tree_path_free( treepath );
cell->StartEditing( model_row, renderrect );
return NULL;
}
static void
gtk_wx_cell_renderer_get_size (GtkCellRenderer *renderer,
GtkWidget *widget,
@@ -1870,6 +1922,49 @@ wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path,
// wxDataViewCtrl
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// InsertChild for wxDataViewCtrl
//-----------------------------------------------------------------------------
static void wxInsertChildInDataViewCtrl( wxWindowGTK* parent, wxWindowGTK* child )
{
wxDataViewCtrl * dvc = (wxDataViewCtrl*) parent;
GtkWidget *treeview = dvc->GtkGetTreeView();
// Insert widget in GtkTreeView
if (GTK_WIDGET_REALIZED(treeview))
gtk_widget_set_parent_window( child->m_widget,
gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview) ) );
gtk_widget_set_parent( child->m_widget, treeview );
}
static
void gtk_dataviewctrl_size_callback( GtkWidget *WXUNUSED(widget),
GtkAllocation *alloc,
wxDataViewCtrl *win )
{
wxWindowList::Node *node = win->GetChildren().GetFirst();
while (node)
{
wxWindow *child = node->GetData();
GtkRequisition req;
gtk_widget_size_request( child->m_widget, &req );
GtkAllocation alloc;
alloc.x = child->m_x;
alloc.y = child->m_y;
alloc.width = child->m_width;
alloc.height = child->m_height;
gtk_widget_size_allocate( child->m_widget, &alloc );
node = node->GetNext();
}
}
IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
wxDataViewCtrl::~wxDataViewCtrl()
@@ -1902,12 +1997,17 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
return false;
}
m_insertCallback = wxInsertChildInDataViewCtrl;
m_widget = gtk_scrolled_window_new (NULL, NULL);
GtkScrolledWindowSetBorder(m_widget, style);
m_treeview = gtk_tree_view_new();
gtk_container_add (GTK_CONTAINER (m_widget), m_treeview);
g_signal_connect (m_treeview, "size_allocate",
G_CALLBACK (gtk_dataviewctrl_size_callback), this);
#ifdef __WXGTK26__
if (!gtk_check_version(2,6,0))