void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); INSTALL_UNBUFFERED_DC( dc, m_canvas ); if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::DraggableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } switch( item->Type() ) { case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_LINE_T: case SCH_JUNCTION_T: if( item->GetLayer() == LAYER_BUS ) break; // Fall thru if item is not on bus layer. case SCH_COMPONENT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_SHEET_T: m_canvas->MoveCursorToCrossHair(); // The easiest way to handle a drag component or sheet command // is to simulate a block drag command if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK ) { if( !HandleBlockBegin( &dc, BLOCK_DRAG, GetCrossHairPosition() ) ) break; // Give a non null size to the search block: screen->m_BlockLocate.Inflate( 1 ); HandleBlockEnd( &dc ); } break; default: wxFAIL_MSG( wxString::Format( wxT( "Cannot drag schematic item type %s." ), GetChars( item->GetClass() ) ) ); } }
void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); INSTALL_UNBUFFERED_DC( dc, m_canvas ); // Allows block rotate operation on hot key. if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { if( aEvent.GetId() == ID_SCH_MIRROR_X ) { m_canvas->MoveCursorToCrossHair(); screen->m_BlockLocate.SetMessageBlock( this ); screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_X ); HandleBlockEnd( &dc ); } else if( aEvent.GetId() == ID_SCH_MIRROR_Y ) { m_canvas->MoveCursorToCrossHair(); screen->m_BlockLocate.SetMessageBlock( this ); screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_Y ); HandleBlockEnd( &dc ); } else { wxFAIL_MSG( wxT( "Unknown block oriention command ID." ) ); } return; } if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::OrientableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } switch( item->Type() ) { case SCH_COMPONENT_T: if( aEvent.GetId() == ID_SCH_MIRROR_X ) OrientComponent( CMP_MIRROR_X ); else if( aEvent.GetId() == ID_SCH_MIRROR_Y ) OrientComponent( CMP_MIRROR_Y ); else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL ) OrientComponent( CMP_NORMAL ); else wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) ); break; case SCH_BITMAP_T: if( aEvent.GetId() == ID_SCH_MIRROR_X ) MirrorImage( (SCH_BITMAP*) item, true ); else if( aEvent.GetId() == ID_SCH_MIRROR_Y ) MirrorImage( (SCH_BITMAP*) item, false ); break; default: wxFAIL_MSG( wxString::Format( wxT( "Schematic object type %s cannot be oriented." ), GetChars( item->GetClass() ) ) ); } if( item->GetFlags() == 0 ) screen->SetCurItem( NULL ); }
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); INSTALL_UNBUFFERED_DC( dc, m_canvas ); // Allows block rotate operation on hot key. if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { screen->m_BlockLocate.SetCommand( BLOCK_ROTATE ); HandleBlockEnd( &dc ); return; } if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } switch( item->Type() ) { case SCH_COMPONENT_T: if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE ) OrientComponent( CMP_ROTATE_CLOCKWISE ); else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ) OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE ); else wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) ); break; case SCH_TEXT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: m_canvas->MoveCursorToCrossHair(); ChangeTextOrient( (SCH_TEXT*) item, &dc ); break; case SCH_FIELD_T: m_canvas->MoveCursorToCrossHair(); RotateField( (SCH_FIELD*) item, &dc ); break; case SCH_BITMAP_T: RotateImage( (SCH_BITMAP*) item ); break; case SCH_SHEET_T: /// @todo allow sheet rotate on hotkey default: wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ), GetChars( item->GetClass() ) ) ); } if( item->GetFlags() == 0 ) screen->SetCurItem( NULL ); }
void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); INSTALL_UNBUFFERED_DC( dc, m_canvas ); if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); // Set the locat filter, according to the edit command const KICAD_T* filterList = SCH_COLLECTOR::EditableItems; const KICAD_T* filterListAux = NULL; switch( aEvent.GetId() ) { case ID_SCH_EDIT_COMPONENT_REFERENCE: filterList = SCH_COLLECTOR::CmpFieldReferenceOnly; filterListAux = SCH_COLLECTOR::ComponentsOnly; break; case ID_SCH_EDIT_COMPONENT_VALUE: filterList = SCH_COLLECTOR::CmpFieldValueOnly; filterListAux = SCH_COLLECTOR::ComponentsOnly; break; case ID_SCH_EDIT_COMPONENT_FOOTPRINT: filterList = SCH_COLLECTOR::CmpFieldFootprintOnly; filterListAux = SCH_COLLECTOR::ComponentsOnly; break; default: break; } item = LocateAndShowItem( data->GetPosition(), filterList, aEvent.GetInt() ); // If no item found, and if an auxiliary filter exists, try to use it if( !item && filterListAux ) item = LocateAndShowItem( data->GetPosition(), filterListAux, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } switch( item->Type() ) { case SCH_COMPONENT_T: { switch( aEvent.GetId() ) { case ID_SCH_EDIT_COMPONENT_REFERENCE: EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( REFERENCE ) ); break; case ID_SCH_EDIT_COMPONENT_VALUE: EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( VALUE ) ); break; case ID_SCH_EDIT_COMPONENT_FOOTPRINT: EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( FOOTPRINT ) ); break; case ID_SCH_EDIT_ITEM: EditComponent( (SCH_COMPONENT*) item ); break; default: wxFAIL_MSG( wxString::Format( wxT( "Invalid schematic component edit command ID %d" ), aEvent.GetId() ) ); } break; } case SCH_SHEET_T: EditSheet( (SCH_SHEET*) item, &dc ); break; case SCH_SHEET_PIN_T: EditSheetPin( (SCH_SHEET_PIN*) item, &dc ); break; case SCH_TEXT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: EditSchematicText( (SCH_TEXT*) item ); break; case SCH_FIELD_T: EditComponentFieldText( (SCH_FIELD*) item ); break; case SCH_BITMAP_T: EditImage( (SCH_BITMAP*) item ); break; default: wxFAIL_MSG( wxString::Format( wxT( "Cannot edit schematic item type %s." ), GetChars( item->GetClass() ) ) ); } if( item->GetFlags() == 0 ) screen->SetCurItem( NULL ); }
bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) { SCH_ITEM* item = GetScreen()->GetCurItem(); bool blockActive = GetScreen()->IsBlockActive(); wxString msg; // Do not start a block command on context menu. m_canvas->SetCanStartBlock( -1 ); if( blockActive ) { AddMenusForBlock( PopMenu, this ); PopMenu->AppendSeparator(); // If we have a block containing only one main element // we append its edition submenu if( item != NULL ) { switch( item->Type() ) { case SCH_COMPONENT_T: AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item, Prj().SchLibs() ); PopMenu->AppendSeparator(); break; case SCH_TEXT_T: msg = AddHotkeyName( _( "Edit Text" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); PopMenu->AppendSeparator(); break; case SCH_LABEL_T: msg = AddHotkeyName( _( "Edit Label" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); PopMenu->AppendSeparator(); break; case SCH_GLOBAL_LABEL_T: msg = AddHotkeyName( _( "Edit Global Label" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); PopMenu->AppendSeparator(); break; case SCH_HIERARCHICAL_LABEL_T: msg = AddHotkeyName( _( "Edit Hierarchical Label" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); PopMenu->AppendSeparator(); break; case SCH_BITMAP_T: msg = AddHotkeyName( _( "Edit Image" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( image_xpm ) ); PopMenu->AppendSeparator(); break; default: break; } } return true; } // Try to locate items at cursor position. if( (item == NULL) || (item->GetFlags() == 0) ) { item = LocateAndShowItem( aPosition, SCH_COLLECTOR::AllItemsButPins ); // If the clarify item selection context menu is aborted, don't show the context menu. if( item == NULL && m_canvas->GetAbortRequest() ) { m_canvas->SetAbortRequest( false ); return false; } } // If a command is in progress: add "cancel" and "end tool" menu // If if( GetToolId() != ID_NO_TOOL_SELECTED ) { if( item && item->GetFlags() ) { AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } else { AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "End Tool" ), KiBitmap( cursor_xpm ) ); } PopMenu->AppendSeparator(); switch( GetToolId() ) { case ID_WIRE_BUTT: AddMenusForWire( PopMenu, NULL, this ); if( item == NULL ) PopMenu->AppendSeparator(); break; case ID_BUS_BUTT: AddMenusForBus( PopMenu, NULL, this ); if( item == NULL ) PopMenu->AppendSeparator(); break; default: break; } } else { if( item && item->GetFlags() ) { AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); PopMenu->AppendSeparator(); } } if( item == NULL ) { if( m_CurrentSheet->Last() != g_RootSheet ) { msg = AddHotkeyName( _( "Leave Sheet" ), g_Schematic_Hokeys_Descr, HK_LEAVE_SHEET ); AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg, KiBitmap( leave_sheet_xpm ) ); PopMenu->AppendSeparator(); } return true; } bool is_new = item->IsNew(); switch( item->Type() ) { case SCH_NO_CONNECT_T: AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete No Connect" ), KiBitmap( delete_xpm ) ); break; case SCH_JUNCTION_T: addJunctionMenuEntries( PopMenu, (SCH_JUNCTION*) item ); break; case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: AddMenusForBusEntry( PopMenu, static_cast<SCH_BUS_ENTRY_BASE*>( item ) ); break; case SCH_MARKER_T: AddMenusForMarkers( PopMenu, (SCH_MARKER*) item, this ); break; case SCH_TEXT_T: AddMenusForText( PopMenu, (SCH_TEXT*) item ); break; case SCH_LABEL_T: AddMenusForLabel( PopMenu, (SCH_LABEL*) item ); break; case SCH_GLOBAL_LABEL_T: AddMenusForGLabel( PopMenu, (SCH_GLOBALLABEL*) item ); break; case SCH_HIERARCHICAL_LABEL_T: AddMenusForHLabel( PopMenu, (SCH_HIERLABEL*) item ); break; case SCH_FIELD_T: AddMenusForComponentField( PopMenu, (SCH_FIELD*) item ); break; case SCH_COMPONENT_T: AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchLibs() ); break; case SCH_BITMAP_T: AddMenusForBitmap( PopMenu, (SCH_BITMAP*) item ); break; case SCH_LINE_T: switch( item->GetLayer() ) { case LAYER_WIRE: AddMenusForWire( PopMenu, (SCH_LINE*) item, this ); break; case LAYER_BUS: AddMenusForBus( PopMenu, (SCH_LINE*) item, this ); break; default: if( is_new ) AddMenuItem( PopMenu, ID_POPUP_END_LINE, _( "End Drawing" ), KiBitmap( checked_ok_xpm ) ); AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete Drawing" ), KiBitmap( delete_xpm ) ); break; } break; case SCH_SHEET_T: AddMenusForHierchicalSheet( PopMenu, (SCH_SHEET*) item ); break; case SCH_SHEET_PIN_T: AddMenusForSheetPin( PopMenu, (SCH_SHEET_PIN*) item ); break; default: wxFAIL_MSG( wxString::Format( wxT( "Cannot create context menu for unknown type %d" ), item->Type() ) ); break; } PopMenu->AppendSeparator(); return true; }
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { // trying to move an item when there is a block at the same time is not acceptable return; } if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } INSTALL_UNBUFFERED_DC( dc, m_canvas ); switch( item->Type() ) { case SCH_LINE_T: break; case SCH_JUNCTION_T: case SCH_NO_CONNECT_T: case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_TEXT_T: case SCH_COMPONENT_T: case SCH_SHEET_PIN_T: case SCH_FIELD_T: MoveItem( item, &dc ); break; case SCH_BITMAP_T: MoveImage( (SCH_BITMAP*) item, &dc ); break; case SCH_SHEET_T: StartMoveSheet( (SCH_SHEET*) item, &dc ); break; case SCH_MARKER_T: default: wxFAIL_MSG( wxString::Format( wxT( "Cannot move item type %s" ), GetChars( item->GetClass() ) ) ); break; } if( GetToolId() == ID_NO_TOOL_SELECTED ) SetRepeatItem( NULL ); }
/** * Function OnLeftDClick * called on a double click event from the drawpanel mouse handler * if an editable item is found (text, component) * Call the suitable dialog editor. * Id a create command is in progress: * validate and finish the command */ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) { EDA_ITEM* item = GetScreen()->GetCurItem(); switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { item = LocateAndShowItem( aPosition ); } if( ( item == NULL ) || ( item->GetFlags() != 0 ) ) break; switch( item->Type() ) { case SCH_SHEET_T: m_CurrentSheet->push_back( (SCH_SHEET*) item ); DisplayCurrentSheet(); break; case SCH_COMPONENT_T: EditComponent( (SCH_COMPONENT*) item ); GetCanvas()->MoveCursorToCrossHair(); if( item->GetFlags() == 0 ) GetScreen()->SetCurItem( NULL ); GetCanvas()->Refresh(); break; case SCH_TEXT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: EditSchematicText( (SCH_TEXT*) item ); break; case SCH_BITMAP_T: EditImage( (SCH_BITMAP*) item ); break; case SCH_FIELD_T: EditComponentFieldText( (SCH_FIELD*) item ); GetCanvas()->MoveCursorToCrossHair(); break; case SCH_MARKER_T: ( (SCH_MARKER*) item )->DisplayMarkerInfo( this ); break; default: break; } break; case ID_BUS_BUTT: case ID_WIRE_BUTT: case ID_LINE_COMMENT_BUTT: if( item && item->IsNew() ) EndSegment( aDC ); break; } }
void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { SCH_ITEM* item = GetScreen()->GetCurItem(); wxPoint gridPosition = GetGridPosition( aPosition ); if( ( GetToolId() == ID_NO_TOOL_SELECTED ) || ( item && item->GetFlags() ) ) { m_canvas->SetAutoPanRequest( false ); SetRepeatItem( NULL ); if( item && item->GetFlags() ) { switch( item->Type() ) { case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_TEXT_T: case SCH_SHEET_PIN_T: case SCH_SHEET_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_BUS_ENTRY_T: case SCH_JUNCTION_T: case SCH_COMPONENT_T: case SCH_FIELD_T: case SCH_BITMAP_T: case SCH_NO_CONNECT_T: addCurrentItemToList(); return; case SCH_LINE_T: // May already be drawing segment. break; default: wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick error. Item type <" ) + item->GetClass() + wxT( "> is already being edited." ) ); item->ClearFlags(); break; } } else { item = LocateAndShowItem( aPosition ); } } switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: break; case ID_HIGHLIGHT: HighlightConnectionAtPosition( aPosition ); break; case ID_HIERARCHY_PUSH_POP_BUTT: if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) ) break; item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsOnly ); if( item ) // The user has clicked on a sheet: this is an enter sheet command { m_CurrentSheet->push_back( (SCH_SHEET*) item ); DisplayCurrentSheet(); } else if( m_CurrentSheet->Last() != g_RootSheet ) { // The user has clicked ouside a sheet:this is an leave sheet command m_CurrentSheet->pop_back(); DisplayCurrentSheet(); } break; case ID_NOCONN_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { if( GetScreen()->GetItem( gridPosition, 0, SCH_NO_CONNECT_T ) == NULL ) { SCH_NO_CONNECT* no_connect = AddNoConnect( aDC, gridPosition ); SetRepeatItem( no_connect ); GetScreen()->SetCurItem( no_connect ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList(); } break; case ID_JUNCTION_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { if( GetScreen()->GetItem( gridPosition, 0, SCH_JUNCTION_T ) == NULL ) { SCH_JUNCTION* junction = AddJunction( aDC, gridPosition, true ); SetRepeatItem( junction ); GetScreen()->SetCurItem( junction ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList(); } break; case ID_WIRETOBUS_ENTRY_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { CreateBusWireEntry(); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_BUSTOBUS_ENTRY_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { CreateBusBusEntry(); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_SCHEMATIC_DELETE_ITEM_BUTT: DeleteItemAtCrossHair( aDC ); break; case ID_WIRE_BUTT: BeginSegment( aDC, LAYER_WIRE ); m_canvas->SetAutoPanRequest( true ); break; case ID_BUS_BUTT: BeginSegment( aDC, LAYER_BUS ); m_canvas->SetAutoPanRequest( true ); break; case ID_LINE_COMMENT_BUTT: BeginSegment( aDC, LAYER_NOTES ); m_canvas->SetAutoPanRequest( true ); break; case ID_TEXT_COMMENT_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_NOTES ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_ADD_IMAGE_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewImage( aDC ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_LABEL_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_LOCLABEL ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_GLABEL_BUTT: case ID_HIERLABEL_BUTT: if( (item == NULL) || (item->GetFlags() == 0) ) { if( GetToolId() == ID_GLABEL_BUTT ) GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_GLOBLABEL ) ); if( GetToolId() == ID_HIERLABEL_BUTT ) GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_HIERLABEL ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_SHEET_SYMBOL_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { item = CreateSheet( aDC ); if( item != NULL ) { GetScreen()->SetCurItem( item ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList(); } break; case ID_IMPORT_HLABEL_BUTT: case ID_SHEET_PIN_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsAndSheetLabels ); if( item == NULL ) break; if( (item->Type() == SCH_SHEET_T) && (item->GetFlags() == 0) ) { if( GetToolId() == ID_IMPORT_HLABEL_BUTT ) GetScreen()->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, aDC ) ); else GetScreen()->SetCurItem( CreateSheetPin( (SCH_SHEET*) item, aDC ) ); } else if( (item->Type() == SCH_SHEET_PIN_T) && (item->GetFlags() != 0) ) { addCurrentItemToList(); } break; case ID_SCH_PLACE_COMPONENT: if( (item == NULL) || (item->GetFlags() == 0) ) { GetScreen()->SetCurItem( Load_Component( aDC, NULL, s_CmpNameList, s_CmpLastUnit, true ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; case ID_PLACE_POWER_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { SCHLIB_FILTER filter; filter.FilterPowerParts( true ); GetScreen()->SetCurItem( Load_Component( aDC, &filter, s_PowerNameList, s_LastPowerUnit, false ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList(); } break; #ifdef KICAD_SPICE case ID_SIM_PROBE: { const KICAD_T wiresAndComponents[] = { SCH_LINE_T, SCH_COMPONENT_T, SCH_SHEET_PIN_T }; item = LocateAndShowItem( aPosition, wiresAndComponents ); if( !item ) break; NETLIST_OBJECT_LIST* netlist = BuildNetListBase(); for( NETLIST_OBJECT* obj : *netlist ) { if( obj->m_Comp == item ) { SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false ); if( simFrame ) simFrame->AddVoltagePlot( obj->GetNetName() ); break; } } } break; case ID_SIM_TUNE: { const KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T }; item = LocateAndShowItem( aPosition, fieldsAndComponents ); if( !item ) return; if( item->Type() != SCH_COMPONENT_T ) { item = static_cast<SCH_ITEM*>( item->GetParent() ); if( item->Type() != SCH_COMPONENT_T ) return; } SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false ); if( simFrame ) simFrame->AddTuner( static_cast<SCH_COMPONENT*>( item ) ); } break; #endif /* KICAD_SPICE */ default: SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick invalid tool ID <" ) + wxString::Format( wxT( "%d> selected." ), GetToolId() ) ); } }
/* * Hot keys. Some commands are relative to the item under the mouse cursor * Commands are case insensitive */ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem ) { if( aHotKey == 0 ) return false; wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); SCH_SCREEN* screen = GetScreen(); // itemInEdit == false means no item currently edited. We can ask for editing a new item bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags(); // blocInProgress == false means no block in progress. // Because a drag command uses a drag block, false means also no drag in progress // If false, we can ask for editing a new item bool blocInProgress = screen->m_BlockLocate.GetState() != STATE_NO_BLOCK; // notBusy == true means no item currently edited and no other command in progress // We can change active tool and ask for editing a new item bool notBusy = (!itemInEdit) && (!blocInProgress); /* 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'; // Search command from key : EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List ); if( hotKey == NULL ) hotKey = GetDescriptorFromHotkey( aHotKey, schematic_Hotkey_List ); if( hotKey == NULL ) return false; switch( hotKey->m_Idcommand ) { default: case HK_NOT_FOUND: return false; case HK_HELP: // Display Current hotkey list DisplayHotkeyList( this, g_Schematic_Hokeys_Descr ); break; case HK_RESET_LOCAL_COORD: // Reset the relative coord GetScreen()->m_O_Curseur = GetCrossHairPosition(); break; case ID_HOTKEY_HIGHLIGHT: if( notBusy ) HighlightConnectionAtPosition( GetCrossHairPosition() ); break; case HK_LEFT_CLICK: case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) { GetCanvas()->SetAutoPanRequest( false ); HandleBlockPlace( aDC ); } else if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK ) { OnLeftClick( aDC, aPosition ); if( hotKey->m_Idcommand == HK_LEFT_DCLICK ) OnLeftDClick( aDC, aPosition ); } break; case HK_ZOOM_IN: case HK_ZOOM_OUT: case HK_ZOOM_REDRAW: case HK_ZOOM_CENTER: case HK_ZOOM_AUTO: case HK_ZOOM_SELECTION: case HK_MOVEBLOCK_TO_DRAGBLOCK: // Switch to drag mode, when block moving case HK_SAVE_BLOCK: // Copy block to paste buffer. cmd.SetId( hotKey->m_IdMenuEvent ); GetEventHandler()->ProcessEvent( cmd ); break; case HK_DELETE: if( notBusy ) DeleteItemAtCrossHair( aDC ); break; case HK_REPEAT_LAST: if( notBusy ) RepeatDrawItem( aDC ); break; case HK_END_CURR_LINEWIREBUS: // this key terminates a new line/bus/wire in progress if( aItem && aItem->IsNew() && aItem->Type() == SCH_LINE_T ) { cmd.SetId( hotKey->m_IdMenuEvent ); GetEventHandler()->ProcessEvent( cmd ); } break; case HK_UNDO: // Hot keys that map to command IDs that cannot be called case HK_REDO: // while busy performing another command. case HK_FIND_ITEM: case HK_FIND_REPLACE: case HK_DELETE_NODE: case HK_LEAVE_SHEET: if( notBusy ) { cmd.SetId( hotKey->m_IdMenuEvent ); GetEventHandler()->ProcessEvent( cmd ); } break; case HK_FIND_NEXT_ITEM: case HK_FIND_NEXT_DRC_MARKER: if( notBusy ) { wxFindDialogEvent event( hotKey->m_IdMenuEvent, GetId() ); event.SetEventObject( this ); event.SetFlags( m_findReplaceData->GetFlags() ); event.SetFindString( m_findReplaceData->GetFindString() ); GetEventHandler()->ProcessEvent( event ); } break; case HK_ADD_NEW_COMPONENT: // Add component case HK_ADD_NEW_POWER: // Add power component case HK_ADD_LABEL: case HK_ADD_HLABEL: case HK_ADD_GLABEL: case HK_ADD_JUNCTION: case HK_ADD_WIRE_ENTRY: case HK_ADD_BUS_ENTRY: case HK_ADD_HIER_SHEET: case HK_ADD_GRAPHIC_TEXT: case HK_ADD_GRAPHIC_POLYLINE: case HK_ADD_NOCONN_FLAG: // Add a no connected flag case HK_BEGIN_BUS: case HK_BEGIN_WIRE: if( notBusy ) { EDA_HOTKEY_CLIENT_DATA data( aPosition ); cmd.SetInt( aHotKey ); cmd.SetClientObject( &data ); cmd.SetId( hotKey->m_IdMenuEvent ); GetEventHandler()->ProcessEvent( cmd ); } else if( aItem && aItem->IsNew() ) { // If the item is a bus or a wire, a begin command is not possible. if( (GetToolId() == ID_BUS_BUTT) && (aItem->Type() == SCH_LINE_T) ) { SCH_LINE* segment = (SCH_LINE*) aItem; if( segment->GetLayer() != LAYER_BUS ) break; // Bus in progress: OnLeftClick( aDC, aPosition ); } else if( (GetToolId() == ID_WIRE_BUTT ) && (aItem->Type() == SCH_LINE_T) ) { SCH_LINE* segment = (SCH_LINE*) aItem; if( segment->GetLayer() != LAYER_WIRE ) break; // Wire in progress: OnLeftClick( aDC, aPosition ); } } break; case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label if( itemInEdit ) break; if( aItem == NULL ) { aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::CopyableItems ); if( aItem == NULL ) break; } cmd.SetId( hotKey->m_IdMenuEvent ); wxPostEvent( this, cmd ); break; case HK_DRAG: // Start drag case HK_MOVE_COMPONENT_OR_ITEM: // Start move schematic item. if( ! notBusy ) break; // Fall through case HK_EDIT: // Edit schematic item. Do not allow sheet edition when mowing // Because a sheet edition can be complex. if( itemInEdit && screen->GetCurItem()->Type() == SCH_SHEET_T ) break; // Fall through case HK_EDIT_COMPONENT_VALUE: // Edit component value field. case HK_EDIT_COMPONENT_REFERENCE: // Edit component value reference. case HK_EDIT_COMPONENT_FOOTPRINT: // Edit component footprint field. case HK_MIRROR_Y: // Mirror Y case HK_MIRROR_X: // Mirror X case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component) case HK_ROTATE: // Rotate schematic item. case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component { // force a new item search on hot keys at current position, // if there is no currently edited item, // to avoid using a previously selected item if( ! itemInEdit ) screen->SetCurItem( NULL ); EDA_HOTKEY_CLIENT_DATA data( aPosition ); cmd.SetInt( hotKey->m_Idcommand ); cmd.SetClientObject( &data ); cmd.SetId( hotKey->m_IdMenuEvent ); GetEventHandler()->ProcessEvent( cmd ); } break; } // Hot key handled. return true; }
void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { SCH_ITEM* item = GetScreen()->GetCurItem(); wxPoint gridPosition = GetGridPosition( aPosition ); if( ( GetToolId() == ID_NO_TOOL_SELECTED ) || ( item && item->GetFlags() ) ) { m_canvas->SetAutoPanRequest( false ); SetRepeatItem( NULL ); if( item && item->GetFlags() ) { switch( item->Type() ) { case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_TEXT_T: case SCH_SHEET_PIN_T: case SCH_SHEET_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_BUS_ENTRY_T: case SCH_JUNCTION_T: case SCH_COMPONENT_T: case SCH_FIELD_T: case SCH_BITMAP_T: case SCH_NO_CONNECT_T: addCurrentItemToList( aDC ); return; case SCH_LINE_T: // May already be drawing segment. break; default: wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick error. Item type <" ) + item->GetClass() + wxT( "> is already being edited." ) ); item->ClearFlags(); break; } } else { item = LocateAndShowItem( aPosition ); } } switch( GetToolId() ) { case ID_NO_TOOL_SELECTED: break; case ID_HIERARCHY_PUSH_POP_BUTT: if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) ) break; item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsOnly ); if( item ) // The user has clicked on a sheet: this is an enter sheet command { m_CurrentSheet->Push( (SCH_SHEET*) item ); DisplayCurrentSheet(); } else if( m_CurrentSheet->Last() != g_RootSheet ) { // The user has clicked ouside a sheet:this is an leave sheet command m_CurrentSheet->Pop(); DisplayCurrentSheet(); } break; case ID_NOCONN_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { if( false == GetScreen()->GetItem( gridPosition, 0, SCH_NO_CONNECT_T ) ) { SCH_NO_CONNECT* no_connect = AddNoConnect( aDC, gridPosition ); SetRepeatItem( no_connect ); GetScreen()->SetCurItem( no_connect ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList( aDC ); } break; case ID_JUNCTION_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { if( false == GetScreen()->GetItem( gridPosition, 0, SCH_JUNCTION_T ) ) { SCH_JUNCTION* junction = AddJunction( aDC, gridPosition, true ); SetRepeatItem( junction ); GetScreen()->SetCurItem( junction ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList( aDC ); } break; case ID_WIRETOBUS_ENTRY_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { CreateBusWireEntry( aDC ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_BUSTOBUS_ENTRY_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { CreateBusBusEntry( aDC ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_SCHEMATIC_DELETE_ITEM_BUTT: DeleteItemAtCrossHair( aDC ); break; case ID_WIRE_BUTT: BeginSegment( aDC, LAYER_WIRE ); m_canvas->SetAutoPanRequest( true ); break; case ID_BUS_BUTT: BeginSegment( aDC, LAYER_BUS ); m_canvas->SetAutoPanRequest( true ); break; case ID_LINE_COMMENT_BUTT: BeginSegment( aDC, LAYER_NOTES ); m_canvas->SetAutoPanRequest( true ); break; case ID_TEXT_COMMENT_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_NOTES ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_ADD_IMAGE_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewImage( aDC ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_LABEL_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_LOCLABEL ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_GLABEL_BUTT: case ID_HIERLABEL_BUTT: if( (item == NULL) || (item->GetFlags() == 0) ) { if( GetToolId() == ID_GLABEL_BUTT ) GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_GLOBLABEL ) ); if( GetToolId() == ID_HIERLABEL_BUTT ) GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_HIERLABEL ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_SHEET_SYMBOL_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { item = CreateSheet( aDC ); if( item != NULL ) { GetScreen()->SetCurItem( item ); m_canvas->SetAutoPanRequest( true ); } } else { addCurrentItemToList( aDC ); } break; case ID_IMPORT_HLABEL_BUTT: case ID_SHEET_PIN_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsAndSheetLabels ); if( item == NULL ) break; if( (item->Type() == SCH_SHEET_T) && (item->GetFlags() == 0) ) { if( GetToolId() == ID_IMPORT_HLABEL_BUTT ) GetScreen()->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, aDC ) ); else GetScreen()->SetCurItem( CreateSheetPin( (SCH_SHEET*) item, aDC ) ); } else if( (item->Type() == SCH_SHEET_PIN_T) && (item->GetFlags() != 0) ) { addCurrentItemToList( aDC ); } break; case ID_SCH_PLACE_COMPONENT: if( (item == NULL) || (item->GetFlags() == 0) ) { GetScreen()->SetCurItem( Load_Component( aDC, wxEmptyString, s_CmpNameList, s_CmpLastUnit, true ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; case ID_PLACE_POWER_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { GetScreen()->SetCurItem( Load_Component( aDC, wxT( "power" ), s_PowerNameList, s_LastPowerUnit, false ) ); m_canvas->SetAutoPanRequest( true ); } else { addCurrentItemToList( aDC ); } break; default: SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick invalid tool ID <" ) + wxString::Format( wxT( "%d> selected." ), GetToolId() ) ); } }
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); INSTALL_UNBUFFERED_DC( dc, m_canvas ); // Allows block rotate operation on hot key. if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { screen->m_BlockLocate.SetCommand( BLOCK_ROTATE ); HandleBlockEnd( &dc ); return; } if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } switch( item->Type() ) { case SCH_COMPONENT_T: { SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item ); if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE ) OrientComponent( CMP_ROTATE_CLOCKWISE ); else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ) OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE ); else wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) ); if( m_autoplaceFields ) component->AutoAutoplaceFields( GetScreen() ); m_canvas->Refresh(); break; } case SCH_TEXT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: m_canvas->MoveCursorToCrossHair(); ChangeTextOrient( (SCH_TEXT*) item ); m_canvas->Refresh(); break; case SCH_FIELD_T: m_canvas->MoveCursorToCrossHair(); RotateField( (SCH_FIELD*) item ); if( item->GetParent()->Type() == SCH_COMPONENT_T ) { // Now that we're moving a field, they're no longer autoplaced. SCH_COMPONENT *parent = static_cast<SCH_COMPONENT*>( item->GetParent() ); parent->ClearFieldsAutoplaced(); } m_canvas->Refresh(); break; case SCH_BITMAP_T: RotateImage( (SCH_BITMAP*) item ); break; case SCH_SHEET_T: if( !item->IsNew() ) // rotate a sheet during its creation has no sense { bool retCCW = ( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ); RotateHierarchicalSheet( static_cast<SCH_SHEET*>( item ), retCCW ); } break; case SCH_JUNCTION_T: case SCH_NO_CONNECT_T: // these items are not rotated, because rotation does not change them. break; default: // Other items (wires...) cannot be rotated, at least during creation if( item->IsNew() ) break; wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ), GetChars( item->GetClass() ) ) ); } if( item->GetFlags() == 0 ) screen->SetCurItem( NULL ); }
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ) { // trying to move an item when there is a block at the same time is not acceptable return; } if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; } INSTALL_UNBUFFERED_DC( dc, m_canvas ); switch( item->Type() ) { case SCH_LINE_T: break; case SCH_JUNCTION_T: case SCH_NO_CONNECT_T: case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_TEXT_T: case SCH_COMPONENT_T: case SCH_SHEET_PIN_T: case SCH_FIELD_T: case SCH_SHEET_T: PrepareMoveItem( item, &dc ); break; case SCH_BITMAP_T: // move an image is a special case: // we cannot undraw/redraw a bitmap just using our xor mode // the MoveImage function handle this undraw/redraw difficulty // By redrawing the full bounding box MoveImage( (SCH_BITMAP*) item, &dc ); break; case SCH_MARKER_T: // Moving a marker has no sense break; default: // Unknown items cannot be moved wxFAIL_MSG( wxString::Format( wxT( "Cannot move item type %d" ), item->Type() ) ); break; } if( GetToolId() == ID_NO_TOOL_SELECTED ) SetRepeatItem( NULL ); }
void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); // The easiest way to handle a menu or a hot key drag command // is to simulate a block drag command // // When a drag item is requested, some items use a BLOCK_DRAG_ITEM drag type // an some items use a BLOCK_DRAG drag type (mainly a junction) // a BLOCK_DRAG collects all items in a block (here a 2x2 rect centered on the cursor) // and BLOCK_DRAG_ITEM drag only the selected item BLOCK_COMMAND_T dragType = BLOCK_DRAG_ITEM; if( item == NULL ) { // If we didn't get here by a hot key, then something has gone wrong. if( aEvent.GetInt() == 0 ) return; EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::DraggableItems, aEvent.GetInt() ); // Exit if no item found at the current location or the item is already being edited. if( (item == NULL) || (item->GetFlags() != 0) ) return; // When a junction or a node is found, a BLOCK_DRAG is better if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false ) || m_collectedItems.IsDraggableJunction() ) dragType = BLOCK_DRAG; } switch( item->Type() ) { case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_LINE_T: case SCH_JUNCTION_T: case SCH_COMPONENT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_SHEET_T: m_canvas->MoveCursorToCrossHair(); if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK ) { INSTALL_UNBUFFERED_DC( dc, m_canvas ); if( !HandleBlockBegin( &dc, dragType, GetCrossHairPosition() ) ) break; // Give a non null size to the search block: screen->m_BlockLocate.Inflate( 1 ); HandleBlockEnd( &dc ); } break; default: wxFAIL_MSG( wxString::Format( wxT( "Cannot drag schematic item type %s." ), GetChars( item->GetClass() ) ) ); } }