kicad-source/pcbnew/edit_pcb_text.cpp
Dick Hollenbeck 4578ea8b9e 1) Add 32 Cu Layers.
2) Change from legacy Cu stack to counting down from top=(F_Cu or 0).
   The old Cu stack required knowing the count of Cu layers to make
   sense of the layer number when converting to many exported file types.
   The new Cu stack is more commonly used, although ours still gives
   B_Cu a fixed number.
3) Introduce class LSET and enum LAYER_ID.
4) Change *.kicad_pcb file format version to 4 from 3.
5) Change fixed names Inner1_Cu-Inner14_Cu to In1_Cu-In30_Cu and their
   meanings are typically flipped.
6) Moved the #define LAYER_N_* stuff into legacy_plugin.cpp where they
   can die a quiet death, and switch to enum LAYER_ID symbols throughout.
7) Removed the LEGACY_PLUGIN::Save() and FootprintSave() functions.
   You will need to convert to the format immediately, *.kicad_pcb and
   *.kicad_mod (=pretty) since legacy format was never going to know
   about 32 Cu layers and additional technical layers and the reversed Cu
   stack.
2014-06-24 11:17:18 -05:00

288 lines
7.8 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file edit_pcb_text.cpp
* @brief Editimg of text on copper and technical layers (TEXTE_PCB class)
*/
#include <fctsys.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <macros.h>
#include <class_board.h>
#include <class_pcb_text.h>
#include <class_board_item.h>
static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase );
static void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC );
static TEXTE_PCB s_TextCopy( (BOARD_ITEM*) NULL ); /* copy of the edited text
* (used to undo/redo/abort
* a complex edition command
*/
/*
* Abort current text edit progress.
* If a text is selected, its initial coord are regenerated
*/
void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
TEXTE_PCB* TextePcb = (TEXTE_PCB*) Panel->GetScreen()->GetCurItem();
( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
Panel->SetMouseCapture( NULL, NULL );
if( TextePcb == NULL ) // Should not occur
return;
#ifndef USE_WX_OVERLAY
TextePcb->Draw( Panel, DC, GR_XOR );
#endif
if( TextePcb->IsNew() ) // If new: remove it
{
TextePcb->DeleteStructure();
return;
}
TextePcb->SwapData( &s_TextCopy );
TextePcb->ClearFlags();
#ifndef USE_WX_OVERLAY
TextePcb->Draw( Panel, DC, GR_OR );
#else
Panel->Refresh();
#endif
}
/*
* Place the current text being moving
*/
void PCB_EDIT_FRAME::Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
{
m_canvas->SetMouseCapture( NULL, NULL );
SetCurItem( NULL );
if( TextePcb == NULL )
return;
TextePcb->Draw( m_canvas, DC, GR_OR );
OnModify();
if( TextePcb->IsNew() ) // If new: prepare undo command
{
SaveCopyInUndoList( TextePcb, UR_NEW );
TextePcb->ClearFlags();
return;
}
if( TextePcb->IsMoving() ) // If moved only
{
SaveCopyInUndoList( TextePcb, UR_MOVED,
TextePcb->GetTextPosition() - s_TextCopy.GetTextPosition() );
}
else
{
// Restore initial params
TextePcb->SwapData( &s_TextCopy );
// Prepare undo command
SaveCopyInUndoList( TextePcb, UR_CHANGED );
// Restore current params
TextePcb->SwapData( &s_TextCopy );
}
TextePcb->ClearFlags();
#ifdef USE_WX_OVERLAY
m_canvas->Refresh();
#endif
}
void PCB_EDIT_FRAME::StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aErase )
{
if( aTextePcb == NULL )
return;
// if it is an existing item: prepare a copy to undo/abort command
if( !aTextePcb->IsNew() )
s_TextCopy.Copy( aTextePcb );
aTextePcb->SetFlags( IS_MOVED );
SetMsgPanel( aTextePcb );
#ifdef USE_WX_OVERLAY
m_canvas->Refresh();
#endif
SetCrossHairPosition( aTextePcb->GetTextPosition() );
m_canvas->MoveCursorToCrossHair();
m_canvas->SetMouseCapture( Move_Texte_Pcb, Abort_Edit_Pcb_Text );
SetCurItem( aTextePcb );
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, aErase );
}
// Move PCB text following the cursor.
static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{
TEXTE_PCB* TextePcb = (TEXTE_PCB*) aPanel->GetScreen()->GetCurItem();
if( TextePcb == NULL )
return;
if( aErase )
TextePcb->Draw( aPanel, aDC, GR_XOR );
TextePcb->SetTextPosition( aPanel->GetParent()->GetCrossHairPosition() );
TextePcb->Draw( aPanel, aDC, GR_XOR );
}
void PCB_EDIT_FRAME::Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
{
if( TextePcb == NULL )
return;
TextePcb->Draw( m_canvas, DC, GR_XOR );
SaveCopyInUndoList( TextePcb, UR_DELETED );
TextePcb->UnLink();
m_canvas->SetMouseCapture( NULL, NULL );
SetCurItem( NULL );
}
TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
{
TEXTE_PCB* textePcb = new TEXTE_PCB( GetBoard() );
if( aText )
{
textePcb->Copy( aText );
GetBoard()->Add( textePcb );
textePcb->SetFlags( IS_NEW );
if( aDC )
StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
}
else
{
GetBoard()->Add( textePcb );
textePcb->SetFlags( IS_NEW );
LAYER_ID layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
textePcb->SetLayer( layer );
// Set the mirrored option for layers on the BACK side of the board
if( layer == B_Cu || layer == B_SilkS ||
layer == B_Paste || layer == B_Mask ||
layer == B_Adhes
)
textePcb->SetMirrored( true );
textePcb->SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
textePcb->SetTextPosition( GetCrossHairPosition() );
textePcb->SetThickness( GetBoard()->GetDesignSettings().m_PcbTextWidth );
InstallTextPCBOptionsFrame( textePcb, aDC );
if( textePcb->GetText().IsEmpty() )
{
textePcb->DeleteStructure();
textePcb = NULL;
}
else if( aDC )
{
StartMoveTextePcb( textePcb, aDC );
}
}
return textePcb;
}
void PCB_EDIT_FRAME::Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
{
int angle = 900;
if( TextePcb == NULL )
return;
// Erase previous text:
TextePcb->Draw( m_canvas, DC, GR_XOR );
TextePcb->SetOrientation( TextePcb->GetOrientation() + angle );
// Redraw text in new position:
TextePcb->Draw( m_canvas, DC, GR_XOR );
SetMsgPanel( TextePcb );
if( TextePcb->GetFlags() == 0 ) // i.e. not edited, or moved
SaveCopyInUndoList( TextePcb, UR_ROTATED, TextePcb->GetTextPosition() );
else // set flag edit, to show it was a complex command
TextePcb->SetFlags( IN_EDIT );
OnModify();
#ifdef USE_WX_OVERLAY
m_canvas->Refresh();
#endif
}
void PCB_EDIT_FRAME::FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC )
{
if( aTextePcb == NULL )
return;
aTextePcb->Draw( m_canvas, aDC, GR_XOR );
aTextePcb->Flip( aTextePcb->GetTextPosition() );
aTextePcb->Draw( m_canvas, aDC, GR_XOR );
SetMsgPanel( aTextePcb );
if( aTextePcb->GetFlags() == 0 ) // i.e. not edited, or moved
SaveCopyInUndoList( aTextePcb, UR_FLIPPED, aTextePcb->GetTextPosition() );
else // set edit flag, for the current command
aTextePcb->SetFlags( IN_EDIT );
OnModify();
#ifdef USE_WX_OVERLAY
m_canvas->Refresh();
#endif
}