X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c0c133e13b36a923c65f94499554e432bc3a0daa..8d6e8e45fe72afcb38d1da3b2b90c307ac052b0c:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 49120ac939..f6e109d249 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -1526,6 +1526,9 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) wxDataViewTreeNode *node = GetTreeNodeByRow(row); indent = GetOwner()->GetIndent() * node->GetIndentLevel(); indent = indent + m_lineHeight; //try to use the m_lineHeight as the expander space + + if(!node->HasChildren()) + delete node; } width -= indent; @@ -1915,9 +1918,23 @@ void wxDataViewMainWindow::OnRenameTimer() break; xpos += c->GetWidth(); } - wxRect labelRect( xpos, + + // we have to take an expander column into account and compute its indentation + // to get the editor at the correct x position where the actual text is + int indent = 0; + if (!IsVirtualList() && GetOwner()->GetExpanderColumn() == m_currentCol) + { + wxDataViewTreeNode* node = GetTreeNodeByRow(m_currentRow); + indent = GetOwner()->GetIndent() * node->GetIndentLevel(); + indent = indent + m_lineHeight; + + if(!node->HasChildren()) + delete node; + } + + wxRect labelRect( xpos + indent, GetLineStart( m_currentRow ), - m_currentCol->GetWidth(), + m_currentCol->GetWidth() - indent, GetLineHeight( m_currentRow ) ); GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y, @@ -1925,7 +1942,6 @@ void wxDataViewMainWindow::OnRenameTimer() wxDataViewItem item = GetItemByRow( m_currentRow ); m_currentCol->GetRenderer()->StartEditing( item, labelRect ); - } //------------------------------------------------------------------ @@ -2878,6 +2894,23 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row ) SortPrepare(); ::BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node); } + + // By expanding the node all row indices that are currently in the selection list + // and are greater than our node have become invalid. So we have to correct that now. + const unsigned rowAdjustment = node->GetSubTreeCount(); + for(unsigned i=0; i row) + ChangeCurrentRow(m_currentRow + rowAdjustment); + m_count = -1; UpdateDisplay(); //Send the expanded event @@ -2911,7 +2944,55 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row) wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,node->GetItem()); if( e.GetSkipped() ) return; - node->ToggleOpen(); + + // Find out if there are selected items below the current node. + bool selectCollapsingRow = false; + const unsigned rowAdjustment = node->GetSubTreeCount(); + unsigned maxRowToBeTested = row + rowAdjustment; + for(unsigned i=0; i row && testRow <= maxRowToBeTested) + { + selectCollapsingRow = true; + // get out as soon as we have found a node that is selected + break; + } + } + + node->ToggleOpen(); + + // If the node to be closed has selected items the user won't see those any longer. + // We select the collapsing node in this case. + if(selectCollapsingRow) + { + SelectAllRows(false); + ChangeCurrentRow(row); + SelectRow(row, true); + SendSelectionChangedEvent(GetItemByRow(row)); + } + else + { + // if there were no selected items below our node we still need to "fix" the + // selection list to adjust for the changing of the row indices. + // We actually do the opposite of what we are doing in OnExpanding(). + for(unsigned i=0; i row && m_currentRow <= maxRowToBeTested) + ChangeCurrentRow(row); + else if(m_currentRow > row) + ChangeCurrentRow(m_currentRow - rowAdjustment); + } + m_count = -1; UpdateDisplay(); SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,nd->GetItem()); @@ -3342,7 +3423,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) } //Test whether the mouse is hovered on the tree item button - bool hover = false; + bool hoverOverExpander = false; if ((!IsVirtualList()) && (GetOwner()->GetExpanderColumn() == col)) { wxDataViewTreeNode * node = GetTreeNodeByRow(current); @@ -3350,14 +3431,16 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { int indent = node->GetIndentLevel(); indent = GetOwner()->GetIndent()*indent; - wxRect rect( xpos + indent + EXPANDER_MARGIN, - GetLineStart( current ) + EXPANDER_MARGIN + (GetLineHeight(current)/2) - (m_lineHeight/2) - EXPANDER_OFFSET, - m_lineHeight-2*EXPANDER_MARGIN, - m_lineHeight-2*EXPANDER_MARGIN + EXPANDER_OFFSET); - if( rect.Contains( x, y) ) + + // we make the rectangle we are looking in a bit bigger than the actual + // visual expander so the user can hit that little thing reliably + wxRect rect( xpos + indent, + GetLineStart( current ) + (GetLineHeight(current) - m_lineHeight)/2, + m_lineHeight, m_lineHeight); + if( rect.Contains(x, y) ) { //So the mouse is over the expander - hover = true; + hoverOverExpander = true; if (m_underMouse && m_underMouse != node) { //wxLogMessage("Undo the row: %d", GetRowByItem(m_underMouse->GetItem())); @@ -3374,7 +3457,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (node!=NULL && !node->HasChildren()) delete node; } - if (!hover) + if (!hoverOverExpander) { if (m_underMouse != NULL) { @@ -3436,7 +3519,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) } #endif // wxUSE_DRAG_AND_DROP - bool forceClick = false; + bool simulateClick = false; if (event.ButtonDClick()) { @@ -3452,7 +3535,12 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (event.LeftDClick()) { - if ( current == m_lineLastClicked ) + if(hoverOverExpander) + { + // a double click on the expander will be converted into a "simulated" normal click + simulateClick = true; + } + else if ( current == m_lineLastClicked ) { if ((!ignore_other_columns) && (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE)) { @@ -3480,11 +3568,11 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { // The first click was on another item, so don't interpret this as // a double click, but as a simple click instead - forceClick = true; + simulateClick = true; } } - if (event.LeftUp()) + if (event.LeftUp() && !hoverOverExpander) { if (m_lineSelectSingleOnUp != (unsigned int)-1) { @@ -3494,34 +3582,8 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } - //Process the event of user clicking the expander - bool expander = false; - if ((!IsVirtualList()) && (GetOwner()->GetExpanderColumn() == col)) - { - wxDataViewTreeNode * node = GetTreeNodeByRow(current); - if( node!=NULL && node->HasChildren() ) - { - int indent = node->GetIndentLevel(); - indent = GetOwner()->GetIndent()*indent; - wxRect rect( xpos + indent + EXPANDER_MARGIN, - GetLineStart( current ) + EXPANDER_MARGIN + (GetLineHeight(current)/2) - (m_lineHeight/2) - EXPANDER_OFFSET, - m_lineHeight-2*EXPANDER_MARGIN, - m_lineHeight-2*EXPANDER_MARGIN + EXPANDER_OFFSET); - - if( rect.Contains( x, y) ) - { - expander = true; - if( node->IsOpen() ) - OnCollapsing(current); - else - OnExpanding( current ); - } - } - if (node && !node->HasChildren()) - delete node; - } //If the user click the expander, we do not do editing even if the column with expander are editable - if (m_lastOnSame && !expander && !ignore_other_columns) + if (m_lastOnSame && !ignore_other_columns) { if ((col == m_currentCol) && (current == m_currentRow) && (cell->GetMode() & wxDATAVIEW_CELL_EDITABLE) ) @@ -3533,7 +3595,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) m_lastOnSame = false; m_lineSelectSingleOnUp = (unsigned int)-1; } - else + else if(!event.LeftUp()) { // This is necessary, because after a DnD operation in // from and to ourself, the up event is swallowed by the @@ -3570,7 +3632,18 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) else if (event.MiddleDown()) { } - if (event.LeftDown() || forceClick) + + if((event.LeftDown() || simulateClick) && hoverOverExpander) + { + wxDataViewTreeNode* node = GetTreeNodeByRow(current); + // hoverOverExpander being true tells us that our node must be valid and have children. + // So we don't need any extra checks. + if( node->IsOpen() ) + OnCollapsing(current); + else + OnExpanding(current); + } + else if ((event.LeftDown() || simulateClick) && !hoverOverExpander) { SetFocus(); @@ -3635,7 +3708,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) // Update selection here... m_currentCol = col; - m_lastOnSame = !forceClick && ((col == oldCurrentCol) && + m_lastOnSame = !simulateClick && ((col == oldCurrentCol) && (current == oldCurrentRow)) && oldWasSelected; // Call LeftClick after everything else as under GTK+