Make HasValue virtual in wxDataViewModel and have implementations use it. This addresses issue https://trac.wxwidgets.org/ticket/18724

This commit is contained in:
Jorge Moraleda
2020-04-12 23:15:21 -07:00
parent 697bd07441
commit c2e4bc422c
4 changed files with 74 additions and 66 deletions

View File

@@ -208,7 +208,7 @@ public:
// return true if the given item has a value to display in the given // return true if the given item has a value to display in the given
// column: this is always true except for container items which by default // column: this is always true except for container items which by default
// only show their label in the first column (but see HasContainerColumns()) // only show their label in the first column (but see HasContainerColumns())
bool HasValue(const wxDataViewItem& item, unsigned col) const virtual bool HasValue(const wxDataViewItem& item, unsigned col) const
{ {
return col == 0 || !IsContainer(item) || HasContainerColumns(item); return col == 0 || !IsContainer(item) || HasContainerColumns(item);
} }

View File

@@ -304,14 +304,17 @@ public:
All normal items have values in all columns but the container items All normal items have values in all columns but the container items
only show their label in the first column (@a col == 0) by default (but only show their label in the first column (@a col == 0) by default (but
see HasContainerColumns()). So this function always returns true for see HasContainerColumns()). So this function by default returns true for
the first column while for the other ones it returns true only if the the first column while for the other ones it returns true only if the
item is not a container or HasContainerColumns() was overridden to item is not a container or HasContainerColumns() was overridden to
return true for it. return true for it.
Override this method to explicitly specify for which columns a given
item has values.
@since 2.9.1 @since 2.9.1
*/ */
bool HasValue(const wxDataViewItem& item, unsigned col) const; virtual bool HasValue(const wxDataViewItem& item, unsigned col) const;
/** /**
Override this to indicate of @a item is a container, i.e.\ if Override this to indicate of @a item is a container, i.e.\ if

View File

@@ -2394,15 +2394,17 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
if ( m_useCellFocus && m_currentCol && m_currentColSetByKeyboard ) if ( m_useCellFocus && m_currentCol && m_currentColSetByKeyboard )
{ {
renderColumnFocus = true; // If this is an item with a single column, render full-row focus:
numColsWithValue = 0;
// If this is container node without columns, render full-row focus: unsigned int cols = GetOwner()->GetColumnCount();
if ( !IsList() ) for ( unsigned int i = 0; i < cols; i++ )
{ {
wxDataViewTreeNode *node = GetTreeNodeByRow(item); if ( model->HasValue(item, i) )
if ( node->HasChildren() && !model->HasContainerColumns(node->GetItem()) ) numColsWithValue++;
renderColumnFocus = false; if ( numColsWithValue > 1 )
break;
} }
renderColumnFocus = numColsWithValue<2;
} }
if ( renderColumnFocus ) if ( renderColumnFocus )
@@ -2547,11 +2549,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dataitem = node->GetItem(); dataitem = node->GetItem();
// Skip all columns of "container" rows except the expander // Skip al columns that do not have values
// column itself unless HasContainerColumns() overrides this. if ( !model->HasValue(dataitem, col->GetModelColumn()) )
if ( col != expander &&
model->IsContainer(dataitem) &&
!model->HasContainerColumns(dataitem) )
{ {
cell_rect.y += line_height; cell_rect.y += line_height;
continue; continue;
@@ -3491,9 +3490,7 @@ int wxDataViewMainWindow::QueryAndCacheLineHeight(unsigned int row, wxDataViewIt
if (column->IsHidden()) if (column->IsHidden())
continue; // skip it! continue; // skip it!
if ((col != 0) && if ( !model->HasValue(item, col) )
model->IsContainer(item) &&
!model->HasContainerColumns(item))
continue; // skip it! continue; // skip it!
wxDataViewRenderer *renderer = wxDataViewRenderer *renderer =
@@ -4108,8 +4105,7 @@ wxDataViewMainWindow::FindColumnForEditing(const wxDataViewItem& item, wxDataVie
// may be directly editable: // may be directly editable:
if ( candidate && if ( candidate &&
GetOwner()->GetExpanderColumn() != candidate && GetOwner()->GetExpanderColumn() != candidate &&
GetModel()->IsContainer(item) && !GetModel()->HasValue(item, candidate->GetModelColumn()) )
!GetModel()->HasContainerColumns(item) )
{ {
candidate = GetOwner()->GetExpanderColumn(); candidate = GetOwner()->GetExpanderColumn();
} }
@@ -4500,8 +4496,13 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxK
if ( node ) if ( node )
{ {
// navigation shouldn't work in branch nodes without other columns: // navigation shouldn't work in nodes with fewer than two columns
if ( node->HasChildren() && !GetModel()->HasContainerColumns(node->GetItem()) ) numColsWithValue = 0;
unsigned int cols = GetOwner()->GetColumnCount();
for ( unsigned int i = 0; i < cols; i++ )
if ( GetModel()->HasValue(node->GetItem(), i) )
numColsWithValue++;
if (numColsWithValue<2)
return false; return false;
} }
@@ -4509,7 +4510,13 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxK
{ {
if ( forward ) if ( forward )
{ {
m_currentCol = GetOwner()->GetColumnAt(0); // find first column with value
unsigned int i = 0;
unsigned int cols = GetOwner()->GetColumnCount();
for ( ; i < cols; i++ )
if ( GetModel()->HasValue(node->GetItem(), i) )
break;
m_currentCol = GetOwner()->GetColumnAt(i);
m_currentColSetByKeyboard = true; m_currentColSetByKeyboard = true;
RefreshRow(m_currentRow); RefreshRow(m_currentRow);
return true; return true;
@@ -4521,41 +4528,49 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxK
} }
} }
int idx = GetOwner()->GetColumnIndex(m_currentCol) + (forward ? +1 : -1); int idx = GetOwner()->GetColumnIndex(m_currentCol);
unsigned int cols = GetOwner()->GetColumnCount();
if ( idx >= (int)GetOwner()->GetColumnCount() ) for ( unsigned int i = 0; i < cols; i++ )
{ {
if ( !wrapAround ) idx += (forward ? +1 : -1);
return false; if ( idx >= (int)GetOwner()->GetColumnCount() )
{
if ( !wrapAround )
return false;
if ( GetCurrentRow() < GetRowCount() - 1 ) if ( GetCurrentRow() < GetRowCount() - 1 )
{ {
// go to the first column of the next row: // go to the first column of the next row:
idx = 0; idx = 0;
OnVerticalNavigation(wxKeyEvent()/*dummy*/, +1); OnVerticalNavigation(wxKeyEvent()/*dummy*/, +1);
}
else
{
// allow focus change
event.Skip();
return false;
}
} }
else else if ( idx < 0 )
{ {
// allow focus change if ( !wrapAround )
event.Skip(); return false;
return false;
}
}
if ( idx < 0 && wrapAround ) if ( GetCurrentRow() > 0 )
{ {
if ( GetCurrentRow() > 0 ) // go to the last column of the previous row:
{ idx = col_last-1;
// go to the last column of the previous row: OnVerticalNavigation(wxKeyEvent()/*dummy*/, -1);
idx = (int)GetOwner()->GetColumnCount() - 1; }
OnVerticalNavigation(wxKeyEvent()/*dummy*/, -1); else
} {
else // allow focus change
{ event.Skip();
// allow focus change return false;
event.Skip(); }
return false;
} }
if ( GetModel()->HasValue(node->GetItem(), i) )
break;
} }
GetOwner()->EnsureVisibleRowCol(m_currentRow, idx); GetOwner()->EnsureVisibleRowCol(m_currentRow, idx);
@@ -4767,9 +4782,8 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
} }
bool ignore_other_columns = bool ignore_other_columns =
((expander != col) && (expander != col) &&
(model->IsContainer(item)) && (!model->HasValue(item, col->GetModelColumn()));
(!model->HasContainerColumns(item)));
if (event.LeftDClick()) if (event.LeftDClick())
{ {
@@ -6495,7 +6509,7 @@ wxAccStatus wxDataViewCtrlAccessible::GetDescription(int childId, wxString* desc
const unsigned int numCols = dvCtrl->GetColumnCount(); const unsigned int numCols = dvCtrl->GetColumnCount();
for ( unsigned int col = 0; col < numCols; col++ ) for ( unsigned int col = 0; col < numCols; col++ )
{ {
if ( model->IsContainer(item) && !model->HasContainerColumns(item) ) if ( !model->HasValue(item, col) )
continue; // skip it continue; // skip it
wxDataViewColumn *dvCol = dvCtrl->GetColumnAt(col); wxDataViewColumn *dvCol = dvCtrl->GetColumnAt(col);

View File

@@ -3146,16 +3146,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column),
if (!wx_model->IsVirtualListModel()) if (!wx_model->IsVirtualListModel())
{ {
gboolean visible; gboolean visible = wx_model->HasValue(item, column);
if (wx_model->IsContainer( item ))
{
visible = wx_model->HasContainerColumns( item ) || (column == 0);
}
else
{
visible = true;
}
GValue gvalue = G_VALUE_INIT; GValue gvalue = G_VALUE_INIT;
g_value_init( &gvalue, G_TYPE_BOOLEAN ); g_value_init( &gvalue, G_TYPE_BOOLEAN );
g_value_set_boolean( &gvalue, visible ); g_value_set_boolean( &gvalue, visible );