void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) { if( aItem->IsSelected() ) { deselect( aItem ); // Inform other potentially interested tools TOOL_EVENT deselectEvent( DeselectedEvent ); m_toolMgr->ProcessEvent( deselectEvent ); } else { if( !m_additive ) clearSelection(); // Prevent selection of invisible or inactive items if( selectable( aItem ) ) { select( aItem ); // Inform other potentially interested tools TOOL_EVENT selectEvent( SelectedEvent ); m_toolMgr->ProcessEvent( selectEvent ); } } }
bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? m_multiple = true; // Multiple selection mode is active KIGFX::VIEW* view = getView(); getViewControls()->SetAutoPan( true ); SELECTION_AREA area; view->Add( &area ); while( OPT_TOOL_EVENT evt = Wait() ) { if( evt->IsCancel() ) { cancelled = true; break; } if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) clearSelection(); // Start drawing a selection box area.SetOrigin( evt->DragOrigin() ); area.SetEnd( evt->Position() ); area.ViewSetVisible( true ); area.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } if( evt->IsMouseUp( BUT_LEFT ) ) { // End drawing the selection box area.ViewSetVisible( false ); // Mark items within the selection box as selected std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems; BOX2I selectionBox = area.ViewBBox(); view->Query( selectionBox, selectedItems ); // Get the list of selected items std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end; for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) { BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first ); // Add only those items that are visible and fully within the selection box if( !item->IsSelected() && selectable( item ) && selectionBox.Contains( item->ViewBBox() ) ) { select( item ); } } // Do not display information about selected item,as there is more than one m_frame->SetCurItem( NULL ); if( !m_selection.Empty() ) { // Inform other potentially interested tools m_toolMgr->ProcessEvent( SelectedEvent ); } break; // Stop waiting for events } } // Stop drawing the selection box area.ViewSetVisible( false ); view->Remove( &area ); m_multiple = false; // Multiple selection mode is inactive getViewControls()->SetAutoPan( false ); return cancelled; }
bool SELECTION_TOOL::selectCursor( const VECTOR2I& aWhere, bool aOnDrag ) { BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; if( m_editModules ) collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::ModuleItems, wxPoint( aWhere.x, aWhere.y ), guide ); else collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::AllBoardItems, wxPoint( aWhere.x, aWhere.y ), guide ); bool anyCollected = collector.GetCount() != 0; // Remove unselectable items for( int i = collector.GetCount() - 1; i >= 0; --i ) { if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) ) collector.Remove( i ); } switch( collector.GetCount() ) { case 0: if( !m_additive && anyCollected ) clearSelection(); return false; case 1: toggleSelection( collector[0] ); return true; default: // Apply some ugly heuristics to avoid disambiguation menus whenever possible guessSelectionCandidates( collector ); // Let's see if there is still disambiguation in selection.. if( collector.GetCount() == 1 ) { toggleSelection( collector[0] ); return true; } else if( collector.GetCount() > 1 ) { if( aOnDrag ) Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) ); item = disambiguationMenu( &collector ); if( item ) { toggleSelection( item ); return true; } } break; } return false; }
bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; // Preferred types (they have the priority when if they are covered by a bigger item) const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, PCB_MODULE_TEXT_T, EOT }; if( m_editModules ) collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::ModuleItems, wxPoint( aWhere.x, aWhere.y ), guide ); else collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::AllBoardItems, wxPoint( aWhere.x, aWhere.y ), guide ); switch( collector.GetCount() ) { case 0: if( !m_additive ) clearSelection(); return false; case 1: toggleSelection( collector[0] ); return true; default: // Remove unselectable items for( int i = collector.GetCount() - 1; i >= 0; --i ) { if( !selectable( collector[i] ) ) collector.Remove( i ); } // Check if among the selection candidates there is only one instance of preferred type item = prefer( collector, types ); if( item ) { toggleSelection( item ); return true; } // Let's see if there is still disambiguation in selection.. if( collector.GetCount() == 1 ) { toggleSelection( collector[0] ); return true; } else if( aAllowDisambiguation && collector.GetCount() > 1 ) { item = disambiguationMenu( &collector ); if( item ) { toggleSelection( item ); return true; } } break; } return false; }