int PCB_EDIT_FRAME::OnHotkeyCopyItem() { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); if( itemCurrentlyEdited ) return 0; item = PcbGeneralLocateAndDisplay(); if( item == NULL ) return 0; SetCurItem( item ); int eventId = 0; switch( item->Type() ) { case PCB_TEXT_T: eventId = ID_POPUP_PCB_COPY_TEXTEPCB; break; default: eventId = 0; break; } return eventId; }
bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) { BOARD_ITEM* item = GetCurItem(); bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED; bool itemCurrentlyEdited = item && item->GetFlags(); m_canvas->SetAutoPanRequest( false ); if( itemCurrentlyEdited ) { m_canvas->SetIgnoreMouseEvents( true ); m_canvas->CrossHairOff( aDC ); switch( item->Type() ) { case PCB_TRACE_T: case PCB_VIA_T: if( item->IsDragging() ) PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( item ), aDC ); break; case PCB_TEXT_T: Place_Texte_Pcb( static_cast<TEXTE_PCB*>( item ), aDC ); break; case PCB_MODULE_TEXT_T: PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), aDC ); break; case PCB_PAD_T: PlacePad( static_cast<D_PAD*>( item ), aDC ); break; case PCB_MODULE_T: PlaceModule( static_cast<MODULE*>( item ), aDC ); break; case PCB_TARGET_T: PlaceTarget( static_cast<PCB_TARGET*>( item ), aDC ); break; case PCB_LINE_T: if( no_tool ) // when no tools: existing item moving. Place_DrawItem( static_cast<DRAWSEGMENT*>( item ), aDC ); break; default: break; } m_canvas->SetIgnoreMouseEvents( false ); m_canvas->CrossHairOn( aDC ); return true; } return false; }
bool FOOTPRINT_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE; if( itemCurrentlyEdited || blockActive ) return false; item = ModeditLocateAndDisplay(); if( item == NULL ) return false; SetCurItem( item ); int evt_type = 0; // Used to post a wxCommandEvent on demand switch( item->Type() ) { case PCB_MODULE_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_MODULE_PRMS; break; case PCB_PAD_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_PAD; break; case PCB_MODULE_TEXT_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE; break; case PCB_MODULE_EDGE_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_MODEDIT_EDIT_BODY_ITEM; break; default: break; } if( evt_type != 0 ) { wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); evt.SetEventObject( this ); evt.SetId( evt_type ); wxPostEvent( this, evt ); return true; } return false; }
bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); int evt_type = 0; // Used to post a wxCommandEvent on demand wxASSERT( aIdCommand == HK_ROTATE_ITEM ); // Allows block rotate operation on hot key. if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { evt_type = ID_POPUP_ROTATE_BLOCK; } else { if( !itemCurrentlyEdited ) item = PcbGeneralLocateAndDisplay(); if( item == NULL ) return false; SetCurItem( item ); switch( item->Type() ) { case PCB_MODULE_T: evt_type = ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE; break; case PCB_TEXT_T: evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB; break; case PCB_MODULE_TEXT_T: evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE; break; default: break; } } if( evt_type != 0 ) { wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); evt.SetEventObject( this ); evt.SetId( evt_type ); GetEventHandler()->ProcessEvent( evt ); return true; } return false; }
/* * Called on a mouse left button double click */ void FOOTPRINT_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) { BOARD_ITEM* item = GetCurItem(); switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { item = ModeditLocateAndDisplay(); } if( ( item == NULL ) || ( item->GetFlags() != 0 ) ) break; // Item found SetCurItem( item ); OnEditItemRequest( DC, item ); break; // end case 0 case ID_PCB_ADD_LINE_BUTT: { if( item && item->IsNew() ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } break; } default: break; } }
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !hoverSelection( false ) ) return 0; // Tracks & vias are treated in a special way: if( ( SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Tracks ) )( selection ) ) { DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection ); if( dlg.ShowModal() ) { dlg.Apply( *m_commit ); m_commit->Push( _( "Edit track/via properties" ) ); } } else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); // Store flags, so they can be restored later STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY // Display properties dialog provided by the legacy canvas frame editFrame->OnEditItemRequest( NULL, item ); m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true ); item->SetFlags( flags ); } if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); return 0; }
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); if( !hoverSelection( selection, false ) ) return 0; // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed PICKED_ITEMS_LIST* lastChange = undoList.empty() ? NULL : undoList.back(); // Display properties dialog editFrame->OnEditItemRequest( NULL, item ); PICKED_ITEMS_LIST* currentChange = undoList.empty() ? NULL : undoList.back(); if( lastChange != currentChange ) // Something has changed { processChanges( currentChange ); updateRatsnest( true ); getModel<BOARD>()->GetRatsnest()->Recalculate(); item->ViewUpdate(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } return 0; }
bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); if( itemCurrentlyEdited ) return false; item = PcbGeneralLocateAndDisplay(); if( item == NULL ) return false; SetCurItem( item ); int evt_type = 0; // Used to post a wxCommandEvent on demand switch( item->Type() ) { case PCB_TRACE_T: case PCB_VIA_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE; if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT; if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE ) evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE; break; case PCB_MODULE_T: { if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_MODULE_REQUEST; if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_MODULE_REQUEST; } break; case PCB_PAD_T: // Post MODULE_REQUEST events here to prevent pads // from being moved or dragged by hotkeys. // Process_Special_Functions takes care of finding // the parent. if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_MODULE_REQUEST; if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_MODULE_REQUEST; break; case PCB_TEXT_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST; break; case PCB_TARGET_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_PCB_TARGET_REQUEST; break; case PCB_ZONE_AREA_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_ZONE_OUTLINES; if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT; break; case PCB_MODULE_TEXT_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST; break; case PCB_LINE_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_DRAWING_REQUEST; break; case PCB_DIMENSION_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST; break; default: break; } if( evt_type != 0 ) { wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); evt.SetEventObject( this ); evt.SetId( evt_type ); GetEventHandler()->ProcessEvent( evt ); return true; } return false; }
/* handle the double click on the mouse left button */ void PCB_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) { BOARD_ITEM* DrawStruct = GetCurItem(); switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = PcbGeneralLocateAndDisplay(); } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() != 0) ) break; SendMessageToEESCHEMA( DrawStruct ); // An item is found SetCurItem( DrawStruct ); switch( DrawStruct->Type() ) { case PCB_TRACE_T: case PCB_VIA_T: if( DrawStruct->IsNew() ) { if( End_Route( (TRACK*) DrawStruct, aDC ) ) m_canvas->SetAutoPanRequest( false ); } else if( DrawStruct->GetFlags() == 0 ) { Edit_TrackSegm_Width( aDC, (TRACK*) DrawStruct ); } break; case PCB_TEXT_T: case PCB_PAD_T: case PCB_MODULE_T: case PCB_TARGET_T: case PCB_DIMENSION_T: case PCB_MODULE_TEXT_T: OnEditItemRequest( aDC, DrawStruct ); m_canvas->MoveCursorToCrossHair(); break; case PCB_LINE_T: OnEditItemRequest( aDC, DrawStruct ); break; case PCB_ZONE_AREA_T: if( DrawStruct->GetFlags() ) break; OnEditItemRequest( aDC, DrawStruct ); break; default: break; } break; // end case 0 case ID_TRACK_BUTT: if( DrawStruct && DrawStruct->IsNew() ) { if( End_Route( (TRACK*) DrawStruct, aDC ) ) m_canvas->SetAutoPanRequest( false ); } break; case ID_PCB_ZONES_BUTT: case ID_PCB_KEEPOUT_AREA_BUTT: if( End_Zone( aDC ) ) { m_canvas->SetAutoPanRequest( false ); SetCurItem( NULL ); } break; case ID_PCB_ADD_LINE_BUTT: case ID_PCB_ARC_BUTT: case ID_PCB_CIRCLE_BUTT: if( DrawStruct == NULL ) break; if( DrawStruct->Type() != PCB_LINE_T ) { DisplayError( this, wxT( "DrawStruct Type error" ) ); m_canvas->SetAutoPanRequest( false ); break; } if( DrawStruct->IsNew() ) { End_Edge( (DRAWSEGMENT*) DrawStruct, aDC ); m_canvas->SetAutoPanRequest( false ); SetCurItem( NULL ); } break; } }
bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); if( itemCurrentlyEdited ) return false; item = PcbGeneralLocateAndDisplay(); if( item == NULL ) return false; SetCurItem( item ); int evt_type = 0; //Used to post a wxCommandEvent on demand switch( item->Type() ) { case PCB_TRACE_T: case PCB_VIA_T: if( aIdCommand == HK_EDIT_ITEM ) { // Be sure the corresponding netclass is selected before edit: SetCurrentNetClass( ( (BOARD_CONNECTED_ITEM*)item )->GetNetClassName() ); evt_type = ID_POPUP_PCB_EDIT_TRACKSEG; } break; case PCB_TEXT_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB; break; case PCB_MODULE_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_MODULE_PRMS; else if( aIdCommand == HK_EDIT_MODULE_WITH_MODEDIT ) evt_type = ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT; break; case PCB_PAD_T: // Until dec 2012 a EDIT_MODULE event is posted here to prevent pads // from being edited by hotkeys. // Process_Special_Functions takes care of finding the parent. // After dec 2012 a EDIT_PAD event is posted, because there is no // reason to not allow pad edit by hotkey // (pad coordinates are no more modified by rounding, in nanometer version // when using inches or mm in dialog) if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_PAD; break; case PCB_TARGET_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_PCB_TARGET; break; case PCB_DIMENSION_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_DIMENSION; break; case PCB_MODULE_TEXT_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE; break; case PCB_LINE_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_DRAWING; break; case PCB_ZONE_AREA_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_ZONE_PARAMS; break; default: break; } if( evt_type != 0 ) { wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); evt.SetEventObject( this ); evt.SetId( evt_type ); GetEventHandler()->ProcessEvent( evt ); return true; } return false; }
bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) { BOARD_ITEM* item = GetCurItem(); bool ItemFree = (item == NULL) || (item->GetFlags() == 0); switch( GetToolId() ) { case ID_TRACK_BUTT: if( !IsCopperLayer ( GetActiveLayer() ) ) return false; if( ItemFree ) { item = PcbGeneralLocateAndDisplay(); if( item && !item->IsTrack() ) return false; Delete_Track( aDC, (TRACK*) item ); } else if( item->IsTrack( ) ) { // simple lines for debugger: TRACK* track = (TRACK*) item; track = Delete_Segment( aDC, track ); SetCurItem( track ); OnModify(); return true; } break; case ID_PCB_MODULE_BUTT: if( ItemFree ) { wxPoint pos = RefPos( false ); MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false ); if( module == NULL || module->IsLocked() ) return false; RemoveStruct( module, aDC ); } else return false; break; default: if( ItemFree ) { item = PcbGeneralLocateAndDisplay(); // Shouldn't there be a check for locked tracks and vias here? if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) ) return false; RemoveStruct( item, aDC ); } else return false; } OnModify(); SetCurItem( NULL ); return true; }
bool PCB_EDIT_FRAME::OnHotkeyDuplicateOrArrayItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); bool itemCurrentlyEdited = item && item->GetFlags(); if( itemCurrentlyEdited ) return false; item = PcbGeneralLocateAndDisplay(); if( item == NULL ) return false; SetCurItem( item ); int evt_type = 0; // Used to post a wxCommandEvent on demand bool canDuplicate = true; switch( item->Type() ) { // Only handle items we know we can handle case PCB_PAD_T: canDuplicate = false; // no break case PCB_MODULE_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TRACE_T: case PCB_ZONE_AREA_T: case PCB_TARGET_T: case PCB_DIMENSION_T: switch( aIdCommand ) { case HK_CREATE_ARRAY: if( canDuplicate ) evt_type = ID_POPUP_PCB_CREATE_ARRAY; break; case HK_DUPLICATE_ITEM_AND_INCREMENT: if( canDuplicate ) evt_type = ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT; break; case HK_DUPLICATE_ITEM: if( canDuplicate ) evt_type = ID_POPUP_PCB_DUPLICATE_ITEM; break; case HK_MOVE_ITEM_EXACT: evt_type = ID_POPUP_PCB_MOVE_EXACT; break; default: // We don't handle other commands here break; } break; default: evt_type = 0; break; } return PostCommandMenuEvent( evt_type ); }
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !hoverSelection( selection, false ) ) return 0; // Tracks & vias are treated in a special way: if( ( SELECTION_CONDITIONS::OnlyTypes( m_tracksViasType ) )( selection ) ) { DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection ); if( dlg.ShowModal() ) { RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); dlg.Apply(); selection.ForAll<KIGFX::VIEW_ITEM>( boost::bind( &KIGFX::VIEW_ITEM::ViewUpdate, _1, KIGFX::VIEW_ITEM::ALL ) ); selection.ForAll<BOARD_ITEM>( boost::bind( &RN_DATA::Update, ratsnest, _1 ) ); ratsnest->Recalculate(); } } else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); // Store the head of the undo list to compare if anything has changed std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed, so store the current undo save point PICKED_ITEMS_LIST* undoSavePoint = undoList.empty() ? NULL : undoList.back(); // Display properties dialog provided by the legacy canvas frame editFrame->OnEditItemRequest( NULL, item ); if( !undoList.empty() && undoList.back() != undoSavePoint ) // Undo buffer has changed { // Process changes stored after undoSavePoint processUndoBuffer( undoSavePoint ); // Update the modified item item->ViewUpdate(); RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); ratsnest->Recalculate(); // TODO OBSERVER! I miss you so much.. m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); return 0; }
/* * Called on a mouse left button double click */ void FOOTPRINT_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) { BOARD_ITEM* item = GetCurItem(); switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { item = ModeditLocateAndDisplay(); } if( ( item == NULL ) || ( item->GetFlags() != 0 ) ) break; // Item found SetCurItem( item ); switch( item->Type() ) { case PCB_PAD_T: InstallPadOptionsFrame( (D_PAD*) item ); m_canvas->MoveCursorToCrossHair(); break; case PCB_MODULE_T: { DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) item ); int ret = dialog.ShowModal(); GetScreen()->GetCurItem()->ClearFlags(); m_canvas->MoveCursorToCrossHair(); if( ret > 0 ) m_canvas->Refresh(); } break; case PCB_MODULE_TEXT_T: InstallTextModOptionsFrame( (TEXTE_MODULE*) item, DC ); m_canvas->MoveCursorToCrossHair(); break; case PCB_MODULE_EDGE_T : m_canvas->MoveCursorToCrossHair(); InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) item ); m_canvas->Refresh(); break; default: break; } break; // end case 0 case ID_PCB_ADD_LINE_BUTT: { if( item && item->IsNew() ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } break; } default: break; } }
bool FOOTPRINT_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem ) { if( aHotKey == 0 ) return false; bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE; BOARD_ITEM* item = GetCurItem(); bool ItemFree = (item == 0) || (item->GetFlags() == 0); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); /* Convert lower to upper case (the usual toupper function has problem with non ascii * codes like function keys */ if( (aHotKey >= 'a') && (aHotKey <= 'z') ) aHotKey += 'A' - 'a'; EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List ); if( HK_Descr == NULL ) HK_Descr = GetDescriptorFromHotkey( aHotKey, module_edit_Hotkey_List ); if( HK_Descr == NULL ) return false; switch( HK_Descr->m_Idcommand ) { default: case HK_NOT_FOUND: return false; case HK_HELP: // Display Current hotkey list DisplayHotkeyList( this, g_Module_Editor_Hokeys_Descr ); break; case HK_RESET_LOCAL_COORD: // set local (relative) coordinate origin GetScreen()->m_O_Curseur = GetCrossHairPosition(); break; case HK_LEFT_CLICK: OnLeftClick( aDC, aPosition ); break; case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events OnLeftClick( aDC, aPosition ); OnLeftDClick( aDC, aPosition ); break; case HK_SET_GRID_ORIGIN: SetGridOrigin( GetCrossHairPosition() ); m_canvas->Refresh(); break; case HK_RESET_GRID_ORIGIN: SetGridOrigin( wxPoint(0,0) ); m_canvas->Refresh(); break; case HK_SWITCH_UNITS: cmd.SetId( (g_UserUnit == INCHES) ? ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_IN: cmd.SetId( ID_POPUP_ZOOM_IN ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_OUT: cmd.SetId( ID_POPUP_ZOOM_OUT ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_REDRAW: cmd.SetId( ID_ZOOM_REDRAW ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_ZOOM_CENTER: cmd.SetId( ID_POPUP_ZOOM_CENTER ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_UNDO: case HK_REDO: if( ItemFree && !blockActive ) { wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent ); wxPostEvent( this, event ); } break; case HK_ZOOM_AUTO: cmd.SetId( ID_ZOOM_PAGE ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_EDIT_ITEM: OnHotkeyEditItem( HK_EDIT_ITEM ); break; case HK_DELETE: OnHotkeyDeleteItem( HK_DELETE ); break; case HK_MOVE_ITEM: OnHotkeyMoveItem( HK_MOVE_ITEM ); break; case HK_ROTATE_ITEM: OnHotkeyRotateItem( HK_ROTATE_ITEM ); break; } return true; }
bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) { wxString msg; STATUS_FLAGS flags = 0; bool trackFound = false; // Flag set to true, // if a track is being the cursor, to avoid // to display menus relative to tracks twice bool blockActive = !GetScreen()->m_BlockLocate.IsIdle(); BOARD_ITEM* item = GetCurItem(); m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block command when clicking on menu // If a command or a block is in progress: // Put the Cancel command (if needed) and the End command if( blockActive ) { createPopUpBlockMenu( aPopMenu ); aPopMenu->AppendSeparator(); return true; } if( GetToolId() != ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } else { AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL, _( "End Tool" ), KiBitmap( cursor_xpm ) ); } aPopMenu->AppendSeparator(); } else { if( item && item->GetFlags() ) { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); aPopMenu->AppendSeparator(); } } // Select a proper item wxPoint cursorPos = GetCrossHairPosition(); wxPoint selectPos = m_Collector->GetRefPos(); selectPos = GetNearestGridPosition( selectPos ); /* We can reselect another item only if there are no item being edited * because ALL moving functions use GetCurItem(), therefore GetCurItem() * must return the same item during moving. We know an item is moving * if( item && (item->m_Flags != 0)) is true and after calling * PcbGeneralLocateAndDisplay(), GetCurItem() is any arbitrary BOARD_ITEM, * not the current item being edited. In such case we cannot call * PcbGeneralLocateAndDisplay(). */ if( !item || (item->GetFlags() == 0) ) { // show the "item selector" menu if no item selected or // if there is a selected item but the mouse has moved // (therefore a new item is perhaps under the cursor) if( !item || cursorPos != selectPos ) { m_canvas->SetAbortRequest( false ); PcbGeneralLocateAndDisplay(); if( m_canvas->GetAbortRequest() ) { return false; } } } item = GetCurItem(); flags = item ? item->GetFlags() : 0; // Add the context menu, which depends on the picked item: if( item ) { switch( item->Type() ) { case PCB_MODULE_T: createPopUpMenuForFootprints( (MODULE*) item, aPopMenu ); if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) ) { aPopMenu->AppendSeparator(); if( !( (MODULE*) item )->IsLocked() ) { msg = AddHotkeyName( _("Lock Footprint" ), g_Board_Editor_Hokeys_Descr, HK_LOCK_UNLOCK_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE, msg, KiBitmap( locked_xpm ) ); } else { msg = AddHotkeyName( _( "Unlock Footprint" ), g_Board_Editor_Hokeys_Descr, HK_LOCK_UNLOCK_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FREE_MODULE, msg, KiBitmap( unlocked_xpm ) ); } if( !flags ) aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE, _( "Automatically Place Footprint" ) ); } if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { if( !flags ) aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, _( "Automatically Route Footprint" ) ); } break; case PCB_PAD_T: createPopUpMenuForFpPads( static_cast<D_PAD*>( item ), aPopMenu ); break; case PCB_MODULE_TEXT_T: createPopUpMenuForFpTexts( static_cast<TEXTE_MODULE*>( item ), aPopMenu ); break; case PCB_LINE_T: // Some graphic items on technical layers if( (flags & IS_NEW) ) { AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING, _( "End Drawing" ), KiBitmap( checked_ok_xpm ) ); } if( !flags ) { msg = AddHotkeyName( _( "Move Drawing" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST, msg, KiBitmap( move_xpm ) ); msg = AddHotkeyName( _( "Duplicate Drawing" ), g_Board_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_line_xpm ) ); msg = AddHotkeyName( _("Move Drawing Exactly" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_line_xpm ) ); msg = AddHotkeyName( _("Create Drawing Array" ), g_Board_Editor_Hokeys_Descr, HK_CREATE_ARRAY ); AddMenuItem( aPopMenu, ID_POPUP_PCB_CREATE_ARRAY, msg, KiBitmap( array_line_xpm ) ); msg = AddHotkeyName( _( "Edit Drawing" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING, msg, KiBitmap( edit_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING, _( "Delete Drawing" ), KiBitmap( delete_xpm ) ); if( !IsCopperLayer( item->GetLayer() ) ) AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER, _( "Delete All Drawings on Layer" ), KiBitmap( delete_xpm ) ); } break; case PCB_ZONE_T: // Item used to fill a zone AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE, _( "Delete Zone Filling" ), KiBitmap( delete_xpm ) ); break; case PCB_ZONE_AREA_T: // Item used to handle a zone area (outlines, holes ...) if( flags & IS_NEW ) { AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE, _( "Close Zone Outline" ), KiBitmap( checked_ok_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER, _( "Delete Last Corner" ), KiBitmap( delete_xpm ) ); } else { createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu ); } break; case PCB_TEXT_T: createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu ); break; case PCB_TRACE_T: case PCB_VIA_T: trackFound = true; createPopupMenuForTracks( (TRACK*) item, aPopMenu ); break; case PCB_MARKER_T: createPopUpMenuForMarkers( (MARKER_PCB*) item, aPopMenu ); break; case PCB_DIMENSION_T: if( !flags ) { msg = AddHotkeyName( _( "Edit Dimension" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DIMENSION, msg, KiBitmap( edit_xpm ) ); msg = AddHotkeyName( _( "Move Dimension Text" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST, msg, KiBitmap( move_text_xpm ) ); msg = AddHotkeyName( _( "Duplicate Dimension" ), g_Board_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_text_xpm ) ); msg = AddHotkeyName( _("Move Dimension Exactly" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_text_xpm ) ); msg = AddHotkeyName( _( "Delete Dimension" ), g_Board_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DIMENSION, msg, KiBitmap( delete_xpm ) ); } break; case PCB_TARGET_T: if( !flags ) { msg = AddHotkeyName( _( "Move Target" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_MIRE_REQUEST, msg, KiBitmap( move_target_xpm ) ); msg = AddHotkeyName( _("Move Target Exactly" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_target_xpm ) ); msg = AddHotkeyName( _( "Duplicate Target" ), g_Board_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_target_xpm ) ); msg = AddHotkeyName( _("Create Target Array" ), g_Board_Editor_Hokeys_Descr, HK_CREATE_ARRAY ); AddMenuItem( aPopMenu, ID_POPUP_PCB_CREATE_ARRAY, msg, KiBitmap( array_target_xpm ) ); msg = AddHotkeyName( _( "Edit Target" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_MIRE, msg, KiBitmap( edit_xpm ) ); msg = AddHotkeyName( _( "Delete Target" ), g_Board_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MIRE, msg, KiBitmap( delete_xpm ) ); } break; case PCB_MODULE_EDGE_T: case SCREEN_T: case TYPE_NOT_INIT: case PCB_T: msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unexpected DrawType %d" ), item->Type() ); wxMessageBox( msg ); SetCurItem( NULL ); break; default: msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unknown DrawType %d" ), item->Type() ); wxMessageBox( msg ); // Attempt to clear error (but should no occurs ) if( item->Type() >= MAX_STRUCT_TYPE_ID ) SetCurItem( NULL ); break; } aPopMenu->AppendSeparator(); } if( !flags ) { msg = AddHotkeyName( _( "Get and Move Footprint" ), g_Board_Editor_Hokeys_Descr, HK_GET_AND_MOVE_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST, msg, KiBitmap( move_module_xpm ) ); } // Display context sensitive commands: switch( GetToolId() ) { case ID_PCB_ZONES_BUTT: if( GetBoard()->m_ZoneDescriptorList.size() > 0 ) { aPopMenu->AppendSeparator(); msg = AddHotkeyName( _( "Fill or Refill All Zones" ), g_Board_Editor_Hokeys_Descr, HK_ZONE_FILL_OR_REFILL ); AddMenuItem( aPopMenu, ID_POPUP_PCB_FILL_ALL_ZONES, msg, KiBitmap( fill_zone_xpm ) ); msg = AddHotkeyName( _( "Remove Filled Areas in All Zones" ), g_Board_Editor_Hokeys_Descr, HK_ZONE_REMOVE_FILLED ); AddMenuItem( aPopMenu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES, msg, KiBitmap( zone_unfill_xpm ) ); aPopMenu->AppendSeparator(); } AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_PCB_KEEPOUT_AREA_BUTT: AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_TRACK_BUTT: if ( ! trackFound ) // This menu is already added when a track is located { aPopMenu->AppendSeparator(); msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) ); AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), KiBitmap( width_track_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR, _( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) ); aPopMenu->AppendSeparator(); } break; case ID_PCB_CIRCLE_BUTT: case ID_PCB_ARC_BUTT: case ID_PCB_ADD_TEXT_BUTT: case ID_PCB_ADD_LINE_BUTT: case ID_PCB_DIMENSION_BUTT: AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_NO_CU_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_PCB_MODULE_BUTT: if( !flags ) { AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC, _( "Footprint Documentation" ), KiBitmap( book_xpm ) ); aPopMenu->AppendSeparator(); } break; case ID_NO_TOOL_SELECTED: if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) ) { wxMenu* commands = new wxMenu; AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS, _( "Global Spread and Place" ), KiBitmap( move_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES, _( "Unlock All Footprints" ), KiBitmap( unlocked_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES, _( "Lock All Footprints" ), KiBitmap( locked_xpm ) ); commands->AppendSeparator(); AddMenuItem( commands, ID_POPUP_PCB_SPREAD_ALL_MODULES, _( "Spread out All Footprints" ), KiBitmap( move_xpm ) ); commands->Append( ID_POPUP_PCB_SPREAD_NEW_MODULES, _( "Spread out Footprints not Already on Board" ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, _( "Automatically Place All Footprints" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, _( "Automatically Place New Footprints" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, _( "Automatically Place Next Footprints" ) ); commands->AppendSeparator(); AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES, _( "Orient All Footprints" ), KiBitmap( rotate_module_cw_xpm ) ); aPopMenu->AppendSeparator(); } if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { wxMenu* commands = new wxMenu; aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_COMMANDS, _( "Autoroute" ), commands ); AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR, _( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, _( "Automatically Route All Footprints" ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) ); aPopMenu->AppendSeparator(); } if( !trackFound ) { msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) ); AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), KiBitmap( width_track_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); } break; } return true; }
/** * Function Magnetize * tests to see if there are any magnetic items within near reach of the given * "curpos". If yes, then curpos is adjusted appropriately according to that * near magnetic item and true is returned. * @param frame = the current frame * @param aCurrentTool = the current tool id (from vertical right toolbar) * @param aGridSize = the current grid size * @param on_grid = the on grid position near initial position ( often on_grid = curpos) * @param curpos The initial position, and what to adjust if a change is needed. * @return bool - true if the position was adjusted magnetically, else false. */ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, wxPoint on_grid, wxPoint* curpos ) { bool doCheckNet = g_MagneticPadOption != capture_always && g_Drc_On; bool doTrack = false; bool doPad = false; bool amMovingVia = false; BOARD* m_Pcb = frame->GetBoard(); TRACK* currTrack = g_CurrentTrackSegment; BOARD_ITEM* currItem = frame->GetCurItem(); PCB_SCREEN* screen = frame->GetScreen(); wxPoint pos = frame->RefPos( true ); // D( printf( "currTrack=%p currItem=%p currTrack->Type()=%d currItem->Type()=%d\n", currTrack, currItem, currTrack ? currTrack->Type() : 0, currItem ? currItem->Type() : 0 ); ) if( !currTrack && currItem && currItem->Type()==PCB_VIA_T && currItem->GetFlags() ) { // moving a VIA currTrack = (TRACK*) currItem; amMovingVia = true; return false; // comment this return out and play with it. } else if( currItem != currTrack ) { currTrack = NULL; } if( g_MagneticPadOption == capture_always ) doPad = true; if( g_MagneticTrackOption == capture_always ) doTrack = true; if( aCurrentTool == ID_TRACK_BUTT || amMovingVia ) { int q = capture_cursor_in_track_tool; if( g_MagneticPadOption == q ) doPad = true; if( g_MagneticTrackOption == q ) doTrack = true; } // D(printf("doPad=%d doTrack=%d aCurrentTool=%d amMovingVia=%d\n", doPad, doTrack, aCurrentTool, amMovingVia );) // The search precedence order is pads, then tracks/vias if( doPad ) { LSET layer_mask( screen->m_Active_Layer ); D_PAD* pad = m_Pcb->GetPad( pos, layer_mask ); if( pad ) { if( doCheckNet && currTrack && currTrack->GetNetCode() != pad->GetNetCode() ) return false; *curpos = pad->GetPosition(); return true; } } // after pads, only track & via tests remain, skip them if not desired if( doTrack ) { LAYER_ID layer = screen->m_Active_Layer; for( TRACK* via = m_Pcb->m_Track; via && (via = via->GetVia( *curpos, layer )) != NULL; via = via->Next() ) { if( via != currTrack ) // a via cannot influence itself { if( !doCheckNet || !currTrack || currTrack->GetNetCode() == via->GetNetCode() ) { *curpos = via->GetStart(); // D(printf("via hit\n");) return true; } } } if( !currTrack ) { LSET layers( layer ); TRACK* track = m_Pcb->GetVisibleTrack( m_Pcb->m_Track, pos, layers ); if( !track || track->Type() != PCB_TRACE_T ) { // D(printf("!currTrack and track=%p not found, layer_mask=0x%X\n", track, layer_mask );) return false; } // D( printf( "Project\n" ); ) return Project( curpos, on_grid, track ); } /* * In two segment mode, ignore the final segment if it's inside a grid square. */ if( !amMovingVia && currTrack && g_TwoSegmentTrackBuild && currTrack->Back() && currTrack->GetStart().x - aGridSize.x < currTrack->GetEnd().x && currTrack->GetStart().x + aGridSize.x > currTrack->GetEnd().x && currTrack->GetStart().y - aGridSize.y < currTrack->GetEnd().y && currTrack->GetStart().y + aGridSize.y > currTrack->GetEnd().y ) { currTrack = currTrack->Back(); } for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() ) { if( track->Type() != PCB_TRACE_T ) continue; if( doCheckNet && currTrack && currTrack->GetNetCode() != track->GetNetCode() ) continue; if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false ) continue; // omit the layer check if moving a via if( !amMovingVia && !track->IsOnLayer( layer ) ) continue; if( !track->HitTest( *curpos ) ) continue; // D(printf( "have track prospect\n");) if( Join( curpos, track->GetStart(), track->GetEnd(), currTrack->GetStart(), currTrack->GetEnd() ) ) { // D(printf( "join currTrack->Type()=%d\n", currTrack->Type() );) return true; } if( aCurrentTool == ID_TRACK_BUTT || amMovingVia ) { // At this point we have a drawing mouse on a track, we are drawing // a new track and that new track is parallel to the track the // mouse is on. Find the nearest end point of the track under mouse // to the mouse and return that. double distStart = GetLineLength( *curpos, track->GetStart() ); double distEnd = GetLineLength( *curpos, track->GetEnd() ); // if track not via, or if its a via dragging but not with its adjacent track if( currTrack->Type() != PCB_VIA_T || ( currTrack->GetStart() != track->GetStart() && currTrack->GetStart() != track->GetEnd() )) { double max_dist = currTrack->GetWidth() / 2.0f; if( distStart <= max_dist ) { // D(printf("nearest end is start\n");) *curpos = track->GetStart(); return true; } if( distEnd <= max_dist ) { // D(printf("nearest end is end\n");) *curpos = track->GetEnd(); return true; } // @todo otherwise confine curpos such that it stays centered within "track" } } } } return false; }
void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) { BOARD_ITEM* item = GetCurItem(); m_canvas->CrossHairOff( DC ); if( GetToolId() == ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) // Move item command in progress { switch( item->Type() ) { case PCB_MODULE_TEXT_T: PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), DC ); break; case PCB_MODULE_EDGE_T: SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); Place_EdgeMod( static_cast<EDGE_MODULE*>( item ) ); break; case PCB_PAD_T: PlacePad( static_cast<D_PAD*>( item ), DC ); break; default: { wxString msg; msg.Printf( wxT( "WinEDA_ModEditFrame::OnLeftClick err:Struct %d, m_Flag %X" ), item->Type(), item->GetFlags() ); DisplayError( this, msg ); item->ClearFlags(); break; } } } else { if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT ) && !wxGetKeyState( WXK_CONTROL ) ) item = ModeditLocateAndDisplay(); SetCurItem( item ); } } item = GetCurItem(); bool no_item_edited = item == NULL || item->GetFlags() == 0; switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: break; case ID_MODEDIT_CIRCLE_TOOL: case ID_MODEDIT_ARC_TOOL: case ID_MODEDIT_LINE_TOOL: if( no_item_edited ) { STROKE_T shape = S_SEGMENT; if( GetToolId() == ID_MODEDIT_CIRCLE_TOOL ) shape = S_CIRCLE; if( GetToolId() == ID_MODEDIT_ARC_TOOL ) shape = S_ARC; SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) NULL, DC, shape ) ); } else if( item->IsNew() ) { if( ( (EDGE_MODULE*) item )->GetShape() == S_CIRCLE ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } else if( ( (EDGE_MODULE*) item )->GetShape() == S_ARC ) { End_Edge_Module( (EDGE_MODULE*) item ); SetCurItem( NULL ); m_canvas->Refresh(); } else if( ( (EDGE_MODULE*) item )->GetShape() == S_SEGMENT ) { SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) item, DC, S_SEGMENT ) ); } else { wxMessageBox( wxT( "ProcessCommand error: unknown shape" ) ); } } break; case ID_MODEDIT_DELETE_TOOL: if( ! no_item_edited ) // Item in edit, cannot delete it break; item = ModeditLocateAndDisplay(); if( item && item->Type() != PCB_MODULE_T ) // Cannot delete the module itself { SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); RemoveStruct( item ); SetCurItem( NULL ); } break; case ID_MODEDIT_ANCHOR_TOOL: { MODULE* module = GetBoard()->m_Modules; if( module == NULL // No module loaded || (module->GetFlags() != 0) ) break; SaveCopyInUndoList( module, UR_MODEDIT ); // set the new relative internal local coordinates of footprint items wxPoint moveVector = module->GetPosition() - GetCrossHairPosition(); module->MoveAnchorPosition( moveVector ); // Usually, we do not need to change twice the anchor position, // so deselect the active tool SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); SetCurItem( NULL ); m_canvas->Refresh(); } break; case ID_MODEDIT_PLACE_GRID_COORD: m_canvas->DrawGridAxis( DC, GR_XOR, GetBoard()->GetGridOrigin() ); SetGridOrigin( GetCrossHairPosition() ); m_canvas->DrawGridAxis( DC, GR_COPY, GetBoard()->GetGridOrigin() ); GetScreen()->SetModify(); break; case ID_MODEDIT_TEXT_TOOL: if( GetBoard()->m_Modules == NULL ) break; SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); CreateTextModule( GetBoard()->m_Modules, DC ); break; case ID_MODEDIT_PAD_TOOL: if( GetBoard()->m_Modules ) { SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT ); AddPad( GetBoard()->m_Modules, true ); } break; default: DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); } m_canvas->CrossHairOn( DC ); }
bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) { BOARD_ITEM* item = GetCurItem(); wxString msg; bool blockActive = !GetScreen()->m_BlockLocate.IsIdle(); // Simple location of elements where possible. if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { SetCurItem( item = ModeditLocateAndDisplay() ); } // End command in progress. if( GetToolId() != ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); else AddMenuItem( PopMenu, ID_POPUP_CLOSE_CURRENT_TOOL, _( "End Tool" ), KiBitmap( cursor_xpm ) ); PopMenu->AppendSeparator(); } else { if( (item && item->GetFlags()) || blockActive ) { if( blockActive ) // Put block commands in list { AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ), KiBitmap( cancel_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_ZOOM_BLOCK, _( "Zoom Block (drag middle mouse)" ), KiBitmap( zoom_area_xpm ) ); PopMenu->AppendSeparator(); AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_COPY_BLOCK, _( "Copy Block (shift + drag mouse)" ), KiBitmap( copyblock_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_MIRROR_X_BLOCK, _( "Mirror Block (alt + drag mouse)" ), KiBitmap( mirror_h_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_ROTATE_BLOCK, _( "Rotate Block (ctrl + drag mouse)" ), KiBitmap( rotate_ccw_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK, _( "Delete Block (shift+ctrl + drag mouse)" ), KiBitmap( delete_xpm ) ); } else { AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } PopMenu->AppendSeparator(); } } if( blockActive ) return true; if( item ) { STATUS_FLAGS flags = item->GetFlags(); switch( item->Type() ) { case PCB_MODULE_T: { wxMenu* transform_choice = new wxMenu; AddMenuItem( transform_choice, ID_MODEDIT_MODULE_ROTATE, _( "Rotate" ), KiBitmap( rotate_module_ccw_xpm ) ); AddMenuItem( transform_choice, ID_MODEDIT_MODULE_MIRROR, _( "Mirror" ), KiBitmap( mirror_footprint_axisY_xpm ) ); msg = AddHotkeyName( _( "Edit Module" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg, KiBitmap( edit_module_xpm ) ); AddMenuItem( PopMenu, transform_choice, ID_MODEDIT_TRANSFORM_MODULE, _( "Transform Module" ), KiBitmap( edit_xpm ) ); break; } case PCB_PAD_T: if( !flags ) { msg = AddHotkeyName( _("Move Pad" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_PAD_REQUEST, msg, KiBitmap( move_pad_xpm ) ); } msg = AddHotkeyName( _("Edit Pad" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_PAD, msg, KiBitmap( options_pad_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_PCB_IMPORT_PAD_SETTINGS, _( "New Pad Settings" ), KiBitmap( options_new_pad_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_PCB_EXPORT_PAD_SETTINGS, _( "Export Pad Settings" ), KiBitmap( export_options_pad_xpm ) ); msg = AddHotkeyName( _("Delete Pad" ), g_Module_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_PAD, msg, KiBitmap( delete_pad_xpm ) ); if( !flags ) { PopMenu->AppendSeparator(); AddMenuItem( PopMenu, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS, _( "Global Pad Settings" ), KiBitmap( global_options_pad_xpm ) ); } break; case PCB_MODULE_TEXT_T: if( !flags ) { msg = AddHotkeyName( _("Move Text Mod." ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST, msg, KiBitmap( move_field_xpm ) ); } msg = AddHotkeyName( _("Rotate Text Mod." ), g_Module_Editor_Hokeys_Descr, HK_ROTATE_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_ROTATE_TEXTMODULE, msg, KiBitmap( rotate_field_xpm ) ); if( !flags ) { msg = AddHotkeyName( _("Edit Text Mod." ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TEXTMODULE, msg, KiBitmap( edit_text_xpm ) ); if( ( static_cast<TEXTE_MODULE*>( item ) )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS ) { msg = AddHotkeyName( _("Delete Text Mod." ), g_Module_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_TEXTMODULE, msg, KiBitmap( delete_text_xpm ) ); } } break; case PCB_MODULE_EDGE_T: { if( (flags & IS_NEW) ) AddMenuItem( PopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING, _( "End edge" ), KiBitmap( checked_ok_xpm ) ); if( !flags ) { msg = AddHotkeyName( _("Move Edge" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EDGE, msg, KiBitmap( move_line_xpm ) ); } if( ( flags & (IS_NEW | IS_MOVED) ) == IS_MOVED ) AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_EDGE, _( "Place edge" ), KiBitmap( checked_ok_xpm ) ); msg = AddHotkeyName( _("Edit" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( PopMenu, ID_POPUP_MODEDIT_EDIT_BODY_ITEM, msg, KiBitmap( options_segment_xpm ) ); msg = AddHotkeyName( _("Delete Edge" ), g_Module_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_EDGE, msg, KiBitmap( delete_xpm ) ); wxMenu* edit_global_mnu = new wxMenu; AddMenuItem( PopMenu, edit_global_mnu, ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE, _( "Global Changes" ), KiBitmap( edit_xpm ) ); AddMenuItem( edit_global_mnu, ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE, _( "Change Body Items Width" ), KiBitmap( width_segment_xpm ) ); AddMenuItem( edit_global_mnu, ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE, _( "Change Body Items Layer" ), KiBitmap( select_layer_pair_xpm ) ); } break; case PCB_LINE_T: case PCB_TEXT_T: case PCB_VIA_T: case PCB_TRACE_T: case PCB_ZONE_T: case PCB_MARKER_T: case PCB_DIMENSION_T: case PCB_TARGET_T: msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: Unexpected DrawType %d" ), item->Type() ); DisplayError( this, msg ); break; case SCREEN_T: case TYPE_NOT_INIT: case PCB_T: msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: illegal DrawType %d" ), item->Type() ); DisplayError( this, msg ); break; default: msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: unknown DrawType %d" ), item->Type() ); DisplayError( this, msg ); break; } PopMenu->AppendSeparator(); } if( ( GetToolId() == ID_MODEDIT_LINE_TOOL ) || ( GetToolId() == ID_MODEDIT_CIRCLE_TOOL ) || ( GetToolId() == ID_MODEDIT_ARC_TOOL ) ) { AddMenuItem( PopMenu, ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH, _("Set Line Width" ), KiBitmap( width_segment_xpm ) ); PopMenu->AppendSeparator(); } return true; }
bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) { wxString msg; int flags = 0; bool locate_track = false; bool blockActive = (GetScreen()->m_BlockLocate.m_Command != BLOCK_IDLE); wxClientDC dc( m_canvas ); BOARD_ITEM* item = GetCurItem(); m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block coomand when clicking on menu // If a command or a block is in progress: // Put the Cancel command (if needed) and the End command if( blockActive ) { createPopUpBlockMenu( aPopMenu ); aPopMenu->AppendSeparator(); return true; } m_canvas->CrossHairOff( &dc ); if( GetToolId() != ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } else { AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL, _( "End Tool" ), KiBitmap( cursor_xpm ) ); } aPopMenu->AppendSeparator(); } else { if( item && item->GetFlags() ) { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); aPopMenu->AppendSeparator(); } } /* Select a proper item */ wxPoint cursorPos = GetScreen()->GetCrossHairPosition(); wxPoint selectPos = m_Collector->GetRefPos(); selectPos = GetScreen()->GetNearestGridPosition( selectPos ); /* We can reselect another item only if there are no item being edited * because ALL moving functions use GetCurItem(), therefore GetCurItem() * must return the same item during moving. We know an item is moving * if( item && (item->m_Flags != 0)) is true and after calling * PcbGeneralLocateAndDisplay(), GetCurItem() is any arbitrary BOARD_ITEM, * not the current item being edited. In such case we cannot call * PcbGeneralLocateAndDisplay(). */ if( !item || (item->GetFlags() == 0) ) { // show "item selector" menu only if no item now or selected item was not // previously picked at this position if( !item || cursorPos != selectPos ) { m_canvas->SetAbortRequest( false ); item = PcbGeneralLocateAndDisplay(); if( m_canvas->GetAbortRequest() ) { m_canvas->CrossHairOn( &dc ); return false; } } } item = GetCurItem(); if( item ) flags = item->GetFlags(); else flags = 0; if( item ) { switch( item->Type() ) { case PCB_MODULE_T: createPopUpMenuForFootprints( (MODULE*) item, aPopMenu ); if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) ) { aPopMenu->AppendSeparator(); if( !( (MODULE*) item )->IsLocked() ) { msg = AddHotkeyName( _("Lock Module" ), g_Board_Editor_Hokeys_Descr, HK_LOCK_UNLOCK_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE, msg, KiBitmap( locked_xpm ) ); } else { msg = AddHotkeyName( _( "Unlock Module" ), g_Board_Editor_Hokeys_Descr, HK_LOCK_UNLOCK_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FREE_MODULE, msg, KiBitmap( unlocked_xpm ) ); } if( !flags ) aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE, _( "Auto Place Module" ) ); } if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { if( !flags ) aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, _( "Autoroute Module" ) ); } break; case PCB_PAD_T: createPopUpMenuForFpPads( (D_PAD*) item, aPopMenu ); break; case PCB_MODULE_TEXT_T: createPopUpMenuForFpTexts( (TEXTE_MODULE*) item, aPopMenu ); break; case PCB_LINE_T: // Some graphic items on technical layers if( (flags & IS_NEW) ) { AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING, _( "End Drawing" ), KiBitmap( apply_xpm ) ); } if( !flags ) { msg = AddHotkeyName( _( "Move Drawing" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST, msg, KiBitmap( move_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING, _( "Edit Drawing" ), KiBitmap( edit_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING, _( "Delete Drawing" ), KiBitmap( delete_xpm ) ); if( item->GetLayer() > LAST_COPPER_LAYER ) AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER, _( "Delete All Drawing on Layer" ), KiBitmap( delete_xpm ) ); } break; case PCB_ZONE_T: // Item used to fill a zone AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE, _( "Delete Zone Filling" ), KiBitmap( delete_xpm ) ); break; case PCB_ZONE_AREA_T: // Item used to handle a zone area (outlines, holes ...) if( flags & IS_NEW ) { AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE, _( "Close Zone Outline" ), KiBitmap( apply_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER, _( "Delete Last Corner" ), KiBitmap( delete_xpm ) ); } else { createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu ); } break; case PCB_TEXT_T: createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu ); break; case PCB_TRACE_T: case PCB_VIA_T: locate_track = true; createPopupMenuForTracks( (TRACK*) item, aPopMenu ); break; case PCB_MARKER_T: createPopUpMenuForMarkers( (MARKER_PCB*) item, aPopMenu ); break; case PCB_DIMENSION_T: if( !flags ) { msg = AddHotkeyName( _( "Edit Dimension" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DIMENSION, msg, KiBitmap( edit_xpm ) ); msg = AddHotkeyName( _( "Move Dimension Text" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST, msg, KiBitmap( move_text_xpm ) ); msg = AddHotkeyName( _( "Delete Dimension" ), g_Board_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DIMENSION, msg, KiBitmap( delete_xpm ) ); } break; case PCB_TARGET_T: if( !flags ) { msg = AddHotkeyName( _( "Move Target" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_MIRE_REQUEST, msg, KiBitmap( move_xpm ) ); msg = AddHotkeyName( _( "Edit Target" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_MIRE, msg, KiBitmap( edit_xpm ) ); msg = AddHotkeyName( _( "Delete Target" ), g_Board_Editor_Hokeys_Descr, HK_DELETE ); AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MIRE, msg, KiBitmap( delete_xpm ) ); } break; case PCB_MODULE_EDGE_T: case SCREEN_T: case TYPE_NOT_INIT: case PCB_T: msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unexpected DrawType %d" ), item->Type() ); wxMessageBox( msg ); SetCurItem( NULL ); break; default: msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unknown DrawType %d" ), item->Type() ); wxMessageBox( msg ); // Attempt to clear error (but should no occurs ) if( item->Type() >= MAX_STRUCT_TYPE_ID ) SetCurItem( NULL ); break; } aPopMenu->AppendSeparator(); } if( !flags ) { msg = AddHotkeyName( _( "Get and Move Footprint" ), g_Board_Editor_Hokeys_Descr, HK_GET_AND_MOVE_FOOTPRINT ); AddMenuItem( aPopMenu, ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST, msg, KiBitmap( move_module_xpm ) ); } /* Display context sensitive commands: */ switch( GetToolId() ) { case ID_PCB_ZONES_BUTT: if( GetBoard()->m_ZoneDescriptorList.size() > 0 ) { aPopMenu->AppendSeparator(); AddMenuItem( aPopMenu, ID_POPUP_PCB_FILL_ALL_ZONES, _( "Fill or Refill All Zones" ), KiBitmap( fill_zone_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES, _( "Remove Filled Areas in All Zones" ), KiBitmap( zone_unfill_xpm ) ); aPopMenu->AppendSeparator(); } AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_TRACK_BUTT: if ( ! locate_track ) // This menu is already added when a track is located AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), KiBitmap( width_track_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR, _( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_PCB_CIRCLE_BUTT: case ID_PCB_ARC_BUTT: case ID_PCB_ADD_TEXT_BUTT: case ID_PCB_ADD_LINE_BUTT: case ID_PCB_DIMENSION_BUTT: AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_NO_CU_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_PCB_MODULE_BUTT: AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC, _( "Footprint Documentation" ), KiBitmap( book_xpm ) ); aPopMenu->AppendSeparator(); break; case ID_NO_TOOL_SELECTED: if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) ) { wxMenu* commands = new wxMenu; AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS, _( "Glob Move and Place" ), KiBitmap( move_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES, _( "Unlock All Modules" ), KiBitmap( unlocked_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES, _( "Lock All Modules" ), KiBitmap( locked_xpm ) ); commands->AppendSeparator(); AddMenuItem( commands, ID_POPUP_PCB_AUTOMOVE_ALL_MODULES, _( "Move All Modules" ), KiBitmap( move_xpm ) ); commands->Append( ID_POPUP_PCB_AUTOMOVE_NEW_MODULES, _( "Move New Modules" ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, _( "Autoplace All Modules" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, _( "Autoplace New Modules" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, _( "Autoplace Next Module" ) ); commands->AppendSeparator(); AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES, _( "Orient All Modules" ), KiBitmap( rotate_module_pos_xpm ) ); aPopMenu->AppendSeparator(); } if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { wxMenu* commands = new wxMenu; aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_COMMANDS, _( "Autoroute" ), commands ); AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR, _( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, _( "Autoroute All Modules" ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) ); aPopMenu->AppendSeparator(); } if( locate_track ) AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), KiBitmap( width_track_xpm ) ); AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) ); aPopMenu->AppendSeparator(); break; } m_canvas->CrossHairOn( &dc ); return true; }
int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); if( !makeSelection( selection ) ) { setTransitions(); return 0; } // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); // Check if user wants to edit pad or module properties if( item->Type() == PCB_MODULE_T ) { VECTOR2D cursor = getViewControls()->GetCursorPosition(); for( D_PAD* pad = static_cast<MODULE*>( item )->Pads(); pad; pad = pad->Next() ) { if( pad->ViewBBox().Contains( cursor ) ) { // Turns out that user wants to edit a pad properties item = pad; break; } } } std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed PICKED_ITEMS_LIST* lastChange = undoList.empty() ? NULL : undoList.back(); // Display properties dialog editFrame->OnEditItemRequest( NULL, item ); PICKED_ITEMS_LIST* currentChange = undoList.empty() ? NULL : undoList.back(); if( lastChange != currentChange ) // Something has changed { processChanges( currentChange ); updateRatsnest( true ); getModel<BOARD>()->GetRatsnest()->Recalculate(); item->ViewUpdate(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } setTransitions(); return 0; }
/* Handle the left button mouse click, when a tool is active */ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { BOARD_ITEM* DrawStruct = GetCurItem(); bool exit = false; bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED; if( no_tool || ( DrawStruct && DrawStruct->GetFlags() ) ) { m_canvas->SetAutoPanRequest( false ); if( DrawStruct && DrawStruct->GetFlags() ) // Command in progress { m_canvas->SetIgnoreMouseEvents( true ); m_canvas->CrossHairOff( aDC ); switch( DrawStruct->Type() ) { case PCB_ZONE_AREA_T: if( DrawStruct->IsNew() ) { m_canvas->SetAutoPanRequest( true ); Begin_Zone( aDC ); } else { End_Move_Zone_Corner_Or_Outlines( aDC, (ZONE_CONTAINER*) DrawStruct ); } exit = true; break; case PCB_TRACE_T: case PCB_VIA_T: if( DrawStruct->IsDragging() ) { PlaceDraggedOrMovedTrackSegment( (TRACK*) DrawStruct, aDC ); exit = true; } break; case PCB_TEXT_T: Place_Texte_Pcb( (TEXTE_PCB*) DrawStruct, aDC ); exit = true; break; case PCB_MODULE_TEXT_T: PlaceTexteModule( (TEXTE_MODULE*) DrawStruct, aDC ); exit = true; break; case PCB_PAD_T: PlacePad( (D_PAD*) DrawStruct, aDC ); exit = true; break; case PCB_MODULE_T: PlaceModule( (MODULE*) DrawStruct, aDC ); exit = true; break; case PCB_TARGET_T: PlaceTarget( (PCB_TARGET*) DrawStruct, aDC ); exit = true; break; case PCB_LINE_T: if( no_tool ) // when no tools: existing item moving. { Place_DrawItem( (DRAWSEGMENT*) DrawStruct, aDC ); exit = true; } break; case PCB_DIMENSION_T: if( ! DrawStruct->IsNew() ) { // We are moving the text of an existing dimension. Place it PlaceDimensionText( (DIMENSION*) DrawStruct, aDC ); exit = true; } break; default: DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() err: DrawType %d m_Flags != 0" ), DrawStruct->Type() ); exit = true; break; } m_canvas->SetIgnoreMouseEvents( false ); m_canvas->CrossHairOn( aDC ); if( exit ) return; } else if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT ) && !wxGetKeyState( WXK_CONTROL ) ) { DrawStruct = PcbGeneralLocateAndDisplay(); if( DrawStruct ) SendMessageToEESCHEMA( DrawStruct ); } } if( DrawStruct ) // display netclass info for zones, tracks and pads { switch( DrawStruct->Type() ) { case PCB_ZONE_AREA_T: case PCB_TRACE_T: case PCB_VIA_T: case PCB_PAD_T: GetDesignSettings().SetCurrentNetClass( ((BOARD_CONNECTED_ITEM*)DrawStruct)->GetNetClassName() ); updateTraceWidthSelectBox(); updateViaSizeSelectBox(); break; default: break; } } switch( GetToolId() ) { case ID_MAIN_MENUBAR: case ID_NO_TOOL_SELECTED: break; case ID_PCB_MUWAVE_TOOL_SELF_CMD: case ID_PCB_MUWAVE_TOOL_GAP_CMD: case ID_PCB_MUWAVE_TOOL_STUB_CMD: case ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD: case ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD: MuWaveCommand( aDC, aPosition ); break; case ID_PCB_HIGHLIGHT_BUTT: { int netcode = SelectHighLight( aDC ); if( netcode < 0 ) SetMsgPanel( GetBoard() ); else { NETINFO_ITEM* net = GetBoard()->FindNet( netcode ); if( net ) { MSG_PANEL_ITEMS items; net->GetMsgPanelInfo( items ); SetMsgPanel( items ); } } } break; case ID_PCB_SHOW_1_RATSNEST_BUTT: DrawStruct = PcbGeneralLocateAndDisplay(); Show_1_Ratsnest( DrawStruct, aDC ); if( DrawStruct ) SendMessageToEESCHEMA( DrawStruct ); break; case ID_PCB_MIRE_BUTT: if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { SetCurItem( (BOARD_ITEM*) CreateTarget( aDC ) ); m_canvas->MoveCursorToCrossHair(); } else if( DrawStruct->Type() == PCB_TARGET_T ) { PlaceTarget( (PCB_TARGET*) DrawStruct, aDC ); } else { DisplayError( this, wxT( "OnLeftClick err: not a PCB_TARGET_T" ) ); } break; case ID_PCB_CIRCLE_BUTT: case ID_PCB_ARC_BUTT: case ID_PCB_ADD_LINE_BUTT: { STROKE_T shape = S_SEGMENT; if( GetToolId() == ID_PCB_CIRCLE_BUTT ) shape = S_CIRCLE; if( GetToolId() == ID_PCB_ARC_BUTT ) shape = S_ARC; if( IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Graphic not allowed on Copper layers" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) Begin_DrawSegment( NULL, shape, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && (DrawStruct->Type() == PCB_LINE_T) && DrawStruct->IsNew() ) { DrawStruct = (BOARD_ITEM*) Begin_DrawSegment( (DRAWSEGMENT*) DrawStruct, shape, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } } break; case ID_TRACK_BUTT: if( !IsCopperLayer( GetActiveLayer() ) ) { DisplayError( this, _( "Tracks on Copper layers only " ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) Begin_Route( NULL, aDC ); SetCurItem( DrawStruct ); if( DrawStruct ) m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && DrawStruct->IsNew() ) { TRACK* track = Begin_Route( (TRACK*) DrawStruct, aDC ); // SetCurItem() must not write to the msg panel // because a track info is displayed while moving the mouse cursor if( track ) // A new segment was created SetCurItem( DrawStruct = (BOARD_ITEM*) track, false ); m_canvas->SetAutoPanRequest( true ); } break; case ID_PCB_ZONES_BUTT: case ID_PCB_KEEPOUT_AREA_BUTT: /* ZONE or KEEPOUT Tool is selected. Determine action for a left click: * this can be start a new zone or select and move an existing zone outline corner * if found near the mouse cursor */ if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { if( Begin_Zone( aDC ) ) { m_canvas->SetAutoPanRequest( true ); DrawStruct = GetBoard()->m_CurrentZoneContour; GetScreen()->SetCurItem( DrawStruct ); } } else if( DrawStruct && (DrawStruct->Type() == PCB_ZONE_AREA_T) && DrawStruct->IsNew() ) { // Add a new corner to the current outline being created: m_canvas->SetAutoPanRequest( true ); Begin_Zone( aDC ); DrawStruct = GetBoard()->m_CurrentZoneContour; GetScreen()->SetCurItem( DrawStruct ); } else { DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() zone internal error" ) ); } break; case ID_PCB_ADD_TEXT_BUTT: if( IsLayerInList( EDGE_LAYER, GetActiveLayer() ) ) { DisplayError( this, _( "Texts not allowed on Edge Cut layer" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { SetCurItem( CreateTextePcb( aDC ) ); m_canvas->MoveCursorToCrossHair(); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct->Type() == PCB_TEXT_T ) { Place_Texte_Pcb( (TEXTE_PCB*) DrawStruct, aDC ); m_canvas->SetAutoPanRequest( false ); } else { DisplayError( this, wxT( "OnLeftClick err: not a PCB_TEXT_T" ) ); } break; case ID_PCB_MODULE_BUTT: if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { m_canvas->MoveCursorToCrossHair(); DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary( wxEmptyString, Prj().PcbFootprintLibs(), true, aDC ); SetCurItem( DrawStruct ); if( DrawStruct ) StartMoveModule( (MODULE*) DrawStruct, aDC, false ); } else if( DrawStruct->Type() == PCB_MODULE_T ) { PlaceModule( (MODULE*) DrawStruct, aDC ); m_canvas->SetAutoPanRequest( false ); } else { DisplayError( this, wxT( "Internal err: Struct not PCB_MODULE_T" ) ); } break; case ID_PCB_DIMENSION_BUTT: if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, GetActiveLayer() ) ) { DisplayError( this, _( "Dimension not allowed on Copper or Edge Cut layers" ) ); break; } if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) { DrawStruct = (BOARD_ITEM*) EditDimension( NULL, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else if( DrawStruct && (DrawStruct->Type() == PCB_DIMENSION_T) && DrawStruct->IsNew() ) { DrawStruct = (BOARD_ITEM*) EditDimension( (DIMENSION*) DrawStruct, aDC ); SetCurItem( DrawStruct ); m_canvas->SetAutoPanRequest( true ); } else { DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() error item is not a DIMENSION" ) ); } break; case ID_PCB_DELETE_ITEM_BUTT: if( !DrawStruct || !DrawStruct->GetFlags() ) { DrawStruct = PcbGeneralLocateAndDisplay(); if( DrawStruct && (DrawStruct->GetFlags() == 0) ) { RemoveStruct( DrawStruct, aDC ); SetCurItem( DrawStruct = NULL ); } } break; case ID_PCB_PLACE_OFFSET_COORD_BUTT: m_canvas->DrawAuxiliaryAxis( aDC, GR_XOR ); SetAuxOrigin( GetCrossHairPosition() ); m_canvas->DrawAuxiliaryAxis( aDC, GR_COPY ); OnModify(); break; case ID_PCB_PLACE_GRID_COORD_BUTT: m_canvas->DrawGridAxis( aDC, GR_XOR, GetBoard()->GetGridOrigin() ); SetGridOrigin( GetCrossHairPosition() ); m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() ); break; default: DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); break; } }