Continous mode for drawing tools (i.e. they do not finish after adding a single object).

This commit is contained in:
Maciej Suminski 2014-02-19 13:51:32 +01:00
parent a802ca87e0
commit 57c69b41db
4 changed files with 287 additions and 175 deletions

View File

@ -207,7 +207,7 @@ public:
///> Returns information about difference between current mouse cursor position and the place ///> Returns information about difference between current mouse cursor position and the place
///> where dragging has started. ///> where dragging has started.
const VECTOR2D Delta() const const VECTOR2D& Delta() const
{ {
assert( m_category == TC_MOUSE ); // this should be used only with mouse events assert( m_category == TC_MOUSE ); // this should be used only with mouse events
return m_mouseDelta; return m_mouseDelta;

View File

@ -26,6 +26,7 @@
#include "class_board.h" #include "class_board.h"
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <id.h>
#include <view/view_controls.h> #include <view/view_controls.h>
#include <pcbcommon.h> #include <pcbcommon.h>
#include <pcb_painter.h> #include <pcb_painter.h>
@ -464,6 +465,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent )
ctls->ShowCursor( false ); ctls->ShowCursor( false );
ctls->ForceCursorPosition( false ); ctls->ForceCursorPosition( false );
getEditFrame<PCB_EDIT_FRAME>()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }

View File

