You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							329 lines
						
					
					
						
							9.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							329 lines
						
					
					
						
							9.6 KiB
						
					
					
				
								/*
							 | 
						|
								 * This program source code file is part of KiCad, a free EDA CAD application.
							 | 
						|
								 *
							 | 
						|
								 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
							 | 
						|
								 * Copyright (C) 1992-2018 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 edtxtmod.cpp
							 | 
						|
								 * @brief Edit texts in footprints.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#include <fctsys.h>
							 | 
						|
								#include <gr_basic.h>
							 | 
						|
								#include <common.h>
							 | 
						|
								#include <class_drawpanel.h>
							 | 
						|
								#include <draw_graphic_text.h>
							 | 
						|
								#include <trigo.h>
							 | 
						|
								#include <pcb_base_frame.h>
							 | 
						|
								#include <macros.h>
							 | 
						|
								
							 | 
						|
								#include <pcbnew.h>
							 | 
						|
								#include <pcb_edit_frame.h>
							 | 
						|
								#include <footprint_edit_frame.h>
							 | 
						|
								
							 | 
						|
								#include <class_board.h>
							 | 
						|
								#include <class_module.h>
							 | 
						|
								#include <class_text_mod.h>
							 | 
						|
								#include <class_pcb_text.h>
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
							 | 
						|
								                                   bool aErase );
							 | 
						|
								static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								wxPoint        MoveVector;              // Move vector for move edge, exported
							 | 
						|
								                                        // to dialog_edit mod_text.cpp
							 | 
						|
								static wxPoint TextInitialPosition;     // Mouse cursor initial position for
							 | 
						|
								                                        // undo/abort move command
							 | 
						|
								static double  TextInitialOrientation;  // module text initial orientation for
							 | 
						|
								                                        // undo/abort move+rot command+rot
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/* Add a new graphical text to the active module (footprint)
							 | 
						|
								 *  Note there always are 2 mandatory texts: reference and value.
							 | 
						|
								 *  New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
							 | 
						|
								 */
							 | 
						|
								TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
							 | 
						|
								{
							 | 
						|
								    TEXTE_MODULE* text = new TEXTE_MODULE( aModule );
							 | 
						|
								
							 | 
						|
								    text->SetFlags( IS_NEW );
							 | 
						|
								
							 | 
						|
								    if( LSET::AllTechMask().test( GetActiveLayer() ) )    // i.e. a possible layer for a text
							 | 
						|
								        text->SetLayer( GetActiveLayer() );
							 | 
						|
								
							 | 
						|
								    InstallTextOptionsFrame( text, NULL );
							 | 
						|
								
							 | 
						|
								    if( text->GetText().IsEmpty() )
							 | 
						|
								    {
							 | 
						|
								        delete text;
							 | 
						|
								        return NULL;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // Add the new text object to the beginning of the footprint draw list.
							 | 
						|
								    if( aModule )
							 | 
						|
								        aModule->GraphicalItemsList().PushFront( text );
							 | 
						|
								
							 | 
						|
								    text->ClearFlags();
							 | 
						|
								
							 | 
						|
								    if( aDC )
							 | 
						|
								        text->Draw( m_canvas, aDC, GR_OR );
							 | 
						|
								
							 | 
						|
								    SetMsgPanel( text );
							 | 
						|
								
							 | 
						|
								    return text;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC )
							 | 
						|
								{
							 | 
						|
								    if( Text == NULL )
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    MODULE* module = (MODULE*) Text->GetParent();
							 | 
						|
								
							 | 
						|
								    if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
							 | 
						|
								    {
							 | 
						|
								        if( IsType( FRAME_PCB ) )
							 | 
						|
								            SaveCopyInUndoList( module, UR_CHANGED );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // we expect MoveVector to be (0,0) if there is no move in progress
							 | 
						|
								    Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
							 | 
						|
								
							 | 
						|
								    Text->SetTextAngle( Text->GetTextAngle() + 900 );
							 | 
						|
								
							 | 
						|
								    Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
							 | 
						|
								    SetMsgPanel( Text );
							 | 
						|
								
							 | 
						|
								    if( module )
							 | 
						|
								        module->SetLastEditTime();
							 | 
						|
								
							 | 
						|
								    OnModify();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void PCB_BASE_FRAME::DeleteTextModule( TEXTE_MODULE* aText )
							 | 
						|
								{
							 | 
						|
								    MODULE* module;
							 | 
						|
								
							 | 
						|
								    if( aText == NULL )
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    module = static_cast<MODULE*>( aText->GetParent() );
							 | 
						|
								
							 | 
						|
								    if( aText->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
							 | 
						|
								    {
							 | 
						|
								        if( module && module->GetFlags() == 0 && aText->GetFlags() == 0 && IsType( FRAME_PCB ) )
							 | 
						|
								            SaveCopyInUndoList( module, UR_CHANGED );
							 | 
						|
								
							 | 
						|
								        m_canvas->RefreshDrawingRect( aText->GetBoundingBox() );
							 | 
						|
								        aText->DeleteStructure();
							 | 
						|
								        OnModify();
							 | 
						|
								        module->SetLastEditTime();
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Abort text move in progress.
							 | 
						|
								 *
							 | 
						|
								 * If a text is selected, its initial coordinates are regenerated.
							 | 
						|
								 */
							 | 
						|
								static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
							 | 
						|
								{
							 | 
						|
								    BASE_SCREEN*  screen = Panel->GetScreen();
							 | 
						|
								    TEXTE_MODULE* Text   = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
							 | 
						|
								    MODULE*       Module;
							 | 
						|
								
							 | 
						|
								    Panel->SetMouseCapture( NULL, NULL );
							 | 
						|
								
							 | 
						|
								    if( Text == NULL )
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    Module = static_cast<MODULE*>( Text->GetParent() );
							 | 
						|
								
							 | 
						|
								    Text->DrawUmbilical( Panel, DC, GR_XOR, -MoveVector );
							 | 
						|
								    Text->Draw( Panel, DC, GR_XOR, MoveVector );
							 | 
						|
								
							 | 
						|
								    // If the text was moved (the move does not change internal data)
							 | 
						|
								    // it could be rotated while moving. So set old value for orientation
							 | 
						|
								    if( Text->IsMoving() )
							 | 
						|
								        Text->SetTextAngle( TextInitialOrientation );
							 | 
						|
								
							 | 
						|
								    // Redraw the text
							 | 
						|
								    Panel->RefreshDrawingRect( Text->GetBoundingBox() );
							 | 
						|
								
							 | 
						|
								    // leave it at (0,0) so we can use it Rotate when not moving.
							 | 
						|
								    MoveVector.x = MoveVector.y = 0;
							 | 
						|
								
							 | 
						|
								    Text->ClearFlags();
							 | 
						|
								    Module->ClearFlags();
							 | 
						|
								
							 | 
						|
								    screen->SetCurItem( NULL );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void PCB_BASE_FRAME::StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC )
							 | 
						|
								{
							 | 
						|
								    if( Text == NULL )
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    MODULE *Module = static_cast<MODULE*>( Text->GetParent() );
							 | 
						|
								
							 | 
						|
								    Text->SetFlags( IS_MOVED );
							 | 
						|
								    Module->SetFlags( IN_EDIT );
							 | 
						|
								
							 | 
						|
								    MoveVector.x = MoveVector.y = 0;
							 | 
						|
								
							 | 
						|
								    TextInitialPosition    = Text->GetTextPos();
							 | 
						|
								    TextInitialOrientation = Text->GetTextAngle();
							 | 
						|
								
							 | 
						|
								    // Center cursor on initial position of text
							 | 
						|
								    SetCrossHairPosition( TextInitialPosition );
							 | 
						|
								    m_canvas->MoveCursorToCrossHair();
							 | 
						|
								
							 | 
						|
								    SetMsgPanel( Text );
							 | 
						|
								    SetCurItem( Text );
							 | 
						|
								    m_canvas->SetMouseCapture( Show_MoveTexte_Module, AbortMoveTextModule );
							 | 
						|
								    m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
							 | 
						|
								{
							 | 
						|
								    if( Text != NULL )
							 | 
						|
								    {
							 | 
						|
								        m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
							 | 
						|
								        Text->DrawUmbilical( m_canvas, DC, GR_XOR, -MoveVector );
							 | 
						|
								
							 | 
						|
								        // Update the coordinates for anchor.
							 | 
						|
								        MODULE* Module = static_cast<MODULE*>( Text->GetParent() );
							 | 
						|
								
							 | 
						|
								        if( Module )
							 | 
						|
								        {
							 | 
						|
								            // Prepare undo command (a rotation can be made while moving)
							 | 
						|
								            double tmp = Text->GetTextAngle();
							 | 
						|
								            Text->SetTextAngle( TextInitialOrientation );
							 | 
						|
								
							 | 
						|
								            if( IsType( FRAME_PCB ) )
							 | 
						|
								                SaveCopyInUndoList( Module, UR_CHANGED );
							 | 
						|
								            else
							 | 
						|
								                SaveCopyInUndoList( Module, UR_CHANGED );
							 | 
						|
								
							 | 
						|
								            Text->SetTextAngle( tmp );
							 | 
						|
								
							 | 
						|
								            // Set the new position for text.
							 | 
						|
								            Text->SetTextPos( GetCrossHairPosition() );
							 | 
						|
								            wxPoint textRelPos = Text->GetTextPos() - Module->GetPosition();
							 | 
						|
								            RotatePoint( &textRelPos, -Module->GetOrientation() );
							 | 
						|
								            Text->SetPos0( textRelPos );
							 | 
						|
								            Text->ClearFlags();
							 | 
						|
								            Module->ClearFlags();
							 | 
						|
								            Module->SetLastEditTime();
							 | 
						|
								            OnModify();
							 | 
						|
								
							 | 
						|
								            // Redraw text.
							 | 
						|
								            m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            Text->SetTextPos( GetCrossHairPosition() );
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // leave it at (0,0) so we can use it Rotate when not moving.
							 | 
						|
								    MoveVector.x = MoveVector.y = 0;
							 | 
						|
								
							 | 
						|
								    m_canvas->SetMouseCapture( NULL, NULL );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
							 | 
						|
								                                   bool aErase )
							 | 
						|
								{
							 | 
						|
								    BASE_SCREEN*  screen = aPanel->GetScreen();
							 | 
						|
								    TEXTE_MODULE* Text   = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
							 | 
						|
								
							 | 
						|
								    if( Text == NULL )
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    // Erase umbilical and text if necessary
							 | 
						|
								    if( aErase )
							 | 
						|
								    {
							 | 
						|
								        Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
							 | 
						|
								        Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    MoveVector = TextInitialPosition - aPanel->GetParent()->GetCrossHairPosition();
							 | 
						|
								
							 | 
						|
								    // Draw umbilical if text moved
							 | 
						|
								    if( MoveVector.x || MoveVector.y )
							 | 
						|
								        Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
							 | 
						|
								
							 | 
						|
								    // Redraw text
							 | 
						|
								    Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
							 | 
						|
								{
							 | 
						|
								    wxSize newSize = GetDesignSettings().GetTextSize( aItem->GetLayer() );
							 | 
						|
								    int newThickness = GetDesignSettings().GetTextThickness( aItem->GetLayer() );
							 | 
						|
								    bool newItalic = GetDesignSettings().GetTextItalic( aItem->GetLayer() );
							 | 
						|
								
							 | 
						|
								    if( aItem->Type() == PCB_TEXT_T )
							 | 
						|
								    {
							 | 
						|
								        TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem );
							 | 
						|
								
							 | 
						|
								        // Exit if there's nothing to do
							 | 
						|
								        if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
							 | 
						|
								            return;
							 | 
						|
								
							 | 
						|
								        SaveCopyInUndoList( text, UR_CHANGED );
							 | 
						|
								        text->SetTextSize( newSize );
							 | 
						|
								        text->SetThickness( newThickness );
							 | 
						|
								        text->SetItalic( newItalic );
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    else if( aItem->Type() ==  PCB_MODULE_TEXT_T )
							 | 
						|
								    {
							 | 
						|
								        TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
							 | 
						|
								
							 | 
						|
								        // Exit if there's nothing to do
							 | 
						|
								        if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
							 | 
						|
								            return;
							 | 
						|
								
							 | 
						|
								        SaveCopyInUndoList( text->GetParent(), UR_CHANGED );
							 | 
						|
								        text->SetTextSize( newSize );
							 | 
						|
								        text->SetThickness( newThickness );
							 | 
						|
								        text->SetItalic( newItalic );
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								        return;
							 | 
						|
								
							 | 
						|
								    if( aDC )
							 | 
						|
								        m_canvas->Refresh();
							 | 
						|
								
							 | 
						|
								    OnModify();
							 | 
						|
								}
							 |