/** * Function highlightNet() * Looks for a BOARD_CONNECTED_ITEM in a given spot, and if one is found - it enables * highlight for its net. * @param aPoint is the point where an item is expected (world coordinates). */ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) { KIGFX::RENDER_SETTINGS* render = aToolMgr->GetView()->GetPainter()->GetSettings(); GENERAL_COLLECTORS_GUIDE guide = static_cast<PCB_BASE_FRAME*>( aToolMgr->GetEditFrame() )->GetCollectorsGuide(); BOARD* board = static_cast<BOARD*>( aToolMgr->GetModel() ); GENERAL_COLLECTOR collector; int net = -1; // Find a connected item for which we are going to highlight a net collector.Collect( board, GENERAL_COLLECTOR::PadsTracksOrZones, wxPoint( aPosition.x, aPosition.y ), guide ); bool enableHighlight = ( collector.GetCount() > 0 ); // Obtain net code for the clicked item if( enableHighlight ) net = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] )->GetNetCode(); // Toggle highlight when the same net was picked if( net > 0 && net == render->GetHighlightNetCode() ) enableHighlight = !render->IsHighlightEnabled(); if( enableHighlight != render->IsHighlightEnabled() || net != render->GetHighlightNetCode() ) { render->SetHighlight( enableHighlight, net ); aToolMgr->GetView()->UpdateAllLayersColor(); } return true; }
/** * Function highlightNet() * Looks for a BOARD_CONNECTED_ITEM in a given spot, and if one is found - it enables * highlight for its net. * @param aPoint is the point where an item is expected (world coordinates). */ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) { auto render = aToolMgr->GetView()->GetPainter()->GetSettings(); auto frame = static_cast<PCB_EDIT_FRAME*>( aToolMgr->GetEditFrame() ); auto guide = frame->GetCollectorsGuide(); BOARD* board = static_cast<BOARD*>( aToolMgr->GetModel() ); GENERAL_COLLECTOR collector; int net = -1; // Find a connected item for which we are going to highlight a net collector.Collect( board, GENERAL_COLLECTOR::PadsTracksOrZones, wxPoint( aPosition.x, aPosition.y ), guide ); for( int i = 0; i < collector.GetCount(); i++ ) { if( collector[i]->Type() == PCB_PAD_T ) { frame->SendMessageToEESCHEMA( static_cast<BOARD_CONNECTED_ITEM*>( collector[i] ) ); break; } } bool enableHighlight = ( collector.GetCount() > 0 ); // Obtain net code for the clicked item if( enableHighlight ) net = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] )->GetNetCode(); // Toggle highlight when the same net was picked if( net > 0 && net == render->GetHighlightNetCode() ) enableHighlight = !render->IsHighlightEnabled(); if( enableHighlight != render->IsHighlightEnabled() || net != render->GetHighlightNetCode() ) { render->SetHighlight( enableHighlight, net ); aToolMgr->GetView()->UpdateAllLayersColor(); } // Store the highlighted netcode in the current board (for dialogs for instance) if( enableHighlight && net >= 0 ) board->SetHighLightNet( net ); else board->ResetHighLight(); return true; }
void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { BOARD* pcb = getModel<BOARD>( PCB_T ); BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = getEditFrame<PCB_EDIT_FRAME>()->GetCollectorsGuide(); GENERAL_COLLECTOR collector; collector.Collect( pcb, GENERAL_COLLECTOR::AllBoardItems, wxPoint( aWhere.x, aWhere.y ), guide ); switch( collector.GetCount() ) { case 0: if( !m_additive ) clearSelection(); break; case 1: toggleSelection( collector[0] ); break; default: // Remove unselectable items for( int i = collector.GetCount() - 1; i >= 0 ; --i ) { if( !selectable( collector[i] ) ) collector.Remove( i ); } // Let's see if there is still disambiguation in selection.. if( collector.GetCount() == 1 ) { toggleSelection( collector[0] ); } else if( collector.GetCount() > 1 ) { item = disambiguationMenu( &collector ); if( item ) toggleSelection( item ); } break; } }
void SELECTION_TOOL::highlightNet( const VECTOR2I& aPoint ) { KIGFX::RENDER_SETTINGS* render = getView()->GetPainter()->GetSettings(); GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; int net = -1; // Find a connected item for which we are going to highlight a net collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::PadsTracksOrZones, wxPoint( aPoint.x, aPoint.y ), guide ); bool enableHighlight = ( collector.GetCount() > 0 ); // Obtain net code for the clicked item if( enableHighlight ) net = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] )->GetNetCode(); if( enableHighlight != render->GetHighlight() || net != render->GetHighlightNetCode() ) { render->SetHighlight( enableHighlight, net ); getView()->UpdateAllLayersColor(); } }
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; }
int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent ) { std::list<D_PAD*> pads; std::set<D_PAD*> allPads; if( !m_board->m_Modules || !m_board->m_Modules->Pads() ) return 0; GENERAL_COLLECTOR collector; const KICAD_T types[] = { PCB_PAD_T, EOT }; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); guide.SetIgnoreMTextsMarkedNoShow( true ); guide.SetIgnoreMTextsOnBack( true ); guide.SetIgnoreMTextsOnFront( true ); guide.SetIgnoreModulesVals( true ); guide.SetIgnoreModulesRefs( true ); // Create a set containing all pads (to avoid double adding to the list) for( D_PAD* p = m_board->m_Modules->Pads(); p; p = p->Next() ) allPads.insert( p ); DIALOG_ENUM_PADS settingsDlg( m_frame ); if( settingsDlg.ShowModal() == wxID_CANCEL ) return 0; int padNumber = settingsDlg.GetStartNumber(); wxString padPrefix = settingsDlg.GetPrefix(); m_frame->DisplayToolMsg( _( "Hold left mouse button and move cursor over pads to enumerate them" ) ); Activate(); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); VECTOR2I oldCursorPos = m_controls->GetCursorPosition(); std::list<D_PAD*> selectedPads; while( OPT_TOOL_EVENT evt = Wait() ) { if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) { selectedPads.clear(); VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsClick( BUT_LEFT ) ) { oldCursorPos = m_controls->GetCursorPosition(); collector.Empty(); collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide ); for( int i = 0; i < collector.GetCount(); ++i ) { if( collector[i]->Type() == PCB_PAD_T ) selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) ); } } else //evt->IsDrag( BUT_LEFT ) { // wxWidgets deliver mouse move events not frequently enough, resulting in skipping // pads if the user moves cursor too fast. To solve it, create a line that approximates // the mouse move and select items intersecting with the line. int distance = ( cursorPos - oldCursorPos ).EuclideanNorm(); int segments = distance / 100000 + 1; const wxPoint LINE_STEP( ( cursorPos - oldCursorPos ).x / segments, ( cursorPos - oldCursorPos ).y / segments ); collector.Empty(); for( int j = 0; j < segments; ++j ) { collector.Collect( m_board, types, wxPoint( oldCursorPos.x, oldCursorPos.y ) + j * LINE_STEP, guide ); for( int i = 0; i < collector.GetCount(); ++i ) { if( collector[i]->Type() == PCB_PAD_T ) selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) ); } } selectedPads.unique(); } for( D_PAD* pad : selectedPads ) { std::set<D_PAD*>::iterator it = allPads.find( pad ); // Add the pad to the list, if it was not selected previously.. if( it != allPads.end() ) { allPads.erase( it ); pads.push_back( pad ); pad->SetSelected(); } // ..or remove it from the list if it was clicked else if( evt->IsClick( BUT_LEFT ) ) { allPads.insert( pad ); pads.remove( pad ); pad->ClearSelected(); } } oldCursorPos = cursorPos; } else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) || evt->IsDblClick( BUT_LEFT ) ) { // Accept changes BOARD_COMMIT commit( m_frame ); m_frame->OnModify(); for( D_PAD* pad : pads ) { commit.Modify( pad ); pad->SetPadName( wxString::Format( wxT( "%s%d" ), padPrefix.c_str(), padNumber++ ) ); } commit.Push( _( "Enumerate pads" ) ); break; } else if( evt->IsCancel() || evt->IsActivate() ) { break; } } for( D_PAD* pad : pads ) pad->ClearSelected(); m_frame->DisplayToolMsg( wxEmptyString ); m_controls->ShowCursor( false ); return 0; }
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; }