@ -26,6 +26,7 @@
#include "common_actions.h" #include "common_actions.h"
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <id.h>
#include <confirm.h> #include <confirm.h>
#include <view/view_group.h> #include <view/view_group.h>
@ -83,13 +84,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
double startAngle; // angle of the first arc line double startAngle; // angle of the first arc line
VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
// Init the new item attributes DRAWSEGMENT* arc;
DRAWSEGMENT* arc = new DRAWSEGMENT( m_board );
arc->SetShape( S_ARC );
arc->SetAngle( 0.0 );
arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth );
arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) );
DRAWSEGMENT helperLine; DRAWSEGMENT helperLine;
helperLine.SetShape( S_SEGMENT ); helperLine.SetShape( S_SEGMENT );
helperLine.SetLayer( DRAW_N ); helperLine.SetLayer( DRAW_N );
@ -120,11 +115,19 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
if( step != SET_ORIGIN ) // start from the beginning
{
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
delete arc; delete arc;
step = SET_ORIGIN;
}
else
break; break;
} }
else if( evt->IsKeyUp() ) else if( evt->IsKeyUp() && step != SET_ORIGIN )
{ {
int width = arc->GetWidth(); int width = arc->GetWidth();
@ -161,9 +164,17 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
} }
else else
{ {
helperLine.SetStart( arc->GetCenter() ); // Init the new item attributes
arc = new DRAWSEGMENT( m_board );
arc->SetShape( S_ARC );
arc->SetAngle( 0.0 );
arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth );
arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) );
arc->SetLayer( layer ); arc->SetLayer( layer );
helperLine.SetStart( arc->GetCenter() );
helperLine.SetEnd( arc->GetCenter() );
preview.Add( arc ); preview.Add( arc );
preview.Add( &helperLine ); preview.Add( &helperLine );
@ -200,6 +211,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( arc, UR_NEW ); m_frame->SaveCopyInUndoList( arc, UR_NEW );
preview.Remove( arc );
preview.Remove( &helperLine );
} }
else else
--step; // one another chance to draw a proper arc --step; // one another chance to draw a proper arc
@ -208,17 +222,16 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
} }
if( ++step == FINISHED ) if( ++step == FINISHED )
break; {
step = SET_ORIGIN;
m_controls->SetAutoPan( false );
}
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() )
{ {
switch( step ) switch( step )
{ {
case SET_ORIGIN:
arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) );
break;
case SET_END: case SET_END:
helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) );
@ -226,10 +239,10 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
case SET_ANGLE: case SET_ANGLE:
{ {
// Compute the current angle
VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - arc->GetCenter() ); VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - arc->GetCenter() );
double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle );
// Adjust the new angle to (counter)clockwise setting
if( clockwise && newAngle < 0.0 ) if( clockwise && newAngle < 0.0 )
newAngle += 3600.0; newAngle += 3600.0;
else if( !clockwise && newAngle > 0.0 ) else if( !clockwise && newAngle > 0.0 )
@ -251,6 +264,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -258,17 +272,10 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
{ {
// Init the new item attributes TEXTE_PCB* text;
TEXTE_PCB* text = m_frame->CreateTextePcb( NULL );
if( text == NULL )
{
setTransitions();
return 0;
}
// Add a VIEW_GROUP that serves as a preview for the new item // Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view ); KIGFX::VIEW_GROUP preview( m_view );
preview.Add( text );
m_view->Add( &preview ); m_view->Add( &preview );
m_controls->ShowCursor( true ); m_controls->ShowCursor( true );
@ -276,6 +283,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
m_controls->SetAutoPan( true ); m_controls->SetAutoPan( true );
Activate(); Activate();
bool created = false;
// Main loop: keep receiving events // Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
@ -284,12 +292,20 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
// it was already added by CreateTextPcb() if( created )
m_board->Delete( text ); {
// Delete the old text and have another try
m_board->Delete( text ); // it was already added by CreateTextPcb()
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
created = false;
m_controls->ShowCursor( true );
}
else
break; break;
} }
else if( evt->Category() == TC_COMMAND ) else if( created && evt->Category() == TC_COMMAND )
{ {
if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{ {
@ -304,6 +320,18 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{
if( !created )
{
// Init the new item attributes
text = m_frame->CreateTextePcb( NULL );
if( text == NULL )
continue;
m_controls->ShowCursor( false );
preview.Add( text );
}
else
{ {
assert( text->GetText().Length() > 0 ); assert( text->GetText().Length() > 0 );
assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
@ -316,10 +344,14 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( text, UR_NEW ); m_frame->SaveCopyInUndoList( text, UR_NEW );
break; preview.Remove( text );
m_controls->ShowCursor( true );
} }
else if( evt->IsMotion() ) created = !created;
}
else if( created && evt->IsMotion() )
{ {
text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
@ -334,6 +366,7 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -341,19 +374,8 @@ int DRAWING_TOOL::DrawText( TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent )
{ {
DIMENSION* dimension = new DIMENSION( m_board ); DIMENSION* dimension;
int width, maxThickness;
// Init the new item attributes
dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize );
int width = m_board->GetDesignSettings().m_PcbTextWidth;
int maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() );
if( width > maxThickness )
width = maxThickness;
dimension->Text().SetThickness( width );
dimension->SetWidth( width );
dimension->AdjustDimensionDetails();
// Add a VIEW_GROUP that serves as a preview for the new item // Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view ); KIGFX::VIEW_GROUP preview( m_view );
@ -380,11 +402,19 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent )
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
if( step != SET_ORIGIN ) // start from the beginning
{
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
delete dimension; delete dimension;
step = SET_ORIGIN;
}
else
break; break;
} }
else if( evt->IsKeyUp() ) else if( evt->IsKeyUp() && step != SET_ORIGIN )
{ {
width = dimension->GetWidth(); width = dimension->GetWidth();
@ -405,19 +435,33 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent )
{ {
LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer;
if( IsCopperLayer( layer ) ) if( IsCopperLayer( layer ) || layer == EDGE_N )
{ {
DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); DisplayInfoMessage( NULL, _( "Dimension not allowed on Copper or Edge Cut layers" ) );
--step; --step;
} }
else else
{ {
m_controls->SetAutoPan( true ); // Init the new item attributes
dimension = new DIMENSION( m_board );
dimension->SetLayer( layer ); dimension->SetLayer( layer );
dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) ); dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize );
width = m_board->GetDesignSettings().m_PcbTextWidth;
maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() );
if( width > maxThickness )
width = maxThickness;
dimension->Text().SetThickness( width );
dimension->SetWidth( width );
dimension->AdjustDimensionDetails();
preview.Add( dimension ); preview.Add( dimension );
m_controls->SetAutoPan( true );
} }
} }
break; break;
@ -441,13 +485,18 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent )
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( dimension, UR_NEW ); m_frame->SaveCopyInUndoList( dimension, UR_NEW );
preview.Remove( dimension );
} }
} }
break; break;
} }
if( ++step == FINISHED ) if( ++step == FINISHED )
break; {
step = SET_ORIGIN;
m_controls->SetAutoPan( false );
}
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() )
@ -476,12 +525,16 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent )
} }
} }
if( step != SET_ORIGIN )
delete dimension;
m_controls->ShowCursor( false ); m_controls->ShowCursor( false );
m_controls->SetSnapping( false ); m_controls->SetSnapping( false );
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -527,10 +580,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent )
cursorPos = m_controls->GetCursorPosition(); cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() ) if( evt->IsCancel() )
{
delete target;
break; break;
}
else if( evt->IsKeyUp() ) else if( evt->IsKeyUp() )
{ {
@ -557,7 +607,11 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent )
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( target, UR_NEW ); m_frame->SaveCopyInUndoList( target, UR_NEW );
break; preview.Remove( target );
// Create next PCB_TARGET
target = new PCB_TARGET( *target );
preview.Add( target );
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() )
@ -567,11 +621,14 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent )
} }
} }
delete target;
m_controls->SetSnapping( false ); m_controls->SetSnapping( false );
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -579,42 +636,42 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent )
int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent )
{ {
MODULE* module = m_frame->LoadModuleFromLibrary( wxEmptyString, MODULE* module;
m_frame->GetFootprintLibraryTable(), true, NULL );
if( module == NULL )
{
setTransitions();
return 0;
}
// Init the new item attributes
VECTOR2I cursorPos = m_controls->GetCursorPosition();
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add a VIEW_GROUP that serves as a preview for the new item // Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view ); KIGFX::VIEW_GROUP preview( m_view );
preview.Add( module );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ), &preview ) );
m_view->Add( &preview ); m_view->Add( &preview );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true ); m_controls->SetSnapping( true );
m_controls->SetAutoPan( true ); m_controls->SetAutoPan( true );
Activate(); Activate();
bool created = false;
// Main loop: keep receiving events // Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
{ {
cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
m_board->Delete( module ); if( created )
{
m_board->Delete( module ); // it was added by LoadModuleFromLibrary
m_controls->ShowCursor( true );
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
created = false;
}
else
break; break;
} }
else if( evt->Category() == TC_COMMAND ) else if( created && evt->Category() == TC_COMMAND )
{ {
if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{ {
@ -629,6 +686,27 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent )
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{
if( !created )
{
// Init the new item attributes
module = m_frame->LoadModuleFromLibrary( wxEmptyString,
m_frame->GetFootprintLibraryTable(),
true, NULL );
if( module == NULL )
continue;
m_controls->ShowCursor( false );
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Add all the drawable parts to preview
preview.Add( module );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Add ),
&preview ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else
{ {
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) ); module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), m_view ) );
m_view->Add( module ); m_view->Add( module );
@ -637,21 +715,31 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent )
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_NEW ); m_frame->SaveCopyInUndoList( module, UR_NEW );
break; // Remove from preview
preview.Remove( module );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW_GROUP::Remove ),
&preview ) );
m_controls->ShowCursor( true );
} }
else if( evt->IsMotion() ) created = !created;
}
else if( created && evt->IsMotion() )
{ {
module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
} }
} }
m_controls->ShowCursor( false );
m_controls->SetSnapping( false ); m_controls->SetSnapping( false );
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -662,12 +750,8 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
// Only two shapes are currently supported // Only two shapes are currently supported
assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
// Init the new item attributes DRAWSEGMENT* graphic = NULL;
DRAWSEGMENT* graphic = new DRAWSEGMENT( m_board ); DRAWSEGMENT line45;
graphic->SetShape( (STROKE_T) aShape );
graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth );
DRAWSEGMENT line45( *graphic ); // used only for direction 45 mode with lines
// Add a VIEW_GROUP that serves as a preview for the new item // Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view ); KIGFX::VIEW_GROUP preview( m_view );
@ -678,9 +762,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
Activate(); Activate();
bool started = false;
bool direction45 = false; // 45 degrees only mode bool direction45 = false; // 45 degrees only mode
int addedSegments = 0; int addedSegments = 0;
bool created = false;
// Main loop: keep receiving events // Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
@ -689,7 +773,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I cursorPos = m_controls->GetCursorPosition();
// Enable 45 degrees lines only mode by holding control // Enable 45 degrees lines only mode by holding control
if( direction45 != ( evt->Modifier( MD_CTRL ) && aShape == S_SEGMENT && started ) ) if( direction45 != evt->Modifier( MD_CTRL ) && created && aShape == S_SEGMENT )
{ {
direction45 = evt->Modifier( MD_CTRL ); direction45 = evt->Modifier( MD_CTRL );
@ -710,16 +794,20 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
if( direction45 ) if( direction45 )
preview.Remove( &line45 ); preview.Remove( &line45 ); // prevent line45 from being deleted
preview.FreeItems(); preview.FreeItems();
if( !started ) updatePreview = true;
delete graphic;
if( !created )
break; break;
// We did not exit the loop? So go once again
created = false;
m_controls->SetAutoPan( false );
} }
else if( evt->IsKeyUp() ) else if( created && evt->IsKeyUp() )
{ {
int width = graphic->GetWidth(); int width = graphic->GetWidth();
@ -734,7 +822,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
if( !started ) if( !created )
{ {
LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer;
@ -744,15 +832,23 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
} }
else else
{ {
m_controls->SetAutoPan( true ); // Init the new item attributes
graphic = new DRAWSEGMENT( m_board );
graphic->SetShape( (STROKE_T) aShape );
graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth );
graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
graphic->SetLayer( layer ); graphic->SetLayer( layer );
line45.SetLayer( layer );
preview.Add( graphic );
started = true; if( aShape == S_SEGMENT )
{
line45 = *graphic; // used only for direction 45 mode with lines
line45.SetLayer( layer );
}
preview.Add( graphic );
created = true;
m_controls->SetAutoPan( true );
} }
} }
else else
@ -765,15 +861,17 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
m_view->Add( graphic ); m_view->Add( graphic );
m_board->Add( graphic ); m_board->Add( graphic );
graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
preview.Remove( graphic );
++addedSegments;
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( graphic, UR_NEW ); m_frame->SaveCopyInUndoList( graphic, UR_NEW );
preview.Remove( graphic );
++addedSegments;
if( aContinous ) if( aContinous )
{ {
graphic = new DRAWSEGMENT( *graphic ); graphic = new DRAWSEGMENT( *graphic );
// Start the new line in the same spot where the previous one has ended // Start the new line in the same spot where the previous one has ended
graphic->SetStart( graphic->GetEnd() ); graphic->SetStart( graphic->GetEnd() );
@ -782,20 +880,24 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
preview.Add( graphic ); preview.Add( graphic );
} }
else else // start a new graphic
{ {
break; addedSegments = 0;
created = false;
m_controls->SetAutoPan( false );
} }
} }
else if( addedSegments > 0 ) // User has clicked twice in the same spot else if( addedSegments > 0 ) // User has clicked twice in the same spot
{ { // a clear sign that the current drawing is finished
delete graphic; // seems like a clear sign that the drawing is finished created = false; // but only if at least one graphic was created
break; // and we should remove the latest DRAWSEGMENT we have created preview.Remove( graphic ); // otherwise - force user to draw or cancel
delete graphic;
m_controls->SetAutoPan( false );
} }
} }
} }
else if( evt->IsMotion() && started ) else if( created && evt->IsMotion() )
{ {
// 45 degree lines // 45 degree lines
if( direction45 && aShape == S_SEGMENT ) if( direction45 && aShape == S_SEGMENT )
@ -814,7 +916,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
m_controls->SetSnapping( false ); m_controls->SetSnapping( false );
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_view->Remove( &preview ); m_view->Remove( &preview );
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }
@ -822,42 +926,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous )
int DRAWING_TOOL::drawZone( bool aKeepout ) int DRAWING_TOOL::drawZone( bool aKeepout )
{ {
ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); ZONE_CONTAINER* zone;
DRAWSEGMENT line45;
// Get the current, default settings for zones DRAWSEGMENT* helperLine; // we will need more than one helper line
ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings();
zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer;
// Show options dialog
ZONE_EDIT_T dialogResult;
if( aKeepout )
dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo );
else
{
if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) )
dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo );
else
dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo );
}
if( dialogResult == ZONE_ABORT )
{
delete zone;
setTransitions();
return 0;
}
// Apply the selected settings
zoneInfo.ExportSetting( *zone );
m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer );
// Helper line represents the currently drawn line of the zone polygon
DRAWSEGMENT* helperLine = new DRAWSEGMENT;
helperLine->SetShape( S_SEGMENT );
helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer );
helperLine->SetWidth( 1 );
DRAWSEGMENT line45( *helperLine );
// Add a VIEW_GROUP that serves as a preview for the new item // Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view ); KIGFX::VIEW_GROUP preview( m_view );
@ -865,7 +936,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
m_controls->ShowCursor( true ); m_controls->ShowCursor( true );
m_controls->SetSnapping( true ); m_controls->SetSnapping( true );
m_controls->SetAutoPan( true );
Activate(); Activate();
@ -873,7 +943,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
VECTOR2I origin; VECTOR2I origin;
int numPoints = 0; int numPoints = 0;
bool direction45 = false; // 45 degrees only mode bool direction45 = false; // 45 degrees only mode
bool cancelled = false;
// Main loop: keep receiving events // Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() ) while( OPT_TOOL_EVENT evt = Wait() )
@ -902,15 +971,28 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
if( evt->IsCancel() ) if( evt->IsCancel() )
{ {
cancelled = true; if( numPoints > 0 ) // cancel the current zone
{
delete zone;
m_controls->SetAutoPan( false );
if( direction45 )
preview.Remove( &line45 );
preview.FreeItems();
updatePreview = true;
numPoints = 0;
}
else // there is no zone currently drawn - just stop the tool
break; break;
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
// Check if it is double click / closing line (so we have to finish the zone)
if( lastCursorPos == cursorPos || ( numPoints > 0 && cursorPos == origin ) ) if( lastCursorPos == cursorPos || ( numPoints > 0 && cursorPos == origin ) )
{ {
if( numPoints > 2 ) if( numPoints > 2 ) // valid zone consists of more than 2 points
{ {
assert( zone->GetNumCorners() > 2 ); assert( zone->GetNumCorners() > 2 );
@ -930,23 +1012,56 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
m_frame->SaveCopyInUndoList( zone, UR_NEW ); m_frame->SaveCopyInUndoList( zone, UR_NEW );
} }
else else
{ delete zone;
// If there are less than 3 points, then it is not a valid zone
cancelled = true;
}
break; numPoints = 0;
m_controls->SetAutoPan( false );
preview.FreeItems();
updatePreview = true;
} }
else else
{ {
if( numPoints == 0 ) if( numPoints == 0 ) // it's the first click
{ {
// Get the current default settings for zones
ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings();
zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer;
// Show options dialog
ZONE_EDIT_T dialogResult;
if( aKeepout )
dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo );
else
{
if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) )
dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo );
else
dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo );
}
if( dialogResult == ZONE_ABORT )
continue;
// Apply the selected settings
zone = new ZONE_CONTAINER( m_board );
zoneInfo.ExportSetting( *zone );
m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer );
// Add the first point // Add the first point
zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer,
cursorPos.x, cursorPos.y, cursorPos.x, cursorPos.y,
zone->GetHatchStyle() ); zone->GetHatchStyle() );
helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
origin = cursorPos; origin = cursorPos;
// Helper line represents the currently drawn line of the zone polygon
helperLine = new DRAWSEGMENT;
helperLine->SetShape( S_SEGMENT );
helperLine->SetWidth( 1 );
helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer );
helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
line45 = *helperLine;
preview.Add( helperLine ); preview.Add( helperLine );
} }
else else
@ -956,15 +1071,15 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
helperLine->SetStart( helperLine->GetEnd() ); helperLine->SetStart( helperLine->GetEnd() );
preview.Add( helperLine ); preview.Add( helperLine );
} }
++numPoints;
++numPoints;
updatePreview = true; updatePreview = true;
} }
lastCursorPos = cursorPos; lastCursorPos = cursorPos;
} }
else if( evt->IsMotion() ) else if( evt->IsMotion() && numPoints > 0 )
{ {
// 45 degree lines // 45 degree lines
if( direction45 ) if( direction45 )
@ -985,14 +1100,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_view->Remove( &preview ); m_view->Remove( &preview );
// Clean
if( cancelled )
delete zone;
if( direction45 )
preview.Remove( &line45 );
preview.FreeItems();
setTransitions(); setTransitions();
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0; return 0;
} }

View File

@ -116,7 +116,7 @@ public:
/** /**
* Function PlaceModule() * Function PlaceModule()
* Displays a dialog to selected a module to be added and then allows user to set its position.. * Displays a dialog to selected a module to be added and then allows user to set its position.
*/ */
int PlaceModule( TOOL_EVENT& aEvent ); int PlaceModule( TOOL_EVENT& aEvent );