Merge branch 'dvc-virtual-has-value'
Allow overriding wxDataViewModel::HasValue() to specify which cells should, and should not, show anything. Closes https://github.com/wxWidgets/wxWidgets/pull/1792 Closes #18724.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -304,14 +304,18 @@ 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.
|
||||||
|
|
||||||
|
Since wxWidgets 3.1.4, this method is virtual and can be overridden to
|
||||||
|
explicitly specify for which columns a given item has, and doesn't
|
||||||
|
have, 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
|
||||||
|
@@ -170,6 +170,9 @@ private:
|
|||||||
enum Lang { Lang_English, Lang_French };
|
enum Lang { Lang_English, Lang_French };
|
||||||
void FillIndexList(Lang lang);
|
void FillIndexList(Lang lang);
|
||||||
|
|
||||||
|
// HasValue page.
|
||||||
|
void OnHasValueValueChanged(wxDataViewEvent& event);
|
||||||
|
|
||||||
|
|
||||||
wxNotebook* m_notebook;
|
wxNotebook* m_notebook;
|
||||||
|
|
||||||
@@ -182,6 +185,7 @@ private:
|
|||||||
Page_TreeStore,
|
Page_TreeStore,
|
||||||
Page_VarHeight,
|
Page_VarHeight,
|
||||||
Page_IndexList,
|
Page_IndexList,
|
||||||
|
Page_HasValue,
|
||||||
Page_Max
|
Page_Max
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -713,6 +717,16 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
|
|||||||
sixthPanelSz->Add(button_sizer6);
|
sixthPanelSz->Add(button_sizer6);
|
||||||
sixthPanel->SetSizerAndFit(sixthPanelSz);
|
sixthPanel->SetSizerAndFit(sixthPanelSz);
|
||||||
|
|
||||||
|
// page showing that some columns don't have values for some items
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
wxPanel *seventhPanel = new wxPanel( m_notebook, wxID_ANY );
|
||||||
|
|
||||||
|
BuildDataViewCtrl(seventhPanel, Page_HasValue);
|
||||||
|
|
||||||
|
wxSizer *seventhPanelSz = new wxBoxSizer( wxVERTICAL );
|
||||||
|
seventhPanelSz->Add(m_ctrl[Page_HasValue], 1, wxGROW|wxALL, 5);
|
||||||
|
seventhPanel->SetSizerAndFit(seventhPanelSz);
|
||||||
|
|
||||||
// complete GUI
|
// complete GUI
|
||||||
// ------------
|
// ------------
|
||||||
@@ -723,6 +737,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
|
|||||||
m_notebook->AddPage(fourthPanel, "wxDataViewTreeCtrl");
|
m_notebook->AddPage(fourthPanel, "wxDataViewTreeCtrl");
|
||||||
m_notebook->AddPage(fifthPanel, "Variable line height");
|
m_notebook->AddPage(fifthPanel, "Variable line height");
|
||||||
m_notebook->AddPage(sixthPanel, "MyIndexListModel");
|
m_notebook->AddPage(sixthPanel, "MyIndexListModel");
|
||||||
|
m_notebook->AddPage(seventhPanel, "MyDataViewHasValue");
|
||||||
|
|
||||||
wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
|
wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
@@ -987,7 +1002,50 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
|||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Page_HasValue:
|
||||||
|
{
|
||||||
|
wxDataViewListCtrl* lc =
|
||||||
|
new wxDataViewListCtrl( parent, wxID_ANY, wxDefaultPosition,
|
||||||
|
wxDefaultSize, style );
|
||||||
|
m_ctrl[Page_HasValue] = lc;
|
||||||
|
|
||||||
|
MyListStoreDerivedModel* page7_model = new MyListStoreHasValueModel();
|
||||||
|
lc->AssociateModel(page7_model);
|
||||||
|
page7_model->DecRef();
|
||||||
|
|
||||||
|
lc->AppendToggleColumn( "Toggle" );
|
||||||
|
|
||||||
|
// We're not limited to convenience column-appending functions, it
|
||||||
|
// can also be done fully manually, which allows us to customize
|
||||||
|
// the renderer being used.
|
||||||
|
wxDataViewToggleRenderer* const rendererRadio =
|
||||||
|
new wxDataViewToggleRenderer("bool", wxDATAVIEW_CELL_ACTIVATABLE);
|
||||||
|
rendererRadio->ShowAsRadio();
|
||||||
|
wxDataViewColumn* const colRadio =
|
||||||
|
new wxDataViewColumn("Radio", rendererRadio, 1);
|
||||||
|
lc->AppendColumn(colRadio, "bool");
|
||||||
|
|
||||||
|
lc->AppendTextColumn( "Text" );
|
||||||
|
lc->AppendProgressColumn( "Progress" )->SetMinWidth(FromDIP(100));
|
||||||
|
|
||||||
|
wxVector<wxVariant> data;
|
||||||
|
for (unsigned int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
data.clear();
|
||||||
|
data.push_back( (i%3) == 0 );
|
||||||
|
data.push_back( i == 7 ); // select a single (random) radio item
|
||||||
|
data.push_back( wxString::Format("row %d", i) );
|
||||||
|
data.push_back( long(5*i) );
|
||||||
|
|
||||||
|
lc->AppendItem( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
lc->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &MyFrame::OnHasValueValueChanged, this);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1717,3 +1775,45 @@ void MyFrame::OnIndexListSelectionChanged(wxDataViewEvent& event)
|
|||||||
|
|
||||||
wxLogMessage("Selected week day: %s", weekday);
|
wxLogMessage("Selected week day: %s", weekday);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MyFrame - event handlers for the HasValue (wxDataViewListCtrl) page
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MyFrame::OnHasValueValueChanged(wxDataViewEvent& event)
|
||||||
|
{
|
||||||
|
// Ignore changes coming from our own SetToggleValue() calls below.
|
||||||
|
if ( m_eventFromProgram )
|
||||||
|
{
|
||||||
|
m_eventFromProgram = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDataViewListCtrl* const lc = static_cast<wxDataViewListCtrl*>(m_ctrl[Page_HasValue]);
|
||||||
|
|
||||||
|
const int columnToggle = 1;
|
||||||
|
|
||||||
|
// Handle selecting a radio button by unselecting all the other ones.
|
||||||
|
if ( event.GetColumn() == columnToggle )
|
||||||
|
{
|
||||||
|
const int rowChanged = lc->ItemToRow(event.GetItem());
|
||||||
|
if ( lc->GetToggleValue(rowChanged, columnToggle) )
|
||||||
|
{
|
||||||
|
for ( int row = 0; row < lc->GetItemCount(); ++row )
|
||||||
|
{
|
||||||
|
if ( row != rowChanged )
|
||||||
|
{
|
||||||
|
m_eventFromProgram = true;
|
||||||
|
lc->SetToggleValue(false, row, columnToggle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // The item was cleared.
|
||||||
|
{
|
||||||
|
// Explicitly check it back, we want to always have exactly one
|
||||||
|
// checked radio item in this column.
|
||||||
|
m_eventFromProgram = true;
|
||||||
|
lc->SetToggleValue(true, rowChanged, columnToggle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -626,3 +626,15 @@ bool MyListStoreDerivedModel::IsEnabledByRow(unsigned int row, unsigned int col)
|
|||||||
// disabled the last two checkboxes
|
// disabled the last two checkboxes
|
||||||
return !(col == 0 && 8 <= row && row <= 9);
|
return !(col == 0 && 8 <= row && row <= 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MyListStoreHasValueModel
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool MyListStoreHasValueModel::HasValue(const wxDataViewItem &item, unsigned int col) const
|
||||||
|
{
|
||||||
|
unsigned int row = GetRow( item );
|
||||||
|
// the diagonal entries don't have values. This is just a silly example to demonstrate the
|
||||||
|
// usage of overriding HasValue to specify that some columns don't have values for some items
|
||||||
|
return row != col;
|
||||||
|
}
|
||||||
|
@@ -266,6 +266,16 @@ public:
|
|||||||
virtual bool IsEnabledByRow(unsigned int row, unsigned int col) const wxOVERRIDE;
|
virtual bool IsEnabledByRow(unsigned int row, unsigned int col) const wxOVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MyListStoreHasValueModel
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyListStoreHasValueModel : public MyListStoreDerivedModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool HasValue(const wxDataViewItem &item, unsigned int col) const wxOVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// MyIndexListModel
|
// MyIndexListModel
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -334,8 +334,13 @@ int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem
|
|||||||
unsigned int column, bool ascending ) const
|
unsigned int column, bool ascending ) const
|
||||||
{
|
{
|
||||||
wxVariant value1,value2;
|
wxVariant value1,value2;
|
||||||
GetValue( value1, item1, column );
|
|
||||||
GetValue( value2, item2, column );
|
// Avoid calling GetValue() for the cells that are not supposed to have any
|
||||||
|
// value, this might be unexpected.
|
||||||
|
if ( HasValue(item1, column) )
|
||||||
|
GetValue( value1, item1, column );
|
||||||
|
if ( HasValue(item2, column) )
|
||||||
|
GetValue( value2, item2, column );
|
||||||
|
|
||||||
if (!ascending)
|
if (!ascending)
|
||||||
{
|
{
|
||||||
|
@@ -910,6 +910,39 @@ private:
|
|||||||
// assumes that all columns were modified, otherwise just this one.
|
// assumes that all columns were modified, otherwise just this one.
|
||||||
bool DoItemChanged(const wxDataViewItem& item, int view_column);
|
bool DoItemChanged(const wxDataViewItem& item, int view_column);
|
||||||
|
|
||||||
|
// Return whether the item has at most one column with a value.
|
||||||
|
bool IsItemSingleValued(const wxDataViewItem& item) const
|
||||||
|
{
|
||||||
|
bool hadColumnWithValue = false;
|
||||||
|
const unsigned int cols = GetOwner()->GetColumnCount();
|
||||||
|
const wxDataViewModel* const model = GetModel();
|
||||||
|
for ( unsigned int i = 0; i < cols; i++ )
|
||||||
|
{
|
||||||
|
if ( model->HasValue(item, i) )
|
||||||
|
{
|
||||||
|
if ( hadColumnWithValue )
|
||||||
|
return false;
|
||||||
|
hadColumnWithValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the first column with a value in it.
|
||||||
|
wxDataViewColumn* FindFirstColumnWithValue(const wxDataViewItem& item) const
|
||||||
|
{
|
||||||
|
const unsigned int cols = GetOwner()->GetColumnCount();
|
||||||
|
const wxDataViewModel* const model = GetModel();
|
||||||
|
for ( unsigned int i = 0; i < cols; i++ )
|
||||||
|
{
|
||||||
|
if ( model->HasValue(item, i) )
|
||||||
|
return GetOwner()->GetColumnAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxDataViewCtrl *m_owner;
|
wxDataViewCtrl *m_owner;
|
||||||
int m_lineHeight;
|
int m_lineHeight;
|
||||||
@@ -2396,11 +2429,11 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
{
|
{
|
||||||
renderColumnFocus = true;
|
renderColumnFocus = true;
|
||||||
|
|
||||||
// If this is container node without columns, render full-row focus:
|
// If there is just a single value, render full-row focus:
|
||||||
if ( !IsList() )
|
if ( !IsList() )
|
||||||
{
|
{
|
||||||
wxDataViewTreeNode *node = GetTreeNodeByRow(item);
|
wxDataViewTreeNode *node = GetTreeNodeByRow(item);
|
||||||
if ( node->HasChildren() && !model->HasContainerColumns(node->GetItem()) )
|
if ( IsItemSingleValued(node->GetItem()) )
|
||||||
renderColumnFocus = false;
|
renderColumnFocus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2547,11 +2580,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 +3521,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 =
|
||||||
@@ -4071,20 +4099,25 @@ wxDataViewMainWindow::FindColumnForEditing(const wxDataViewItem& item, wxDataVie
|
|||||||
|
|
||||||
wxDataViewColumn *candidate = m_currentCol;
|
wxDataViewColumn *candidate = m_currentCol;
|
||||||
|
|
||||||
if ( candidate &&
|
if ( candidate && !IsCellEditableInMode(item, candidate, mode) )
|
||||||
!IsCellEditableInMode(item, candidate, mode) &&
|
|
||||||
!m_currentColSetByKeyboard )
|
|
||||||
{
|
{
|
||||||
// If current column was set by mouse to something not editable (in
|
if ( m_currentColSetByKeyboard )
|
||||||
// 'mode') and the user pressed Space/F2 to edit it, treat the
|
{
|
||||||
// situation as if there was whole-row focus, because that's what is
|
// If current column was set by keyboard to something not editable (in
|
||||||
// visually indicated and the mouse click could very well be targeted
|
// 'mode') and the user pressed Space/F2 then do not edit anything
|
||||||
// on the row rather than on an individual cell.
|
// because focus is visually on that column and editing
|
||||||
//
|
// something else would be surprising.
|
||||||
// But if it was done by keyboard, respect that even if the column
|
return NULL;
|
||||||
// isn't editable, because focus is visually on that column and editing
|
}
|
||||||
// something else would be surprising.
|
else
|
||||||
candidate = NULL;
|
{
|
||||||
|
// But if the current column was set by mouse to something not editable (in
|
||||||
|
// 'mode') and the user pressed Space/F2 to edit it, treat the
|
||||||
|
// situation as if there was whole-row focus, because that's what is
|
||||||
|
// visually indicated and the mouse click could very well be targeted
|
||||||
|
// on the row rather than on an individual cell.
|
||||||
|
candidate = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !candidate )
|
if ( !candidate )
|
||||||
@@ -4104,23 +4137,17 @@ wxDataViewMainWindow::FindColumnForEditing(const wxDataViewItem& item, wxDataVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If on container item without columns, only the expander column
|
// Switch to the first column with value if the current column has no value
|
||||||
// may be directly editable:
|
if ( candidate && !GetModel()->HasValue(item, candidate->GetModelColumn()) )
|
||||||
if ( candidate &&
|
candidate = FindFirstColumnWithValue(item);
|
||||||
GetOwner()->GetExpanderColumn() != candidate &&
|
|
||||||
GetModel()->IsContainer(item) &&
|
|
||||||
!GetModel()->HasContainerColumns(item) )
|
|
||||||
{
|
|
||||||
candidate = GetOwner()->GetExpanderColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !candidate )
|
if ( !candidate )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ( !IsCellEditableInMode(item, candidate, mode) )
|
if ( !IsCellEditableInMode(item, candidate, mode) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDataViewMainWindow::IsCellEditableInMode(const wxDataViewItem& item,
|
bool wxDataViewMainWindow::IsCellEditableInMode(const wxDataViewItem& item,
|
||||||
@@ -4133,6 +4160,9 @@ bool wxDataViewMainWindow::IsCellEditableInMode(const wxDataViewItem& item,
|
|||||||
if ( !GetModel()->IsEnabled(item, col->GetModelColumn()) )
|
if ( !GetModel()->IsEnabled(item, col->GetModelColumn()) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ( !GetModel()->HasValue(item, col->GetModelColumn()) )
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4498,18 +4528,26 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxK
|
|||||||
|
|
||||||
const bool wrapAround = event.GetKeyCode() == WXK_TAB;
|
const bool wrapAround = event.GetKeyCode() == WXK_TAB;
|
||||||
|
|
||||||
if ( node )
|
// navigation shouldn't work in nodes with fewer than two columns
|
||||||
{
|
if ( node && IsItemSingleValued(node->GetItem()) )
|
||||||
// navigation shouldn't work in branch nodes without other columns:
|
return false;
|
||||||
if ( node->HasChildren() && !GetModel()->HasContainerColumns(node->GetItem()) )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_currentCol == NULL || !m_currentColSetByKeyboard )
|
if ( m_currentCol == NULL || !m_currentColSetByKeyboard )
|
||||||
{
|
{
|
||||||
if ( forward )
|
if ( forward )
|
||||||
{
|
{
|
||||||
m_currentCol = GetOwner()->GetColumnAt(0);
|
if ( node )
|
||||||
|
{
|
||||||
|
// find first column with value
|
||||||
|
m_currentCol = FindFirstColumnWithValue(node->GetItem());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// in the special "list" case, all columns have values, so just
|
||||||
|
// take the first one
|
||||||
|
m_currentCol = GetOwner()->GetColumnAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
m_currentColSetByKeyboard = true;
|
m_currentColSetByKeyboard = true;
|
||||||
RefreshRow(m_currentRow);
|
RefreshRow(m_currentRow);
|
||||||
return true;
|
return true;
|
||||||
@@ -4521,41 +4559,49 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxK
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = GetOwner()->GetColumnIndex(m_currentCol) + (forward ? +1 : -1);
|
int idx = GetOwner()->GetColumnIndex(m_currentCol);
|
||||||
|
const 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 = (int)GetOwner()->GetColumnCount() - 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 ( !node || GetModel()->HasValue(node->GetItem(), i) )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetOwner()->EnsureVisibleRowCol(m_currentRow, idx);
|
GetOwner()->EnsureVisibleRowCol(m_currentRow, idx);
|
||||||
@@ -4767,9 +4813,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 +6540,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);
|
||||||
|
@@ -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 );
|
||||||
|
Reference in New Issue
Block a user