From d49ecb1b919e9bfb8d54380dca5a3c016d57df32 Mon Sep 17 00:00:00 2001 From: Chris Pavlina Date: Sat, 11 Jun 2016 09:51:05 -0400 Subject: [PATCH] Add zoom-to-selection and block move to pl_editor --- .../page_layout/page_layout_graphic_items.cpp | 200 +++++++++++---- include/worksheet_shape_builder.h | 67 ++++- pagelayout_editor/CMakeLists.txt | 1 + pagelayout_editor/block.cpp | 235 ++++++++++++++++++ pagelayout_editor/events_functions.cpp | 27 +- pagelayout_editor/hotkeys.cpp | 11 +- pagelayout_editor/pl_editor_frame.cpp | 11 +- pagelayout_editor/pl_editor_frame.h | 46 +++- pagelayout_editor/toolbars_pl_editor.cpp | 19 +- 9 files changed, 538 insertions(+), 79 deletions(-) create mode 100644 pagelayout_editor/block.cpp diff --git a/common/page_layout/page_layout_graphic_items.cpp b/common/page_layout/page_layout_graphic_items.cpp index c927e935df..dc424b5d43 100644 --- a/common/page_layout/page_layout_graphic_items.cpp +++ b/common/page_layout/page_layout_graphic_items.cpp @@ -1,13 +1,8 @@ -/** - * @file page_layout_graphic_items.cpp - * @brief description of graphic items and texts to build a title block - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2013 Jean-Pierre Charras . - * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * * * This program is free software; you can redistribute it and/or @@ -27,7 +22,10 @@ * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - +/** + * @file page_layout_graphic_items.cpp + * @brief description of graphic items and texts to build a title block + */ /* * the class WORKSHEET_DATAITEM (and WORKSHEET_DATAITEM_TEXT) defines @@ -60,6 +58,7 @@ #include #include #include +#include /* a helper function to draw graphic symbols at start point or end point of * an item. @@ -81,6 +80,7 @@ inline void drawMarker( EDA_RECT* aClipBox, wxDC* aDC, 0, GREEN, GREEN ); } + /* Draws the item list created by BuildWorkSheetGraphicList * aClipBox = the clipping rect, or NULL if no clipping * aDC = the current Device Context @@ -172,6 +172,7 @@ void WS_DRAW_ITEM_LIST::Draw( EDA_RECT* aClipBox, wxDC* aDC ) } } + WS_DRAW_ITEM_TEXT::WS_DRAW_ITEM_TEXT( WORKSHEET_DATAITEM* aParent, wxString& aText, wxPoint aPos, wxSize aSize, int aPenWidth, EDA_COLOR_T aColor, @@ -185,20 +186,29 @@ WS_DRAW_ITEM_TEXT::WS_DRAW_ITEM_TEXT( WORKSHEET_DATAITEM* aParent, SetBold( aBold ); } -void WS_DRAW_ITEM_TEXT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) + +void WS_DRAW_ITEM_TEXT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { - Draw( aClipBox, aDC, wxPoint(0,0), - GetColor(), UNSPECIFIED_DRAWMODE, FILLED, UNSPECIFIED_COLOR ); + Draw( aClipBox, aDC, aOffset, + aColor == UNSPECIFIED_COLOR ? GetColor() : aColor, + aDrawMode == UNSPECIFIED_DRAWMODE ? GR_COPY : aDrawMode, + FILLED, UNSPECIFIED_COLOR ); } -// return true if the point aPosition is on the text + bool WS_DRAW_ITEM_TEXT::HitTest( const wxPoint& aPosition) const { return EDA_TEXT::TextHitTest( aPosition, 0 ); } -/* return true if the point aPosition is on the starting point of this item - */ + +bool WS_DRAW_ITEM_TEXT::HitTest( const EDA_RECT& aRect ) const +{ + return EDA_TEXT::TextHitTest( aRect, 0, 0 ); +} + + bool WS_DRAW_ITEM_TEXT::HitTestStartPoint( const wxPoint& aPosition) { wxPoint pos = GetTextPosition(); @@ -210,25 +220,61 @@ bool WS_DRAW_ITEM_TEXT::HitTestStartPoint( const wxPoint& aPosition) return false; } -void WS_DRAW_ITEM_POLYGON::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) + +void WS_DRAW_ITEM_POLYGON::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { + std::vector points_moved; + wxPoint *points; + + if( aOffset.x || aOffset.y ) + { + for( auto point: m_Corners ) + points_moved.push_back( point + aOffset ); + points = &points_moved[0]; + } + else + { + points = &m_Corners[0]; + } + + auto color = ( aColor == UNSPECIFIED_COLOR ) ? GetColor() : aColor; + + GRSetDrawMode( aDC, ( aDrawMode == UNSPECIFIED_DRAWMODE ? GR_COPY : aDrawMode ) ); GRPoly( aClipBox, aDC, - m_Corners.size(), &m_Corners[0], + m_Corners.size(), points, IsFilled() ? FILLED_SHAPE : NO_FILL, GetPenWidth(), - GetColor(), GetColor() ); + color, color ); + GRSetDrawMode( aDC, GR_COPY ); } -// return true if the point aPosition is inside one of polygons -#include + bool WS_DRAW_ITEM_POLYGON::HitTest( const wxPoint& aPosition) const { return TestPointInsidePolygon( &m_Corners[0], m_Corners.size(), aPosition ); } -/* return true if the point aPosition is on the starting point of this item - */ + +bool WS_DRAW_ITEM_POLYGON::HitTest( const EDA_RECT& aRect ) const +{ + // Intersection of two polygons is nontrivial. Test if the rectangle intersects + // each line, instead. + + if( m_Corners.size() < 2 ) + return false; + + for( size_t i = 1; i < m_Corners.size(); ++i ) + { + if( aRect.Intersects( m_Corners[i - 1], m_Corners[i] ) ) + return true; + } + + return false; +} + + bool WS_DRAW_ITEM_POLYGON::HitTestStartPoint( const wxPoint& aPosition) { wxPoint pos = GetPosition(); @@ -240,16 +286,21 @@ bool WS_DRAW_ITEM_POLYGON::HitTestStartPoint( const wxPoint& aPosition) return false; } -void WS_DRAW_ITEM_RECT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) + +void WS_DRAW_ITEM_RECT::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { + GRSetDrawMode( aDC, ( aDrawMode == UNSPECIFIED_DRAWMODE ? GR_COPY : aDrawMode ) ); GRRect( aClipBox, aDC, - GetStart().x, GetStart().y, - GetEnd().x, GetEnd().y, - GetPenWidth(), GetColor() ); + GetStart().x + aOffset.x, GetStart().y + aOffset.y, + GetEnd().x + aOffset.x, GetEnd().y + aOffset.y, + GetPenWidth(), + ( aColor == UNSPECIFIED_COLOR ) ? GetColor() : aColor ); + GRSetDrawMode( aDC, GR_COPY ); } -// return true if the point aPosition is on the rect outline -bool WS_DRAW_ITEM_RECT::HitTest( const wxPoint& aPosition) const + +bool WS_DRAW_ITEM_RECT::HitTest( const wxPoint& aPosition ) const { int dist = GetPenWidth()/2; wxPoint start = GetStart(); @@ -282,8 +333,40 @@ bool WS_DRAW_ITEM_RECT::HitTest( const wxPoint& aPosition) const return false; } -/* return true if the point aPosition is on the starting point of this item - */ + +bool WS_DRAW_ITEM_RECT::HitTest( const EDA_RECT& aRect ) const +{ + wxPoint start = GetStart(); + wxPoint end; + end.x = GetEnd().x; + end.y = start.y; + + // Upper line + if( aRect.Intersects( start, end ) ) + return true; + + // Right line + start = end; + end.y = GetEnd().y; + if( aRect.Intersects( start, end ) ) + return true; + + // lower line + start = end; + end.x = GetStart().x; + if( aRect.Intersects( start, end ) ) + return true; + + // left line + start = end; + end = GetStart(); + if( aRect.Intersects( start, end ) ) + return true; + + return false; +} + + bool WS_DRAW_ITEM_RECT::HitTestStartPoint( const wxPoint& aPosition) { wxPoint dist = GetStart() - aPosition; @@ -295,8 +378,7 @@ bool WS_DRAW_ITEM_RECT::HitTestStartPoint( const wxPoint& aPosition) return false; } -/* return true if the point aPosition is on the ending point of this item - */ + bool WS_DRAW_ITEM_RECT::HitTestEndPoint( const wxPoint& aPosition) { wxPoint pos = GetEnd(); @@ -309,20 +391,30 @@ bool WS_DRAW_ITEM_RECT::HitTestEndPoint( const wxPoint& aPosition) return false; } -void WS_DRAW_ITEM_LINE::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) + +void WS_DRAW_ITEM_LINE::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { - GRLine( aClipBox, aDC, GetStart(), GetEnd(), - GetPenWidth(), GetColor() ); + GRSetDrawMode( aDC, ( aDrawMode == UNSPECIFIED_DRAWMODE ) ? GR_COPY : aDrawMode ); + GRLine( aClipBox, aDC, GetStart() + aOffset, GetEnd() + aOffset, + GetPenWidth(), + ( aColor == UNSPECIFIED_COLOR ) ? GetColor() : aColor ); + GRSetDrawMode( aDC, GR_COPY ); } -// return true if the point aPosition is on the text + bool WS_DRAW_ITEM_LINE::HitTest( const wxPoint& aPosition) const { return TestSegmentHit( aPosition, GetStart(), GetEnd(), GetPenWidth()/2 ); } -/* return true if the point aPosition is on the starting point of this item - */ + +bool WS_DRAW_ITEM_LINE::HitTest( const EDA_RECT& aRect ) const +{ + return aRect.Intersects( GetStart(), GetEnd() ); +} + + bool WS_DRAW_ITEM_LINE::HitTestStartPoint( const wxPoint& aPosition) { wxPoint dist = GetStart() - aPosition; @@ -334,8 +426,7 @@ bool WS_DRAW_ITEM_LINE::HitTestStartPoint( const wxPoint& aPosition) return false; } -/* return true if the point aPosition is on the ending point of this item - */ + bool WS_DRAW_ITEM_LINE::HitTestEndPoint( const wxPoint& aPosition) { wxPoint dist = GetEnd() - aPosition; @@ -347,10 +438,7 @@ bool WS_DRAW_ITEM_LINE::HitTestEndPoint( const wxPoint& aPosition) return false; } -/* Locate graphic items in m_graphicList at location aPosition - * aList = the list of items found - * aPosition is the position (in user units) to locate items - */ + void WS_DRAW_ITEM_LIST::Locate( std::vector & aList, const wxPoint& aPosition) { @@ -378,22 +466,21 @@ void WS_DRAW_ITEM_LIST::Locate( std::vector & aList, } } -/** The function to draw a WS_DRAW_ITEM_BITMAP - */ -void WS_DRAW_ITEM_BITMAP::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) + +void WS_DRAW_ITEM_BITMAP::DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { WORKSHEET_DATAITEM_BITMAP* parent = (WORKSHEET_DATAITEM_BITMAP*)GetParent(); if( parent->m_ImageBitmap ) { - parent->m_ImageBitmap->DrawBitmap( NULL, aDC, m_pos ); + GRSetDrawMode( aDC, ( aDrawMode == UNSPECIFIED_DRAWMODE ) ? GR_COPY : aDrawMode ); + parent->m_ImageBitmap->DrawBitmap( NULL, aDC, m_pos + aOffset ); + GRSetDrawMode( aDC, GR_COPY ); } } -/** - * Virtual function - * return true if the point aPosition is on bitmap - */ + bool WS_DRAW_ITEM_BITMAP::HitTest( const wxPoint& aPosition) const { const WORKSHEET_DATAITEM_BITMAP* parent = static_cast( GetParent() ); @@ -407,6 +494,19 @@ bool WS_DRAW_ITEM_BITMAP::HitTest( const wxPoint& aPosition) const } +bool WS_DRAW_ITEM_BITMAP::HitTest( const EDA_RECT& aRect ) const +{ + const WORKSHEET_DATAITEM_BITMAP* parent = static_cast( GetParent() ); + + if( parent->m_ImageBitmap == NULL ) + return false; + + EDA_RECT rect = parent->m_ImageBitmap->GetBoundingBox(); + rect.Move( m_pos ); + return rect.Intersects( aRect ); +} + + /** * return true if the point aPosition is on the reference point of this item. */ diff --git a/include/worksheet_shape_builder.h b/include/worksheet_shape_builder.h index a54a3612db..6ff408eded 100644 --- a/include/worksheet_shape_builder.h +++ b/include/worksheet_shape_builder.h @@ -88,7 +88,16 @@ public: /** The function to draw a WS_DRAW_ITEM */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ) = 0; + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC) + { + wxPoint offset( 0, 0 ); + DrawWsItem( aClipBox, aDC, offset, UNSPECIFIED_DRAWMODE, UNSPECIFIED_COLOR ); + } + + /// More advanced version of DrawWsItem. This is what must be + /// defined in the derived type. + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ) = 0; /** * Abstract function: should exist for derived items @@ -96,6 +105,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const = 0; + /** + * Abstract function: should exist for derived items + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const = 0; + /** * Abstract function: should exist for derived items * return true if the point aPosition is near the starting point of this item, @@ -143,7 +158,8 @@ public: /** The function to draw a WS_DRAW_ITEM_LINE */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ); + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ); /** * Virtual function @@ -151,6 +167,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const; + /** + * Virtual function + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const; + /** * return true if the point aPosition is on the starting point of this item. */ @@ -193,7 +215,8 @@ public: /** The function to draw a WS_DRAW_ITEM_POLYGON */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ); + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ); /** * Virtual function @@ -201,6 +224,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const; + /** + * Virtual function + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const; + /** * return true if the point aPosition is on the starting point of this item. */ @@ -221,7 +250,8 @@ public: /** The function to draw a WS_DRAW_ITEM_RECT */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ); + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ); /** * Virtual function @@ -229,6 +259,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const; + /** + * Virtual function + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const; + /** * return true if the point aPosition is on the starting point of this item. */ @@ -255,7 +291,8 @@ public: /** The function to draw a WS_DRAW_ITEM_TEXT */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ); + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ); // Accessors: int GetPenWidth() { return GetThickness(); } @@ -266,6 +303,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const; + /** + * Virtual function + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const; + /** * return true if the point aPosition is on the starting point of this item. */ @@ -293,7 +336,8 @@ public: /** The function to draw a WS_DRAW_ITEM_BITMAP */ - virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC ); + virtual void DrawWsItem( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, + GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ); /** * Virtual function @@ -301,6 +345,12 @@ public: */ virtual bool HitTest( const wxPoint& aPosition) const; + /** + * Virtual function + * return true if the rect aRect intersects on the item + */ + virtual bool HitTest( const EDA_RECT& aRect ) const; + /** * return true if the point aPosition is on the reference point of this item. */ @@ -457,6 +507,11 @@ public: return NULL; } + void GetAllItems( std::vector* aList ) + { + *aList = m_graphicList; + } + /** * Draws the item list created by BuildWorkSheetGraphicList * @param aClipBox = the clipping rect, or NULL if no clipping diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index 69f9433177..70ebc9a5d1 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -28,6 +28,7 @@ set( PL_EDITOR_SRCS hotkeys.cpp menubar.cpp toolbars_pl_editor.cpp + block.cpp ) set( PL_EDITOR_EXTRA_SRCS diff --git a/pagelayout_editor/block.cpp b/pagelayout_editor/block.cpp new file mode 100644 index 0000000000..993443bd98 --- /dev/null +++ b/pagelayout_editor/block.cpp @@ -0,0 +1,235 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2016 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 pagelayout_editor/block.cpp + * @brief Block operations + */ + + +#include +#include +#include +#include +#include +#include + + +static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, + bool erase ); + +static void DrawMovingItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC ); + +static PL_EDITOR_FRAME* block_frame = NULL; + + +int PL_EDITOR_FRAME::BlockCommand( EDA_KEY key ) +{ + int cmd = 0; + + switch( key ) + { + default: + cmd = key & 0x255; + break; + + case 0: + cmd = BLOCK_MOVE; + break; + + case GR_KB_SHIFT: + case GR_KB_CTRL: + case GR_KB_SHIFTCTRL: + case GR_KB_ALT: + break; + + case MOUSE_MIDDLE: + cmd = BLOCK_ZOOM; + break; + } + + return cmd; +} + + +void PL_EDITOR_FRAME::HandleBlockPlace( wxDC* DC ) +{ + wxASSERT( m_canvas->IsMouseCaptured() ); + + GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP ); + + switch( GetScreen()->m_BlockLocate.GetCommand() ) + { + case BLOCK_MOVE: /* Move */ + if( m_canvas->IsMouseCaptured() ) + m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); + + Block_Move( DC ); + GetScreen()->m_BlockLocate.ClearItemsList(); + break; + + default: + wxFAIL_MSG( wxT("HandleBlockPlace: Unexpected block command") ); + break; + } + + m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); + GetScreen()->SetModify(); + GetScreen()->ClearBlockCommand(); + + wxASSERT( GetScreen()->m_BlockLocate.GetCount() == 0 ); + + DisplayToolMsg( wxEmptyString ); +} + + +bool PL_EDITOR_FRAME::HandleBlockEnd( wxDC* DC ) +{ + bool nextcmd = false; + bool zoom_command = false; + + if( m_canvas->IsMouseCaptured() ) + + block_frame = this; + switch( GetScreen()->m_BlockLocate.GetCommand() ) + { + case BLOCK_MOVE: /* Move */ + GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE ); + nextcmd = true; + m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); + m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines ); + m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); + break; + + case BLOCK_ZOOM: /* Window Zoom */ + zoom_command = true; + break; + + default: + break; + } + + if( ! nextcmd ) + { + block_frame = NULL; + GetScreen()->ClearBlockCommand(); + m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, + false ); + } + + if( zoom_command ) + Window_Zoom( GetScreen()->m_BlockLocate ); + + return nextcmd ; +} + + +static void DrawMovingItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) +{ + // Get items + WS_DRAW_ITEM_LIST drawList; + auto screen = static_cast( aPanel->GetScreen() ); + drawList.SetPenSize( 0 ); + drawList.SetMilsToIUfactor( IU_PER_MILS ); + drawList.SetSheetNumber( screen->m_ScreenNumber ); + drawList.SetSheetCount( screen->m_NumberOfScreens ); + drawList.SetFileName( block_frame->GetCurrFileName() ); + drawList.SetSheetName( block_frame->GetScreenDesc() ); + drawList.BuildWorkSheetGraphicList( block_frame->GetPageSettings(), block_frame->GetTitleBlock(), RED, RED ); + std::vector items; + drawList.GetAllItems( &items ); + + // Draw items + for( auto item: items ) + { + if( item->HitTest( screen->m_BlockLocate ) ) + { + item->DrawWsItem( NULL, aDC, screen->m_BlockLocate.GetMoveVector(), + g_XorMode, g_GhostColor ); + } + } +} + + +/* Traces the outline of the block structures of a repositioning move + */ +static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPositon, + bool aErase ) +{ + auto screen = aPanel->GetScreen(); + auto block = &screen->m_BlockLocate; + + if( aErase ) + { + block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() ); + DrawMovingItems( aPanel, aDC ); + } + + block->SetMoveVector( aPanel->GetParent()->GetCrossHairPosition() - block->GetLastCursorPosition() ); + block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() ); + DrawMovingItems( aPanel, aDC ); +} + + +void PL_EDITOR_FRAME::Block_Move( wxDC* DC ) +{ + wxPoint delta; + wxPoint oldpos; + + oldpos = GetCrossHairPosition(); + m_canvas->SetMouseCaptureCallback( NULL ); + + SetCrossHairPosition( oldpos ); + m_canvas->MoveCursorToCrossHair(); + GetScreen()->SetModify(); + GetScreen()->m_BlockLocate.Normalize(); + + // Calculate displacement vectors. + delta = GetScreen()->m_BlockLocate.GetMoveVector(); + + // Get the items + WS_DRAW_ITEM_LIST drawList; + auto screen = static_cast( GetScreen() ); + drawList.SetPenSize( 0 ); + drawList.SetMilsToIUfactor( IU_PER_MILS ); + drawList.SetSheetNumber( screen->m_ScreenNumber ); + drawList.SetSheetCount( screen->m_NumberOfScreens ); + drawList.SetFileName( GetCurrFileName() ); + drawList.SetSheetName( GetScreenDesc() ); + drawList.BuildWorkSheetGraphicList( GetPageSettings(), GetTitleBlock(), RED, RED ); + std::vector items; + drawList.GetAllItems( &items ); + + // Move items in block + SaveCopyInUndoList(); + for( auto item: items ) + { + if( item->HitTest( screen->m_BlockLocate ) ) + { + auto data_item = item->GetParent(); + data_item->MoveToUi( data_item->GetStartPosUi() + delta ); + } + } + + m_canvas->Refresh( true ); +} diff --git a/pagelayout_editor/events_functions.cpp b/pagelayout_editor/events_functions.cpp index 1c6ec10e20..79d4cc2824 100644 --- a/pagelayout_editor/events_functions.cpp +++ b/pagelayout_editor/events_functions.cpp @@ -1,11 +1,8 @@ -/** - * @file pagelayout_editor/events_functions.cpp - * @brief page layout editor command event functions. - */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * * This program is free software; you can redistribute it and/or @@ -26,6 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file pagelayout_editor/events_functions.cpp + * @brief page layout editor command event functions. + */ + #include #include #include @@ -88,7 +90,9 @@ BEGIN_EVENT_TABLE( PL_EDITOR_FRAME, EDA_DRAW_FRAME ) EVT_TOOL( wxID_PREVIEW, PL_EDITOR_FRAME::ToPrinter ) EVT_TOOL( ID_SHEET_SET, PL_EDITOR_FRAME::Process_Special_Functions ) EVT_TOOL( ID_SHOW_REAL_MODE, PL_EDITOR_FRAME::OnSelectTitleBlockDisplayMode ) - EVT_TOOL( ID_SHOW_PL_EDITOR_MODE, PL_EDITOR_FRAME::OnSelectTitleBlockDisplayMode ) + // EVT_TOOL( ID_SHOW_PL_EDITOR_MODE, PL_EDITOR_FRAME::OnSelectTitleBlockDisplayMode ) // mentioned below + EVT_TOOL( ID_NO_TOOL_SELECTED, PL_EDITOR_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_ZOOM_SELECTION, PL_EDITOR_FRAME::Process_Special_Functions ) EVT_CHOICE( ID_SELECT_COORDINATE_ORIGIN, PL_EDITOR_FRAME::OnSelectCoordOriginCorner) EVT_CHOICE( ID_SELECT_PAGE_NUMBER, PL_EDITOR_FRAME::Process_Special_Functions) @@ -98,6 +102,8 @@ BEGIN_EVENT_TABLE( PL_EDITOR_FRAME, EDA_DRAW_FRAME ) EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE, PL_EDITOR_FRAME::Process_Special_Functions ) + EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, PL_EDITOR_FRAME::OnUpdateSelectTool ) + EVT_UPDATE_UI( ID_ZOOM_SELECTION, PL_EDITOR_FRAME::OnUpdateSelectTool ) EVT_UPDATE_UI( ID_SHOW_REAL_MODE, PL_EDITOR_FRAME::OnUpdateTitleBlockDisplayNormalMode ) EVT_UPDATE_UI( ID_SHOW_PL_EDITOR_MODE, PL_EDITOR_FRAME::OnUpdateTitleBlockDisplaySpecialMode ) @@ -122,6 +128,10 @@ void PL_EDITOR_FRAME::Process_Special_Functions( wxCommandEvent& event ) SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); break; + case ID_ZOOM_SELECTION: + SetToolID( ID_ZOOM_SELECTION, wxCURSOR_MAGNIFIER, _( "Zoom to selection" ) ); + break; + case ID_SELECT_PAGE_NUMBER: m_canvas->Refresh(); break; @@ -587,3 +597,10 @@ void PL_EDITOR_FRAME::OnUpdateTitleBlockDisplaySpecialMode( wxUpdateUIEvent& eve { event.Check( WORKSHEET_DATAITEM::m_SpecialMode == true ); } + + +void PL_EDITOR_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent ) +{ + if( aEvent.GetEventObject() == m_mainToolBar ) + aEvent.Check( GetToolId() == aEvent.GetId() ); +} diff --git a/pagelayout_editor/hotkeys.cpp b/pagelayout_editor/hotkeys.cpp index 095553e2b8..d9ab9086ce 100644 --- a/pagelayout_editor/hotkeys.cpp +++ b/pagelayout_editor/hotkeys.cpp @@ -1,10 +1,8 @@ -/** - * @file pagelayout_editor/hotkeys.cpp - */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * * This program is free software; you can redistribute it and/or @@ -25,6 +23,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file pagelayout_editor/hotkeys.cpp + */ + #include #include #include @@ -75,6 +77,7 @@ static EDA_HOTKEY HkZoomCenter( _HKI( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4 static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3, ID_ZOOM_REDRAW ); static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2, ID_POPUP_ZOOM_OUT ); static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, WXK_F1, ID_POPUP_ZOOM_IN ); +static EDA_HOTKEY HkZoomSelection( _HKI( "Zoom to Selection" ), HK_ZOOM_SELECTION, '@', ID_ZOOM_SELECTION ); static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' ); static EDA_HOTKEY HkMoveItem( _HKI( "Move Item" ), HK_MOVE_ITEM, 'M', ID_POPUP_ITEM_MOVE ); static EDA_HOTKEY HkPlaceItem( _HKI( "Place Item" ), HK_PLACE_ITEM, 'P', ID_POPUP_ITEM_PLACE ); @@ -94,7 +97,7 @@ EDA_HOTKEY* s_Common_Hotkey_List[] = { &HkHelp, &HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomCenter, - &HkZoomAuto, &HkResetLocalCoord, + &HkZoomAuto, &HkZoomSelection, &HkResetLocalCoord, &HkUndo, &HkRedo, &HkMouseLeftClick, &HkMouseLeftDClick, diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 1a6f9711cf..c305e7948a 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -1,11 +1,8 @@ -/** - * @file pl_editor_frame.cpp - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * * This program is free software; you can redistribute it and/or @@ -26,6 +23,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file pl_editor_frame.cpp + */ + #include #include #include @@ -71,7 +72,7 @@ PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_propertiesFrameWidth = 200; if( m_canvas ) - m_canvas->SetEnableBlockCommands( false ); + m_canvas->SetEnableBlockCommands( true ); // Give an icon wxIcon icon; diff --git a/pagelayout_editor/pl_editor_frame.h b/pagelayout_editor/pl_editor_frame.h index 67a5a29fd4..12e44b6da5 100644 --- a/pagelayout_editor/pl_editor_frame.h +++ b/pagelayout_editor/pl_editor_frame.h @@ -1,11 +1,8 @@ -/** - * @file pl_editor_frame.h - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * * This program is free software; you can redistribute it and/or @@ -26,6 +23,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file pl_editor_frame.h + */ + #ifndef _PL_EDITOR_FRAME_H #define _PL_EDITOR_FRAME_H @@ -229,6 +230,43 @@ public: void OnUpdateTitleBlockDisplayNormalMode( wxUpdateUIEvent& event ); void OnUpdateTitleBlockDisplaySpecialMode( wxUpdateUIEvent& event ); + void OnUpdateSelectTool( wxUpdateUIEvent& aEvent ); + + /** + * Function BlockCommand + * returns the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to + * the \a aKey (ALT, SHIFT ALT ..) + */ + virtual int BlockCommand( EDA_KEY key ); + + /** + * Function HandleBlockPlace + * handles the block place command. + */ + virtual void HandleBlockPlace( wxDC* DC ); + + /** + * Function HandleBlockEnd( ) + * handles the end of a block command, + * It is called at the end of the definition of the area of a block. + * Depending on the current block command, this command is executed + * or parameters are initialized to prepare a call to HandleBlockPlace + * in GetScreen()->m_BlockLocate + * + * @return false if no item selected, or command finished, + * true if some items found and HandleBlockPlace must be called later. + */ + virtual bool HandleBlockEnd( wxDC* DC ); + + /** + * Function Block_Move + * moves all items within the selected block. + * New location is determined by the current offset from the selected + * block's original location. + * + * @param DC A device context to draw on. + */ + void Block_Move( wxDC* DC ); /** * Function OnQuit diff --git a/pagelayout_editor/toolbars_pl_editor.cpp b/pagelayout_editor/toolbars_pl_editor.cpp index ceac7fb97b..3370e5c383 100644 --- a/pagelayout_editor/toolbars_pl_editor.cpp +++ b/pagelayout_editor/toolbars_pl_editor.cpp @@ -1,11 +1,7 @@ -/** - * @file toolbars_pl_editor.cpp - * @brief Build tool bars - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * + * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2013 CERN * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * @@ -27,6 +23,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file toolbars_pl_editor.cpp + * @brief Build tool bars + */ + #include #include @@ -87,6 +88,14 @@ void PL_EDITOR_FRAME::ReCreateHToolbar( void ) msg = AddHotkeyName( _( "Zoom auto" ), PlEditorHokeysDescr, HK_ZOOM_AUTO, IS_COMMENT ); m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg ); + // Zoom-to-selection + m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ), + wxEmptyString, wxITEM_CHECK ); + + m_mainToolBar->AddTool( ID_ZOOM_SELECTION, wxEmptyString, KiBitmap( zoom_area_xpm ), + _( "Zoom to selection" ), wxITEM_CHECK ); + // Display mode switch m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_SHOW_REAL_MODE, wxEmptyString,