487 lines
16 KiB
C++
487 lines
16 KiB
C++
/*****************************************/
|
|
/* Edition du pcb: Gestion des cotations */
|
|
/*****************************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "common.h"
|
|
#include "class_drawpanel.h"
|
|
#include "pcbnew.h"
|
|
#include "wxPcbStruct.h"
|
|
#include "class_board_design_settings.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, bool aDoNotChangeText = false );
|
|
|
|
/* 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_TEXTPCB_SELECT_LAYER = 1900
|
|
};
|
|
|
|
/************************************/
|
|
/* 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()
|
|
{
|
|
}
|
|
|
|
|
|
private:
|
|
void OnCancelClick( wxCommandEvent& event );
|
|
void OnOkClick( wxCommandEvent& event );
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
BEGIN_EVENT_TABLE( WinEDA_CotationPropertiesFrame, wxDialog )
|
|
EVT_BUTTON( wxID_OK, WinEDA_CotationPropertiesFrame::OnOkClick )
|
|
EVT_BUTTON( wxID_CANCEL, WinEDA_CotationPropertiesFrame::OnCancelClick )
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
WinEDA_CotationPropertiesFrame::WinEDA_CotationPropertiesFrame( WinEDA_PcbFrame* parent,
|
|
COTATION* Cotation, wxDC* DC,
|
|
const wxPoint& framepos ) :
|
|
wxDialog( parent, -1, _( "Dimension properties" ), framepos, wxSize( 340, 270 ),
|
|
DIALOG_STYLE )
|
|
{
|
|
wxButton* Button;
|
|
|
|
m_Parent = parent;
|
|
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, wxID_OK, _( "OK" ) );
|
|
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
|
|
|
|
Button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
|
|
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_Mirror )
|
|
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 );
|
|
|
|
for( int layer = FIRST_NO_COPPER_LAYER; layer<NB_LAYERS; layer++ )
|
|
{
|
|
m_SelLayerBox->Append( parent->GetBoard()->GetLayerName( layer ) );
|
|
}
|
|
|
|
m_SelLayerBox->SetSelection( Cotation->GetLayer() - FIRST_NO_COPPER_LAYER );
|
|
|
|
GetSizer()->Fit( this );
|
|
GetSizer()->SetSizeHints( this );
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
void WinEDA_CotationPropertiesFrame::OnCancelClick( wxCommandEvent& WXUNUSED (event) )
|
|
/**********************************************************************/
|
|
{
|
|
EndModal( -1 );
|
|
}
|
|
|
|
|
|
/***********************************************************************************/
|
|
void WinEDA_CotationPropertiesFrame::OnOkClick( wxCommandEvent& event )
|
|
/***********************************************************************************/
|
|
{
|
|
if( m_DC ) // Effacement ancien texte
|
|
{
|
|
CurrentCotation->Draw( m_Parent->DrawPanel, m_DC, GR_XOR );
|
|
}
|
|
|
|
m_Parent->SaveCopyInUndoList(CurrentCotation, UR_CHANGED);
|
|
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_Mirror = (m_Mirror->GetSelection() == 1) ? true : false;
|
|
|
|
CurrentCotation->SetLayer( m_SelLayerBox->GetChoice() + FIRST_NO_COPPER_LAYER );
|
|
|
|
if( m_DC ) // Affichage nouveau texte
|
|
{
|
|
/* Redessin du Texte */
|
|
CurrentCotation->Draw( m_Parent->DrawPanel, m_DC, GR_OR );
|
|
}
|
|
|
|
m_Parent->GetScreen()->SetModify();
|
|
EndModal( 1 );
|
|
}
|
|
|
|
|
|
/**************************************************************/
|
|
static void Exit_EditCotation( WinEDA_DrawPanel* Panel, wxDC* DC )
|
|
/**************************************************************/
|
|
{
|
|
COTATION* Cotation = (COTATION*) Panel->GetScreen()->GetCurItem();
|
|
|
|
if( Cotation )
|
|
{
|
|
if( Cotation->m_Flags & IS_NEW )
|
|
{
|
|
Cotation->Draw( Panel, DC, GR_XOR );
|
|
Cotation->DeleteStructure();
|
|
}
|
|
else
|
|
{
|
|
Cotation->Draw( Panel, DC, GR_OR );
|
|
}
|
|
}
|
|
|
|
status_cotation = 0;
|
|
Panel->ManageCurseur = NULL;
|
|
Panel->ForceCloseManageCurseur = NULL;
|
|
((WinEDA_PcbFrame*)Panel->GetParent())->SetCurItem(NULL);
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
COTATION* WinEDA_PcbFrame::Begin_Cotation( COTATION* Cotation, wxDC* DC )
|
|
/*************************************************************************/
|
|
{
|
|
wxPoint pos;
|
|
|
|
if( Cotation == NULL ) /* debut reel du trace */
|
|
{
|
|
status_cotation = 1;
|
|
pos = GetScreen()->m_Curseur;
|
|
|
|
Cotation = new COTATION( GetBoard() );
|
|
Cotation->m_Flags = IS_NEW;
|
|
|
|
Cotation->SetLayer( ((PCB_SCREEN*)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_Size = g_DesignSettings.m_PcbTextSize;
|
|
Cotation->m_Text->m_Width = g_DesignSettings.m_PcbTextWidth;
|
|
|
|
Ajuste_Details_Cotation( Cotation );
|
|
|
|
Cotation->Draw( DrawPanel, DC, 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, GR_OR );
|
|
Cotation->m_Flags = 0;
|
|
|
|
/* Insertion de la structure dans le Chainage .Drawings du PCB */
|
|
GetBoard()->Add( Cotation );
|
|
|
|
GetScreen()->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->GetCurItem();
|
|
wxPoint pos = screen->m_Curseur;
|
|
|
|
if( Cotation == NULL )
|
|
return;
|
|
|
|
/* efface ancienne position */
|
|
if( erase )
|
|
{
|
|
Cotation->Draw( panel, DC, GR_XOR );
|
|
}
|
|
|
|
Cotation->SetLayer( 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( (double)deltay, (double)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, 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 );
|
|
|
|
Ajuste_Details_Cotation( Cotation, true );
|
|
frame->ShowModal();
|
|
frame->Destroy();
|
|
}
|
|
|
|
|
|
/*******************************************************************/
|
|
void WinEDA_PcbFrame::Delete_Cotation( COTATION* Cotation, wxDC* DC )
|
|
/*******************************************************************/
|
|
{
|
|
if( Cotation == NULL )
|
|
return;
|
|
|
|
if( DC )
|
|
Cotation->Draw( DrawPanel, DC, GR_XOR );
|
|
|
|
SaveCopyInUndoList(Cotation, UR_DELETED);
|
|
Cotation->UnLink();
|
|
GetScreen()->SetModify();
|
|
}
|
|
|
|
|
|
/*****************************************************/
|
|
static void Ajuste_Details_Cotation( COTATION* Cotation, bool aDoNotChangeText )
|
|
/*****************************************************/
|
|
|
|
/* 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->SetLayer( Cotation->GetLayer() );
|
|
|
|
/* 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( (double) deltax, (double) deltay ) + 0.5 );
|
|
|
|
if( deltax || deltay )
|
|
angle = atan2( (double) deltay, (double) 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) ( ( (double) deltay * hx ) / mesure ) );
|
|
hy = (abs) ( (int) ( ( (double) 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;
|
|
|
|
if( !aDoNotChangeText )
|
|
{
|
|
Cotation->m_Value = mesure;
|
|
valeur_param( Cotation->m_Value, msg );
|
|
Cotation->SetText( msg );
|
|
}
|
|
}
|