/*****************************************/ /* Edition du pcb: Gestion des cotations */ /*****************************************/ #include "fctsys.h" #include "common.h" #include "pcbnew.h" #include "protos.h" /* Routines Locales */ static void Exit_EditCotation(WinEDA_DrawPanel * Panel, wxDC *DC); static void Montre_Position_New_Cotation(WinEDA_DrawPanel * panel, wxDC * DC, bool erase); static void Ajuste_Details_Cotation(COTATION * pts); /* Variables "locales" : */ static int status_cotation; /* = 0 : pas de cotation en cours = 1 : debut place, fin a placer = 2 : fin placee, texte a ajuster */ /* Les routines generent une cotation de la forme - cote usuelle: | | | dist | |<---------->| | | */ #define MAX_CHAR 40 /* longueur maxi de la cotation */ /* Dimension des fleches */ #define FLECHE_L 500 enum id_Cotation_properties { ID_ACCEPT_COTATION_PROPERTIES = 1900, ID_CLOSE_COTATION_PROPERTIES, ID_TEXTPCB_SELECT_LAYER }; /************************************/ /* class WinEDA_CotationPropertiesFrame */ /************************************/ class WinEDA_CotationPropertiesFrame: public wxDialog { private: WinEDA_PcbFrame * m_Parent; wxDC * m_DC; COTATION * CurrentCotation; WinEDA_EnterText * m_Name; WinEDA_SizeCtrl * m_TxtSizeCtrl; WinEDA_ValueCtrl * m_TxtWidthCtrl; wxRadioBox * m_Mirror; WinEDAChoiceBox * m_SelLayerBox; public: // Constructor and destructor WinEDA_CotationPropertiesFrame(WinEDA_PcbFrame *parent, COTATION * Cotation, wxDC * DC, const wxPoint & pos); ~WinEDA_CotationPropertiesFrame(void) { } private: void OnQuit(wxCommandEvent& event); void CotationPropertiesAccept(wxCommandEvent& event); DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(WinEDA_CotationPropertiesFrame, wxDialog) EVT_BUTTON(ID_ACCEPT_COTATION_PROPERTIES, WinEDA_CotationPropertiesFrame::CotationPropertiesAccept) EVT_BUTTON(ID_CLOSE_COTATION_PROPERTIES, WinEDA_CotationPropertiesFrame::OnQuit) END_EVENT_TABLE() WinEDA_CotationPropertiesFrame::WinEDA_CotationPropertiesFrame(WinEDA_PcbFrame *parent, COTATION * Cotation,wxDC * DC, const wxPoint & framepos): wxDialog(parent, -1, _("Cotation properties"), framepos, wxSize(340, 270), DIALOG_STYLE) { wxButton * Button; m_Parent = parent; SetFont(*g_DialogFont); m_DC = DC; Centre(); CurrentCotation = Cotation; wxBoxSizer * MainBoxSizer = new wxBoxSizer(wxHORIZONTAL); SetSizer(MainBoxSizer); wxBoxSizer * LeftBoxSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer * RightBoxSizer = new wxBoxSizer(wxVERTICAL); MainBoxSizer->Add(LeftBoxSizer, 0, wxGROW|wxALL, 5); MainBoxSizer->Add(RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); /* Creation des boutons de commande */ Button = new wxButton(this, ID_ACCEPT_COTATION_PROPERTIES, _("Ok")); Button->SetForegroundColour(*wxRED); RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); Button = new wxButton(this, ID_CLOSE_COTATION_PROPERTIES, _("Cancel")); Button->SetForegroundColour(*wxBLUE); RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); wxString display_msg[2] = { _("Normal"), _("Mirror") }; m_Mirror = new wxRadioBox(this, -1, _("Display"), wxDefaultPosition, wxSize(-1,-1), 2, display_msg, 1, wxRA_SPECIFY_COLS ); if ( ! Cotation->m_Text->m_Miroir ) m_Mirror->SetSelection(1);; RightBoxSizer->Add(m_Mirror, 0, wxGROW|wxALL, 5); m_Name = new WinEDA_EnterText(this, wxT("Text:"), Cotation->m_Text->m_Text, LeftBoxSizer, wxSize( 200, -1) ); m_TxtSizeCtrl = new WinEDA_SizeCtrl(this, _("Size"), Cotation->m_Text->m_Size, g_UnitMetric, LeftBoxSizer, m_Parent->m_InternalUnits); m_TxtWidthCtrl = new WinEDA_ValueCtrl(this, _("Width"), Cotation->m_Width, g_UnitMetric, LeftBoxSizer, m_Parent->m_InternalUnits); wxStaticText * text = new wxStaticText(this, -1, _("Layer:")); LeftBoxSizer->Add(text, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); m_SelLayerBox = new WinEDAChoiceBox(this, ID_TEXTPCB_SELECT_LAYER, wxDefaultPosition, wxDefaultSize); LeftBoxSizer->Add(m_SelLayerBox, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); int ii; for ( ii = CMP_N + 1; ii < 29 ; ii ++ ) { m_SelLayerBox->Append(ReturnPcbLayerName(ii)); } m_SelLayerBox->SetSelection( Cotation->m_Layer - (CMP_N + 1) ); GetSizer()->Fit(this); GetSizer()->SetSizeHints(this); } /**********************************************************************/ void WinEDA_CotationPropertiesFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) /**********************************************************************/ { Close(true); // true is to force the frame to close } /***********************************************************************************/ void WinEDA_CotationPropertiesFrame::CotationPropertiesAccept(wxCommandEvent& event) /***********************************************************************************/ { if ( m_DC ) // Effacement ancien texte { CurrentCotation->Draw(m_Parent->DrawPanel, m_DC, wxPoint(0,0), GR_XOR); } if ( m_Name->GetValue() != wxEmptyString ) { CurrentCotation->SetText( m_Name->GetValue()); } CurrentCotation->m_Text->m_Size = m_TxtSizeCtrl->GetValue(); CurrentCotation->m_Text->m_Width = CurrentCotation->m_Width = m_TxtWidthCtrl->GetValue(); CurrentCotation->m_Text->m_Miroir = (m_Mirror->GetSelection() == 0) ? 1 : 0; CurrentCotation->m_Layer = CurrentCotation->m_Text->m_Layer = m_SelLayerBox->GetChoice() + CMP_N + 1; CurrentCotation->m_Text->CreateDrawData(); if ( m_DC ) // Affichage nouveau texte { /* Redessin du Texte */ CurrentCotation->Draw(m_Parent->DrawPanel, m_DC, wxPoint(0,0), GR_OR); } m_Parent->m_CurrentScreen->SetModify(); Close(TRUE); } /**************************************************************/ static void Exit_EditCotation(WinEDA_DrawPanel * Panel, wxDC *DC) /**************************************************************/ { COTATION * Cotation = (COTATION*) Panel->GetScreen()->m_CurrentItem; if( Cotation ) { if ( Cotation->m_Flags & IS_NEW) { Cotation->Draw(Panel, DC,wxPoint(0,0),GR_XOR) ; DeleteStructure( Cotation); } else { Cotation->Draw(Panel, DC,wxPoint(0,0),GR_OR) ; } } status_cotation = 0; Panel->ManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL; Panel->GetScreen()->m_CurrentItem = NULL; } /*************************************************************************/ COTATION * WinEDA_PcbFrame::Begin_Cotation(COTATION * Cotation, wxDC * DC) /*************************************************************************/ { wxPoint pos ; if(Cotation == NULL ) /* debut reel du trace */ { status_cotation = 1; pos = m_CurrentScreen->m_Curseur; Cotation = new COTATION(m_Pcb); Cotation->m_Flags = IS_NEW; Cotation->m_Layer = GetScreen()->m_Active_Layer; Cotation->m_Width = g_DesignSettings.m_DrawSegmentWidth; Cotation->m_Text->m_Width = Cotation->m_Width; Cotation->Barre_ox = Cotation->Barre_fx = pos.x ; Cotation->Barre_oy = Cotation->Barre_fy = pos.y ; Cotation->TraitD_ox = Cotation->TraitD_fx = pos.x ; Cotation->TraitD_oy = Cotation->TraitD_fy = pos.y ; Cotation->TraitG_ox = Cotation->TraitG_fx = pos.x ; Cotation->TraitG_oy = Cotation->TraitG_fy = pos.y ; Cotation->FlecheG1_ox = Cotation->FlecheG1_fx = pos.x ; Cotation->FlecheG1_oy = Cotation->FlecheG1_fy = pos.y ; Cotation->FlecheG2_ox = Cotation->FlecheG2_fx = pos.x ; Cotation->FlecheG2_oy = Cotation->FlecheG2_fy = pos.y ; Cotation->FlecheD1_ox = Cotation->FlecheD1_fx = pos.x ; Cotation->FlecheD1_oy = Cotation->FlecheD1_fy = pos.y ; Cotation->FlecheD2_ox = Cotation->FlecheD2_fx = pos.x ; Cotation->FlecheD2_oy = Cotation->FlecheD2_fy = pos.y ; Cotation->m_Text->m_Miroir = 1; Cotation->m_Text->m_Size = g_DesignSettings.m_PcbTextSize; Cotation->m_Text->m_Width = g_DesignSettings.m_PcbTextWidth; Ajuste_Details_Cotation(Cotation); Cotation->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR); DrawPanel->ManageCurseur = Montre_Position_New_Cotation; DrawPanel->ForceCloseManageCurseur = Exit_EditCotation; return Cotation; } // Cotation != NULL if( status_cotation == 1 ) { status_cotation = 2; return Cotation; } Cotation->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR); Cotation->m_Flags = 0; /* Insertion de la structure dans le Chainage .Drawings du PCB */ Cotation->Pback = m_Pcb; Cotation->Pnext = m_Pcb->m_Drawings; if( m_Pcb->m_Drawings) m_Pcb->m_Drawings->Pback = Cotation; m_Pcb->m_Drawings = Cotation; m_CurrentScreen->SetModify(); DrawPanel->ManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL; return NULL; } /************************************************************************************/ static void Montre_Position_New_Cotation(WinEDA_DrawPanel * panel, wxDC * DC, bool erase ) /************************************************************************************/ /* redessin du contour de la piste lors des deplacements de la souris */ { PCB_SCREEN * screen = (PCB_SCREEN *)panel->GetScreen(); COTATION * Cotation = (COTATION *) screen->m_CurrentItem; wxPoint pos = screen->m_Curseur; if( Cotation == NULL ) return ; /* efface ancienne position */ if( erase) { Cotation->Draw(panel, DC, wxPoint(0,0),GR_XOR) ; } Cotation->m_Layer = screen->m_Active_Layer; if( status_cotation == 1) { Cotation->TraitD_ox = pos.x; Cotation->TraitD_oy = pos.y; Cotation->Barre_fx = Cotation->TraitD_ox; Cotation->Barre_fy = Cotation->TraitD_oy; Ajuste_Details_Cotation(Cotation); } else { int deltax, deltay, dx , dy; float angle, depl; deltax = Cotation->TraitD_ox - Cotation->TraitG_ox; deltay = Cotation->TraitD_oy - Cotation->TraitG_oy; /* Calcul de la direction de deplacement ( perpendiculaire a l'axe de la cote ) */ angle = atan2(deltay,deltax) + (M_PI / 2); deltax = pos.x - Cotation->TraitD_ox; deltay = pos.y - Cotation->TraitD_oy; depl = (deltax * cos(angle)) + (deltay * sin(angle)); dx = (int)(depl * cos(angle)); dy = (int)(depl * sin(angle)); Cotation->Barre_ox = Cotation->TraitG_ox + dx; Cotation->Barre_oy = Cotation->TraitG_oy + dy ; Cotation->Barre_fx = Cotation->TraitD_ox + dx; Cotation->Barre_fy = Cotation->TraitD_oy + dy ; Ajuste_Details_Cotation(Cotation); } Cotation->Draw(panel, DC, wxPoint(0,0),GR_XOR) ; } /***************************************************************/ void WinEDA_PcbFrame::Install_Edit_Cotation(COTATION * Cotation, wxDC * DC, const wxPoint & pos) /***************************************************************/ { if( Cotation == NULL) return; WinEDA_CotationPropertiesFrame * frame = new WinEDA_CotationPropertiesFrame(this, Cotation, DC, pos); frame->ShowModal(); frame->Destroy(); } /*******************************************************************/ void WinEDA_PcbFrame::Delete_Cotation(COTATION * Cotation, wxDC * DC) /*******************************************************************/ { if( Cotation == NULL) return; if ( DC ) Cotation->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR ); DeleteStructure( Cotation); m_CurrentScreen->SetModify(); } /*****************************************************/ static void Ajuste_Details_Cotation(COTATION * Cotation) /*****************************************************/ /* Calcule les details des coordonnees des differents segments constitutifs de la cotation */ { int ii; int mesure, deltax, deltay; /* valeur de la mesure sur les axes X et Y */ int fleche_up_X=0, fleche_up_Y=0; /* coord des fleches : barre / */ int fleche_dw_X=0, fleche_dw_Y=0; /* coord des fleches : barre \ */ int hx, hy; /* coord des traits de rappel de cote */ float angle, angle_f; wxString msg; /* Init des couches : */ Cotation->m_Text->m_Layer = Cotation->m_Layer; /* calcul de la hauteur du texte + trait de cotation */ ii = Cotation->m_Text->m_Size.y + Cotation->m_Text->m_Width + (Cotation->m_Width * 3); deltax = Cotation->TraitD_ox - Cotation->TraitG_ox; deltay = Cotation->TraitD_oy - Cotation->TraitG_oy; /* Calcul de la cote */ mesure = (int)(hypot( (float)deltax, (float)deltay ) + 0.5 ) ; if( deltax || deltay) angle = atan2( (float)deltay,(float)deltax); else angle = 0.0; /* Calcul des parametre dimensions X et Y des fleches et traits de cotes */ hx = hy = ii; /* On tient compte de l'inclinaison de la cote */ if(mesure) { hx = (abs)((int)( ( (float)deltay * hx) / mesure)); hy = (abs)((int)( ( (float)deltax * hy) / mesure)); if( Cotation->TraitG_ox > Cotation->Barre_ox ) hx = -hx; if( Cotation->TraitG_ox == Cotation->Barre_ox ) hx = 0; if( Cotation->TraitG_oy > Cotation->Barre_oy ) hy = -hy; if( Cotation->TraitG_oy == Cotation->Barre_oy ) hy = 0; angle_f = angle + (M_PI * 27.5 /180); fleche_up_X = (int)(FLECHE_L * cos(angle_f)); fleche_up_Y = (int)(FLECHE_L * sin(angle_f)); angle_f = angle - (M_PI * 27.5 /180); fleche_dw_X = (int)(FLECHE_L * cos(angle_f)); fleche_dw_Y = (int)(FLECHE_L * sin(angle_f)); } Cotation->FlecheG1_ox = Cotation->Barre_ox; Cotation->FlecheG1_oy = Cotation->Barre_oy; Cotation->FlecheG1_fx = Cotation->Barre_ox + fleche_up_X ; Cotation->FlecheG1_fy = Cotation->Barre_oy + fleche_up_Y; Cotation->FlecheG2_ox = Cotation->Barre_ox ; Cotation->FlecheG2_oy = Cotation->Barre_oy ; Cotation->FlecheG2_fx = Cotation->Barre_ox + fleche_dw_X; Cotation->FlecheG2_fy = Cotation->Barre_oy + fleche_dw_Y; /*la fleche de droite est symetrique a celle de gauche: / = -\ et \ = -/ */ Cotation->FlecheD1_ox = Cotation->Barre_fx ; Cotation->FlecheD1_oy = Cotation->Barre_fy ; Cotation->FlecheD1_fx = Cotation->Barre_fx - fleche_dw_X; Cotation->FlecheD1_fy = Cotation->Barre_fy - fleche_dw_Y; Cotation->FlecheD2_ox = Cotation->Barre_fx ; Cotation->FlecheD2_oy = Cotation->Barre_fy ; Cotation->FlecheD2_fx = Cotation->Barre_fx - fleche_up_X; Cotation->FlecheD2_fy = Cotation->Barre_fy - fleche_up_Y; Cotation->TraitG_fx = Cotation->Barre_ox + hx; Cotation->TraitG_fy = Cotation->Barre_oy + hy; Cotation->TraitD_fx = Cotation->Barre_fx + hx; Cotation->TraitD_fy = Cotation->Barre_fy + hy; /* Calcul de la position du centre du texte et son orientation: */ Cotation->m_Pos.x = Cotation->m_Text->m_Pos.x = (Cotation->Barre_fx + Cotation->TraitG_fx) / 2; Cotation->m_Pos.y = Cotation->m_Text->m_Pos.y = (Cotation->Barre_fy + Cotation->TraitG_fy) / 2; Cotation->m_Text->m_Orient = - (int)(angle * 1800 / M_PI); if(Cotation->m_Text->m_Orient < 0) Cotation->m_Text->m_Orient += 3600; if(Cotation->m_Text->m_Orient >= 3600) Cotation->m_Text->m_Orient -= 3600; if( (Cotation->m_Text->m_Orient > 900) && (Cotation->m_Text->m_Orient <2700) ) Cotation->m_Text->m_Orient -= 1800; Cotation->m_Value = mesure; valeur_param(Cotation->m_Value,msg); Cotation->SetText( msg); Cotation->m_Text->CreateDrawData(); }