478 lines
14 KiB
C++
478 lines
14 KiB
C++
/*****************************************/
|
|
/* 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();
|
|
}
|
|
|