From 45f55fb8c5b7fa592327ab9b1d8b8fa05c24889e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 6 Feb 2014 17:12:37 +0100 Subject: [PATCH] Actually added files for drawing tools. Added possibility of drawing circles. --- pcbnew/tools/common_actions.cpp | 6 +- pcbnew/tools/common_actions.h | 5 +- pcbnew/tools/drawing_tool.cpp | 196 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 72 ++++++++++++ pcbnew/tools/pcb_tools.cpp | 3 +- 5 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 pcbnew/tools/drawing_tool.cpp create mode 100644 pcbnew/tools/drawing_tool.h diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 464a8ab505..22b0c10e2f 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -57,6 +57,10 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); -TOOL_ACTION COMMON_ACTIONS::drawingLine( "pcbnew.InteractiveDrawing.line", +TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", AS_GLOBAL, 'D', "Draw a line", "Draw a line" ); + +TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", + AS_GLOBAL, 'S', + "Draw a circle", "Draw a circle" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 42a03b3cb3..d573a8a96c 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -58,5 +58,8 @@ public: static TOOL_ACTION remove; /// Activation of the drawing tool (line) - static TOOL_ACTION drawingLine; + static TOOL_ACTION drawLine; + + /// Activation of the drawing tool (circle) + static TOOL_ACTION drawCircle; }; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp new file mode 100644 index 0000000000..8f03336bdc --- /dev/null +++ b/pcbnew/tools/drawing_tool.cpp @@ -0,0 +1,196 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 + */ + +#include "drawing_tool.h" +#include "common_actions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DRAWING_TOOL::DRAWING_TOOL() : + TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ) +{ +} + + +DRAWING_TOOL::~DRAWING_TOOL() +{ +} + + +void DRAWING_TOOL::Reset( RESET_REASON aReason ) +{ + setTransitions(); +} + + +int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) +{ + m_continous = true; + + return draw( S_SEGMENT ); +} + + +int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) +{ + m_continous = false; + + return draw( S_CIRCLE ); +} + + +int DRAWING_TOOL::draw( STROKE_T aShape ) +{ + bool started = false; + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel( PCB_T ); + DRAWSEGMENT graphic; + + // Init the new item attributes + graphic.SetShape( aShape ); + graphic.SetWidth( board->GetDesignSettings().m_DrawSegmentWidth ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + view->Add( &preview ); + + controls->ShowCursor( true ); + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + // Enable 45 degrees lines only mode by holding shift + bool linesAngle45 = evt->Modifier( MD_SHIFT ); + VECTOR2D cursorPos = view->ToWorld( controls->GetCursorPosition() ); + + if( evt->IsCancel() ) + break; + + else if( evt->IsKeyUp() ) + { + int width = graphic.GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) + graphic.SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + graphic.SetWidth( width + WIDTH_STEP ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !started ) + { + LAYER_NUM layer = getEditFrame()->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + } + else + { + controls->SetAutoPan( true ); + + graphic.SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + graphic.SetLayer( layer ); + preview.Add( &graphic ); + + started = true; + } + } + else + { + if( wxPoint( cursorPos.x, cursorPos.y ) != graphic.GetStart() ) + { + DRAWSEGMENT* newItem = new DRAWSEGMENT( graphic ); + view->Add( newItem ); + getModel( PCB_T )->Add( newItem ); + newItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + if( m_continous ) + graphic.SetStart( graphic.GetEnd() ); // This is the origin point for a new item + else + break; + } + else // User has clicked twice in the same spot + break; // seems like a clear sign that the drawing is finished + } + } + + else if( evt->IsMotion() && started ) + { + // 45 degree lines + if( linesAngle45 && aShape == S_SEGMENT ) + { + VECTOR2D lineVector( wxPoint( cursorPos.x, cursorPos.y ) - graphic.GetStart() ); + double angle = atan2( lineVector.y, lineVector.x ); + + double newAngle = round( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0; + VECTOR2D newLineVector = lineVector.Rotate( newAngle - angle ); + + // Snap the new line to the grid // TODO fix it, does not work good.. + VECTOR2D newLineEnd = VECTOR2D( graphic.GetStart() ) + newLineVector; + VECTOR2D snapped = view->GetGAL()->GetGridPoint( newLineEnd ); + + graphic.SetEnd( wxPoint( snapped.x, snapped.y ) ); + } + else + { + graphic.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + +void DRAWING_TOOL::setTransitions() +{ + Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); + Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); +} diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h new file mode 100644 index 0000000000..4cef5744cd --- /dev/null +++ b/pcbnew/tools/drawing_tool.h @@ -0,0 +1,72 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 + */ + +#ifndef __DRAWING_TOOL_H +#define __DRAWING_TOOL_H + +#include +#include + +/** + * Class DRAWING_TOOL + * + * Tool responsible for drawing graphical elements like lines, arcs, circles, etc. + */ + +class DRAWING_TOOL : public TOOL_INTERACTIVE +{ +public: + DRAWING_TOOL(); + ~DRAWING_TOOL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ); + + /** + * Function DrawLine() + * Starts interactively drawing a line. After invoking the function it expects the user + * to click at least twice to determine the origin and the end for a line. If there are + * more clicks, the line is drawn as a continous polyline. + */ + int DrawLine( TOOL_EVENT& aEvent ); + + int DrawCircle( TOOL_EVENT& aEvent ); + + int DrawArc( TOOL_EVENT& aEvent ); + +private: + ///> Starts drawing a selected shape. + int draw( STROKE_T aShape ); + + ///> Sets up handlers for various events. + void setTransitions(); + + ///> Should drawing be stopped after drawing one object or should it continue with another one. + bool m_continous; + + // How does line width change after one -/+ key press. + static const int WIDTH_STEP = 100000; +}; + +#endif /* __DRAWING_TOOL_H */ diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 63c98d5009..5dff5788a9 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -55,7 +55,8 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); m_toolManager->RegisterAction( &COMMON_ACTIONS::remove ); m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); - m_toolManager->RegisterAction( &COMMON_ACTIONS::drawingLine ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawLine ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::drawCircle ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL );