/***************/ /* hotkeys.cpp */ /***************/ #include "fctsys.h" #include "gr_basic.h" #include "common.h" #include "pcbnew.h" #include "id.h" #include "protos.h" /* Routines locales */ /* variables externes */ /***********************************************************/ void WinEDA_PcbFrame::OnHotKey(wxDC * DC, int hotkey, EDA_BaseStruct * DrawStruct) /***********************************************************/ /* Gestion des commandes rapides (Raccourcis claviers) concernant l'element sous le courseur souris Les majuscules/minuscules sont indifferenciees touche DELETE: Effacement (Module ou piste selon commande en cours) touche V: Place via en cours de trace de piste touche R: Rotation module touche S: Change couche module (Composant <-> Cuivre) touche M: Start Move module touche G: Start Drag module */ { bool PopupOn = GetScreen()->m_CurrentItem && GetScreen()->m_CurrentItem->m_Flags; bool ItemFree = (GetScreen()->m_CurrentItem == 0 ) || (GetScreen()->m_CurrentItem->m_Flags == 0); if ( hotkey == 0 ) return; // code Ctrl A = 1, Ctr B = 2 ..., remapped, (more easy to understand in switch) if ( hotkey & GR_KB_CTRL ) hotkey += 'A' - 1; MODULE* module = NULL; if ( hotkey <= 0xFF) hotkey = toupper(hotkey); switch (hotkey) { case WXK_DELETE: case WXK_NUMPAD_DELETE: OnHotkeyDeleteItem(DC, DrawStruct); break; case WXK_BACK: if( m_ID_current_state == ID_TRACK_BUTT && GetScreen()->m_Active_Layer <= CMP_N ) { bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) || (GetScreen()->m_CurrentItem->m_Flags == 0); if ( ItemFree ) { //no track is currently being edited - select a segment and remove it. DrawStruct = PcbGeneralLocateAndDisplay(); //don't let backspace delete modules!! if ( DrawStruct && (DrawStruct->m_StructType == TYPETRACK || DrawStruct->m_StructType == TYPEVIA)) Delete_Segment(DC, (TRACK*)DrawStruct); GetScreen()->SetModify(); } else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK ) { //then an element is being edited - remove the last segment. GetScreen()->m_CurrentItem = Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem); GetScreen()->SetModify(); } } break; case WXK_END: DrawPanel->MouseToCursorSchema(); End_Route( (TRACK *) (GetScreen()->m_CurrentItem), DC); break; case 'F' + GR_KB_CTRL : { wxCommandEvent evt; evt.SetId(ID_FIND_ITEMS); Process_Special_Functions(evt); } break; case (int('O') + GR_KB_CTRL) : { //try not to duplicate save, load code etc. wxCommandEvent evt; evt.SetId(ID_LOAD_FILE); Files_io(evt); } break; case 'S' + GR_KB_CTRL: { //try not to duplicate save, load code etc. wxCommandEvent evt; evt.SetId(ID_SAVE_BOARD); Files_io(evt); } break; case 'V': // Switch to alternate layer and Place a via if a track is in progress if ( m_ID_current_state != ID_TRACK_BUTT ) return; if ( ItemFree ) { Other_Layer_Route( NULL, DC); break; } if ( GetScreen()->m_CurrentItem->m_StructType != TYPETRACK ) return; if ( (GetScreen()->m_CurrentItem->m_Flags & IS_NEW) == 0 ) return; Other_Layer_Route( (TRACK *) GetScreen()->m_CurrentItem, DC); if ( DisplayOpt.ContrastModeDisplay ) GetScreen()->SetRefreshReq(); break; // Footprint edition: case 'L': // toggle module "MODULE_is_LOCKED" status: // get any module, locked or not locked and toggle its locked status if ( ItemFree ) module = Locate_Prefered_Module( m_Pcb, CURSEUR_OFF_GRILLE | VISIBLE_ONLY ); else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE) module = (MODULE*)GetScreen()->m_CurrentItem; if( module ) { GetScreen()->m_CurrentItem = module; module->SetLocked( !module->IsLocked() ); module->Display_Infos(this); } break; case 'G': // Start move (and drag) module case 'M': // Start move module if ( PopupOn ) break; case 'R': // Rotation case 'S': // move to other side if ( ItemFree ) { module = Locate_Prefered_Module(m_Pcb, CURSEUR_OFF_GRILLE | IGNORE_LOCKED | VISIBLE_ONLY /*MATCH_LAYER */ ); if ( module == NULL ) // no footprint found { module = Locate_Prefered_Module(m_Pcb, CURSEUR_OFF_GRILLE ); if ( module ) // a footprint is found, but locked or on an other layer { if ( module->IsLocked() ) DisplayInfo(this, _("Footprint found, but locked") ); module = NULL; } } } else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE) { module = (MODULE*)GetScreen()->m_CurrentItem; // @todo: might need to add a layer check in if() below if ( (GetScreen()->m_CurrentItem->m_Flags == 0) && module->IsLocked() ) module = NULL; // do not move, rotate ... it. } if ( module == NULL) break; GetScreen()->m_CurrentItem = module; switch (hotkey) { case 'R': // Rotation Rotate_Module(DC, module, 900, TRUE); break; case 'S': // move to other side Change_Side_Module(module, DC); break; case 'G': // Start move (and drag) module g_Drag_Pistes_On = TRUE; // fall through case 'M': // Start move module StartMove_Module( module, DC); break; } module->Display_Infos(this); break; } } /***********************************************************/ void WinEDA_ModuleEditFrame::OnHotKey(wxDC * DC, int hotkey, EDA_BaseStruct * DrawStruct) /***********************************************************/ /* Gestion des commandes rapides (Raccourcis claviers) concernant l'element sous le courseur souris Les majuscules/minuscules sont indifferenciees */ { bool PopupOn = GetScreen()->m_CurrentItem && GetScreen()->m_CurrentItem->m_Flags; if ( hotkey == 0 ) return; switch (hotkey) { case WXK_DELETE: case WXK_NUMPAD_DELETE: if ( PopupOn ) break; break; case 'r': // Rotation case 'R': break; case 'y': // Mirror Y (drawlibpart) case 'Y': break; case 'x': // Mirror X (drawlibpart) case 'X': break; case 'n': case 'N': // Orient 0, no mirror (drawlibpart) break; case 'm': case 'M': // Start move drawlibpart if ( PopupOn ) break; break; } } /******************************************************************************/ bool WinEDA_PcbFrame::OnHotkeyDeleteItem(wxDC * DC, EDA_BaseStruct * DrawStruct) /******************************************************************************/ /* Efface l'item pointe par la souris, en reponse a la touche "Del" Effet dependant de l'outil selectionne: Outil trace de pistes Efface le segment en cours ou la piste si pas d'element Outil module: Efface le module. */ { bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) || (GetScreen()->m_CurrentItem->m_Flags == 0); switch ( m_ID_current_state ) { case ID_TRACK_BUTT: if ( GetScreen()->m_Active_Layer > CMP_N ) return FALSE; if ( ItemFree ) { DrawStruct = PcbGeneralLocateAndDisplay(); if ( DrawStruct && DrawStruct->m_StructType != TYPETRACK ) return FALSE; Delete_Track(DC, (TRACK*)DrawStruct); } else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK ) { GetScreen()->m_CurrentItem = Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem); GetScreen()->SetModify(); return TRUE; } break; case ID_COMPONENT_BUTT: if ( ItemFree ) { MODULE * module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE); if ( module == NULL ) return FALSE; if( ! IsOK(this, _("Delete module?")) ) return FALSE; RemoveStruct(module, DC); } else return FALSE; break; default: return FALSE; } GetScreen()->SetModify(); GetScreen()->m_CurrentItem = NULL; return TRUE; }