Merged lp:~cern-kicad/kicad/drawing_tool branch.

This commit is contained in:
Maciej Suminski 2014-05-13 10:19:37 +02:00
commit 009d28d48c
127 changed files with 9031 additions and 3914 deletions

View File

@ -477,6 +477,8 @@ if( KICAD_SKIP_BOOST )
message( FATAL_ERROR "Boost 1.54+ libraries are required." )
endif()
add_custom_target( boost ) # it is required to meet some further dependencies
message( WARNING "
WARNING: You decided to skip building boost library.
KiCad developers strongly advise you to build the bundled boost library, as it is known to work with KiCad.

View File

@ -29,7 +29,7 @@ add_custom_target(
set( GAL_SRCS
# Common part
drawpanel_gal.cpp
draw_panel_gal.cpp
painter.cpp
worksheet_viewitem.cpp
gal/graphics_abstraction_layer.cpp

View File

@ -175,13 +175,6 @@ void BASE_SCREEN::SetGridList( GRIDS& gridlist )
}
void BASE_SCREEN::GetGrids( GRIDS& aList )
{
for( size_t i = 0; i < m_grids.size(); i++ )
aList.push_back( m_grids[ i ] );
}
int BASE_SCREEN::SetGrid( const wxRealPoint& size )
{
wxASSERT( !m_grids.empty() );

View File

@ -19,8 +19,8 @@
// Default marquer shape:
#define M_SHAPE_SCALE 6 // default scaling factor for MarkerShapeCorners coordinates
#define CORNERS_COUNT 8
const int M_SHAPE_SCALE = 6; // default scaling factor for MarkerShapeCorners coordinates
const int CORNERS_COUNT = 8;
/* corners of the default shape
* actual coordinates are these values * .m_ScalingFactor
*/
@ -46,10 +46,10 @@ void MARKER_BASE::init()
m_Color = RED;
wxPoint start = MarkerShapeCorners[0];
wxPoint end = MarkerShapeCorners[0];
for( unsigned ii = 0; ii < CORNERS_COUNT; ii++ )
{
wxPoint corner = MarkerShapeCorners[ii];
m_Corners.push_back( corner );
start.x = std::min( start.x, corner.x);
start.y = std::min( start.y, corner.y);
end.x = std::max( end.x, corner.x);
@ -64,7 +64,6 @@ void MARKER_BASE::init()
MARKER_BASE::MARKER_BASE( const MARKER_BASE& aMarker )
{
m_Pos = aMarker.m_Pos;
m_Corners = aMarker.m_Corners;
m_MarkerType = aMarker.m_MarkerType;
m_Color = aMarker.m_Color;
m_ShapeBoundingBox = aMarker.m_ShapeBoundingBox;
@ -154,9 +153,9 @@ void MARKER_BASE::DrawMarker( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDr
GRSetDrawMode( aDC, aDrawMode );
for( unsigned ii = 0; ii < m_Corners.size(); ii++ )
for( unsigned ii = 0; ii < CORNERS_COUNT; ii++ )
{
corners[ii] = m_Corners[ii];
corners[ii] = MarkerShapeCorners[ii];
corners[ii].x *= m_ScalingFactor;
corners[ii].y *= m_ScalingFactor;
corners[ii] += m_Pos + aOffset;

View File

@ -36,7 +36,7 @@
#include <macros.h>
#include <id.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <class_base_screen.h>
#include <msgpanel.h>
#include <draw_frame.h>
@ -48,6 +48,7 @@
#include <wx/fontdlg.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <gal/graphics_abstraction_layer.h>
/**
@ -395,7 +396,7 @@ void EDA_DRAW_FRAME::OnSelectGrid( wxCommandEvent& event )
if( IsGalCanvasActive() )
{
GetGalCanvas()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGrid().m_Size.x,
screen->GetGrid().m_Size.y ) );
screen->GetGrid().m_Size.y ) );
GetGalCanvas()->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
}
@ -532,6 +533,38 @@ wxPoint EDA_DRAW_FRAME::GetGridPosition( const wxPoint& aPosition ) const
}
void EDA_DRAW_FRAME::SetNextGrid()
{
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( ( m_gridSelectBox->GetSelection() + 1 ) %
m_gridSelectBox->GetCount() );
wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED );
// cmd.SetEventObject( this );
OnSelectGrid( cmd );
}
}
void EDA_DRAW_FRAME::SetPrevGrid()
{
if( m_gridSelectBox )
{
int cnt = m_gridSelectBox->GetSelection();
if( --cnt < 0 )
cnt = m_gridSelectBox->GetCount() - 1;
m_gridSelectBox->SetSelection( cnt );
wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED );
// cmd.SetEventObject( this );
OnSelectGrid( cmd );
}
}
int EDA_DRAW_FRAME::BlockCommand( int key )
{
return 0;
@ -1007,9 +1040,17 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
wxPoint EDA_DRAW_FRAME::GetCrossHairPosition( bool aInvertY ) const
{
// subject to change, borrow from old BASE_SCREEN for now.
if( IsGalCanvasActive() )
{
VECTOR2I cursor = GetGalCanvas()->GetViewControls()->GetCursorPosition();
BASE_SCREEN* screen = GetScreen(); // virtual call
return screen->getCrossHairPosition( aInvertY );
return wxPoint( cursor.x, cursor.y );
}
else
{
BASE_SCREEN* screen = GetScreen(); // virtual call
return screen->getCrossHairPosition( aInvertY );
}
}

View File

@ -35,7 +35,7 @@
#include <macros.h>
#include <id.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <class_base_screen.h>
#include <draw_frame.h>

View File

@ -29,7 +29,7 @@
#include <wx/colour.h>
#include <wx/filename.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <view/wx_view_controls.h>
#include <pcb_painter.h>
@ -45,8 +45,6 @@
#include <profile.h>
#endif /* __WXDEBUG__ */
#define METRIC_UNIT_LENGTH (1e9)
EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
const wxPoint& aPosition, const wxSize& aSize,
GalType aGalType ) :
@ -61,11 +59,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
SwitchBackend( aGalType );
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
// Initial display settings
m_gal->SetLookAtPoint( VECTOR2D( 0, 0 ) );
m_gal->SetZoomFactor( 1.0 );
m_gal->ComputeWorldScreenMatrix();
m_painter = new KIGFX::PCB_PAINTER( m_gal );
m_view = new KIGFX::VIEW( true );
@ -90,8 +83,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) );
Connect( wxEVT_KEY_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_KEY_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_CHAR, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
Connect( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE,
wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
@ -131,17 +123,22 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
{
m_drawing = true;
m_view->UpdateItems();
m_gal->BeginDrawing();
m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
m_gal->ClearScreen();
m_view->ClearTargets();
// Grid has to be redrawn only when the NONCACHED target is redrawn
if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->DrawGrid();
m_view->Redraw();
m_gal->DrawCursor( m_viewControls->GetCursorPosition() );
if( m_view->IsDirty() )
{
m_view->ClearTargets();
// Grid has to be redrawn only when the NONCACHED target is redrawn
if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->DrawGrid();
m_view->Redraw();
}
m_gal->DrawCursor( m_viewControls->GetCursorPosition() );
m_gal->EndDrawing();
m_drawing = false;
@ -196,14 +193,14 @@ void EDA_DRAW_PANEL_GAL::StopDrawing()
void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
{
// Protect from refreshing during backend switch
m_pendingRefresh = true;
m_refreshTimer.Stop();
// Do not do anything if the currently used GAL is correct
if( aGalType == m_currentGal && m_gal != NULL )
return;
// Prevent refreshing canvas during backend switch
m_pendingRefresh = true;
m_refreshTimer.Stop();
delete m_gal;
switch( aGalType )
@ -220,21 +217,15 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
return;
}
m_gal->SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers
m_gal->SetScreenDPI( 106 ); // Display resolution setting
m_gal->ComputeWorldScreenMatrix();
wxSize size = GetClientSize();
m_gal->ResizeScreen( size.GetX(), size.GetY() );
m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
if( m_painter )
m_painter->SetGAL( m_gal );
if( m_view )
{
m_view->SetGAL( m_gal );
m_view->RecacheAllItems( true );
}
m_currentGal = aGalType;
m_pendingRefresh = false;

View File

@ -35,9 +35,6 @@
using namespace KIGFX;
///> Opacity of a single layer
const float LAYER_ALPHA = 0.8;
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
wxEvtHandler* aPaintListener, const wxString& aName ) :
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
@ -73,14 +70,16 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
#endif
SetSize( aParent->GetSize() );
screenSize = VECTOR2D( aParent->GetSize() );
initCursor( 20 );
screenSize = VECTOR2I( aParent->GetSize() );
initCursor();
// Grid color settings are different in Cairo and OpenGL
SetGridColor( COLOR4D( 0.1, 0.1, 0.1, 0.8 ) );
// Allocate memory for pixel storage
allocateBitmaps();
initSurface();
}
@ -139,7 +138,7 @@ void CAIRO_GAL::EndDrawing()
*wxOutputPtr++ = value & 0xff; // Blue pixel
}
wxImage img( (int) screenSize.x, (int) screenSize.y, (unsigned char*) wxOutput, true );
wxImage img( screenSize.x, screenSize.y, (unsigned char*) wxOutput, true );
wxBitmap bmp( img );
wxClientDC client_dc( this );
wxBufferedDC dc;
@ -284,7 +283,7 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl
void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
{
screenSize = VECTOR2D( aWidth, aHeight );
screenSize = VECTOR2I( aWidth, aHeight );
// Recreate the bitmaps
deleteBitmaps();
@ -431,7 +430,7 @@ void CAIRO_GAL::SetLayerDepth( double aLayerDepth )
}
void CAIRO_GAL::Transform( MATRIX3x3D aTransformation )
void CAIRO_GAL::Transform( const MATRIX3x3D& aTransformation )
{
cairo_matrix_t cairoTransformation;
@ -885,11 +884,10 @@ void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent )
}
void CAIRO_GAL::initCursor( int aCursorSize )
void CAIRO_GAL::initCursor()
{
cursorPixels = new wxBitmap( aCursorSize, aCursorSize );
cursorPixelsSaved = new wxBitmap( aCursorSize, aCursorSize );
cursorSize = aCursorSize;
cursorPixels = new wxBitmap( cursorSize, cursorSize );
cursorPixelsSaved = new wxBitmap( cursorSize, cursorSize );
wxMemoryDC cursorShape( *cursorPixels );
@ -900,8 +898,8 @@ void CAIRO_GAL::initCursor( int aCursorSize )
cursorShape.SetPen( pen );
cursorShape.Clear();
cursorShape.DrawLine( 0, aCursorSize / 2, aCursorSize, aCursorSize / 2 );
cursorShape.DrawLine( aCursorSize / 2, 0, aCursorSize / 2, aCursorSize );
cursorShape.DrawLine( 0, cursorSize / 2, cursorSize, cursorSize / 2 );
cursorShape.DrawLine( cursorSize / 2, 0, cursorSize / 2, cursorSize );
}
@ -925,14 +923,15 @@ void CAIRO_GAL::blitCursor( wxBufferedDC& clientDC )
}
// Store pixels that are going to be overpainted
cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, cursorPosition.x, cursorPosition.y );
VECTOR2D cursorScreen = ToScreen( cursorPosition ) - cursorSize / 2;
cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, cursorScreen.x, cursorScreen.y );
// Draw the cursor
clientDC.Blit( cursorPosition.x, cursorPosition.y, cursorSize, cursorSize,
clientDC.Blit( cursorScreen.x, cursorScreen.y, cursorSize, cursorSize,
&cursorShape, 0, 0, wxOR );
savedCursorPosition.x = (wxCoord) cursorPosition.x;
savedCursorPosition.y = (wxCoord) cursorPosition.y;
savedCursorPosition.x = (wxCoord) cursorScreen.x;
savedCursorPosition.y = (wxCoord) cursorScreen.y;
}
@ -958,7 +957,8 @@ void CAIRO_GAL::deleteBitmaps()
void CAIRO_GAL::initSurface()
{
wxASSERT( !isInitialized );
if( isInitialized )
return;
// Create the Cairo surface
surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT,

View File

@ -39,7 +39,10 @@ GAL::GAL() :
SetIsStroke( true );
SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
SetLookAtPoint( VECTOR2D( 0, 0 ) );
SetZoomFactor( 1.0 );
SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers
SetScreenDPI( 106 ); // Display resolution setting
SetDepthRange( VECTOR2D( GAL::MIN_DEPTH, GAL::MAX_DEPTH ) );
SetFlip( false, false );
SetLineWidth( 1.0 );
@ -85,7 +88,7 @@ void GAL::ComputeWorldScreenMatrix()
MATRIX3x3D translation;
translation.SetIdentity();
translation.SetTranslation( 0.5 * screenSize );
translation.SetTranslation( 0.5 * VECTOR2D( screenSize ) );
MATRIX3x3D scale;
scale.SetIdentity();
@ -112,23 +115,23 @@ void GAL::DrawGrid()
SetTarget( TARGET_NONCACHED );
// Draw the origin marker
double origSize = static_cast<double>( gridOriginMarkerSize ) / worldScale;
double originSize = gridOriginMarkerSize / worldScale;
SetLayerDepth( GAL::GRID_DEPTH );
SetIsFill( false );
SetIsStroke( true );
SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
SetLineWidth( gridLineWidth / worldScale );
DrawLine( gridOrigin + VECTOR2D( -origSize, -origSize ),
gridOrigin + VECTOR2D( origSize, origSize ) );
DrawLine( gridOrigin + VECTOR2D( -origSize, origSize ),
gridOrigin + VECTOR2D( origSize, -origSize ) );
DrawCircle( gridOrigin, origSize * 0.7 );
DrawLine( gridOrigin + VECTOR2D( -originSize, -originSize ),
gridOrigin + VECTOR2D( originSize, originSize ) );
DrawLine( gridOrigin + VECTOR2D( -originSize, originSize ),
gridOrigin + VECTOR2D( originSize, -originSize ) );
DrawCircle( gridOrigin, originSize * 0.7 );
// Draw the grid
// For the drawing the start points, end points and increments have
// to be calculated in world coordinates
VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 );
VECTOR2D worldEndPoint = screenWorldMatrix * screenSize;
VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize );
int gridScreenSizeDense = round( gridSize.x * worldScale );
int gridScreenSizeCoarse = round( gridSize.x * static_cast<double>( gridTick ) * worldScale );
@ -232,12 +235,12 @@ void GAL::DrawGrid()
}
VECTOR2D GAL::GetGridPoint( VECTOR2D aPoint ) const
VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const
{
VECTOR2D pointWorld = ToWorld( aPoint );
VECTOR2D gridPoint;
pointWorld.x = round( pointWorld.x / gridSize.x ) * gridSize.x;
pointWorld.y = round( pointWorld.y / gridSize.y ) * gridSize.y;
gridPoint.x = round( aPoint.x / gridSize.x ) * gridSize.x;
gridPoint.y = round( aPoint.y / gridSize.y ) * gridSize.y;
return ToScreen( pointWorld );
return gridPoint;
}

View File

@ -17,7 +17,7 @@
* 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:O//www.gnu.org website for the version 2 license,
* 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
*/

View File

@ -86,8 +86,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
#endif
SetSize( aParent->GetSize() );
screenSize = VECTOR2D( aParent->GetSize() );
initCursor( 80 );
screenSize = VECTOR2I( aParent->GetSize() );
// Grid color settings are different in Cairo and OpenGL
SetGridColor( COLOR4D( 0.8, 0.8, 0.8, 0.1 ) );
@ -103,6 +102,8 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
}
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
currentManager = &nonCachedManager;
}
@ -250,6 +251,8 @@ void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoin
const VECTOR2D startEndVector = aEndPoint - aStartPoint;
double lineAngle = startEndVector.Angle();
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
drawLineQuad( aStartPoint, aEndPoint );
// Line caps
@ -467,10 +470,15 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
{
if( aPointList.empty() )
return;
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
// Start from the second point
for( it++; it != aPointList.end(); it++ )
for( ++it; it != aPointList.end(); ++it )
{
const VECTOR2D startEndVector = ( *it - *( it - 1 ) );
double lineAngle = startEndVector.Angle();
@ -554,7 +562,7 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight )
{
screenSize = VECTOR2D( aWidth, aHeight );
screenSize = VECTOR2I( aWidth, aHeight );
// Resize framebuffers
compositor.Resize( aWidth, aHeight );
@ -589,16 +597,7 @@ void OPENGL_GAL::ClearScreen()
}
void OPENGL_GAL::SetStrokeColor( const COLOR4D& aColor )
{
strokeColor = aColor;
// This is the default drawing color
currentManager->Color( aColor.r, aColor.g, aColor.b, aColor.a );
}
void OPENGL_GAL::Transform( MATRIX3x3D aTransformation )
void OPENGL_GAL::Transform( const MATRIX3x3D& aTransformation )
{
GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
@ -767,8 +766,8 @@ void OPENGL_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
{
// Now we should only store the position of the mouse cursor
// The real drawing routines are in blitCursor()
cursorPosition = VECTOR2D( aCursorPosition.x,
screenSize.y - aCursorPosition.y ); // invert Y axis
VECTOR2D screenCursor = worldScreenMatrix * aCursorPosition;
cursorPosition = screenWorldMatrix * VECTOR2D( screenCursor.x, screenSize.y - screenCursor.y );
}
@ -778,13 +777,9 @@ void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
// We do not need a very precise comparison here (the lineWidth is set by GAL::DrawGrid())
if( fabs( lineWidth - 2.0 * gridLineWidth / worldScale ) < 0.1 )
{
glLineWidth( 1.0 );
}
else
{
glLineWidth( 2.0 );
}
glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a );
@ -798,8 +793,23 @@ void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
}
inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{
/* Helper drawing: ____--- v3 ^
* ____---- ... \ \
* ____---- ... \ end \
* v1 ____---- ... ____---- \ width
* ---- ...___---- \ \
* \ ___...-- \ v
* \ ____----... ____---- v2
* ---- ... ____----
* start \ ... ____----
* \... ____----
* ----
* v0
* dots mark triangles' hypotenuses
*/
VECTOR2D startEndVector = aEndPoint - aStartPoint;
double lineLength = startEndVector.EuclideanNorm();
double scale = 0.5 * lineWidth / lineLength;
@ -857,8 +867,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]).
* Shader uses this coordinates to determine if fragments are inside the semicircle or not.
* (if you want to understand more, check the vertex shader source [shader.vert]).
* Shader uses these coordinates to determine if fragments are inside the semicircle or not.
* v2
* /\
* /__\
@ -888,9 +898,9 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
/* Draw a triangle that contains the semicircle, then shade it to leave only
* the semicircle. Parameters given to setShader are indices of the triangle's vertices
* (if you want to understand more, check the vertex shader source [shader.vert]), the
* radius and the line width. Shader uses this coordinates to determine if fragments are
* inside the semicircle or not.
* (if you want to understand more, check the vertex shader source [shader.vert]), the
* radius and the line width. Shader uses these coordinates to determine if fragments are
* inside the semicircle or not.
* v2
* /\
* /__\
@ -968,12 +978,6 @@ void OPENGL_GAL::initGlew()
}
void OPENGL_GAL::initCursor( int aCursorSize )
{
cursorSize = aCursorSize;
}
void OPENGL_GAL::blitCursor()
{
if( !isCursorEnabled )
@ -981,11 +985,9 @@ void OPENGL_GAL::blitCursor()
compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
VECTOR2D cursorBegin = ToWorld( cursorPosition -
VECTOR2D( cursorSize / 2, cursorSize / 2 ) );
VECTOR2D cursorEnd = ToWorld( cursorPosition +
VECTOR2D( cursorSize / 2, cursorSize / 2 ) );
VECTOR2D cursorCenter = ( cursorBegin + cursorEnd ) / 2.0;
VECTOR2D cursorBegin = cursorPosition - cursorSize / ( 2 * worldScale );
VECTOR2D cursorEnd = cursorPosition + cursorSize / ( 2 * worldScale );
VECTOR2D cursorCenter = ( cursorBegin + cursorEnd ) / 2;
glDisable( GL_TEXTURE_2D );
glLineWidth( 1.0 );

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,7 @@ RENDER_SETTINGS::~RENDER_SETTINGS()
void RENDER_SETTINGS::update()
{
m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_highlightFactor,
m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_hiContrastFactor,
m_layerOpacity );
}

View File

@ -26,6 +26,7 @@
#include <tool/tool_manager.h>
#include <tool/tool_event.h>
#include <tool/tool_action.h>
#include <boost/foreach.hpp>
#include <cassert>
ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) :
@ -43,7 +44,12 @@ ACTION_MANAGER::~ACTION_MANAGER()
void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
{
assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before
// Check if the TOOL_ACTION was not registered before
assert( aAction->GetId() == -1 );
// TOOL_ACTIONs are supposed to be named [appName.]toolName.actionName (with dots between)
// action name without specifying at least toolName is not valid
assert( aAction->GetName().find( '.', 0 ) != std::string::npos );
assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() );
assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() );
@ -53,15 +59,7 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
m_actionIdIndex[aAction->m_id] = aAction;
if( aAction->HasHotKey() )
{
// Duplication of hot keys leads to unexpected behaviour
// The right way to change a hotkey is to use ACTION_MANAGER::ClearHotKey() first
assert( m_actionHotKeys.find( aAction->m_currentHotKey ) == m_actionHotKeys.end() );
m_actionHotKeys[aAction->m_currentHotKey] = aAction;
}
aAction->setActionMgr( this );
m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction );
}
@ -71,11 +69,18 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
m_actionIdIndex.erase( aAction->m_id );
// Indicate that the ACTION_MANAGER no longer care about the object
aAction->setActionMgr( NULL );
aAction->setId( -1 );
if( aAction->HasHotKey() )
m_actionHotKeys.erase( aAction->m_currentHotKey );
{
std::list<TOOL_ACTION*>& actions = m_actionHotKeys[aAction->m_currentHotKey];
std::list<TOOL_ACTION*>::iterator action = std::find( actions.begin(), actions.end(), aAction );
if( action != actions.end() )
actions.erase( action );
else
assert( false );
}
}
@ -94,34 +99,80 @@ bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const
if( it == m_actionNameIndex.end() )
return false; // no action with given name found
runAction( it->second );
RunAction( it->second );
return true;
}
bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
{
std::map<int, TOOL_ACTION*>::const_iterator it = m_actionHotKeys.find( aHotKey );
if( it == m_actionHotKeys.end() )
return false; // no appropriate action found for the hotkey
runAction( it->second );
return true;
}
void ACTION_MANAGER::ClearHotKey( int aHotKey )
{
m_actionHotKeys.erase( aHotKey );
}
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const
{
TOOL_EVENT event = aAction->MakeEvent();
m_toolMgr->ProcessEvent( event );
}
bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
{
int key = std::toupper( aHotKey & ~MD_MODIFIER_MASK );
int mod = aHotKey & MD_MODIFIER_MASK;
HOTKEY_LIST::const_iterator it = m_actionHotKeys.find( key | mod );
// If no luck, try without modifier, to handle keys that require a modifier
// e.g. to get ? you need to press Shift+/ without US keyboard layout
// Hardcoding ? as Shift+/ is a bad idea, as on another layout you may need to press a
// different combination
if( it == m_actionHotKeys.end() )
{
it = m_actionHotKeys.find( key );
if( it == m_actionHotKeys.end() )
return false; // no appropriate action found for the hotkey
}
const std::list<TOOL_ACTION*>& actions = it->second;
// Choose the action that has the highest priority on the active tools stack
// If there is none, run the global action associated with the hot key
int highestPriority = -1, priority = -1;
const TOOL_ACTION* context = NULL; // pointer to context action of the highest priority tool
const TOOL_ACTION* global = NULL; // pointer to global action, if there is no context action
BOOST_FOREACH( const TOOL_ACTION* action, actions )
{
if( action->GetScope() == AS_GLOBAL )
{
// Store the global action for the hot key in case there was no possible
// context actions to run
assert( global == NULL ); // there should be only one global action per hot key
global = action;
continue;
}
TOOL_BASE* tool = m_toolMgr->FindTool( action->GetToolName() );
if( tool )
{
priority = m_toolMgr->GetPriority( tool->GetId() );
if( priority >= 0 && priority > highestPriority )
{
highestPriority = priority;
context = action;
}
}
}
if( !global && !context ) // currently there is no valid action to run
return false;
if( context )
RunAction( context );
else if( global )
RunAction( global );
return true;
}

View File

@ -27,18 +27,16 @@
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tools/common_actions.h>
#include <view/view.h>
#include <view/wx_view_controls.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <pcbnew_id.h>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
using boost::optional;
///> Stores information about a mouse button state
struct TOOL_DISPATCHER::BUTTON_STATE
{
@ -128,7 +126,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
{
BUTTON_STATE* st = m_buttons[aIndex];
wxEventType type = aEvent.GetEventType();
optional<TOOL_EVENT> evt;
boost::optional<TOOL_EVENT> evt;
bool isClick = false;
bool up = type == st->upEvent;
@ -207,7 +205,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
{
bool motion = false, buttonEvents = false;
optional<TOOL_EVENT> evt;
boost::optional<TOOL_EVENT> evt;
int type = aEvent.GetEventType();
@ -221,6 +219,9 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
// but changes in world coordinates (e.g. autopanning)
type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
{
wxMouseEvent* me = static_cast<wxMouseEvent*>( &aEvent );
int mods = decodeModifiers<wxMouseEvent>( me );
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetMousePosition();
VECTOR2D pos = getView()->ToWorld( screenPos );
@ -228,6 +229,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
{
motion = true;
m_lastMousePos = pos;
m_editFrame->UpdateStatusBar();
}
for( unsigned int i = 0; i < m_buttons.size(); i++ )
@ -235,29 +237,38 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
if( !buttonEvents && motion )
{
evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_MOTION );
evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_MOTION, mods );
evt->SetMousePosition( pos );
}
}
// Keyboard handling
else if( type == wxEVT_KEY_UP || type == wxEVT_KEY_DOWN )
else if( type == wxEVT_CHAR )
{
wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent );
int key = ke->GetKeyCode();
int mods = decodeModifiers<wxKeyEvent>( ke );
if( type == wxEVT_KEY_UP )
if( mods & MD_CTRL )
{
if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools
evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL );
else
evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_UP, key | mods );
#if !wxCHECK_VERSION( 2, 9, 0 )
// I really look forward to the day when we will use only one version of wxWidgets..
const int WXK_CONTROL_A = 1;
const int WXK_CONTROL_Z = 26;
#endif
// wxWidgets have a quirk related to Ctrl+letter hot keys handled by CHAR_EVT
// http://docs.wxwidgets.org/trunk/classwx_key_event.html:
// "char events for ASCII letters in this case carry codes corresponding to the ASCII
// value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z."
if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
key += 'A' - 1;
}
if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools
evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL );
else
{
evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_DOWN, key | mods );
}
evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_PRESSED, key | mods );
}
if( evt )
@ -268,21 +279,29 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
}
void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
void TOOL_DISPATCHER::DispatchWxCommand( wxCommandEvent& aEvent )
{
bool activateTool = false;
std::string toolName;
boost::optional<TOOL_EVENT> evt;
// fixme: use TOOL_ACTIONs here
switch( aEvent.GetId() )
{
case ID_PNS_ROUTER_TOOL:
toolName = "pcbnew.InteractiveRouter";
activateTool = true;
case ID_ZOOM_IN: // toolbar button "Zoom In"
evt = COMMON_ACTIONS::zoomInCenter.MakeEvent();
break;
case ID_ZOOM_OUT: // toolbar button "Zoom In"
evt = COMMON_ACTIONS::zoomOutCenter.MakeEvent();
break;
case ID_ZOOM_PAGE: // toolbar button "Fit on Screen"
evt = COMMON_ACTIONS::zoomFitScreen.MakeEvent();
break;
default:
aEvent.Skip();
break;
}
// do nothing if the legacy view is active
if( activateTool && m_editFrame->IsGalCanvasActive() )
m_toolMgr->InvokeTool( toolName );
if( evt )
m_toolMgr->ProcessEvent( *evt );
}

View File

@ -81,8 +81,7 @@ const std::string TOOL_EVENT::Format() const
{ TA_MOUSE_DRAG, "drag" },
{ TA_MOUSE_MOTION, "motion" },
{ TA_MOUSE_WHEEL, "wheel" },
{ TA_KEY_UP, "key-up" },
{ TA_KEY_DOWN, "key-down" },
{ TA_KEY_PRESSED, "key-pressed" },
{ TA_VIEW_REFRESH, "view-refresh" },
{ TA_VIEW_ZOOM, "view-zoom" },
{ TA_VIEW_PAN, "view-pan" },

View File

@ -46,6 +46,12 @@ TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
}
void TOOL_INTERACTIVE::Activate()
{
m_toolMgr->InvokeTool( m_toolId );
}
OPT_TOOL_EVENT TOOL_INTERACTIVE::Wait( const TOOL_EVENT_LIST& aEventList )
{
return m_toolMgr->ScheduleWait( this, aEventList );

View File

@ -44,7 +44,7 @@
#include <wxPcbStruct.h>
#include <confirm.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
using boost::optional;
@ -103,6 +103,14 @@ TOOL_MANAGER::TOOL_MANAGER() :
TOOL_MANAGER::~TOOL_MANAGER()
{
DeleteAll();
delete m_actionMgr;
}
void TOOL_MANAGER::DeleteAll()
{
std::map<TOOL_BASE*, TOOL_STATE*>::iterator it, it_end;
@ -113,7 +121,7 @@ TOOL_MANAGER::~TOOL_MANAGER()
delete it->first; // delete the tool itself
}
delete m_actionMgr;
m_toolState.clear();
}
@ -196,6 +204,12 @@ bool TOOL_MANAGER::RunAction( const std::string& aActionName )
}
void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction )
{
m_actionMgr->RunAction( &aAction );
}
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool )
{
wxASSERT( aTool != NULL );
@ -239,9 +253,15 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
return false;
}
// If the tool is already active, do not invoke it again
// If the tool is already active, bring it to the top of the active tools stack
if( isActive( aTool ) )
{
m_activeTools.erase( std::find( m_activeTools.begin(), m_activeTools.end(),
aTool->GetId() ) );
m_activeTools.push_front( aTool->GetId() );
return false;
}
aTool->Reset( TOOL_INTERACTIVE::RUN );
@ -281,6 +301,25 @@ void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason )
}
int TOOL_MANAGER::GetPriority( int aToolId ) const
{
int priority = 0;
for( std::deque<int>::const_iterator it = m_activeTools.begin(),
itEnd = m_activeTools.end(); it != itEnd; ++it )
{
std::cout << FindTool( *it )->GetName() << std::endl;
if( *it == aToolId )
return priority;
++priority;
}
return -1;
}
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
const TOOL_EVENT_LIST& aConditions )
{
@ -378,7 +417,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent )
{
if( aEvent.Action() == TA_KEY_UP )
if( aEvent.Action() == TA_KEY_PRESSED )
{
// Check if there is a hotkey associated
if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) )

View File

@ -45,32 +45,26 @@ VIEW::VIEW( bool aIsDynamic ) :
m_scale( 1.0 ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic ),
m_scaleLimits( 15000.0, 1.0 )
m_dynamic( aIsDynamic )
{
m_panBoundary.SetMaximum();
m_needsUpdate.reserve( 32768 );
// Redraw everything at the beginning
for( int i = 0; i < TARGETS_NUMBER; ++i )
MarkTargetDirty( i );
MarkDirty();
// View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
// pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
// (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
// silkscreen, pads, vias, etc.
for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
{
AddLayer( i );
}
}
VIEW::~VIEW()
{
BOOST_FOREACH( LAYER_MAP::value_type& l, m_layers )
{
delete l.second.items;
}
}
@ -82,7 +76,7 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
m_layers[aLayer].id = aLayer;
m_layers[aLayer].items = new VIEW_RTREE();
m_layers[aLayer].renderingOrder = aLayer;
m_layers[aLayer].enabled = true;
m_layers[aLayer].visible = true;
m_layers[aLayer].displayOnly = aDisplayOnly;
m_layers[aLayer].target = TARGET_CACHED;
}
@ -98,7 +92,7 @@ void VIEW::Add( VIEW_ITEM* aItem )
aItem->ViewGetLayers( layers, layers_count );
aItem->saveLayers( layers, layers_count );
for( int i = 0; i < layers_count; i++ )
for( int i = 0; i < layers_count; ++i )
{
VIEW_LAYER& l = m_layers[layers[i]];
l.items->Insert( aItem );
@ -107,6 +101,9 @@ void VIEW::Add( VIEW_ITEM* aItem )
if( m_dynamic )
aItem->viewAssign( this );
if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE )
MarkForUpdate( aItem );
}
@ -115,6 +112,15 @@ void VIEW::Remove( VIEW_ITEM* aItem )
if( m_dynamic )
aItem->m_view = NULL;
if( aItem->viewRequiredUpdate() != VIEW_ITEM::NONE ) // prevent from updating a removed item
{
std::vector<VIEW_ITEM*>::iterator item = std::find( m_needsUpdate.begin(),
m_needsUpdate.end(), aItem );
if( item != m_needsUpdate.end() )
m_needsUpdate.erase( item );
}
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
aItem->getLayers( layers, layers_count );
@ -126,9 +132,12 @@ void VIEW::Remove( VIEW_ITEM* aItem )
// Clear the GAL cache
int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
}
aItem->deleteGroups();
}
@ -138,13 +147,9 @@ void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
wxASSERT( (unsigned) aRequiredId < m_layers.size() );
if( aRequired )
{
m_layers[aLayerId].requiredLayers.insert( aRequiredId );
}
else
{
m_layers[aLayerId].requiredLayers.erase( aRequired );
}
}
@ -172,12 +177,12 @@ struct queryVisitor
};
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult )
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
{
if( m_orderedLayers.empty() )
return 0;
std::vector<VIEW_LAYER*>::reverse_iterator i;
std::vector<VIEW_LAYER*>::const_reverse_iterator i;
// execute queries in reverse direction, so that items that are on the top of
// the rendering stack are returned first.
@ -197,31 +202,31 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult )
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
{
MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix().Inverse();
const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
if( aAbsolute )
{
return VECTOR2D( matrix * aCoord );
}
else
{
return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
}
}
double VIEW::ToWorld( double aSize ) const
{
const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
return matrix.GetScale().x * aSize;
}
VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
{
MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix();
const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
if( aAbsolute )
{
return VECTOR2D( matrix * aCoord );
}
else
{
return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
}
}
@ -257,12 +262,6 @@ void VIEW::SetGAL( GAL* aGal )
}
void VIEW::SetPainter( PAINTER* aPainter )
{
m_painter = aPainter;
}
BOX2D VIEW::GetViewport() const
{
BOX2D rect;
@ -293,19 +292,8 @@ void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
}
void VIEW::SetScale( double aScale )
{
SetScale( aScale, m_center );
}
void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
{
if( aScale > m_scaleLimits.x )
aScale = m_scaleLimits.x;
else if( aScale < m_scaleLimits.y )
aScale = m_scaleLimits.y;
VECTOR2D a = ToScreen( aAnchor );
m_gal->SetZoomFactor( aScale );
@ -325,19 +313,6 @@ void VIEW::SetCenter( const VECTOR2D& aCenter )
{
m_center = aCenter;
if( !m_panBoundary.Contains( aCenter ) )
{
if( aCenter.x < m_panBoundary.GetLeft() )
m_center.x = m_panBoundary.GetLeft();
else if( aCenter.x > m_panBoundary.GetRight() )
m_center.x = m_panBoundary.GetRight();
if( aCenter.y < m_panBoundary.GetTop() )
m_center.y = m_panBoundary.GetTop();
else if( aCenter.y > m_panBoundary.GetBottom() )
m_center.y = m_panBoundary.GetBottom();
}
m_gal->SetLookAtPoint( m_center );
m_gal->ComputeWorldScreenMatrix();
@ -425,6 +400,7 @@ void VIEW::UpdateLayerColor( int aLayer )
updateItemsColor visitor( aLayer, m_painter, m_gal );
m_layers[aLayer].items->Query( r, visitor );
MarkTargetDirty( m_layers[aLayer].target );
}
@ -484,6 +460,7 @@ void VIEW::ChangeLayerDepth( int aLayer, int aDepth )
changeItemsDepth visitor( aLayer, aDepth, m_gal );
m_layers[aLayer].items->Query( r, visitor );
MarkTargetDirty( m_layers[aLayer].target );
}
@ -578,8 +555,8 @@ void VIEW::UpdateAllLayersOrder()
struct VIEW::drawItem
{
drawItem( VIEW* aView, const VIEW_LAYER* aCurrentLayer ) :
currentLayer( aCurrentLayer ), view( aView )
drawItem( VIEW* aView, int aLayer ) :
view( aView ), layer( aLayer )
{
}
@ -587,18 +564,17 @@ struct VIEW::drawItem
{
// Conditions that have te be fulfilled for an item to be drawn
bool drawCondition = aItem->ViewIsVisible() &&
aItem->ViewGetLOD( currentLayer->id ) < view->m_scale;
aItem->ViewGetLOD( layer ) < view->m_scale;
if( !drawCondition )
return true;
view->draw( aItem, currentLayer->id );
view->draw( aItem, layer );
return true;
}
const VIEW_LAYER* currentLayer;
VIEW* view;
int layersCount, layers[VIEW_MAX_LAYERS];
int layer, layersCount, layers[VIEW_MAX_LAYERS];
};
@ -606,9 +582,9 @@ void VIEW::redrawRect( const BOX2I& aRect )
{
BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers )
{
if( l->enabled && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
{
drawItem drawFunc( this, l );
drawItem drawFunc( this, l->id );
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
@ -618,7 +594,7 @@ void VIEW::redrawRect( const BOX2I& aRect )
}
void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const
void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
{
if( IsCached( aLayer ) && !aImmediate )
{
@ -649,11 +625,12 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const
}
void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const
void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
{
int layers[VIEW_MAX_LAYERS], layers_count;
aItem->ViewGetLayers( layers, layers_count );
// Sorting is needed for drawing order dependent GALs (like Cairo)
SortLayers( layers, layers_count );
@ -665,26 +642,12 @@ void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const
}
void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate ) const
void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
{
std::set<VIEW_ITEM*>::const_iterator it;
for( it = aGroup->Begin(); it != aGroup->End(); ++it )
{
draw( *it, aImmediate );
}
}
bool VIEW::IsDirty() const
{
for( int i = 0; i < TARGETS_NUMBER; ++i )
{
if( IsTargetDirty( i ) )
return true;
}
return false;
}
@ -709,14 +672,14 @@ struct VIEW::recacheItem
bool operator()( VIEW_ITEM* aItem )
{
// Remove previously cached group
int prevGroup = aItem->getGroup( layer );
int group = aItem->getGroup( layer );
if( prevGroup >= 0 )
gal->DeleteGroup( prevGroup );
if( group >= 0 )
gal->DeleteGroup( group );
if( immediately )
{
int group = gal->BeginGroup();
group = gal->BeginGroup();
aItem->setGroup( layer, group );
if( !view->m_painter->Draw( aItem, layer ) )
@ -726,6 +689,7 @@ struct VIEW::recacheItem
}
else
{
aItem->ViewUpdate( VIEW_ITEM::ALL );
aItem->setGroup( layer, -1 );
}
@ -757,6 +721,7 @@ void VIEW::Clear()
}
m_gal->ClearCache();
m_needsUpdate.clear();
}
@ -783,6 +748,11 @@ void VIEW::ClearTargets()
void VIEW::Redraw()
{
#ifdef PROFILE
prof_counter totalRealTime;
prof_start( &totalRealTime );
#endif /* PROFILE */
VECTOR2D screenSize = m_gal->GetScreenPixelSize();
BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
@ -791,13 +761,19 @@ void VIEW::Redraw()
redrawRect( rect );
// All targets were redrawn, so nothing is dirty
clearTargetDirty( TARGET_CACHED );
clearTargetDirty( TARGET_NONCACHED );
clearTargetDirty( TARGET_OVERLAY );
markTargetClean( TARGET_CACHED );
markTargetClean( TARGET_NONCACHED );
markTargetClean( TARGET_OVERLAY );
#ifdef PROFILE
prof_end( &totalRealTime );
wxLogDebug( wxT( "Redraw: %.1f ms" ), totalRealTime.msecs() );
#endif /* PROFILE */
}
VECTOR2D VIEW::GetScreenPixelSize() const
const VECTOR2I& VIEW::GetScreenPixelSize() const
{
return m_gal->GetScreenPixelSize();
}
@ -812,10 +788,7 @@ struct VIEW::clearLayerCache
bool operator()( VIEW_ITEM* aItem )
{
if( aItem->storesGroups() )
{
aItem->deleteGroups();
}
aItem->deleteGroups();
return true;
}
@ -839,7 +812,7 @@ void VIEW::clearGroupCache()
}
void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
{
// updateLayers updates geometry too, so we do not have to update both of them at the same time
if( aUpdateFlags & VIEW_ITEM::LAYERS )
@ -851,24 +824,23 @@ void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
aItem->ViewGetLayers( layers, layers_count );
// Iterate through layers used by the item and recache it immediately
for( int i = 0; i < layers_count; i++ )
for( int i = 0; i < layers_count; ++i )
{
int layerId = layers[i];
if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) )
if( IsCached( layerId ) )
{
// Redraw
if( IsCached( layerId ) )
if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) )
updateItemGeometry( aItem, layerId );
}
else if( aUpdateFlags & VIEW_ITEM::COLOR )
{
updateItemColor( aItem, layerId );
else if( aUpdateFlags & VIEW_ITEM::COLOR )
updateItemColor( aItem, layerId );
}
// Mark those layers as dirty, so the VIEW will be refreshed
MarkTargetDirty( m_layers[layerId].target );
}
aItem->clearUpdateFlags();
}
@ -890,6 +862,7 @@ void VIEW::sortLayers()
void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
{
wxASSERT( (unsigned) aLayer < m_layers.size() );
wxASSERT( IsCached( aLayer ) );
// Obtain the color that should be used for coloring the item on the specific layerId
const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
@ -904,20 +877,25 @@ void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
{
wxASSERT( (unsigned) aLayer < m_layers.size() );
wxASSERT( IsCached( aLayer ) );
VIEW_LAYER& l = m_layers.at( aLayer );
m_gal->SetTarget( l.target );
m_gal->SetLayerDepth( l.renderingOrder );
// Redraw the item from scratch
int prevGroup = aItem->getGroup( aLayer );
int group = aItem->getGroup( aLayer );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
if( group >= 0 )
m_gal->DeleteGroup( group );
int group = m_gal->BeginGroup();
group = m_gal->BeginGroup();
aItem->setGroup( aLayer, group );
m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer );
if( !m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ) );
aItem->ViewDraw( aLayer, m_gal ); // Alternative drawing method
m_gal->EndGroup();
}
@ -928,7 +906,7 @@ void VIEW::updateBbox( VIEW_ITEM* aItem )
aItem->ViewGetLayers( layers, layers_count );
for( int i = 0; i < layers_count; i++ )
for( int i = 0; i < layers_count; ++i )
{
VIEW_LAYER& l = m_layers[layers[i]];
l.items->Remove( aItem );
@ -945,17 +923,23 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
// Remove the item from previous layer set
aItem->getLayers( layers, layers_count );
for( int i = 0; i < layers_count; i++ )
for( int i = 0; i < layers_count; ++i )
{
VIEW_LAYER& l = m_layers[layers[i]];
l.items->Remove( aItem );
MarkTargetDirty( l.target );
// Redraw the item from scratch
int prevGroup = aItem->getGroup( layers[i] );
if( IsCached( l.id ) )
{
// Redraw the item from scratch
int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
if( prevGroup >= 0 )
{
m_gal->DeleteGroup( prevGroup );
aItem->setGroup( l.id, -1 );
}
}
}
// Add the item to new layer set
@ -981,7 +965,7 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
{
// That is enough if just one layer is not enabled
if( !m_layers.at( *it ).enabled )
if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) )
return false;
}
@ -1023,13 +1007,15 @@ void VIEW::RecacheAllItems( bool aImmediately )
}
bool VIEW::IsTargetDirty( int aTarget ) const
void VIEW::UpdateItems()
{
wxASSERT( aTarget < TARGETS_NUMBER );
// Update items that need this
BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate )
{
assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE );
// Check the target status
if( m_dirtyTargets[aTarget] )
return true;
invalidateItem( item, item->viewRequiredUpdate() );
}
return false;
m_needsUpdate.clear();
}

View File

@ -31,25 +31,12 @@ using namespace KIGFX;
void VIEW_ITEM::ViewSetVisible( bool aIsVisible )
{
bool update = false;
if( m_visible != aIsVisible )
update = true;
m_visible = aIsVisible;
// update only if the visibility has really changed
if( update )
if( m_visible != aIsVisible )
{
m_visible = aIsVisible;
ViewUpdate( APPEARANCE );
}
void VIEW_ITEM::ViewUpdate( int aUpdateFlags )
{
if( !m_view )
return;
m_view->InvalidateItem( this, aUpdateFlags );
}
}

View File

@ -35,9 +35,7 @@ using namespace KIGFX;
const wxEventType WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE = wxNewEventType();
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
VIEW_CONTROLS( aView ),
m_state( IDLE ),
m_parentPanel( aParentPanel )
VIEW_CONTROLS( aView ), m_state( IDLE ), m_parentPanel( aParentPanel )
{
m_parentPanel->Connect( wxEVT_MOTION,
wxMouseEventHandler( WX_VIEW_CONTROLS::onMotion ), NULL, this );
@ -68,13 +66,44 @@ void VIEW_CONTROLS::ShowCursor( bool aEnabled )
}
void VIEW_CONTROLS::setCenter( const VECTOR2D& aCenter )
{
if( !m_panBoundary.Contains( aCenter ) )
{
VECTOR2D newCenter( aCenter );
if( aCenter.x < m_panBoundary.GetLeft() )
newCenter.x = m_panBoundary.GetLeft();
else if( aCenter.x > m_panBoundary.GetRight() )
newCenter.x = m_panBoundary.GetRight();
if( aCenter.y < m_panBoundary.GetTop() )
newCenter.y = m_panBoundary.GetTop();
else if( aCenter.y > m_panBoundary.GetBottom() )
newCenter.y = m_panBoundary.GetBottom();
m_view->SetCenter( newCenter );
}
else
{
m_view->SetCenter( aCenter );
}
}
void VIEW_CONTROLS::setScale( double aScale, const VECTOR2D& aAnchor )
{
if( aScale < m_minScale )
aScale = m_minScale;
else if( aScale > m_maxScale )
aScale = m_maxScale;
m_view->SetScale( aScale, aAnchor );
}
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
m_mousePosition.x = aEvent.GetX();
m_mousePosition.y = aEvent.GetY();
updateCursor();
bool isAutoPanning = false;
if( m_autoPanEnabled )
@ -84,10 +113,10 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
if( m_state == DRAG_PANNING )
{
VECTOR2D d = m_dragStartPoint - m_mousePosition;
VECTOR2D d = m_dragStartPoint - VECTOR2D( aEvent.GetX(), aEvent.GetY() );
VECTOR2D delta = m_view->ToWorld( d, false );
m_view->SetCenter( m_lookStartPoint + delta );
setCenter( m_lookStartPoint + delta );
aEvent.StopPropagation();
}
else
@ -117,7 +146,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
VECTOR2D delta( aEvent.ControlDown() ? -scrollSpeed : 0.0,
aEvent.ShiftDown() ? -scrollSpeed : 0.0 );
m_view->SetCenter( m_view->GetCenter() + delta );
setCenter( m_view->GetCenter() + delta );
}
else
{
@ -140,7 +169,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
}
VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) );
m_view->SetScale( m_view->GetScale() * zoomScale, anchor );
setScale( m_view->GetScale() * zoomScale, anchor );
}
aEvent.Skip();
@ -197,9 +226,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
dir = dir.Resize( borderSize );
dir = m_view->ToWorld( dir, false );
m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
updateCursor();
setCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
// Notify tools that the cursor position has changed in the world coordinates
wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
@ -238,7 +265,7 @@ void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
}
const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const
VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const
{
wxPoint msp = wxGetMousePosition();
wxPoint winp = m_parentPanel->GetScreenPosition();
@ -247,6 +274,22 @@ const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const
}
VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const
{
if( m_forceCursorPosition )
return m_forcedPosition;
else
{
VECTOR2D mousePosition = GetMousePosition();
if( m_snappingEnabled )
return m_view->GetGAL()->GetGridPoint( m_view->ToWorld( mousePosition ) );
else
return m_view->ToWorld( mousePosition );
}
}
bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
{
VECTOR2D p( aEvent.GetX(), aEvent.GetY() );
@ -257,17 +300,19 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
double borderEndX = m_view->GetScreenPixelSize().x - borderStart;
double borderEndY = m_view->GetScreenPixelSize().y - borderStart;
m_panDirection = VECTOR2D();
if( p.x < borderStart )
m_panDirection.x = -( borderStart - p.x );
else if( p.x > borderEndX )
m_panDirection.x = ( p.x - borderEndX );
else
m_panDirection.x = 0;
if( p.y < borderStart )
m_panDirection.y = -( borderStart - p.y );
else if( p.y > borderEndY )
m_panDirection.y = ( p.y - borderEndY );
else
m_panDirection.y = 0;
bool borderHit = ( m_panDirection.x != 0 || m_panDirection.y != 0 );
@ -304,14 +349,3 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
wxASSERT_MSG( false, wxT( "This line should never be reached" ) );
return false; // Should not be reached, just avoid the compiler warnings..
}
void WX_VIEW_CONTROLS::updateCursor()
{
if( m_forceCursorPosition )
m_cursorPosition = m_view->ToScreen( m_forcedPosition );
else if( m_snappingEnabled )
m_cursorPosition = m_view->GetGAL()->GetGridPoint( m_mousePosition );
else
m_cursorPosition = m_mousePosition;
}

View File

@ -189,7 +189,7 @@ void WORKSHEET_VIEWITEM::draw( const WS_DRAW_ITEM_TEXT* aItem, GAL* aGal ) const
aGal->SetStrokeColor( COLOR4D( aItem->GetColor() ) );
aGal->SetLineWidth( aItem->GetThickness() );
aGal->SetTextAttributes( aItem );
aGal->StrokeText( std::wstring( aItem->GetText().wc_str() ), position, 0.0 );
aGal->StrokeText( aItem->GetText(), position, 0.0 );
}

View File

@ -33,7 +33,7 @@
#include <fctsys.h>
#include <id.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <gal/graphics_abstraction_layer.h>
#include <view/view.h>
#include <class_base_screen.h>
@ -194,24 +194,22 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event )
RedrawScreen( center, true );
}
if( IsGalCanvasActive() )
{
// Apply computed view settings to GAL
KIGFX::VIEW* view = GetGalCanvas()->GetView();
KIGFX::GAL* gal = GetGalCanvas()->GetGAL();
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
double zoom = 1.0 / ( zoomFactor * GetZoom() );
view->SetScale( zoom );
view->SetCenter( VECTOR2D( center ) );
GetGalCanvas()->Refresh();
}
UpdateStatusBar();
}
void EDA_DRAW_FRAME::SetNextZoom()
{
GetScreen()->SetNextZoom();
}
void EDA_DRAW_FRAME::SetPrevZoom()
{
GetScreen()->SetPreviousZoom();
}
/* add the zoom list menu the the MasterMenu.
* used in OnRightClick(wxMouseEvent& event)
*/

View File

@ -31,7 +31,7 @@
#include <pgm_base.h>
#include <common.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <confirm.h>
#include <macros.h>
#include <bitmaps.h>

View File

@ -271,9 +271,7 @@ void SCH_EDIT_FRAME::Process_Config( wxCommandEvent& event )
void SCH_EDIT_FRAME::OnSetOptions( wxCommandEvent& event )
{
wxArrayString units;
GRIDS grid_list;
GetScreen()->GetGrids( grid_list );
GRIDS grid_list = GetScreen()->GetGrids();
DIALOG_EESCHEMA_OPTIONS dlg( this );

View File

@ -65,7 +65,7 @@ public:
};
typedef std::vector< GRID_TYPE > GRIDS;
typedef std::vector<GRID_TYPE> GRIDS;
/**
@ -445,11 +445,12 @@ public:
/**
* Function GetGrids().
* Copy the grid list to \a aList.
*
* @param aList - List to copy to.
* Returns the current list of grids.
*/
void GetGrids( GRIDS& aList );
const GRIDS& GetGrids() const
{
return m_grids;
}
/**
* Function GetClass

View File

@ -33,8 +33,6 @@
#include <base_struct.h>
#include <gr_basic.h>
#include <boost/ptr_container/ptr_vector.hpp>
#include <gr_basic.h>
#include <layers_id_colors_and_visibility.h>
/// Abbrevation for fomatting internal units to a string.

View File

@ -23,7 +23,7 @@
*/
/**
* @file class_drawpanel_gal.h:
* @file class_draw_panel_gal.h:
* @brief EDA_DRAW_PANEL_GAL class definition.
*/

View File

@ -13,7 +13,6 @@ class MARKER_BASE
public:
wxPoint m_Pos; ///< position of the marker
protected:
std::vector <wxPoint> m_Corners; ///< Corner list for shape definition (a polygon)
int m_MarkerType; ///< Can be used as a flag
EDA_COLOR_T m_Color; ///< color
EDA_RECT m_ShapeBoundingBox; ///< Bounding box of the graphic symbol, relative

View File

@ -353,6 +353,18 @@ public:
*/
wxPoint GetGridPosition( const wxPoint& aPosition ) const;
/**
* Function SetNextGrid()
* changes the grid size settings to the next one available.
*/
virtual void SetNextGrid();
/**
* Function SetPrevGrid()
* changes the grid size settings to the previous one available.
*/
virtual void SetPrevGrid();
/**
* Command event handler for selecting grid sizes.
*
@ -410,6 +422,18 @@ public:
virtual void OnZoom( wxCommandEvent& event );
/**
* Function SetNextZoom()
* changes the zoom to the next one available.
*/
void SetNextZoom();
/**
* Function SetPrevZoom()
* changes the zoom to the previous one available.
*/
void SetPrevZoom();
/**
* Function RedrawScreen
* redraws the entire screen area by updating the scroll bars and mouse pointer in

View File

@ -164,7 +164,7 @@ public:
// --------------
/// @copydoc GAL::Transform()
virtual void Transform( MATRIX3x3D aTransformation );
virtual void Transform( const MATRIX3x3D& aTransformation );
/// @copydoc GAL::Rotate()
virtual void Rotate( double aAngle );
@ -283,8 +283,6 @@ private:
wxPoint savedCursorPosition; ///< The last cursor position
wxBitmap* cursorPixels; ///< Cursor pixels
wxBitmap* cursorPixelsSaved; ///< Saved cursor pixels
int cursorSize; ///< Cursor size
VECTOR2D cursorPosition; ///< Current cursor position
/// Maximum number of arguments for one command
static const int MAX_CAIRO_ARGUMENTS = 6;
@ -354,8 +352,10 @@ private:
*/
void skipMouseEvent( wxMouseEvent& aEvent );
/// @copydoc GAL::initCursor()
virtual void initCursor( int aCursorSize );
/**
* @brief Prepares cursor bitmap.
*/
virtual void initCursor();
/**
* @brief Blits cursor into the current screen.
@ -386,6 +386,9 @@ private:
/// Format used to store pixels
static const cairo_format_t GAL_FORMAT = CAIRO_FORMAT_RGB24;
///> Opacity of a single layer
static const float LAYER_ALPHA = 0.8;
};
} // namespace KIGFX

View File

@ -31,8 +31,6 @@
#include <stack>
#include <limits>
#include <wx/event.h>
#include <math/matrix3x3.h>
#include <gal/color4d.h>
@ -162,7 +160,7 @@ public:
virtual bool Show( bool aShow ) = 0;
/// @brief Returns GAL canvas size in pixels
VECTOR2D GetScreenPixelSize() const
const VECTOR2I& GetScreenPixelSize() const
{
return screenSize;
}
@ -222,7 +220,7 @@ public:
*
* @return the color for stroking the outline.
*/
inline COLOR4D GetStrokeColor()
inline const COLOR4D& GetStrokeColor() const
{
return strokeColor;
}
@ -252,7 +250,7 @@ public:
*
* @return the actual line width.
*/
inline double GetLineWidth()
inline double GetLineWidth() const
{
return lineWidth;
}
@ -335,7 +333,7 @@ public:
*
* @param aTransformation is the ransformation matrix.
*/
virtual void Transform( MATRIX3x3D aTransformation ) = 0;
virtual void Transform( const MATRIX3x3D& aTransformation ) = 0;
/**
* @brief Rotate the context.
@ -428,11 +426,21 @@ public:
*
* @return the transformation matrix.
*/
MATRIX3x3D GetWorldScreenMatrix()
const MATRIX3x3D& GetWorldScreenMatrix() const
{
return worldScreenMatrix;
}
/**
* @brief Get the screen <-> world transformation matrix.
*
* @return the transformation matrix.
*/
const MATRIX3x3D& GetScreenWorldMatrix() const
{
return screenWorldMatrix;
}
/**
* @brief Set the world <-> screen transformation matrix.
*
@ -487,7 +495,7 @@ public:
*
* @return the look at point.
*/
inline VECTOR2D GetLookAtPoint()
inline const VECTOR2D& GetLookAtPoint() const
{
return lookAtPoint;
}
@ -507,7 +515,7 @@ public:
*
* @return the zoom factor.
*/
inline double GetZoomFactor()
inline double GetZoomFactor() const
{
return zoomFactor;
}
@ -528,7 +536,7 @@ public:
/**
* @brief Returns the minimum depth in the currently used range (the top).
*/
inline double GetMinDepth()
inline double GetMinDepth() const
{
return depthRange.x;
}
@ -536,7 +544,7 @@ public:
/**
* @brief Returns the maximum depth in the currently used range (the bottom).
*/
inline double GetMaxDepth()
inline double GetMaxDepth() const
{
return depthRange.y;
}
@ -546,7 +554,7 @@ public:
*
* @return the actual world scale factor.
*/
inline double GetWorldScale()
inline double GetWorldScale() const
{
return worldScale;
}
@ -694,7 +702,7 @@ public:
*
* @return the grid line width
*/
inline double GetGridLineWidth()
inline double GetGridLineWidth() const
{
return gridLineWidth;
}
@ -709,19 +717,17 @@ public:
gridLineWidth = aGridLineWidth;
}
/// @brief Draw the grid
///> @brief Draw the grid
void DrawGrid();
/**
* Function GetGridPoint()
* For a given point it returns the nearest point belonging to the grid.
* For a given point it returns the nearest point belonging to the grid in world coordinates.
*
* @param aPoint is the point for which the grid point is searched.
* @return The nearest grid point.
* @return The nearest grid point in world coordinates.
*/
VECTOR2D GetGridPoint( VECTOR2D aPoint ) const;
VECTOR2D GetGridPoint( const VECTOR2D& aPoint ) const;
/**
* @brief Change the grid display style.
@ -739,7 +745,7 @@ public:
* @param aPoint the pointposition in screen coordinates.
* @return the point position in world coordinates.
*/
inline virtual VECTOR2D ToWorld( const VECTOR2D& aPoint ) const
inline VECTOR2D ToWorld( const VECTOR2D& aPoint ) const
{
return VECTOR2D( screenWorldMatrix * aPoint );
}
@ -750,15 +756,15 @@ public:
* @param aPoint the pointposition in world coordinates.
* @return the point position in screen coordinates.
*/
inline virtual VECTOR2D ToScreen( const VECTOR2D& aPoint ) const
inline VECTOR2D ToScreen( const VECTOR2D& aPoint ) const
{
return VECTOR2D( worldScreenMatrix * aPoint );
}
/**
* @brief Enable/Disable cursor.
* @brief Enable/disable cursor.
*
* @param aIsCursorEnabled is true if the cursor should be enabled, else false.
* @param aCursorEnabled is true if the cursor should be drawn, else false.
*/
inline void SetCursorEnabled( bool aCursorEnabled )
{
@ -778,7 +784,7 @@ public:
/**
* @brief Set the cursor size.
*
* @param aCursorSize is the size of the cursor.
* @param aCursorSize is the size of the cursor expressed in pixels.
*/
inline void SetCursorSize( unsigned int aCursorSize )
{
@ -821,9 +827,11 @@ public:
/// Depth level on which the grid is drawn
static const int GRID_DEPTH = 1024;
static const double METRIC_UNIT_LENGTH = 1e9;
protected:
std::stack<double> depthStack; ///< Stored depth values
VECTOR2D screenSize; ///< Screen size in screen coordinates
VECTOR2I screenSize; ///< Screen size in screen coordinates
double worldUnitLength; ///< The unit length of the world coordinates [inch]
double screenDPI; ///< The dots per inch of the screen
@ -862,7 +870,8 @@ protected:
bool isCursorEnabled; ///< Is the cursor enabled?
COLOR4D cursorColor; ///< Cursor color
int cursorSize; ///< Size of the cursor in pixels
unsigned int cursorSize; ///< Size of the cursor in pixels
VECTOR2D cursorPosition; ///< Current cursor position (world coordinates)
/// Instance of object that stores information about how to draw texts
STROKE_FONT strokeFont;
@ -881,13 +890,6 @@ protected:
*/
virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) = 0;
/**
* @brief Initialize the cursor.
*
* @param aCursorSize is the size of the cursor.
*/
virtual void initCursor( int aCursorSize ) = 0;
static const int MIN_DEPTH = -2048;
static const int MAX_DEPTH = 2047;
};

View File

@ -145,19 +145,12 @@ public:
/// @copydoc GAL::ClearScreen()
virtual void ClearScreen();
// -----------------
// Attribute setting
// -----------------
/// @copydoc GAL::SetStrokeColor()
virtual void SetStrokeColor( const COLOR4D& aColor );
// --------------
// Transformation
// --------------
/// @copydoc GAL::Transform()
virtual void Transform( MATRIX3x3D aTransformation );
virtual void Transform( const MATRIX3x3D& aTransformation );
/// @copydoc GAL::Rotate()
virtual void Rotate( double aAngle );
@ -299,8 +292,6 @@ private:
bool isShaderInitialized; ///< Was the shader initialized?
bool isGrouping; ///< Was a group started?
VECTOR2D cursorPosition; ///< Current cursor position
// Polygon tesselation
/// The tessellator
GLUtesselator* tesselator;
@ -313,7 +304,7 @@ private:
* @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line.
*/
inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/**
* @brief Draw a semicircle. Depending on settings (isStrokeEnabled & isFilledEnabled) it runs
@ -364,9 +355,6 @@ private:
/// Initialize GLEW
void initGlew();
/// @copydoc GAL::initCursor()
virtual void initCursor( int aCursorSize );
/**
* @brief Blits cursor into the current screen.
*/

View File

@ -46,7 +46,8 @@ public:
* to an object the segment belongs to (e.g. a line chain) or references to locally stored
* points (m_a, m_b).
*/
VECTOR2I& A, B;
VECTOR2I& A;
VECTOR2I& B;
/** Default constructor
* Creates an empty (0, 0) segment, locally-referenced
@ -203,6 +204,8 @@ public:
bool Collide( const SEG& aSeg, int aClearance ) const;
ecoord SquaredDistance( const SEG& aSeg ) const;
/**
* Function Distance()
*
@ -210,14 +213,16 @@ public:
* @param aSeg other segment
* @return minimum distance
*/
ecoord SquaredDistance( const SEG& aSeg ) const;
int Distance( const SEG& aSeg ) const
{
return sqrt( SquaredDistance( aSeg ) );
}
ecoord SquaredDistance( const VECTOR2I& aP ) const
{
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
}
/**
* Function Distance()
*
@ -225,11 +230,6 @@ public:
* @param aP the point
* @return minimum distance
*/
ecoord SquaredDistance( const VECTOR2I& aP ) const
{
return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm();
}
int Distance( const VECTOR2I& aP ) const
{
return sqrt( SquaredDistance( aP ) );
@ -244,14 +244,14 @@ public:
*/
bool Collinear( const SEG& aSeg ) const
{
ecoord qa1 = A.y - B.y;
ecoord qb1 = B.x - A.x;
ecoord qc1 = -qa1 * A.x - qb1 * A.y;
ecoord qa2 = aSeg.A.y - aSeg.B.y;
ecoord qb2 = aSeg.B.x - aSeg.A.x;
ecoord qc2 = -qa2 * aSeg.A.x - qb2 * aSeg.A.y;
ecoord qa = A.y - B.y;
ecoord qb = B.x - A.x;
ecoord qc = -qa * A.x - qb * A.y;
return ( qa1 == qa2 ) && ( qb1 == qb2 ) && ( qc1 == qc2 );
ecoord d1 = std::abs( aSeg.A.x * qa + aSeg.A.y * qb + qc );
ecoord d2 = std::abs( aSeg.B.x * qa + aSeg.B.y * qb + qc );
return ( d1 <= 1 && d2 <= 1 );
}
/**

View File

@ -415,7 +415,7 @@ public:
* @param aP the point to be looked for
* @return index of the correspoinding point in the line chain or negative when not found.
*/
int Find ( const VECTOR2I& aP ) const;
int Find( const VECTOR2I& aP ) const;
/**
* Function Slice()

View File

@ -246,6 +246,7 @@ enum PCB_VISIBLE
PADS_HOLES_VISIBLE,
VIAS_HOLES_VISIBLE,
DRC_VISIBLE, ///< drc markers
WORKSHEET, ///< worksheet frame
GP_OVERLAY, ///< general purpose overlay

View File

@ -28,24 +28,9 @@
#define __BOX2_H
#include <math/vector2d.h>
#include <limits>
template <class Vec>
class BOX2_TRAITS
{
};
template <>
class BOX2_TRAITS<VECTOR2I>
{
public:
enum
{
c_max_size = INT_MAX - 1,
c_min_coord_value = INT_MIN / 2 + 1
};
};
/**
* Class BOX2
* handles a 2-D bounding box, built on top of an origin point
@ -59,8 +44,9 @@ private:
Vec m_Size; // Rectangle Size
public:
typedef typename Vec::coord_type coord_type;
typedef typename Vec::extended_type ecoord_type;
typedef typename Vec::coord_type coord_type;
typedef typename Vec::extended_type ecoord_type;
typedef typename std::numeric_limits<coord_type> coord_limits;
BOX2() {};
@ -73,8 +59,8 @@ public:
void SetMaximum()
{
m_Pos.x = m_Pos.y = BOX2_TRAITS<Vec>().c_min_coord_value;
m_Size.x = m_Size.y = BOX2_TRAITS<Vec>().c_max_size;
m_Pos.x = m_Pos.y = coord_limits::min() / 2 + coord_limits::epsilon();
m_Size.x = m_Size.y = coord_limits::max() - coord_limits::epsilon();
}
Vec Centre() const

View File

@ -109,6 +109,26 @@ public:
return ( m_activeLayers.count( aLayerId ) > 0 );
}
/**
* Function GetHighlight
* Returns current highlight setting.
* @return True if highlight is enabled, false otherwise.
*/
bool GetHighlight() const
{
return m_highlightEnabled;
}
/**
* Function GetHighlightNetCode
* Returns netcode of currently highlighted net.
* @return Netcode of currently highlighted net.
*/
int GetHighlightNetCode() const
{
return m_highlightNetcode;
}
/**
* Function SetHighlight
* Turns on/off highlighting - it may be done for the active layer or the specified net.
@ -119,9 +139,7 @@ public:
inline void SetHighlight( bool aEnabled, int aNetcode = -1 )
{
m_highlightEnabled = aEnabled;
if( aNetcode > 0 )
m_highlightNetcode = aNetcode;
m_highlightNetcode = aNetcode;
}
/**

View File

@ -25,6 +25,7 @@
#ifndef ACTION_MANAGER_H_
#define ACTION_MANAGER_H_
#include <list>
#include <map>
#include <string>
@ -81,6 +82,14 @@ public:
*/
bool RunAction( const std::string& aActionName ) const;
/**
* Function RunAction()
* Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION
* object.
* @param aAction is the action to be run.
*/
void RunAction( const TOOL_ACTION* aAction ) const;
/**
* Function RunHotKey()
* Runs an action associated with a hotkey (if there is one available).
@ -89,13 +98,6 @@ public:
*/
bool RunHotKey( int aHotKey ) const;
/**
* Function ClearHotKey()
* Removes an action associated with a hotkey.
* @param aHotKey is the hotkey to be cleared.
*/
void ClearHotKey( int aHotKey );
private:
///> Tool manager needed to run actions
TOOL_MANAGER* m_toolMgr;
@ -107,15 +109,8 @@ private:
std::map<std::string, TOOL_ACTION*> m_actionNameIndex;
///> Map for indexing actions by their hotkeys
std::map<int, TOOL_ACTION*> m_actionHotKeys;
/**
* Function runAction()
* Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION
* object.
* @param aAction is the action to be run.
*/
void runAction( const TOOL_ACTION* aAction ) const;
typedef std::map<int, std::list<TOOL_ACTION*> > HOTKEY_LIST;
HOTKEY_LIST m_actionHotKeys;
};
#endif /* ACTION_MANAGER_H_ */

View File

@ -30,7 +30,7 @@
#include <cassert>
#include <tool/tool_base.h>
#include <tool/action_manager.h>
#include <tool/tool_manager.h>
/**
* Class TOOL_ACTION
@ -50,14 +50,14 @@ public:
const std::string& aMenuDesc = std::string( "" ) ) :
m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ),
m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL )
m_menuDescription( aMenuDesc ), m_id( -1 )
{
TOOL_MANAGER::Instance().RegisterAction( this );
}
~TOOL_ACTION()
{
if( m_actionMgr )
m_actionMgr->UnregisterAction( this );
TOOL_MANAGER::Instance().UnregisterAction( this );
}
bool operator==( const TOOL_ACTION& aRhs ) const
@ -171,6 +171,21 @@ public:
m_menuDescription = aDescription;
}
TOOL_ACTION_SCOPE GetScope() const
{
return m_scope;
}
/**
* Returns name of the tool associated with the action. It is basically the action name
* stripped of the last part (e.g. for "pcbnew.InteractiveDrawing.drawCircle" it is
* "pcbnew.InteractiveDrawing").
*/
std::string GetToolName() const
{
return m_name.substr( 0, m_name.rfind( '.' ) );
}
private:
friend class ACTION_MANAGER;
@ -180,12 +195,6 @@ private:
m_id = aId;
}
/// Assigns ACTION_MANAGER object that handles the TOOL_ACTION.
void setActionMgr( ACTION_MANAGER* aManager )
{
m_actionMgr = aManager;
}
/// Name of the action (convention is: app.[tool.]action.name)
std::string m_name;
@ -210,9 +219,6 @@ private:
/// Unique ID for fast matching. Assigned by ACTION_MANAGER.
int m_id;
/// Action manager that handles this TOOL_ACTION.
ACTION_MANAGER* m_actionMgr;
/// Origin of the action
// const TOOL_BASE* m_origin;

View File

@ -79,7 +79,7 @@ public:
* specified tool).
* @param aEvent is the wxCommandEvent to be processed.
*/
virtual void DispatchWxCommand( const wxCommandEvent& aEvent );
virtual void DispatchWxCommand( wxCommandEvent& aEvent );
private:
///> Number of mouse buttons that is handled in events.

View File

@ -64,36 +64,35 @@ enum TOOL_ACTIONS
TA_MOUSE_WHEEL = 0x0040,
TA_MOUSE = 0x007f,
TA_KEY_UP = 0x0080,
TA_KEY_DOWN = 0x0100,
TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN,
TA_KEY_PRESSED = 0x0080,
TA_KEYBOARD = TA_KEY_PRESSED,
// View related events
TA_VIEW_REFRESH = 0x0200,
TA_VIEW_ZOOM = 0x0400,
TA_VIEW_PAN = 0x0800,
TA_VIEW_DIRTY = 0x1000,
TA_VIEW = 0x1e00,
TA_VIEW_REFRESH = 0x0100,
TA_VIEW_ZOOM = 0x0200,
TA_VIEW_PAN = 0x0400,
TA_VIEW_DIRTY = 0x0800,
TA_VIEW = 0x0f00,
TA_CHANGE_LAYER = 0x2000,
TA_CHANGE_LAYER = 0x1000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CANCEL_TOOL = 0x4000,
TA_CANCEL_TOOL = 0x2000,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
// over one of choices. Used in dynamic highligting in disambiguation menu
TA_CONTEXT_MENU_UPDATE = 0x8000,
TA_CONTEXT_MENU_UPDATE = 0x4000,
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_CONTEXT_MENU_CHOICE = 0x10000,
TA_CONTEXT_MENU_CHOICE = 0x8000,
// This event is sent *before* undo/redo command is performed.
TA_UNDO_REDO = 0x20000,
TA_UNDO_REDO = 0x10000,
// Tool action (allows to control tools)
TA_ACTION = 0x40000,
TA_ACTION = 0x20000,
TA_ANY = 0xffffffff
};
@ -189,7 +188,7 @@ public:
m_scope( aScope ),
m_mouseButtons( 0 )
{
if( aCategory == TC_COMMAND )
if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
m_commandStr = aExtraParam;
}
@ -207,7 +206,7 @@ public:
///> Returns information about difference between current mouse cursor position and the place
///> 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
return m_mouseDelta;
@ -277,14 +276,9 @@ public:
return m_keyCode;
}
bool IsKeyUp() const
bool IsKeyPressed() const
{
return m_actions == TA_KEY_UP;
}
bool IsKeyDown() const
{
return m_actions == TA_KEY_DOWN;
return m_actions == TA_KEY_PRESSED;
}
void SetMouseDragOrigin( const VECTOR2D& aP )
@ -317,7 +311,7 @@ public:
if( !( m_actions & aEvent.m_actions ) )
return false;
if( m_category == TC_COMMAND )
if( m_category == TC_COMMAND || m_category == TC_MESSAGE )
{
if( m_commandStr && aEvent.m_commandStr )
return *m_commandStr == *aEvent.m_commandStr;

View File

@ -48,6 +48,12 @@ public:
TOOL_INTERACTIVE( const std::string& aName );
virtual ~TOOL_INTERACTIVE();
/**
* Function Activate()
* Runs the tool. After activation, the tool starts receiving events until it is finished.
*/
void Activate();
/**
* Function SetContextMenu()
*

View File

@ -48,9 +48,20 @@ class wxWindow;
class TOOL_MANAGER
{
public:
TOOL_MANAGER();
static TOOL_MANAGER& Instance()
{
static TOOL_MANAGER manager;
return manager;
}
~TOOL_MANAGER();
/**
* Deletes all the tools that were registered in the TOOL_MANAGER.
*/
void DeleteAll();
/**
* Generates an unique ID from for a tool with given name.
*/
@ -101,13 +112,21 @@ public:
/**
* Function RunAction()
* Runs the specified action. The common format is "application.ToolName.Action".
* Runs the specified action. The common format for action names is "application.ToolName.Action".
*
* @param aActionName is the name of action to be invoked.
* @return True if the action finished successfully, false otherwise.
*/
bool RunAction( const std::string& aActionName );
/**
* Function RunAction()
* Runs the specified action.
*
* @param aAction is the action to be invoked.
*/
void RunAction( const TOOL_ACTION& aAction );
/**
* Function FindTool()
* Searches for a tool with given ID.
@ -167,6 +186,36 @@ public:
return m_editFrame;
}
/**
* Returns id of the tool that is on the top of the active tools stack
* (was invoked the most recently).
* @return Id of the currently used tool.
*/
int GetCurrentToolId() const
{
return m_activeTools.front();
}
/**
* Returns the tool that is on the top of the active tools stack
* (was invoked the most recently).
* @return Pointer to the currently used tool.
*/
TOOL_BASE* GetCurrentTool() const
{
return FindTool( GetCurrentToolId() );
}
/**
* Returns priority of a given tool. Higher number means that the tool is closer to the
* beginning of the active tools queue (i.e. receives events earlier, tools with lower
* priority receive events later).
* @param aToolId is the id of queried tool.
* @return The priority of a given tool. If returned number is negative, then it means that
* the tool id is invalid or the tool is not active.
*/
int GetPriority( int aToolId ) const;
/**
* Defines a state transition - the events that cause a given handler method in the tool
* to be called. Called by TOOL_INTERACTIVE::Go(). May be called from a coroutine context.
@ -203,6 +252,8 @@ public:
}
private:
TOOL_MANAGER();
struct TOOL_STATE;
typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;

View File

@ -40,111 +40,152 @@
#ifndef _HALF_EDGE_DART_
#define _HALF_EDGE_DART_
#include <ttl/halfedge/hetriang.h>
namespace hed
{
/**
* \class Dart
* \brief \b %Dart class for the half-edge data structure.
*
* See \ref api for a detailed description of how the member functions
* should be implemented.
*/
class DART
{
EDGE_PTR m_edge;
namespace hed {
/// Dart direction: true if dart is counterclockwise in face
bool m_dir;
//------------------------------------------------------------------------------------------------
// Dart class for the half-edge data structure
//------------------------------------------------------------------------------------------------
/** \class Dart
* \brief \b %Dart class for the half-edge data structure.
*
* See \ref api for a detailed description of how the member functions
* should be implemented.
*/
class Dart {
EdgePtr edge_;
bool dir_; // true if dart is counterclockwise in face
public:
public:
/// Default constructor
Dart() { dir_ = true; }
DART()
{
m_dir = true;
}
/// Constructor
Dart(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
DART( const EDGE_PTR& aEdge, bool aDir = true )
{
m_edge = aEdge;
m_dir = aDir;
}
/// Copy constructor
Dart(const Dart& dart) { edge_ = dart.edge_; dir_ = dart.dir_; }
DART( const DART& aDart )
{
m_edge = aDart.m_edge;
m_dir = aDart.m_dir;
}
/// Destructor
~Dart() {}
~DART()
{
}
/// Assignment operator
Dart& operator = (const Dart& dart) {
if (this == &dart)
DART& operator=( const DART& aDart )
{
if( this == &aDart )
return *this;
m_edge = aDart.m_edge;
m_dir = aDart.m_dir;
return *this;
edge_ = dart.edge_;
dir_ = dart.dir_;
return *this;
}
/// Comparing dart objects
bool operator==(const Dart& dart) const {
if (dart.edge_ == edge_ && dart.dir_ == dir_)
return true;
return false;
bool operator==( const DART& aDart ) const
{
return ( aDart.m_edge == m_edge && aDart.m_dir == m_dir );
}
/// Comparing dart objects
bool operator!=(const Dart& dart) const {
return !(dart==*this);
bool operator!=( const DART& aDart ) const
{
return !( aDart == *this );
}
/// Maps the dart to a different node
Dart& alpha0() { dir_ = !dir_; return *this; }
DART& Alpha0()
{
m_dir = !m_dir;
return *this;
}
/// Maps the dart to a different edge
Dart& alpha1() {
if (dir_) {
edge_ = edge_->getNextEdgeInFace()->getNextEdgeInFace();
dir_ = false;
}
else {
edge_ = edge_->getNextEdgeInFace();
dir_ = true;
}
return *this;
DART& Alpha1()
{
if( m_dir )
{
m_edge = m_edge->GetNextEdgeInFace()->GetNextEdgeInFace();
m_dir = false;
}
else
{
m_edge = m_edge->GetNextEdgeInFace();
m_dir = true;
}
return *this;
}
/// Maps the dart to a different triangle. \b Note: the dart is not changed if it is at the boundary!
Dart& alpha2() {
if (edge_->getTwinEdge()) {
edge_ = edge_->getTwinEdge();
dir_ = !dir_;
}
// else, the dart is at the boundary and should not be changed
return *this;
DART& Alpha2()
{
if( m_edge->GetTwinEdge() )
{
m_edge = m_edge->GetTwinEdge();
m_dir = !m_dir;
}
// else, the dart is at the boundary and should not be changed
return *this;
}
// Utilities not required by TTL
// -----------------------------
/** @name Utilities not required by TTL */
//@{
void Init( const EDGE_PTR& aEdge, bool aDir = true )
{
m_edge = aEdge;
m_dir = aDir;
}
void init(const EdgePtr& edge, bool dir = true) { edge_ = edge; dir_ = dir; }
double X() const
{
return GetNode()->GetX();
}
double x() const { return getNode()->GetX(); } // x-coordinate of source node
double y() const { return getNode()->GetY(); } // y-coordinate of source node
double Y() const
{
return GetNode()->GetY();
}
bool isCounterClockWise() const { return dir_; }
bool IsCCW() const
{
return m_dir;
}
const NodePtr& getNode() const { return dir_ ? edge_->getSourceNode() : edge_->getTargetNode(); }
const NodePtr& getOppositeNode() const { return dir_ ? edge_->getTargetNode() : edge_->getSourceNode(); }
EdgePtr& getEdge() { return edge_; }
const NODE_PTR& GetNode() const
{
return m_dir ? m_edge->GetSourceNode() : m_edge->GetTargetNode();
}
const NODE_PTR& GetOppositeNode() const
{
return m_dir ? m_edge->GetTargetNode() : m_edge->GetSourceNode();
}
EDGE_PTR& GetEdge()
{
return m_edge;
}
//@} // End of Utilities not required by TTL
};
};
}; // End of hed namespace
} // End of hed namespace
#endif

View File

@ -40,136 +40,149 @@
#ifndef _HALF_EDGE_TRAITS_
#define _HALF_EDGE_TRAITS_
#include <ttl/halfedge/hetriang.h>
#include <ttl/halfedge/hedart.h>
namespace hed {
//------------------------------------------------------------------------------------------------
// Traits class for the half-edge data structure
//------------------------------------------------------------------------------------------------
/** \struct TTLtraits
* \brief \b Traits class (static struct) for the half-edge data structure.
*
* The member functions are those required by different function templates
* in the TTL. Documentation is given here to explain what actions
* should be carried out on the actual data structure as required by the functions
* in the \ref ttl namespace.
*
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
* half-edge data structure.
*
* \see \ref api
*
*/
struct TTLtraits {
/** The floating point type used in calculations
* involving scalar products and cross products.
*/
typedef double real_type;
//----------------------------------------------------------------------------------------------
// ------------------------------- Geometric Predicates Group ---------------------------------
//----------------------------------------------------------------------------------------------
namespace hed
{
/**
* \struct TTLtraits
* \brief \b Traits class (static struct) for the half-edge data structure.
*
* The member functions are those required by different function templates
* in the TTL. Documentation is given here to explain what actions
* should be carried out on the actual data structure as required by the functions
* in the \ref ttl namespace.
*
* The source code of \c %HeTraits.h shows how the traits class is implemented for the
* half-edge data structure.
*
* \see \ref api
*/
struct TTLtraits
{
/**
* The floating point type used in calculations involving scalar products and cross products.
*/
typedef double REAL_TYPE;
/** @name Geometric Predicates */
//@{
/**
* Scalar product between two 2D vectors represented as darts.\n
*
* ttl_util::scalarProduct2d can be used.
*/
static REAL_TYPE ScalarProduct2D( const DART& aV1, const DART& aV2 )
{
DART v10 = aV1;
v10.Alpha0();
//----------------------------------------------------------------------------------------------
/** Scalar product between two 2D vectors represented as darts.\n
*
* ttl_util::scalarProduct2d can be used.
*/
static real_type scalarProduct2d(const Dart& v1, const Dart& v2) {
Dart v10 = v1; v10.alpha0();
Dart v20 = v2; v20.alpha0();
return ttl_util::scalarProduct2d(v10.x()-v1.x(), v10.y()-v1.y(),
v20.x()-v2.x(), v20.y()-v2.y());
DART v20 = aV2;
v20.Alpha0();
return ttl_util::ScalarProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(),
v20.X() - aV2.X(), v20.Y() - aV2.Y() );
}
/**
* Scalar product between two 2D vectors.
* The first vector is represented by a dart \e v, and the second
* vector has direction from the source node of \e v to the point \e p.\n
*
* ttl_util::ScalarProduct2D can be used.
*/
static REAL_TYPE ScalarProduct2D( const DART& aV, const NODE_PTR& aP )
{
DART d0 = aV;
d0.Alpha0();
//----------------------------------------------------------------------------------------------
/** Scalar product between two 2D vectors.
* The first vector is represented by a dart \e v, and the second
* vector has direction from the source node of \e v to the point \e p.\n
*
* ttl_util::scalarProduct2d can be used.
*/
static real_type scalarProduct2d(const Dart& v, const NodePtr& p) {
Dart d0 = v; d0.alpha0();
return ttl_util::scalarProduct2d(d0.x() - v.x(), d0.y() - v.y(),
p->GetX() - v.x(), p->GetY() - v.y());
return ttl_util::ScalarProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(),
aP->GetX() - aV.X(), aP->GetY() - aV.Y() );
}
/**
* Cross product between two vectors in the plane represented as darts.
* The z-component of the cross product is returned.\n
*
* ttl_util::CrossProduct2D can be used.
*/
static REAL_TYPE CrossProduct2D( const DART& aV1, const DART& aV2 )
{
DART v10 = aV1;
v10.Alpha0();
//----------------------------------------------------------------------------------------------
/** Cross product between two vectors in the plane represented as darts.
* The z-component of the cross product is returned.\n
*
* ttl_util::crossProduct2d can be used.
*/
static real_type crossProduct2d(const Dart& v1, const Dart& v2) {
Dart v10 = v1; v10.alpha0();
Dart v20 = v2; v20.alpha0();
return ttl_util::crossProduct2d(v10.x()-v1.x(), v10.y()-v1.y(),
v20.x()-v2.x(), v20.y()-v2.y());
DART v20 = aV2;
v20.Alpha0();
return ttl_util::CrossProduct2D( v10.X() - aV1.X(), v10.Y() - aV1.Y(),
v20.X() - aV2.X(), v20.Y() - aV2.Y() );
}
/**
* Cross product between two vectors in the plane.
* The first vector is represented by a dart \e v, and the second
* vector has direction from the source node of \e v to the point \e p.
* The z-component of the cross product is returned.\n
*
* ttl_util::CrossProduct2d can be used.
*/
static REAL_TYPE CrossProduct2D( const DART& aV, const NODE_PTR& aP )
{
DART d0 = aV;
d0.Alpha0();
//----------------------------------------------------------------------------------------------
/** Cross product between two vectors in the plane.
* The first vector is represented by a dart \e v, and the second
* vector has direction from the source node of \e v to the point \e p.
* The z-component of the cross product is returned.\n
*
* ttl_util::crossProduct2d can be used.
*/
static real_type crossProduct2d(const Dart& v, const NodePtr& p) {
Dart d0 = v; d0.alpha0();
return ttl_util::crossProduct2d(d0.x() - v.x(), d0.y() - v.y(),
p->GetX() - v.x(), p->GetY() - v.y());
return ttl_util::CrossProduct2D( d0.X() - aV.X(), d0.Y() - aV.Y(),
aP->GetX() - aV.X(), aP->GetY() - aV.Y() );
}
/**
* Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p
* be a point in the plane. Return a positive value if \e n1, \e n2,
* and \e p occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
*/
static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const NODE_PTR& aP )
{
REAL_TYPE pa[2];
REAL_TYPE pb[2];
REAL_TYPE pc[2];
//----------------------------------------------------------------------------------------------
/** Let \e n1 and \e n2 be the nodes associated with two darts, and let \e p
* be a point in the plane. Return a positive value if \e n1, \e n2,
* and \e p occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
*/
static real_type orient2d(const Dart& n1, const Dart& n2, const NodePtr& p) {
real_type pa[2]; real_type pb[2]; real_type pc[2];
pa[0] = n1.x(); pa[1] = n1.y();
pb[0] = n2.x(); pb[1] = n2.y();
pc[0] = p->GetX(); pc[1] = p->GetY();
return ttl_util::orient2dfast(pa, pb, pc);
pa[0] = aN1.X();
pa[1] = aN1.Y();
pb[0] = aN2.X();
pb[1] = aN2.Y();
pc[0] = aP->GetX();
pc[1] = aP->GetY();
return ttl_util::Orient2DFast( pa, pb, pc );
}
/**
* This is the same predicate as represented with the function above,
* but with a slighty different interface:
* The last parameter is given as a dart where the source node of the dart
* represents a point in the plane.
* This function is required for constrained triangulation.
*/
static REAL_TYPE Orient2D( const DART& aN1, const DART& aN2, const DART& aP )
{
REAL_TYPE pa[2];
REAL_TYPE pb[2];
REAL_TYPE pc[2];
//----------------------------------------------------------------------------------------------
/** This is the same predicate as represented with the function above,
* but with a slighty different interface:
* The last parameter is given as a dart where the source node of the dart
* represents a point in the plane.
* This function is required for constrained triangulation.
*/
static real_type orient2d(const Dart& n1, const Dart& n2, const Dart& p) {
real_type pa[2]; real_type pb[2]; real_type pc[2];
pa[0] = n1.x(); pa[1] = n1.y();
pb[0] = n2.x(); pb[1] = n2.y();
pc[0] = p.x(); pc[1] = p.y();
return ttl_util::orient2dfast(pa, pb, pc);
pa[0] = aN1.X();
pa[1] = aN1.Y();
pb[0] = aN2.X();
pb[1] = aN2.Y();
pc[0] = aP.X();
pc[1] = aP.Y();
return ttl_util::Orient2DFast( pa, pb, pc );
}
//@} // End of Geometric Predicates Group
};
};
}; // End of hed namespace

View File

@ -42,11 +42,9 @@
#ifndef _HE_TRIANG_H_
#define _HE_TRIANG_H_
#define TTL_USE_NODE_ID // Each node gets it's own unique id
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
#include <list>
#include <vector>
#include <iostream>
@ -55,43 +53,40 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace ttl {
class TriangulationHelper;
namespace ttl
{
class TRIANGULATION_HELPER;
};
//--------------------------------------------------------------------------------------------------
// The half-edge data structure
//--------------------------------------------------------------------------------------------------
namespace hed {
// Helper typedefs
class Node;
class Edge;
typedef boost::shared_ptr<Node> NodePtr;
typedef boost::shared_ptr<Edge> EdgePtr;
typedef boost::weak_ptr<Edge> EdgeWeakPtr;
typedef std::vector<NodePtr> NodesContainer;
//------------------------------------------------------------------------------------------------
// Node class for data structures
//------------------------------------------------------------------------------------------------
/** \class Node
* \brief \b Node class for data structures (Inherits from HandleId)
*
* \note
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
* - To enable node flags, TTL_USE_NODE_FLAG must be defined.
* - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is
* required by the application, because they increase the memory usage for each Node object.
*/
class Node {
/**
* The half-edge data structure
*/
namespace hed
{
// Helper typedefs
class NODE;
class EDGE;
typedef boost::shared_ptr<NODE> NODE_PTR;
typedef boost::shared_ptr<EDGE> EDGE_PTR;
typedef boost::weak_ptr<EDGE> EDGE_WEAK_PTR;
typedef std::vector<NODE_PTR> NODES_CONTAINER;
/**
* \class NODE
* \brief \b Node class for data structures (Inherits from HandleId)
*
* \note
* - To enable node IDs, TTL_USE_NODE_ID must be defined.
* - To enable node flags, TTL_USE_NODE_FLAG must be defined.
* - TTL_USE_NODE_ID and TTL_USE_NODE_FLAG should only be enabled if this functionality is
* required by the application, because they increase the memory usage for each Node object.
*/
class NODE
{
protected:
#ifdef TTL_USE_NODE_FLAG
/// TTL_USE_NODE_FLAG must be defined
bool flag_;
bool m_flag;
#endif
#ifdef TTL_USE_NODE_ID
@ -99,303 +94,378 @@ protected:
static int id_count;
/// A unique id for each node (TTL_USE_NODE_ID must be defined)
int id_;
int m_id;
#endif
int x_, y_;
/// Node coordinates
int m_x, m_y;
unsigned int refCount_;
/// Reference count
unsigned int m_refCount;
public:
/// Constructor
Node( int x = 0, int y = 0 ) :
NODE( int aX = 0, int aY = 0 ) :
#ifdef TTL_USE_NODE_FLAG
flag_( false ),
m_flag( false ),
#endif
#ifdef TTL_USE_NODE_ID
id_( id_count++ ),
m_id( id_count++ ),
#endif
x_( x ), y_( y ), refCount_( 0 ) {}
m_x( aX ), m_y( aY ), m_refCount( 0 )
{
}
/// Destructor
~Node() {}
~NODE() {}
/// Returns the x-coordinate
int GetX() const { return x_; }
int GetX() const
{
return m_x;
}
/// Returns the y-coordinate
int GetY() const { return y_; }
int GetY() const
{
return m_y;
}
#ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined)
int Id() const { return id_; }
int Id() const
{
return m_id;
}
#endif
#ifdef TTL_USE_NODE_FLAG
/// Sets the flag (TTL_USE_NODE_FLAG must be defined)
void SetFlag(bool aFlag) { flag_ = aFlag; }
void SetFlag( bool aFlag )
{
m_flag = aFlag;
}
/// Returns the flag (TTL_USE_NODE_FLAG must be defined)
const bool& GetFlag() const { return flag_; }
const bool& GetFlag() const
{
return m_flag;
}
#endif
void IncRefCount() { refCount_++; }
void DecRefCount() { refCount_--; }
unsigned int GetRefCount() const { return refCount_; }
}; // End of class Node
void IncRefCount()
{
m_refCount++;
}
void DecRefCount()
{
m_refCount--;
}
unsigned int GetRefCount() const
{
return m_refCount;
}
};
//------------------------------------------------------------------------------------------------
// Edge class in the half-edge data structure
//------------------------------------------------------------------------------------------------
/** \class Edge
* \brief \b %Edge class in the in the half-edge data structure.
*/
class Edge {
public:
/**
* \class EDGE
* \brief \b %Edge class in the in the half-edge data structure.
*/
class EDGE
{
public:
/// Constructor
Edge() : weight_(0), isLeadingEdge_(false) {}
EDGE() : m_weight( 0 ), m_isLeadingEdge( false )
{
}
/// Destructor
virtual ~Edge() {}
virtual ~EDGE()
{
}
/// Sets the source node
void setSourceNode(const NodePtr& node) { sourceNode_ = node; }
void SetSourceNode( const NODE_PTR& aNode )
{
m_sourceNode = aNode;
}
/// Sets the next edge in face
void setNextEdgeInFace(const EdgePtr& edge) { nextEdgeInFace_ = edge; }
void SetNextEdgeInFace( const EDGE_PTR& aEdge )
{
m_nextEdgeInFace = aEdge;
}
/// Sets the twin edge
void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; }
void SetTwinEdge( const EDGE_PTR& aEdge )
{
m_twinEdge = aEdge;
}
/// Sets the edge as a leading edge
void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; }
void SetAsLeadingEdge( bool aLeading = true )
{
m_isLeadingEdge = aLeading;
}
/// Checks if an edge is a leading edge
bool isLeadingEdge() const { return isLeadingEdge_; }
bool IsLeadingEdge() const
{
return m_isLeadingEdge;
}
/// Returns the twin edge
EdgePtr getTwinEdge() const { return twinEdge_.lock(); };
EDGE_PTR GetTwinEdge() const
{
return m_twinEdge.lock();
}
void clearTwinEdge() { twinEdge_.reset(); }
void ClearTwinEdge()
{
m_twinEdge.reset();
}
/// Returns the next edge in face
const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; }
const EDGE_PTR& GetNextEdgeInFace() const
{
return m_nextEdgeInFace;
}
/// Retuns the source node
const NodePtr& getSourceNode() const { return sourceNode_; }
const NODE_PTR& GetSourceNode() const
{
return m_sourceNode;
}
/// Returns the target node
virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); }
void setWeight( unsigned int weight ) { weight_ = weight; }
unsigned int getWeight() const { return weight_; }
void clear()
virtual const NODE_PTR& GetTargetNode() const
{
sourceNode_.reset();
nextEdgeInFace_.reset();
return m_nextEdgeInFace->GetSourceNode();
}
if( !twinEdge_.expired() )
void SetWeight( unsigned int weight )
{
m_weight = weight;
}
unsigned int GetWeight() const
{
return m_weight;
}
void Clear()
{
m_sourceNode.reset();
m_nextEdgeInFace.reset();
if( !m_twinEdge.expired() )
{
twinEdge_.lock()->clearTwinEdge();
twinEdge_.reset();
m_twinEdge.lock()->ClearTwinEdge();
m_twinEdge.reset();
}
}
protected:
NodePtr sourceNode_;
EdgeWeakPtr twinEdge_;
EdgePtr nextEdgeInFace_;
unsigned int weight_;
bool isLeadingEdge_;
}; // End of class Edge
protected:
NODE_PTR m_sourceNode;
EDGE_WEAK_PTR m_twinEdge;
EDGE_PTR m_nextEdgeInFace;
unsigned int m_weight;
bool m_isLeadingEdge;
};
/** \class EdgeMST
* \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm.
/**
* \class EDGE_MST
* \brief \b Specialization of %EDGE class to be used for Minimum Spanning Tree algorithm.
*/
class EdgeMST : public Edge
{
private:
NodePtr target_;
class EDGE_MST : public EDGE
{
private:
NODE_PTR m_target;
public:
EdgeMST( const NodePtr& source, const NodePtr& target, unsigned int weight = 0 ) :
target_(target)
{ sourceNode_ = source; weight_ = weight; }
EdgeMST( const Edge& edge )
public:
EDGE_MST( const NODE_PTR& aSource, const NODE_PTR& aTarget, unsigned int aWeight = 0 ) :
m_target( aTarget )
{
sourceNode_ = edge.getSourceNode();
target_ = edge.getTargetNode();
weight_ = edge.getWeight();
m_sourceNode = aSource;
m_weight = aWeight;
}
~EdgeMST() {};
EDGE_MST( const EDGE& edge )
{
m_sourceNode = edge.GetSourceNode();
m_target = edge.GetTargetNode();
m_weight = edge.GetWeight();
}
~EDGE_MST()
{
}
/// @copydoc Edge::setSourceNode()
virtual const NodePtr& getTargetNode() const { return target_; }
};
virtual const NODE_PTR& GetTargetNode() const
{
return m_target;
}
};
class DART; // Forward declaration (class in this namespace)
//------------------------------------------------------------------------------------------------
class Dart; // Forward declaration (class in this namespace)
/**
* \class TRIANGULATION
* \brief \b %Triangulation class for the half-edge data structure with adaption to TTL.
*/
class TRIANGULATION
{
protected:
/// One half-edge for each arc
std::list<EDGE_PTR> m_leadingEdges;
//------------------------------------------------------------------------------------------------
// Triangulation class in the half-edge data structure
//------------------------------------------------------------------------------------------------
ttl::TRIANGULATION_HELPER* m_helper;
/** \class Triangulation
* \brief \b %Triangulation class for the half-edge data structure with adaption to TTL.
*/
class Triangulation {
protected:
std::list<EdgePtr> leadingEdges_; // one half-edge for each arc
ttl::TriangulationHelper* helper;
void addLeadingEdge(EdgePtr& edge) {
edge->setAsLeadingEdge();
leadingEdges_.push_front( edge );
void addLeadingEdge( EDGE_PTR& aEdge )
{
aEdge->SetAsLeadingEdge();
m_leadingEdges.push_front( aEdge );
}
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
bool removeLeadingEdgeFromList( EDGE_PTR& aLeadingEdge );
void cleanAll();
/** Swaps the edge associated with \e dart in the actual data structure.
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param dart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
void swapEdge(Dart& dart);
*
* <center>
* \image html swapEdge.gif
* </center>
*
* \param aDart
* Some of the functions require a dart as output.
* If this is required by the actual function, the dart should be delivered
* back in a position as seen if it was glued to the edge when swapping (rotating)
* the edge CCW; see the figure.
*
* \note
* - If the edge is \e constrained, or if it should not be swapped for
* some other reason, this function need not do the actual swap of the edge.
* - Some functions in TTL require that \c swapEdge is implemented such that
* darts outside the quadrilateral are not affected by the swap.
*/
void swapEdge( DART& aDart );
/** Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param dart
* Output: A CCW dart incident with the new node; see the figure.
*/
void splitTriangle(Dart& dart, const NodePtr& point);
/**
* Splits the triangle associated with \e dart in the actual data structure into
* three new triangles joining at \e point.
*
* <center>
* \image html splitTriangle.gif
* </center>
*
* \param aDart
* Output: A CCW dart incident with the new node; see the figure.
*/
void splitTriangle( DART& aDart, const NODE_PTR& aPoint );
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example TrinagulationHelper::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
void reverse_splitTriangle(Dart& dart);
/**
* The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example TrinagulationHelper::RemoveInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
void reverseSplitTriangle( DART& aDart );
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void removeBoundaryTriangle(Dart& d);
/**
* Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void removeBoundaryTriangle( DART& aDart );
public:
public:
/// Default constructor
Triangulation();
TRIANGULATION();
/// Copy constructor
Triangulation(const Triangulation& tr);
TRIANGULATION( const TRIANGULATION& aTriangulation );
/// Destructor
~Triangulation();
~TRIANGULATION();
/// Creates a Delaunay triangulation from a set of points
void createDelaunay(NodesContainer::iterator first,
NodesContainer::iterator last);
void CreateDelaunay( NODES_CONTAINER::iterator aFirst, NODES_CONTAINER::iterator aLast );
/// Creates an initial Delaunay triangulation from two enclosing triangles
// When using rectangular boundary - loop through all points and expand.
// (Called from createDelaunay(...) when starting)
EdgePtr initTwoEnclosingTriangles(NodesContainer::iterator first,
NodesContainer::iterator last);
EDGE_PTR InitTwoEnclosingTriangles( NODES_CONTAINER::iterator aFirst,
NODES_CONTAINER::iterator aLast );
// These two functions are required by TTL for Delaunay triangulation
/// Swaps the edge associated with diagonal
void swapEdge(EdgePtr& diagonal);
void SwapEdge( EDGE_PTR& aDiagonal );
/// Splits the triangle associated with edge into three new triangles joining at point
EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point);
EDGE_PTR SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint );
// Functions required by TTL for removing nodes in a Delaunay triangulation
/// Removes the boundary triangle associated with edge
void removeTriangle(EdgePtr& edge); // boundary triangle required
void RemoveTriangle( EDGE_PTR& aEdge ); // boundary triangle required
/// The reverse operation of removeTriangle
void reverse_splitTriangle(EdgePtr& edge);
void ReverseSplitTriangle( EDGE_PTR& aEdge );
/// Creates an arbitrary CCW dart
Dart createDart();
DART CreateDart();
/// Returns a list of "triangles" (one leading half-edge for each triangle)
const std::list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
const std::list<EDGE_PTR>& GetLeadingEdges() const
{
return m_leadingEdges;
}
/// Returns the number of triangles
int noTriangles() const { return (int)leadingEdges_.size(); }
int NoTriangles() const
{
return (int) m_leadingEdges.size();
}
/// Returns a list of half-edges (one half-edge for each arc)
std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
std::list<EDGE_PTR>* GetEdges( bool aSkipBoundaryEdges = false ) const;
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
void flagNodes(bool flag) const;
void FlagNodes( bool aFlag ) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
std::list<NodePtr>* getNodes() const;
std::list<NODE_PTR>* GetNodes() const;
#endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
void optimizeDelaunay();
void OptimizeDelaunay();
/// Checks if the triangulation is Delaunay
bool checkDelaunay() const;
bool CheckDelaunay() const;
/// Returns an arbitrary interior node (as the source node of the returned edge)
EdgePtr getInteriorNode() const;
EDGE_PTR GetInteriorNode() const;
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
EDGE_PTR GetBoundaryEdgeInTriangle( const EDGE_PTR& aEdge ) const;
/// Returns an arbitrary boundary edge
EdgePtr getBoundaryEdge() const;
EDGE_PTR GetBoundaryEdge() const;
/// Print edges for plotting with, e.g., gnuplot
void printEdges(std::ofstream& os) const;
friend class ttl::TriangulationHelper;
}; // End of class Triangulation
void PrintEdges( std::ofstream& aOutput ) const;
friend class ttl::TRIANGULATION_HELPER;
};
}; // End of hed namespace
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,11 @@
* Applied Mathematics, Norway.
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* SINTEF ICT, DeaPArtment of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of TTL.
* This file is aPArt of TTL.
*
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@ -16,7 +16,7 @@
*
* TTL 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
* MERCHANTABILITY or FITNESS FOR A aPARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
@ -40,28 +40,22 @@
#ifndef _TTL_UTIL_H_
#define _TTL_UTIL_H_
#include <vector>
#include <algorithm>
#ifdef _MSC_VER
# if _MSC_VER < 1300
# include <minmax.h>
# endif
#endif
//using namespace std;
/** \brief Utilities
*
* This name space contains utility functions for TTL.\n
* This name saPAce contains utility functions for TTL.\n
*
* Point and vector algebra such as scalar product and cross product
* between vectors are implemented here.
* These functions are required by functions in the \ref ttl namespace,
* These functions are required by functions in the \ref ttl namesaPAce,
* where they are assumed to be present in the \ref hed::TTLtraits "TTLtraits" class.
* Thus, the user can call these functions from the traits class.
* For efficiency reasons, the user may consider implementing these
@ -77,67 +71,59 @@
* ttl and \ref api
*
* \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no
* <EFBFBD>yvind Hjelle, oyvindhj@ifi.uio.no
*/
namespace ttl_util
{
/** @name Computational geometry */
//@{
/** Scalar product between two 2D vectors.
*
* \aPAr Returns:
* \code
* aDX1*aDX2 + aDY1*aDY2
* \endcode
*/
template <class REAL_TYPE>
REAL_TYPE ScalarProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 )
{
return aDX1 * aDX2 + aDY1 * aDY2;
}
namespace ttl_util {
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
*
* \aPAr Returns:
* \code
* aDX1*aDY2 - aDY1*aDX2
* \endcode
*/
template <class REAL_TYPE>
REAL_TYPE CrossProduct2D( REAL_TYPE aDX1, REAL_TYPE aDY1, REAL_TYPE aDX2, REAL_TYPE aDY2 )
{
return aDX1 * aDY2 - aDY1 * aDX2;
}
/** Returns a positive value if the 2D nodes/points \e aPA, \e aPB, and
* \e aPC occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
*
* \note
* - This is a finite arithmetic fast version. It can be made more robust using
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
* http://www-2.cs.cmu.edu/~quake/robust.html
*/
template <class REAL_TYPE>
REAL_TYPE Orient2DFast( REAL_TYPE aPA[2], REAL_TYPE aPB[2], REAL_TYPE aPC[2] )
{
REAL_TYPE acx = aPA[0] - aPC[0];
REAL_TYPE bcx = aPB[0] - aPC[0];
REAL_TYPE acy = aPA[1] - aPC[1];
REAL_TYPE bcy = aPB[1] - aPC[1];
//------------------------------------------------------------------------------------------------
// ------------------------------ Computational Geometry Group ----------------------------------
//------------------------------------------------------------------------------------------------
/** @name Computational geometry */
//@{
//------------------------------------------------------------------------------------------------
/** Scalar product between two 2D vectors.
*
* \par Returns:
* \code
* dx1*dx2 + dy1*dy2
* \endcode
*/
template <class real_type>
real_type scalarProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
return dx1*dx2 + dy1*dy2;
}
//------------------------------------------------------------------------------------------------
/** Cross product between two 2D vectors. (The z-component of the actual cross product.)
*
* \par Returns:
* \code
* dx1*dy2 - dy1*dx2
* \endcode
*/
template <class real_type>
real_type crossProduct2d(real_type dx1, real_type dy1, real_type dx2, real_type dy2) {
return dx1*dy2 - dy1*dx2;
}
//------------------------------------------------------------------------------------------------
/** Returns a positive value if the 2D nodes/points \e pa, \e pb, and
* \e pc occur in counterclockwise order; a negative value if they occur
* in clockwise order; and zero if they are collinear.
*
* \note
* - This is a finite arithmetic fast version. It can be made more robust using
* exact arithmetic schemes by Jonathan Richard Shewchuk. See
* http://www-2.cs.cmu.edu/~quake/robust.html
*/
template <class real_type>
real_type orient2dfast(real_type pa[2], real_type pb[2], real_type pc[2]) {
real_type acx = pa[0] - pc[0];
real_type bcx = pb[0] - pc[0];
real_type acy = pa[1] - pc[1];
real_type bcy = pb[1] - pc[1];
return acx * bcy - acy * bcx;
}
}
}; // End of ttl_util namespace scope
} // namespace ttl_util
#endif // _TTL_UTIL_H_

View File

@ -94,7 +94,7 @@ public:
* first).
* @return Number of found items.
*/
int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult );
int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const;
/**
* Function SetRequired()
@ -140,7 +140,10 @@ public:
* Function SetPainter()
* Sets the painter object used by the view for drawing VIEW_ITEMS.
*/
void SetPainter( PAINTER* aPainter );
void SetPainter( PAINTER* aPainter )
{
m_painter = aPainter;
}
/**
* Function GetPainter()
@ -181,7 +184,10 @@ public:
* (depending on correct GAL unit length & DPI settings).
* @param aScale: the scalefactor
*/
void SetScale( double aScale );
void SetScale( double aScale )
{
SetScale( aScale, m_center );
}
/**
* Function SetScale()
@ -226,6 +232,14 @@ public:
*/
VECTOR2D ToWorld( const VECTOR2D& aCoord, bool aAbsolute = true ) const;
/**
* Function ToWorld()
* Converts a screen space one dimensional size to a one dimensional size in world
* space coordinates.
* @param aCoord: the size to be converted
*/
double ToWorld( double aSize ) const;
/**
* Function ToScreen()
* Converts a world space point/vector to a point/vector in screen space coordinates.
@ -247,7 +261,7 @@ public:
* Returns the size of the our rendering area, in pixels.
* @return viewport screen size
*/
VECTOR2D GetScreenPixelSize() const;
const VECTOR2I& GetScreenPixelSize() const;
/**
* Function AddLayer()
@ -279,11 +293,11 @@ public:
*/
inline void SetLayerVisible( int aLayer, bool aVisible = true )
{
if( m_layers[aLayer].enabled != aVisible )
if( m_layers[aLayer].visible != aVisible )
{
// Target has to be redrawn after changing its visibility
MarkTargetDirty( m_layers[aLayer].target );
m_layers[aLayer].enabled = aVisible;
m_layers[aLayer].visible = aVisible;
}
}
@ -294,7 +308,7 @@ public:
*/
inline bool IsLayerVisible( int aLayer ) const
{
return m_layers.at( aLayer ).enabled;
return m_layers.at( aLayer ).visible;
}
/**
@ -402,18 +416,11 @@ public:
*/
void Redraw();
/**
* Function PartialRedraw()
* Redraws only the parts of the view that have been affected by items
* for which ViewUpdate() function has been called since last redraw.
*/
void PartialRedraw();
/**
* Function RecacheAllItems()
* Rebuilds GAL display lists.
* @param aForceNow decides if every item should be instantly recached. Otherwise items are
* going to be recached when they become visible.
* going to be recached when they become visible.
*/
void RecacheAllItems( bool aForceNow = false );
@ -432,7 +439,16 @@ public:
* Returns true if any of the VIEW layers needs to be refreshened.
* @return True in case if any of layers is marked as dirty.
*/
bool IsDirty() const;
bool IsDirty() const
{
for( int i = 0; i < TARGETS_NUMBER; ++i )
{
if( IsTargetDirty( i ) )
return true;
}
return false;
}
/**
* Function IsTargetDirty()
@ -440,7 +456,12 @@ public:
* redrawn.
* @return True if the above condition is fulfilled.
*/
bool IsTargetDirty( int aTarget ) const;
bool IsTargetDirty( int aTarget ) const
{
wxASSERT( aTarget < TARGETS_NUMBER );
return m_dirtyTargets[aTarget];
}
/**
* Function MarkTargetDirty()
@ -471,48 +492,33 @@ public:
}
/**
* Function SetPanBoundary()
* Sets limits for panning area.
* @param aBoundary is the box that limits panning area.
* Function MarkForUpdate()
* Adds an item to a list of items that are going to be refreshed upon the next frame rendering.
* @param aItem is the item to be refreshed.
*/
void SetPanBoundary( const BOX2I& aBoundary )
void MarkForUpdate( VIEW_ITEM* aItem )
{
m_panBoundary = aBoundary;
m_needsUpdate.push_back( aItem );
}
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.
* @param aMaximum is the maximum value for scale..
* @param aMinimum is the minimum value for scale.
* Function UpdateItems()
* Iterates through the list of items that asked for updating and updates them.
*/
void SetScaleLimits( double aMaximum, double aMinimum )
{
wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) );
void UpdateItems();
m_scaleLimits = VECTOR2D( aMaximum, aMinimum );
}
/**
* Function InvalidateItem()
* Manages dirty flags & redraw queueing when updating an item.
* @param aItem is the item to be updated.
* @param aUpdateFlags determines the way an item is refreshed.
*/
void InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown
static const int VIEW_MAX_LAYERS = 128; ///< maximum number of layers that may be shown
private:
struct VIEW_LAYER
{
bool enabled; ///* is the layer to be rendered?
bool displayOnly; ///* is the layer display only?
VIEW_RTREE* items; ///* R-tree indexing all items on this layer.
int renderingOrder; ///* rendering order of this layer
int id; ///* layer ID
RENDER_TARGET target; ///* where the layer should be rendered
std::set<int> requiredLayers; ///* layers that have to be enabled to show the layer
bool visible; ///< is the layer to be rendered?
bool displayOnly; ///< is the layer display only?
VIEW_RTREE* items; ///< R-tree indexing all items on this layer.
int renderingOrder; ///< rendering order of this layer
int id; ///< layer ID
RENDER_TARGET target; ///< where the layer should be rendered
std::set<int> requiredLayers; ///< layers that have to be enabled to show the layer
};
// Convenience typedefs
@ -532,7 +538,7 @@ private:
///* Redraws contents within rect aRect
void redrawRect( const BOX2I& aRect );
inline void clearTargetDirty( int aTarget )
inline void markTargetClean( int aTarget )
{
wxASSERT( aTarget < TARGETS_NUMBER );
@ -549,7 +555,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items.
*/
void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ) const;
void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false );
/**
* Function draw()
@ -559,7 +565,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items.
*/
void draw( VIEW_ITEM* aItem, bool aImmediate = false ) const;
void draw( VIEW_ITEM* aItem, bool aImmediate = false );
/**
* Function draw()
@ -569,7 +575,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items.
*/
void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const;
void draw( VIEW_GROUP* aGroup, bool aImmediate = false );
///* Sorts m_orderedLayers when layer rendering order has changed
void sortLayers();
@ -578,6 +584,14 @@ private:
///* used by GAL)
void clearGroupCache();
/**
* Function invalidateItem()
* Manages dirty flags & redraw queueing when updating an item.
* @param aItem is the item to be updated.
* @param aUpdateFlags determines the way an item is refreshed.
*/
void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
/// Updates colors that are used for an item to be drawn
void updateItemColor( VIEW_ITEM* aItem, int aLayer );
@ -633,11 +647,8 @@ private:
/// Rendering order modifier for layers that are marked as top layers
static const int TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
/// Panning boundaries
BOX2I m_panBoundary;
/// Zoom limits
VECTOR2D m_scaleLimits;
/// Items to be updated
std::vector<VIEW_ITEM*> m_needsUpdate;
};
} // namespace KIGFX

View File

@ -46,14 +46,40 @@ class VIEW;
class VIEW_CONTROLS
{
public:
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_forceCursorPosition( false ),
m_snappingEnabled( false ), m_grabMouse( false ), m_autoPanEnabled( false ),
m_autoPanMargin( 0.1 ), m_autoPanSpeed( 0.15 )
{}
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_minScale( 4.0 ), m_maxScale( 15000 ),
m_forceCursorPosition( false ), m_snappingEnabled( false ), m_grabMouse( false ),
m_autoPanEnabled( false ), m_autoPanMargin( 0.1 ), m_autoPanSpeed( 0.15 )
{
m_panBoundary.SetMaximum();
}
virtual ~VIEW_CONTROLS()
{}
/**
* Function SetPanBoundary()
* Sets limits for panning area.
* @param aBoundary is the box that limits panning area.
*/
void SetPanBoundary( const BOX2I& aBoundary )
{
m_panBoundary = aBoundary;
}
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.
* @param aMaximum is the maximum value for scale.
* @param aMinimum is the minimum value for scale.
*/
void SetScaleLimits( double aMaximum, double aMinimum )
{
wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) );
m_minScale = aMinimum;
m_maxScale = aMaximum;
}
/**
* Function SetSnapping()
* Enables/disables snapping cursor to grid.
@ -108,21 +134,22 @@ public:
/**
* Function GetMousePosition()
* Returns the current mouse pointer position in the screen coordinates. Note, that it may be
* Returns the current mouse pointer position in screen coordinates. Note, that it may be
* different from the cursor position if snapping is enabled (@see GetCursorPosition()).
*
* @return The current mouse pointer position.
* @return The current mouse pointer position in screen coordinates.
*/
virtual const VECTOR2D GetMousePosition() const = 0;
virtual VECTOR2D GetMousePosition() const = 0;
/**
* Function GetCursorPosition()
* Returns the current cursor position in the screen coordinates. Note, that it may be
* different from the mouse pointer position if snapping is enabled (@see GetMousePosition()).
* Returns the current cursor position in world coordinates. Note, that it may be
* different from the mouse pointer position if snapping is enabled or cursor position
* is forced to specific point.
*
* @return The current cursor position in screen coordinates.
* @return The current cursor position in world coordinates.
*/
virtual const VECTOR2D GetCursorPosition() const = 0;
virtual VECTOR2D GetCursorPosition() const = 0;
/**
@ -131,7 +158,7 @@ public:
* @param aEnabled enable forced cursor position
* @param aPosition the position
*/
virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D(0, 0) )
virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) )
{
m_forcedPosition = aPosition;
m_forceCursorPosition = aEnabled;
@ -145,11 +172,23 @@ public:
virtual void ShowCursor( bool aEnabled );
protected:
/// Sets center for VIEW, takes into account panning boundaries.
void setCenter( const VECTOR2D& aCenter );
/// Sets scale for VIEW, takes into account scale limits.
void setScale( double aScale, const VECTOR2D& aAnchor );
/// Pointer to controlled VIEW.
VIEW* m_view;
/// Current mouse position
VECTOR2D m_mousePosition;
/// Panning boundaries.
BOX2I m_panBoundary;
/// Scale lower limit.
double m_minScale;
/// Scale upper limit.
double m_maxScale;
/// Current cursor position
VECTOR2D m_cursorPosition;

View File

@ -157,12 +157,16 @@ public:
/**
* Enum VIEW_UPDATE_FLAGS.
* Defines the how severely the shape/appearance of the item has been changed:
* - NONE: TODO
* - APPEARANCE: shape or layer set of the item have not been affected,
* only colors or visibility.
* - COLOR:
* - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it.
* - ALL: all flags above */
* - LAYERS: TODO
* - ALL: all the flags above */
enum VIEW_UPDATE_FLAGS {
NONE = 0x00, /// No updates are required
APPEARANCE = 0x01, /// Visibility flag has changed
COLOR = 0x02, /// Color has changed
GEOMETRY = 0x04, /// Position or shape has changed
@ -170,7 +174,8 @@ public:
ALL = 0xff
};
VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_groups( NULL ), m_groupsSize( 0 ) {}
VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_requiredUpdate( ALL ),
m_groups( NULL ), m_groupsSize( 0 ) {}
/**
* Destructor. For dynamic views, removes the item from the view.
@ -179,7 +184,7 @@ public:
{
ViewRelease();
delete[] m_groups;
};
}
/**
* Function Type
@ -262,9 +267,15 @@ public:
* For dynamic VIEWs, informs the associated VIEW that the graphical representation of
* this item has changed. For static views calling has no effect.
*
* @param aUpdateFlags: how much the object has changed
* @param aUpdateFlags: how much the object has changed.
*/
virtual void ViewUpdate( int aUpdateFlags = ALL );
virtual void ViewUpdate( int aUpdateFlags = ALL )
{
if( m_view && m_requiredUpdate == NONE )
m_view->MarkForUpdate( this );
m_requiredUpdate |= aUpdateFlags;
}
/**
* Function ViewRelease()
@ -298,8 +309,9 @@ protected:
deleteGroups();
}
VIEW* m_view; ///* Current dynamic view the item is assigned to.
bool m_visible; ///* Are we visible in the current dynamic VIEW.
VIEW* m_view; ///< Current dynamic view the item is assigned to.
bool m_visible; ///< Are we visible in the current dynamic VIEW.
int m_requiredUpdate; ///< Flag required for updating
///* Helper for storing cached items group ids
typedef std::pair<int, int> GroupPair;
@ -374,6 +386,24 @@ protected:
m_layers.set( aLayers[i] );
}
}
/**
* Function viewRequiredUpdate()
* Returns current update flag for an item.
*/
virtual int viewRequiredUpdate() const
{
return m_requiredUpdate;
}
/**
* Function clearUpdateFlags()
* Marks an item as already updated, so it is not going to be redrawn.
*/
void clearUpdateFlags()
{
m_requiredUpdate = NONE;
}
};
} // namespace KIGFX

View File

@ -58,13 +58,6 @@ public:
void onEnter( wxMouseEvent& WXUNUSED( aEvent ) );
void onTimer( wxTimerEvent& WXUNUSED( aEvent ) );
///> @copydoc VIEW_CONTROLS::SetSnapping()
void SetSnapping( bool aEnabled )
{
VIEW_CONTROLS::SetSnapping( aEnabled );
updateCursor();
}
/**
* Function SetGrabMouse()
* Enables/disables mouse cursor grabbing (limits the movement field only to the panel area).
@ -88,13 +81,10 @@ public:
}
/// @copydoc VIEW_CONTROLS::GetMousePosition()
const VECTOR2D GetMousePosition() const;
VECTOR2D GetMousePosition() const;
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
const VECTOR2D GetCursorPosition() const
{
return m_cursorPosition;
}
VECTOR2D GetCursorPosition() const;
/// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse
/// cursor does not move in screen coordinates, but does in world coordinates)
@ -119,12 +109,6 @@ private:
*/
bool handleAutoPanning( const wxMouseEvent& aEvent );
/**
* Function updateCursor()
* Recomputes the cursor coordinates basing on the current snapping settings and mouse position.
*/
void updateCursor();
/// Current state of VIEW_CONTROLS
STATE m_state;

View File

@ -76,8 +76,8 @@ public:
EDA_UNITS_T m_UserGridUnit;
wxRealPoint m_UserGridSize;
int m_FastGrid1;
int m_FastGrid2;
int m_FastGrid1; // 1st fast grid setting (index in EDA_DRAW_FRAME::m_gridSelectBox)
int m_FastGrid2; // 2nd fast grid setting (index in EDA_DRAW_FRAME::m_gridSelectBox)
EDA_3D_FRAME* m_Draw3DFrame;
@ -90,7 +90,7 @@ protected:
/// main window.
wxAuiToolBar* m_auxiliaryToolBar;
TOOL_MANAGER* m_toolManager;
TOOL_MANAGER& m_toolManager;
TOOL_DISPATCHER* m_toolDispatcher;
void updateGridSelectBox();
@ -203,13 +203,10 @@ public:
* Function BestZoom
* @return the "best" zoom to show the entire board or footprint on the screen.
*/
virtual double BestZoom();
virtual void Show3D_Frame( wxCommandEvent& event );
public:
// Read/write functions:
EDA_ITEM* ReadDrawSegmentDescr( LINE_READER* aReader );
int ReadListeSegmentDescr( LINE_READER* aReader,
@ -634,6 +631,20 @@ public:
void OnUpdateSelectGrid( wxUpdateUIEvent& aEvent );
void OnUpdateSelectZoom( wxUpdateUIEvent& aEvent );
/**
* Function SetFastGrid1()
*
* Switches grid settings to the 1st "fast" setting predefined by user.
*/
void SetFastGrid1();
/**
* Function SetFastGrid2()
*
* Switches grid settings to the 1st "fast" setting predefined by user.
*/
void SetFastGrid2();
DECLARE_EVENT_TABLE()
};

View File

@ -134,38 +134,10 @@ protected:
void createPopUpBlockMenu( wxMenu* menu );
void createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu );
/**
* Function setActiveLayer
* will change the currently active layer to \a aLayer and also
* update the PCB_LAYER_WIDGET.
*/
void setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true );
/**
* Function getActiveLayer
* returns the active layer
*/
LAYER_NUM getActiveLayer()
{
return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
}
/**
* Function setHighContrastLayer
* takes care of display settings for the given layer to be displayed in high contrast mode.
*/
void setHighContrastLayer( LAYER_NUM aLayer );
/**
* Function setTopLayer
* moves the selected layer to the top, so it is displayed above all others.
*/
void setTopLayer( LAYER_NUM aLayer );
/**
* Function syncLayerWidgetLayer
* updates the currently layer "selection" within the PCB_LAYER_WIDGET.
* The currently selected layer is defined by the return value of getActiveLayer().
* The currently selected layer is defined by the return value of GetActiveLayer().
* <p>
* This function cannot be inline without including layer_widget.h in
* here and we do not want to do that.
@ -225,8 +197,6 @@ public:
bool m_show_microwave_tools;
bool m_show_layer_manager_tools;
public:
virtual ~PCB_EDIT_FRAME();
void OnQuit( wxCommandEvent& event );
@ -560,6 +530,34 @@ public:
*/
virtual void OnModify();
/**
* Function SetHighContrastLayer
* takes care of display settings for the given layer to be displayed in high contrast mode.
*/
void SetHighContrastLayer( LAYER_NUM aLayer );
/**
* Function SetTopLayer
* moves the selected layer to the top, so it is displayed above all others.
*/
void SetTopLayer( LAYER_NUM aLayer );
/**
* Function SetActiveLayer
* will change the currently active layer to \a aLayer and also
* update the PCB_LAYER_WIDGET.
*/
void SetActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true );
/**
* Function GetActiveLayer
* returns the active layer
*/
LAYER_NUM GetActiveLayer() const
{
return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
}
/**
* Function IsElementVisible
* tests whether a given element category is visible. Keep this as an
@ -1479,7 +1477,7 @@ public:
/**
* Function ReadPcbNetlist
* reads \a aNetlistFileName and ppdates the footprints (load missing footprints and
* reads \a aNetlistFileName and updates the footprints (load missing footprints and
* delete on demand extra footprints) on the board.
* Update connectivity info, references, values and "TIME STAMP"
*
@ -1680,12 +1678,6 @@ public:
*/
void UpdateTitle();
void SetTopLayer( LAYER_NUM aLayer )
{
setTopLayer( aLayer );
}
DECLARE_EVENT_TABLE()
};

View File

@ -253,7 +253,12 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp
tools/selection_area.cpp
tools/bright_box.cpp
tools/edit_points.cpp
tools/edit_constraints.cpp
tools/point_editor.cpp
tools/drawing_tool.cpp
tools/edit_tool.cpp
tools/pcbnew_control.cpp
tools/pcb_tools.cpp
tools/common_actions.cpp
)

View File

@ -51,7 +51,7 @@
#include <collectors.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <math/vector2d.h>
#include <trigo.h>
@ -78,6 +78,7 @@ static const wxString FastGrid2Entry( wxT( "FastGrid2" ) );
const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] =
{
ITEM_GAL_LAYER( GP_OVERLAY ),
ITEM_GAL_LAYER( DRC_VISIBLE ),
NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
DRAW_N, COMMENT_N, ECO1_N, ECO2_N, EDGE_N,
UNUSED_LAYER_29, UNUSED_LAYER_30, UNUSED_LAYER_31,
@ -86,7 +87,7 @@ const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] =
ITEM_GAL_LAYER( RATSNEST_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ),
ITEM_GAL_LAYER( VIAS_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ), SOLDERMASK_N_FRONT,
NETNAMES_GAL_LAYER( LAYER_16_NETNAMES_VISIBLE ), LAYER_N_FRONT,
@ -132,10 +133,10 @@ END_EVENT_TABLE()
PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString & aFrameName ) :
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
m_toolManager( TOOL_MANAGER::Instance() )
{
m_Pcb = NULL;
m_toolManager = NULL;
m_toolDispatcher = NULL;
m_DisplayPadFill = true; // How to draw pads
@ -156,7 +157,7 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
SetGalCanvas( new EDA_DRAW_PANEL_GAL(
this, -1, wxPoint( 0, 0 ), m_FrameSize,
EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL ) );
EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ) );
// Hide by default, it has to be explicitly shown
GetGalCanvas()->Hide();
@ -480,7 +481,14 @@ void PCB_BASE_FRAME::OnTogglePadDrawMode( wxCommandEvent& aEvent )
KIGFX::PCB_RENDER_SETTINGS* settings =
static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
settings->LoadDisplayOptions( DisplayOpt );
GetGalCanvas()->GetView()->RecacheAllItems( true );
// Update pads
BOARD* board = GetBoard();
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
m_canvas->Refresh();
}
@ -641,7 +649,7 @@ void PCB_BASE_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
// handle color changes for transitions in and out of ID_TRACK_BUTT
if( ( GetToolId() == ID_TRACK_BUTT && aId != ID_TRACK_BUTT )
|| ( GetToolId() != ID_TRACK_BUTT && aId== ID_TRACK_BUTT ) )
|| ( GetToolId() != ID_TRACK_BUTT && aId == ID_TRACK_BUTT ) )
{
if( DisplayOpt.ContrastModeDisplay )
redraw = true;
@ -649,7 +657,7 @@ void PCB_BASE_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
// must do this after the tool has been set, otherwise pad::Draw() does
// not show proper color when DisplayOpt.ContrastModeDisplay is true.
if( redraw && m_canvas)
if( redraw && m_canvas )
m_canvas->Refresh();
}
@ -838,6 +846,9 @@ void PCB_BASE_FRAME::LoadSettings( wxConfigBase* aCfg )
view->SetRequired( SOLDERPASTE_N_BACK, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
view->SetRequired( SOLDERMASK_N_BACK, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
view->SetRequired( ITEM_GAL_LAYER( PAD_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
view->SetRequired( ITEM_GAL_LAYER( PAD_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY );
view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY );
@ -962,3 +973,29 @@ void PCB_BASE_FRAME::updateZoomSelectBox()
m_zoomSelectBox->SetSelection( i + 1 );
}
}
void PCB_BASE_FRAME::SetFastGrid1()
{
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( m_FastGrid1 );
wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED );
cmd.SetEventObject( this );
OnSelectGrid( cmd );
}
}
void PCB_BASE_FRAME::SetFastGrid2()
{
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( m_FastGrid2 );
wxCommandEvent cmd( wxEVT_COMMAND_COMBOBOX_SELECTED );
cmd.SetEventObject( this );
OnSelectGrid( cmd );
}
}

View File

@ -23,9 +23,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <boost/bind.hpp>
#include <fctsys.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <macros.h>
#include <pcbnew.h>
@ -529,7 +530,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
ratsnest->Remove( item );
@ -540,7 +541,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
ratsnest->Add( item );
@ -556,7 +557,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
view->Remove( item );
@ -570,7 +571,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1) );
}
view->Add( item );
@ -636,7 +637,7 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent )
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
m_toolManager.ProcessEvent( event );
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
@ -659,7 +660,7 @@ void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent )
// Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
m_toolManager.ProcessEvent( event );
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();

View File

@ -68,8 +68,6 @@ namespace KIGFX
// non-owning container of item candidates when searching for items on the same track.
typedef std::vector< TRACK* > TRACK_PTRS;
#define HISTORY_MAX_COUNT 8
/**
* Enum LAYER_T
@ -305,13 +303,13 @@ public:
// the first value is always the value of the current NetClass
// The others values are extra values
/// Vias size and drill list(max count = HISTORY_MAX_COUNT)
std::vector <VIA_DIMENSION> m_ViasDimensionsList;
// The first value is the current netclass via size // TODO verify
/// Vias size and drill list
std::vector<VIA_DIMENSION> m_ViasDimensionsList;
// The first value is the current netclass via size
// tracks widths (max count = HISTORY_MAX_COUNT)
// The first value is the current netclass track width
std::vector <int> m_TrackWidthList;
// The first value is the current netclass track width // TODO verify
/// Track width list
std::vector<int> m_TrackWidthList;
BOARD();

View File

@ -246,13 +246,13 @@ void BOARD_DESIGN_SETTINGS::SetEnabledLayers( LAYER_MSK aMask )
#ifndef NDEBUG
struct static_check {
static_check()
struct list_size_check {
list_size_check()
{
// Int (the type used for saving visibility settings) is only 32 bits guaranteed,
// be sure that we do not cross the limit
assert( END_PCB_VISIBLE_LIST <= 32 );
};
};
static static_check check;
static list_size_check check;
#endif

View File

@ -47,13 +47,9 @@
DIMENSION::DIMENSION( BOARD_ITEM* aParent ) :
BOARD_ITEM( aParent, PCB_DIMENSION_T ),
m_Text( this )
m_Width( Millimeter2iu( 0.2 ) ), m_Unit( INCHES ), m_Value( 0 ), m_Height( 0 ), m_Text( this )
{
m_Layer = DRAW_N;
m_Width = Millimeter2iu( 0.2 );
m_Value = 0;
m_Shape = 0;
m_Unit = INCHES;
}
@ -99,6 +95,7 @@ void DIMENSION::Copy( DIMENSION* source )
SetLayer( source->GetLayer() );
m_Width = source->m_Width;
m_Shape = source->m_Shape;
m_Height = source->m_Height;
m_Unit = source->m_Unit;
SetTimeStamp( GetNewTimeStamp() );
m_Text.Copy( &source->m_Text );
@ -109,13 +106,9 @@ void DIMENSION::Copy( DIMENSION* source )
m_featureLineGF = source->m_featureLineGF;
m_featureLineDO = source->m_featureLineDO;
m_featureLineDF = source->m_featureLineDF;
m_arrowD1O = source->m_arrowD1O;
m_arrowD1F = source->m_arrowD1F;
m_arrowD2O = source->m_arrowD2O;
m_arrowD2F = source->m_arrowD2F;
m_arrowG1O = source->m_arrowG1O;
m_arrowG1F = source->m_arrowG1F;
m_arrowG2O = source->m_arrowG2O;
m_arrowG2F = source->m_arrowG2F;
}
@ -129,13 +122,9 @@ void DIMENSION::Move( const wxPoint& offset )
m_featureLineGF += offset;
m_featureLineDO += offset;
m_featureLineDF += offset;
m_arrowG1O += offset;
m_arrowG1F += offset;
m_arrowG2O += offset;
m_arrowG2F += offset;
m_arrowD1O += offset;
m_arrowD1F += offset;
m_arrowD2O += offset;
m_arrowD2F += offset;
}
@ -162,13 +151,9 @@ void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle )
RotatePoint( &m_featureLineGF, aRotCentre, aAngle );
RotatePoint( &m_featureLineDO, aRotCentre, aAngle );
RotatePoint( &m_featureLineDF, aRotCentre, aAngle );
RotatePoint( &m_arrowG1O, aRotCentre, aAngle );
RotatePoint( &m_arrowG1F, aRotCentre, aAngle );
RotatePoint( &m_arrowG2O, aRotCentre, aAngle );
RotatePoint( &m_arrowG2F, aRotCentre, aAngle );
RotatePoint( &m_arrowD1O, aRotCentre, aAngle );
RotatePoint( &m_arrowD1F, aRotCentre, aAngle );
RotatePoint( &m_arrowD2O, aRotCentre, aAngle );
RotatePoint( &m_arrowD2F, aRotCentre, aAngle );
}
@ -190,15 +175,7 @@ void DIMENSION::Mirror( const wxPoint& axis_pos )
m_Text.SetTextPosition( newPos );
// invert angle
double newAngle = m_Text.GetOrientation();
if( newAngle >= 3600 )
newAngle -= 3600;
if( newAngle > 900 && newAngle < 2700 )
newAngle -= 1800;
m_Text.SetOrientation( newAngle );
m_Text.SetOrientation( -m_Text.GetOrientation() );
INVERT( m_crossBarO.y );
INVERT( m_crossBarF.y );
@ -206,17 +183,49 @@ void DIMENSION::Mirror( const wxPoint& axis_pos )
INVERT( m_featureLineGF.y );
INVERT( m_featureLineDO.y );
INVERT( m_featureLineDF.y );
INVERT( m_arrowG1O.y );
INVERT( m_arrowG1F.y );
INVERT( m_arrowG2O.y );
INVERT( m_arrowG2F.y );
INVERT( m_arrowD1O.y );
INVERT( m_arrowD1F.y );
INVERT( m_arrowD2O.y );
INVERT( m_arrowD2F.y );
}
void DIMENSION::SetOrigin( const wxPoint& aOrigin )
{
m_featureLineGO = aOrigin;
AdjustDimensionDetails();
}
void DIMENSION::SetEnd( const wxPoint& aEnd )
{
m_featureLineDO = aEnd;
AdjustDimensionDetails();
}
void DIMENSION::SetHeight( int aHeight )
{
m_Height = aHeight;
AdjustDimensionDetails();
}
void DIMENSION::UpdateHeight()
{
VECTOR2D featureLine( m_crossBarO - m_featureLineGO );
VECTOR2D crossBar( m_featureLineDO - m_featureLineGO );
if( featureLine.Cross( crossBar ) > 0 )
m_Height = -featureLine.EuclideanNorm();
else
m_Height = featureLine.EuclideanNorm();
}
void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
{
const int arrowz = DMils2iu( 500 ); // size of arrows
@ -271,30 +280,28 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
arrow_dw_Y = wxRound( arrowz * sin( angle_f ) );
}
m_arrowG1O.x = m_crossBarO.x;
m_arrowG1O.y = m_crossBarO.y;
int dx = KiROUND( m_Height * cos( angle + M_PI / 2 ) );
int dy = KiROUND( m_Height * sin( angle + M_PI / 2 ) );
m_crossBarO.x = m_featureLineGO.x + dx;
m_crossBarO.y = m_featureLineGO.y + dy;
m_crossBarF.x = m_featureLineDO.x + dx;
m_crossBarF.y = m_featureLineDO.y + dy;
m_arrowG1F.x = m_crossBarO.x + arrow_up_X;
m_arrowG1F.y = m_crossBarO.y + arrow_up_Y;
m_arrowG2O.x = m_crossBarO.x;
m_arrowG2O.y = m_crossBarO.y;
m_arrowG2F.x = m_crossBarO.x + arrow_dw_X;
m_arrowG2F.y = m_crossBarO.y + arrow_dw_Y;
/* The right arrow is symmetrical to the left.
* / = -\ and \ = -/
*/
m_arrowD1O.x = m_crossBarF.x;
m_arrowD1O.y = m_crossBarF.y;
m_arrowD1F.x = m_crossBarF.x - arrow_dw_X;
m_arrowD1F.y = m_crossBarF.y - arrow_dw_Y;
m_arrowD2O.x = m_crossBarF.x;
m_arrowD2O.y = m_crossBarF.y;
m_arrowD2F.x = m_crossBarF.x - arrow_up_X;
m_arrowD2F.y = m_crossBarF.y - arrow_up_Y;
m_featureLineGF.x = m_crossBarO.x + hx;
m_featureLineGF.y = m_crossBarO.y + hy;
@ -358,13 +365,13 @@ void DIMENSION::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color,
m_featureLineGF + offset, width, gcolor );
GRLine( panel->GetClipBox(), DC, m_featureLineDO + offset,
m_featureLineDF + offset, width, gcolor );
GRLine( panel->GetClipBox(), DC, m_arrowD1O + offset,
GRLine( panel->GetClipBox(), DC, m_crossBarF + offset,
m_arrowD1F + offset, width, gcolor );
GRLine( panel->GetClipBox(), DC, m_arrowD2O + offset,
GRLine( panel->GetClipBox(), DC, m_crossBarF + offset,
m_arrowD2F + offset, width, gcolor );
GRLine( panel->GetClipBox(), DC, m_arrowG1O + offset,
GRLine( panel->GetClipBox(), DC, m_crossBarO + offset,
m_arrowG1F + offset, width, gcolor );
GRLine( panel->GetClipBox(), DC, m_arrowG2O + offset,
GRLine( panel->GetClipBox(), DC, m_crossBarO + offset,
m_arrowG2F + offset, width, gcolor );
break;
@ -375,13 +382,13 @@ void DIMENSION::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color,
m_featureLineGF + offset, width, gcolor );
GRCSegm( panel->GetClipBox(), DC, m_featureLineDO + offset,
m_featureLineDF + offset, width, gcolor );
GRCSegm( panel->GetClipBox(), DC, m_arrowD1O + offset,
GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset,
m_arrowD1F + offset, width, gcolor );
GRCSegm( panel->GetClipBox(), DC, m_arrowD2O + offset,
GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset,
m_arrowD2F + offset, width, gcolor );
GRCSegm( panel->GetClipBox(), DC, m_arrowG1O + offset,
GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset,
m_arrowG1F + offset, width, gcolor );
GRCSegm( panel->GetClipBox(), DC, m_arrowG2O + offset,
GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset,
m_arrowG2F + offset, width, gcolor );
break;
}
@ -414,16 +421,16 @@ bool DIMENSION::HitTest( const wxPoint& aPosition ) const
if( TestSegmentHit( aPosition, m_featureLineDO, m_featureLineDF, dist_max ) )
return true;
if( TestSegmentHit( aPosition, m_arrowD1O, m_arrowD1F, dist_max ) )
if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD1F, dist_max ) )
return true;
if( TestSegmentHit( aPosition, m_arrowD2O, m_arrowD2F, dist_max ) )
if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD2F, dist_max ) )
return true;
if( TestSegmentHit( aPosition, m_arrowG1O, m_arrowG1F, dist_max ) )
if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG1F, dist_max ) )
return true;
if( TestSegmentHit( aPosition, m_arrowG2O, m_arrowG2F, dist_max ) )
if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG2F, dist_max ) )
return true;
return false;

View File

@ -41,25 +41,40 @@ class TEXTE_PCB;
class MSG_PANEL_ITEM;
/**
* Class DIMENSION
*
* For better understanding of the points that make a dimension:
*
* m_featureLineGO m_featureLineDO
* | |
* | |
* | |
* | m_arrowG2F m_arrowD2F |
* | / \ |
* m_crossBarO|/____________________________\|m_crossBarF
* |\ m_Text /|
* | \ / |
* | m_arrowG1F m_arrowD1F |
* | |
* m_featureLineGF m_featureLineDF
*/
class DIMENSION : public BOARD_ITEM
{
int m_Width;
int m_Shape; // / Currently always 0.
int m_Unit; // / 0 = inches, 1 = mm
int m_Value; // / value of PCB dimensions.
int m_Width; ///< Line width
int m_Shape; ///< Currently always 0.
EDA_UNITS_T m_Unit; ///< 0 = inches, 1 = mm
int m_Value; ///< value of PCB dimensions.
int m_Height; ///< length of feature lines
TEXTE_PCB m_Text;
public:
// private: These member should be private. they are public only due to legacy code
// TODO private: These member should be private. they are public only due to legacy code
wxPoint m_crossBarO, m_crossBarF;
wxPoint m_featureLineGO, m_featureLineGF;
wxPoint m_featureLineDO, m_featureLineDF;
wxPoint m_arrowD1O, m_arrowD1F;
wxPoint m_arrowD2O, m_arrowD2F;
wxPoint m_arrowG1O, m_arrowG1F;
wxPoint m_arrowG2O, m_arrowG2F;
wxPoint m_arrowD1F, m_arrowD2F;
wxPoint m_arrowG1F, m_arrowG2F;
DIMENSION( BOARD_ITEM* aParent );
@ -88,6 +103,72 @@ public:
int GetWidth() const { return m_Width; }
void SetWidth( int aWidth ) { m_Width = aWidth; }
/**
* Function SetOrigin
* Sets a new origin of the crossbar line. All remaining lines are adjusted after that.
* @param aOrigin is the new point to be used as the new origin of the crossbar line.
*/
void SetOrigin( const wxPoint& aOrigin );
/**
* Function GetOrigin
* @return Origin of the crossbar line.
*/
const wxPoint& GetOrigin() const
{
return m_featureLineGO;
}
/**
* Function SetEnd
* Sets a new end of the crossbar line. All remaining lines are adjusted after that.
* @param aEnd is the new point to be used as the new end of the crossbar line.
*/
void SetEnd( const wxPoint& aEnd );
/**
* Function GetEnd
* @return End of the crossbar line.
*/
const wxPoint& GetEnd()
{
return m_featureLineDO;
}
/**
* Function SetHeight
* Sets the length of feature lines.
* @param aHeight is the new height.
*/
void SetHeight( int aHeight );
/**
* Function GetHeight
* Returns the length of feature lines.
*/
int GetHeight() const
{
return m_Height;
}
/**
* Function UpdateHeight
* Updates stored height basing on points coordinates.
*/
void UpdateHeight();
/**
* Function GetAngle
* Returns angle of the crossbar.
* @return Angle of the crossbar line expressed in radians.
*/
double GetAngle() const
{
wxPoint delta( m_featureLineDO - m_featureLineGO );
return atan2( delta.y, delta.x );
}
/**
* Function AdjustDimensionDetails
* Calculate coordinates of segments used to draw the dimension.

View File

@ -34,6 +34,7 @@
#include <PolyLine.h>
#include <math_for_graphics.h>
#include <trigo.h>
#include <common.h>
class LINE_READER;

View File

@ -46,7 +46,7 @@
MARKER_PCB::MARKER_PCB( BOARD_ITEM* aParent ) :
BOARD_ITEM( aParent, PCB_MARKER_T ),
MARKER_BASE( )
MARKER_BASE(), m_item( NULL )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
@ -57,8 +57,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos ) :
BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add()
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos )
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ), m_item( NULL )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
@ -67,7 +66,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos ) :
BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add()
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos )
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ), m_item( NULL )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
@ -136,3 +135,10 @@ wxString MARKER_PCB::GetSelectMenuText() const
return text;
}
void MARKER_PCB::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 1;
aLayers[0] = ITEM_GAL_LAYER( DRC_VISIBLE );
}

View File

@ -64,6 +64,16 @@ public:
const wxPoint& GetPosition() const { return m_Pos; }
void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; }
void SetItem( const BOARD_ITEM* aItem )
{
m_item = aItem;
}
const BOARD_ITEM* GetItem() const
{
return m_item;
}
bool HitTest( const wxPoint& aPosition ) const
{
return HitTestMarker( aPosition );
@ -77,9 +87,22 @@ public:
BITMAP_DEF GetMenuImage() const { return drc_xpm; }
///> @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const
{
return GetParent()->ViewBBox();
}
///> @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
#endif
protected:
///> Pointer to BOARD_ITEM that causes DRC error.
const BOARD_ITEM* m_item;
};
#endif // CLASS_MARKER_PCB_H

View File

@ -749,20 +749,20 @@ void MODULE::ViewUpdate( int aUpdateFlags )
if( !m_view )
return;
// Update the module itself
VIEW_ITEM::ViewUpdate( aUpdateFlags );
// Update pads
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
m_view->InvalidateItem( pad, aUpdateFlags );
pad->ViewUpdate( aUpdateFlags );
// Update module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
m_view->InvalidateItem( drawing, aUpdateFlags );
drawing->ViewUpdate( aUpdateFlags );
// Update module's texts
m_view->InvalidateItem( m_Reference, aUpdateFlags );
m_view->InvalidateItem( m_Value, aUpdateFlags );
// Update the module itself
m_view->InvalidateItem( this, aUpdateFlags );
m_Reference->ViewUpdate( aUpdateFlags );
m_Value->ViewUpdate( aUpdateFlags );
}

View File

@ -31,7 +31,7 @@
#include <fctsys.h>
#include <pgm_base.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <painter.h>
@ -185,7 +185,7 @@ void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
if( IsCopperLayer( layer ) )
{
bool loc_visible = visible;
if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
loc_visible = true;
cb->SetValue( loc_visible );
@ -356,7 +356,7 @@ bool PCB_LAYER_WIDGET::OnLayerSelect( LAYER_NUM aLayer )
{
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
// false from this function.
myframe->setActiveLayer( aLayer, false );
myframe->SetActiveLayer( aLayer, false );
if( m_alwaysShowActiveCopperLayer )
OnLayerSelected();

View File

@ -87,11 +87,13 @@ public:
virtual void SetPosition( const wxPoint& aPos )
{
m_Pos = aPos;
SetLocalCoord();
}
void Move( const wxPoint& aMoveVector )
{
m_Pos += aMoveVector;
SetLocalCoord();
}
void Rotate( const wxPoint& aRotCentre, double aAngle );
@ -106,7 +108,7 @@ public:
void SetVisible( bool isVisible ) { m_NoShow = !isVisible; }
bool IsVisible() const { return !m_NoShow; }
void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; }
void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; SetDrawCoord(); }
const wxPoint& GetPos0() const { return m_Pos0; }
void Copy( TEXTE_MODULE* source ); // copy structure

View File

@ -996,7 +996,7 @@ void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
{
// Just show it on common via & via holes layers
aLayers[0] = ITEM_GAL_LAYER( VIAS_VISIBLE );
aLayers[0] = ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE );
aLayers[1] = ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE );
aCount = 2;
}

View File

@ -362,19 +362,6 @@ public:
*/
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
/**
* Function Fill_Zone
* Calculate the zone filling
* The zone outline is a frontier, and can be complex (with holes)
* The filling starts from starting points like pads, tracks.
* If exists the old filling is removed
* @param frame = reference to the main frame
* @param DC = current Device Context
* @param verbose = true to show error messages
* @return error level (0 = no error)
*/
int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true );
/**
* Function FillZoneAreasWithSegments
* Fill sub areas in a zone with segments with m_ZoneMinThickness width

View File

@ -38,6 +38,7 @@
#include <class_track.h>
#include <connect.h>
#include <dialog_cleaning_options.h>
#include <ratsnest_data.h>
// Helper class used to clean tracks and vias
class TRACKS_CLEANER: CONNECTIONS
@ -225,6 +226,8 @@ bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
(alt_via->GetStart() == aVia->GetStart()) )
{
// delete via
m_Brd->GetRatsnest()->Remove( alt_via );
alt_via->ViewRelease();
alt_via->DeleteStructure();
modified = true;
}
@ -262,6 +265,8 @@ bool TRACKS_CLEANER::clean_vias()
if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS )
{
// redundant: delete the via
m_Brd->GetRatsnest()->Remove( via );
via->ViewRelease();
via->DeleteStructure();
modified = true;
break;
@ -372,6 +377,8 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
if( flag_erase )
{
// remove segment from board
m_Brd->GetRatsnest()->Remove( track );
track->ViewRelease();
track->DeleteStructure();
/* keep iterating, because a track connected to the deleted track
@ -398,6 +405,8 @@ bool TRACKS_CLEANER::delete_null_segments()
if( segment->IsNull() ) // Length segment = 0; delete it
{
m_Brd->GetRatsnest()->Remove( segment );
segment->ViewRelease();
segment->DeleteStructure();
modified = true;
}
@ -428,6 +437,8 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
((aTrack->GetStart() == other->GetEnd()) &&
(aTrack->GetEnd() == other->GetStart())))
{
m_Brd->GetRatsnest()->Remove( other );
other->ViewRelease();
other->DeleteStructure();
modified = true;
}
@ -476,6 +487,8 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
if( segDelete )
{
m_Brd->GetRatsnest()->Remove( segDelete );
segDelete->ViewRelease();
segDelete->DeleteStructure();
merged_this = true;
}
@ -520,6 +533,8 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
if( segDelete )
{
m_Brd->GetRatsnest()->Remove( segDelete );
segDelete->ViewRelease();
segDelete->DeleteStructure();
merged_this = true;
}
@ -663,6 +678,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetStart( aCandidate->GetEnd());
aTrackRef->start = aCandidate->end;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
else
@ -670,6 +686,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetStart( aCandidate->GetStart() );
aTrackRef->start = aCandidate->start;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
}
@ -686,6 +703,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetEnd( aCandidate->GetEnd() );
aTrackRef->end = aCandidate->end;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
else
@ -693,6 +711,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
aTrackRef->SetEnd( aCandidate->GetStart() );
aTrackRef->end = aCandidate->start;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
}

View File

@ -34,6 +34,7 @@
#include <wxPcbStruct.h>
#include <macros.h>
#include <pcbcommon.h>
#include <ratsnest_data.h>
#include <class_board.h>
#include <class_track.h>
@ -53,7 +54,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
{
if( g_CurrentTrackList.GetCount() > 0 )
{
LAYER_NUM previous_layer = getActiveLayer();
LAYER_NUM previous_layer = GetActiveLayer();
DBG( g_CurrentTrackList.VerifyListIntegrity(); )
@ -86,7 +87,7 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
// Correct active layer which could change if a via
// has been erased
setActiveLayer( previous_layer );
SetActiveLayer( previous_layer );
UpdateStatusBar();
@ -124,6 +125,8 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
DLIST<TRACK>* container = (DLIST<TRACK>*)aTrack->GetList();
wxASSERT( container );
GetBoard()->GetRatsnest()->Remove( aTrack );
aTrack->ViewRelease();
container->Remove( aTrack );
// redraw the area where the track was
@ -174,6 +177,8 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
if( segm->GetNetCode() != net_code_delete )
break;
GetBoard()->GetRatsnest()->Remove( segm );
segm->ViewRelease();
GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was
@ -219,6 +224,8 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
<< TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \
<< std::endl; )
GetBoard()->GetRatsnest()->Remove( tracksegment );
tracksegment->ViewRelease();
GetBoard()->m_Track.Remove( tracksegment );
// redraw the area where the track was

View File

@ -18,7 +18,7 @@
#include <dialog_display_options.h>
#include <dialog_display_options_base.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <pcb_painter.h>
@ -177,10 +177,7 @@ void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event)
settings->LoadDisplayOptions( DisplayOpt );
view->RecacheAllItems( true );
if( m_Parent->IsGalCanvasActive() )
m_Parent->GetGalCanvas()->Refresh();
else
m_Parent->GetCanvas()->Refresh();
m_Parent->GetCanvas()->Refresh();
EndModal( 1 );
}

View File

@ -40,9 +40,10 @@
#include <kicad_string.h>
#include <pcbnew_id.h>
#include <class_board.h>
#include <collectors.h>
#include <dialog_general_options.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <pcb_painter.h>
#include <base_units.h>
@ -157,7 +158,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
static_cast<KIGFX::PCB_PAINTER*> ( GetGalCanvas()->GetView()->GetPainter() );
KIGFX::PCB_RENDER_SETTINGS* settings =
static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
bool recache = false;
KICAD_T updateType = EOT;
switch( id )
{
@ -192,31 +193,31 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
case ID_TB_OPTIONS_SHOW_ZONES:
DisplayOpt.DisplayZonesMode = 0;
recache = true;
updateType = PCB_ZONE_AREA_T;
m_canvas->Refresh();
break;
case ID_TB_OPTIONS_SHOW_ZONES_DISABLE:
DisplayOpt.DisplayZonesMode = 1;
recache = true;
updateType = PCB_ZONE_AREA_T;
m_canvas->Refresh();
break;
case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY:
DisplayOpt.DisplayZonesMode = 2;
recache = true;
updateType = PCB_ZONE_AREA_T;
m_canvas->Refresh();
break;
case ID_TB_OPTIONS_SHOW_VIAS_SKETCH:
m_DisplayViaFill = DisplayOpt.DisplayViaFill = !state;
recache = true;
updateType = PCB_VIA_T;
m_canvas->Refresh();
break;
case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH:
m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill = !state;
recache = true;
updateType = PCB_TRACE_T;
m_canvas->Refresh();
break;
@ -227,7 +228,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
// Apply new display options to the GAL canvas (this is faster than recaching)
settings->LoadDisplayOptions( DisplayOpt );
setHighContrastLayer( getActiveLayer() );
SetHighContrastLayer( GetActiveLayer() );
m_canvas->Refresh();
break;
@ -260,11 +261,18 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
break;
}
if( recache )
if( updateType != EOT )
{
// Apply new display options to the GAL canvas
settings->LoadDisplayOptions( DisplayOpt );
GetGalCanvas()->GetView()->RecacheAllItems( true );
// Find items that require update
KICAD_T scanList[] = { updateType, EOT };
TYPE_COLLECTOR collector;
collector.Collect( GetBoard(), scanList );
for( int i = 0; i < collector.GetCount(); ++i )
collector[i]->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
if( IsGalCanvasActive() )

View File

@ -1,7 +1,27 @@
/**
* @file dialog_global_deletion.cpp
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2014 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
*/
#include <boost/bind.hpp>
#include <fctsys.h>
#include <class_drawpanel.h>
@ -9,6 +29,7 @@
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <pcbcommon.h>
#include <ratsnest_data.h>
#include <class_board.h>
#include <class_module.h>
@ -39,7 +60,7 @@ DIALOG_GLOBAL_DELETION::DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent )
void PCB_EDIT_FRAME::InstallPcbGlobalDeleteFrame( const wxPoint& pos )
{
DIALOG_GLOBAL_DELETION dlg( this );
dlg.SetCurrentLayer( getActiveLayer() );
dlg.SetCurrentLayer( GetActiveLayer() );
dlg.ShowModal();
}
@ -80,14 +101,15 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
}
else
{
if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) )
return;
BOARD* pcb = m_Parent->GetBoard();
PICKED_ITEMS_LIST pickersList;
ITEM_PICKER itemPicker( NULL, UR_DELETED );
BOARD_ITEM* item, * nextitem;
BOARD_ITEM* item;
BOARD_ITEM* nextitem;
RN_DATA* ratsnest = pcb->GetRatsnest();
LAYER_MSK layers_filter = ALL_LAYERS;
@ -101,12 +123,13 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
while( item != NULL )
{
if( GetLayerMask( item->GetLayer() ) & layers_filter )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
pcb->Remove( item );
item->ViewRelease();
ratsnest->Remove( item );
gen_rastnest = true;
}
else
@ -138,6 +161,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink();
}
}
@ -155,6 +179,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink();
}
}
@ -162,7 +187,6 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
if( m_DelModules->GetValue() )
{
for( item = pcb->m_Modules; item; item = nextitem )
{
nextitem = item->Next();
@ -173,6 +197,10 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
static_cast<MODULE*>( item )->RunOnChildren(
boost::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) );
ratsnest->Remove( item );
item->ViewRelease();
item->UnLink();
gen_rastnest = true;
}
@ -189,27 +217,29 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( )
if( !m_TrackFilterAR->GetValue() )
track_mask_filter |= TRACK_AR;
TRACK * nexttrack;
TRACK* nexttrack;
for( TRACK *track = pcb->m_Track; track != NULL; track = nexttrack )
{
nexttrack = track->Next();
if( (track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter) != 0 )
if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 )
continue;
if( (track->GetState( TRACK_LOCKED | TRACK_AR ) == 0) &&
if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) == 0 ) &&
!m_TrackFilterNormal->GetValue() )
continue;
if( (track->Type() == PCB_VIA_T) && !m_TrackFilterVias->GetValue() )
if( ( track->Type() == PCB_VIA_T ) && !m_TrackFilterVias->GetValue() )
continue;
if( (track->GetLayerMask() & layers_filter) == 0 )
if( ( track->GetLayerMask() & layers_filter ) == 0 )
continue;
itemPicker.SetItem( track );
pickersList.PushItem( itemPicker );
track->ViewRelease();
ratsnest->Remove( track );
track->UnLink();
gen_rastnest = true;
}

View File

@ -1,6 +1,25 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dialog_global_deletion.h
/////////////////////////////////////////////////////////////////////////////
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2014 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
*/
#ifndef _DIALOG_GLOBAL_DELETION_H_
#define _DIALOG_GLOBAL_DELETION_H_
@ -9,20 +28,20 @@
class DIALOG_GLOBAL_DELETION: public DIALOG_GLOBAL_DELETION_BASE
{
private:
PCB_EDIT_FRAME * m_Parent;
LAYER_NUM m_currentLayer;
public:
DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent );
void SetCurrentLayer( LAYER_NUM aLayer );
private:
PCB_EDIT_FRAME* m_Parent;
LAYER_NUM m_currentLayer;
void OnOkClick( wxCommandEvent& event )
{
AcceptPcbDelete();
EndModal(wxID_OK);
}
void OnCancelClick( wxCommandEvent& event )
{
EndModal(wxID_CANCEL);

View File

@ -670,11 +670,11 @@ void PCB_EDIT_FRAME::InstallDialogLayerSetup()
if( dlg.ShowModal() == wxID_CANCEL )
return;
wxLogDebug( wxT( "Current layer selected %d." ), getActiveLayer() );
wxLogDebug( wxT( "Current layer selected %d." ), GetActiveLayer() );
// If the current active layer was removed, find the next avaiable layer to set as the
// active layer.
if( !( GetLayerMask( getActiveLayer() ) & GetBoard()->GetEnabledLayers() ) )
if( !( GetLayerMask( GetActiveLayer() ) & GetBoard()->GetEnabledLayers() ) )
{
for( LAYER_NUM i = FIRST_LAYER; i < NB_LAYERS; ++i )
{
@ -685,14 +685,14 @@ void PCB_EDIT_FRAME::InstallDialogLayerSetup()
if( GetLayerMask( tmp ) & GetBoard()->GetEnabledLayers() )
{
wxLogDebug( wxT( "Setting current layer to %d." ), getActiveLayer() );
setActiveLayer( tmp, true );
wxLogDebug( wxT( "Setting current layer to %d." ), GetActiveLayer() );
SetActiveLayer( tmp, true );
break;
}
}
}
else
{
setActiveLayer( getActiveLayer(), true );
SetActiveLayer( GetActiveLayer(), true );
}
}

View File

@ -255,16 +255,9 @@ DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC )
aDimension = new DIMENSION( GetBoard() );
aDimension->SetFlags( IS_NEW );
aDimension->SetLayer( getActiveLayer() );
aDimension->m_crossBarO = aDimension->m_crossBarF = pos;
aDimension->m_featureLineDO = aDimension->m_featureLineDF = pos;
aDimension->m_featureLineGO = aDimension->m_featureLineGF = pos;
aDimension->m_arrowG1O = aDimension->m_arrowG1F = pos;
aDimension->m_arrowG2O = aDimension->m_arrowG2F = pos;
aDimension->m_arrowD1O = aDimension->m_arrowD1F = pos;
aDimension->m_arrowD2O = aDimension->m_arrowD2F = pos;
aDimension->SetLayer( GetActiveLayer() );
aDimension->SetOrigin( pos );
aDimension->SetEnd( pos );
aDimension->Text().SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
@ -334,24 +327,12 @@ static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
}
else
{
wxPoint delta;
int dx, dy;
double angle, depl;
delta = Dimension->m_featureLineDO - Dimension->m_featureLineGO;
/* Calculating the direction of travel perpendicular to the selected axis. */
angle = atan2( delta.y, delta.x ) + (M_PI / 2);
double angle = Dimension->GetAngle() + (M_PI / 2);
delta = pos - Dimension->m_featureLineDO;
depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
dx = KiROUND( depl * cos( angle ) );
dy = KiROUND( depl * sin( angle ) );
Dimension->m_crossBarO.x = Dimension->m_featureLineGO.x + dx;
Dimension->m_crossBarO.y = Dimension->m_featureLineGO.y + dy;
Dimension->m_crossBarF.x = Dimension->m_featureLineDO.x + dx;
Dimension->m_crossBarF.y = Dimension->m_featureLineDO.y + dy;
Dimension->AdjustDimensionDetails( );
wxPoint delta = pos - Dimension->m_featureLineDO;
double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
Dimension->SetHeight( depl );
}
Dimension->Draw( aPanel, aDC, GR_XOR );

View File

@ -38,6 +38,8 @@
#include <class_track.h>
#include <class_pad.h>
#include <class_zone.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <pcbnew.h>
#include <drc_stuff.h>
@ -312,6 +314,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_CLEARANCE, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -327,6 +330,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_TRACKWIDTH, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -341,6 +345,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_VIASIZE, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -355,6 +360,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_VIADRILLSIZE, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -369,6 +375,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_uVIASIZE, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -383,6 +390,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg )
m_currentMarker = fillMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
ret = false;
}
@ -447,6 +455,7 @@ void DRC::testPad2Pad()
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
}
@ -493,6 +502,7 @@ void DRC::testTracks( bool aShowProgressBar )
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
}
@ -554,6 +564,7 @@ void DRC::testZones()
m_currentMarker = fillMarker( test_area,
DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
}
@ -589,6 +600,7 @@ void DRC::testKeepoutAreas()
m_currentMarker = fillMarker( segm, NULL,
DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
}
@ -605,6 +617,7 @@ void DRC::testKeepoutAreas()
m_currentMarker = fillMarker( segm, NULL,
DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
}

View File

@ -101,12 +101,17 @@ MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorC
else
{
if( aItem )
{
fillMe = new MARKER_PCB( aErrorCode, position,
textA, aTrack->GetPosition(),
textB, posB );
fillMe->SetItem( aItem );
}
else
{
fillMe = new MARKER_PCB( aErrorCode, position,
textA, aTrack->GetPosition() );
}
}
return fillMe;
@ -122,9 +127,14 @@ MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PC
wxPoint posB = bPad->GetPosition();
if( fillMe )
{
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
}
else
{
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB );
fillMe->SetItem( aPad ); // TODO it has to be checked
}
return fillMe;
}
@ -137,9 +147,14 @@ MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB*
wxPoint posA = aArea->GetPosition();
if( fillMe )
{
fillMe->SetData( aErrorCode, posA, textA, posA );
}
else
{
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
fillMe->SetItem( aArea );
}
return fillMe;
}
@ -155,9 +170,14 @@ MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea,
wxPoint posA = aPos;
if( fillMe )
{
fillMe->SetData( aErrorCode, posA, textA, posA );
}
else
{
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
fillMe->SetItem( aArea );
}
return fillMe;
}

View File

@ -55,6 +55,9 @@
#include <dialog_global_edit_tracks_and_vias.h>
#include <invoke_pcb_dialog.h>
#include <tool/tool_manager.h>
#include <tools/common_actions.h>
// Handles the selection of command events.
void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
@ -419,14 +422,14 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->SetIgnoreMouseEvents( true );
wxPoint dlgPosition;
wxGetMousePosition( &dlgPosition.x, &dlgPosition.y );
LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS,
LAYER_NUM layer = SelectLayer( GetActiveLayer(), ALL_NO_CU_LAYERS,
dlgPosition );
m_canvas->SetIgnoreMouseEvents( false );
m_canvas->MoveCursorToCrossHair();
if( getActiveLayer() != layer )
if( GetActiveLayer() != layer )
{
GetScreen()->m_Route_Layer_TOP = getActiveLayer();
GetScreen()->m_Route_Layer_TOP = GetActiveLayer();
GetScreen()->m_Route_Layer_BOTTOM = layer;
Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
}
@ -953,17 +956,17 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_SELECT_LAYER:
itmp = SelectLayer( getActiveLayer() );
itmp = SelectLayer( GetActiveLayer() );
if( itmp >= 0 )
{
// if user changed colors and we are in high contrast mode, then redraw
// because the PAD_SMD pads may change color.
if( DisplayOpt.ContrastModeDisplay && getActiveLayer() != itmp )
if( DisplayOpt.ContrastModeDisplay && GetActiveLayer() != itmp )
{
m_canvas->Refresh();
}
setActiveLayer( itmp );
SetActiveLayer( itmp );
}
m_canvas->MoveCursorToCrossHair();
@ -974,19 +977,19 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_SELECT_NO_CU_LAYER:
itmp = SelectLayer( getActiveLayer(), ALL_CU_LAYERS );
itmp = SelectLayer( GetActiveLayer(), ALL_CU_LAYERS );
if( itmp >= 0 )
setActiveLayer( itmp );
SetActiveLayer( itmp );
m_canvas->MoveCursorToCrossHair();
break;
case ID_POPUP_PCB_SELECT_CU_LAYER:
itmp = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS );
itmp = SelectLayer( GetActiveLayer(), ALL_NO_CU_LAYERS );
if( itmp >= 0 )
setActiveLayer( itmp );
SetActiveLayer( itmp );
break;
@ -996,7 +999,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_TOOLBARH_PCB_SELECT_LAYER:
setActiveLayer( m_SelLayerBox->GetLayerSelection() );
SetActiveLayer( m_SelLayerBox->GetLayerSelection() );
if( DisplayOpt.ContrastModeDisplay )
m_canvas->Refresh( true );
@ -1299,7 +1302,7 @@ void PCB_EDIT_FRAME::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer )
{
LAYER_NUM curLayer = getActiveLayer();
LAYER_NUM curLayer = GetActiveLayer();
// Check if the specified layer matches the present layer
if( layer == curLayer )
@ -1341,7 +1344,7 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer )
GetScreen()->m_Route_Layer_TOP = curLayer;
GetScreen()->m_Route_Layer_BOTTOM = layer;
setActiveLayer( curLayer );
SetActiveLayer( curLayer );
if( Other_Layer_Route( (TRACK*) GetScreen()->GetCurItem(), DC ) )
{
@ -1362,7 +1365,7 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_NUM layer )
// and a non-copper layer, or vice-versa?
// ...
setActiveLayer( layer );
SetActiveLayer( layer );
if( DisplayOpt.ContrastModeDisplay )
m_canvas->Refresh();
@ -1376,99 +1379,125 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
if( GetToolId() == id )
return;
INSTALL_UNBUFFERED_DC( dc, m_canvas );
// Stop the current command and deselect the current tool.
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
switch( id )
if( IsGalCanvasActive() )
{
case ID_NO_TOOL_SELECTED:
SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString );
break;
std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id );
case ID_TRACK_BUTT:
if( g_Drc_On )
SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) );
else
SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) );
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
if( !actionName.empty() || id == ID_NO_TOOL_SELECTED )
{
Compile_Ratsnest( &dc, true );
const int MAX_TRIALS = 10;
int trials = 0;
// Cancel the current tool
// TODO while sending a lot of cancel events works for sure, it is not the most
// elegant way to cancel a tool, this should be probably done another way
while( m_toolManager.GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" &&
trials++ < MAX_TRIALS )
{
TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL );
m_toolManager.ProcessEvent( cancel );
}
if( !actionName.empty() )
m_toolManager.RunAction( actionName );
}
}
else
{
INSTALL_UNBUFFERED_DC( dc, m_canvas );
break;
// Stop the current command and deselect the current tool.
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
case ID_PCB_MODULE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) );
break;
switch( id )
{
case ID_NO_TOOL_SELECTED:
SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString );
break;
case ID_PCB_ZONES_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) );
case ID_TRACK_BUTT:
if( g_Drc_On )
SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) );
else
SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) );
if( DisplayOpt.DisplayZonesMode != 0 )
DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) );
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
{
Compile_Ratsnest( &dc, true );
}
if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) )
HighLight( &dc );
break;
break;
case ID_PCB_MODULE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) );
break;
case ID_PCB_KEEPOUT_AREA_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) );
break;
case ID_PCB_ZONES_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) );
case ID_PCB_MIRE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
break;
if( DisplayOpt.DisplayZonesMode != 0 )
DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) );
case ID_PCB_PLACE_OFFSET_COORD_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) );
break;
if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) )
HighLight( &dc );
case ID_PCB_PLACE_GRID_COORD_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) );
break;
break;
case ID_PCB_ADD_LINE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) );
break;
case ID_PCB_KEEPOUT_AREA_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) );
break;
case ID_PCB_ARC_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
break;
case ID_PCB_MIRE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
break;
case ID_PCB_CIRCLE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
break;
case ID_PCB_PLACE_OFFSET_COORD_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) );
break;
case ID_PCB_ADD_TEXT_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
break;
case ID_PCB_PLACE_GRID_COORD_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) );
break;
case ID_COMPONENT_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Add module" ) );
break;
case ID_PCB_ADD_LINE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) );
break;
case ID_PCB_DIMENSION_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) );
break;
case ID_PCB_ARC_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
break;
case ID_PCB_DELETE_ITEM_BUTT:
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
break;
case ID_PCB_CIRCLE_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
break;
case ID_PCB_HIGHLIGHT_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) );
break;
case ID_PCB_ADD_TEXT_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
break;
case ID_PCB_SHOW_1_RATSNEST_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) );
case ID_COMPONENT_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Add module" ) );
break;
if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
Compile_Ratsnest( &dc, true );
case ID_PCB_DIMENSION_BUTT:
SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) );
break;
break;
case ID_PCB_DELETE_ITEM_BUTT:
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
break;
case ID_PCB_HIGHLIGHT_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) );
break;
case ID_PCB_SHOW_1_RATSNEST_BUTT:
SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) );
if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
Compile_Ratsnest( &dc, true );
break;
}
}
}

View File

@ -195,7 +195,8 @@ TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
textePcb->Copy( aText );
GetBoard()->Add( textePcb );
textePcb->SetFlags( IS_NEW );
StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
if( aDC )
StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
}
else
{
@ -222,7 +223,7 @@ TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
textePcb->DeleteStructure();
textePcb = NULL;
}
else
else if( aDC )
{
StartMoveTextePcb( textePcb, aDC );
}

View File

@ -246,7 +246,7 @@ DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T s
s_large = GetDesignSettings().m_DrawSegmentWidth;
if( getActiveLayer() == EDGE_N )
if( GetActiveLayer() == EDGE_N )
{
s_large = GetDesignSettings().m_EdgeSegmentWidth;
}
@ -255,7 +255,7 @@ DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T s
{
SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );
Segment->SetFlags( IS_NEW );
Segment->SetLayer( getActiveLayer() );
Segment->SetLayer( GetActiveLayer() );
Segment->SetWidth( s_large );
Segment->SetShape( shape );
Segment->SetAngle( 900 );

View File

@ -51,10 +51,10 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
if( aTrack == NULL )
{
if( getActiveLayer() != ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP )
setActiveLayer( ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP );
if( GetActiveLayer() != ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP )
SetActiveLayer( ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP );
else
setActiveLayer(((PCB_SCREEN*)GetScreen())->m_Route_Layer_BOTTOM );
SetActiveLayer(((PCB_SCREEN*)GetScreen())->m_Route_Layer_BOTTOM );
UpdateStatusBar();
return true;
@ -108,7 +108,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
via->SetLayerPair( LAYER_N_BACK, LAYER_N_FRONT );
via->SetDrill( GetBoard()->GetCurrentViaDrill() );
LAYER_NUM first_layer = getActiveLayer();
LAYER_NUM first_layer = GetActiveLayer();
LAYER_NUM last_layer;
// prepare switch to new active layer:
@ -171,7 +171,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
return false;
}
setActiveLayer( last_layer );
SetActiveLayer( last_layer );
TRACK* lastNonVia = g_CurrentTrackSegment;
@ -193,7 +193,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
*/
// set the layer to the new value
track->SetLayer( getActiveLayer() );
track->SetLayer( GetActiveLayer() );
/* the start point is the via position and the end point is the cursor
* which also is on the via (will change when moving mouse)

View File

@ -152,7 +152,6 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
cmd.SetEventObject( this );
LAYER_NUM ll;
unsigned int cnt;
switch( hk_id )
{
@ -225,54 +224,23 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_SWITCH_GRID_TO_FASTGRID1:
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( m_FastGrid1 );
cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED );
OnSelectGrid( cmd );
}
SetFastGrid1();
break;
case HK_SWITCH_GRID_TO_FASTGRID2:
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( m_FastGrid2 );
cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED );
OnSelectGrid( cmd );
}
SetFastGrid2();
break;
case HK_SWITCH_GRID_TO_NEXT:
if( m_gridSelectBox )
{
m_gridSelectBox->SetSelection( ( m_gridSelectBox->GetSelection() + 1 ) %
m_gridSelectBox->GetCount() );
cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED );
OnSelectGrid( cmd );
}
SetNextGrid();
break;
case HK_SWITCH_GRID_TO_PREVIOUS:
if( m_gridSelectBox )
{
cnt = m_gridSelectBox->GetSelection();
if ( cnt == 0 )
cnt = m_gridSelectBox->GetCount() - 1;
else
cnt--;
m_gridSelectBox->SetSelection( cnt );
cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED );
OnSelectGrid( cmd );
}
SetPrevGrid();
break;
case HK_SWITCH_LAYER_TO_PREVIOUS:
ll = getActiveLayer();
ll = GetActiveLayer();
if( (ll <= LAYER_N_BACK) || (ll > LAYER_N_FRONT) )
break;
@ -288,7 +256,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_SWITCH_LAYER_TO_NEXT:
ll = getActiveLayer();
ll = GetActiveLayer();
if( (ll < LAYER_N_BACK) || (ll >= LAYER_N_FRONT) )
break;
@ -395,8 +363,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_SWITCH_TRACK_DISPLAY_MODE:
DisplayOpt.DisplayPcbTrackFill ^= 1;
DisplayOpt.DisplayPcbTrackFill &= 1;
DisplayOpt.DisplayPcbTrackFill = !DisplayOpt.DisplayPcbTrackFill;
m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
m_canvas->Refresh();
break;
@ -406,7 +373,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
break;
case HK_BACK_SPACE:
if( IsCopperLayer( getActiveLayer() ) )
if( IsCopperLayer( GetActiveLayer() ) )
{
if( !itemCurrentlyEdited )
{
@ -621,7 +588,7 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC )
switch( GetToolId() )
{
case ID_TRACK_BUTT:
if( getActiveLayer() > LAYER_N_FRONT )
if( GetActiveLayer() > LAYER_N_FRONT )
return false;
if( ItemFree )
@ -982,7 +949,7 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC )
TRACK * PCB_EDIT_FRAME::OnHotkeyBeginRoute( wxDC* aDC )
{
if( getActiveLayer() > LAYER_N_FRONT )
if( GetActiveLayer() > LAYER_N_FRONT )
return NULL;
bool itemCurrentlyEdited = (GetCurItem() && GetCurItem()->GetFlags());

View File

@ -4,7 +4,7 @@
#include <fctsys.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <view/view.h>
#include <pcb_painter.h>
#include <confirm.h>
@ -69,7 +69,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
GetBoard()->SetVisibleLayers( ALL_LAYERS );
// Set currently selected layer to be shown in high contrast mode, when enabled`
setHighContrastLayer( GetScreen()->m_Active_Layer );
SetHighContrastLayer( GetScreen()->m_Active_Layer );
ReFillLayerWidget();

View File

@ -747,26 +747,26 @@ void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const
FMT_IU( aDimension->m_crossBarF.y ).c_str() );
m_out->Print( aNestLevel+1, "(arrow1a (pts (xy %s %s) (xy %s %s)))\n",
FMT_IU( aDimension->m_arrowD1O.x ).c_str(),
FMT_IU( aDimension->m_arrowD1O.y ).c_str(),
FMT_IU( aDimension->m_crossBarF.x ).c_str(),
FMT_IU( aDimension->m_crossBarF.y ).c_str(),
FMT_IU( aDimension->m_arrowD1F.x ).c_str(),
FMT_IU( aDimension->m_arrowD1F.y ).c_str() );
m_out->Print( aNestLevel+1, "(arrow1b (pts (xy %s %s) (xy %s %s)))\n",
FMT_IU( aDimension->m_arrowD2O.x ).c_str(),
FMT_IU( aDimension->m_arrowD2O.y ).c_str(),
FMT_IU( aDimension->m_crossBarF.x ).c_str(),
FMT_IU( aDimension->m_crossBarF.y ).c_str(),
FMT_IU( aDimension->m_arrowD2F.x ).c_str(),
FMT_IU( aDimension->m_arrowD2F.y ).c_str() );
m_out->Print( aNestLevel+1, "(arrow2a (pts (xy %s %s) (xy %s %s)))\n",
FMT_IU( aDimension->m_arrowG1O.x ).c_str(),
FMT_IU( aDimension->m_arrowG1O.y ).c_str(),
FMT_IU( aDimension->m_crossBarO.x ).c_str(),
FMT_IU( aDimension->m_crossBarO.y ).c_str(),
FMT_IU( aDimension->m_arrowG1F.x ).c_str(),
FMT_IU( aDimension->m_arrowG1F.y ).c_str() );
m_out->Print( aNestLevel+1, "(arrow2b (pts (xy %s %s) (xy %s %s)))\n",
FMT_IU( aDimension->m_arrowG2O.x ).c_str(),
FMT_IU( aDimension->m_arrowG2O.y ).c_str(),
FMT_IU( aDimension->m_crossBarO.x ).c_str(),
FMT_IU( aDimension->m_crossBarO.y ).c_str(),
FMT_IU( aDimension->m_arrowG2F.x ).c_str(),
FMT_IU( aDimension->m_arrowG2F.y ).c_str() );

View File

@ -2340,7 +2340,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
arcsegcount = 32;
zc->SetArcSegmentCount( arcsegcount );
zc->SetIsFilled( fillstate == 'S' ? true : false );
zc->SetIsFilled( fillstate == 'S' );
zc->SetThermalReliefGap( thermalReliefGap );
zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge );
}
@ -2587,13 +2587,11 @@ void LEGACY_PLUGIN::loadDIMENSION()
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD1Ox, &m_arrowD1Oy, &m_arrowD1Fx, &m_arrowD1Fy, &Dummy );
int ignore = intParse( line + SZ( "S1" ), &data );
BIU arrowD10x = biuParse( data, &data );
BIU arrowD10y = biuParse( data, &data );
biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data
BIU arrowD1Fx = biuParse( data, &data );
BIU arrowD1Fy = biuParse( data );
dim->m_arrowD1O.x = arrowD10x;
dim->m_arrowD1O.y = arrowD10y;
dim->m_arrowD1F.x = arrowD1Fx;
dim->m_arrowD1F.y = arrowD1Fy;
(void) ignore;
@ -2604,13 +2602,11 @@ void LEGACY_PLUGIN::loadDIMENSION()
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD2Ox, &m_arrowD2Oy, &m_arrowD2Fx, &m_arrowD2Fy, &Dummy );
int ignore = intParse( line + SZ( "S2" ), &data );
BIU arrowD2Ox = biuParse( data, &data );
BIU arrowD2Oy = biuParse( data, &data );
biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data
BIU arrowD2Fx = biuParse( data, &data );
BIU arrowD2Fy = biuParse( data, &data );
dim->m_arrowD2O.x = arrowD2Ox;
dim->m_arrowD2O.y = arrowD2Oy;
dim->m_arrowD2F.x = arrowD2Fx;
dim->m_arrowD2F.y = arrowD2Fy;
(void) ignore;
@ -2620,13 +2616,11 @@ void LEGACY_PLUGIN::loadDIMENSION()
{
// sscanf( Line + 2, " %d %d %d %d %d %d\n", &Dummy, &m_arrowG1Ox, &m_arrowG1Oy, &m_arrowG1Fx, &m_arrowG1Fy, &Dummy );
int ignore = intParse( line + SZ( "S3" ), &data );
BIU arrowG1Ox = biuParse( data, &data );
BIU arrowG1Oy = biuParse( data, &data );
biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data
BIU arrowG1Fx = biuParse( data, &data );
BIU arrowG1Fy = biuParse( data, &data );
dim->m_arrowG1O.x = arrowG1Ox;
dim->m_arrowG1O.y = arrowG1Oy;
dim->m_arrowG1F.x = arrowG1Fx;
dim->m_arrowG1F.y = arrowG1Fy;
(void) ignore;
@ -2636,13 +2630,11 @@ void LEGACY_PLUGIN::loadDIMENSION()
{
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowG2Ox, &m_arrowG2Oy, &m_arrowG2Fx, &m_arrowG2Fy, &Dummy );
int ignore = intParse( line + SZ( "S4" ), &data );
BIU arrowG2Ox = biuParse( data, &data );
BIU arrowG2Oy = biuParse( data, &data );
biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data
BIU arrowG2Fx = biuParse( data, &data );
BIU arrowG2Fy = biuParse( data, &data );
dim->m_arrowG2O.x = arrowG2Ox;
dim->m_arrowG2O.y = arrowG2Oy;
dim->m_arrowG2F.x = arrowG2Fx;
dim->m_arrowG2F.y = arrowG2Fy;
(void) ignore;
@ -3805,22 +3797,22 @@ void LEGACY_PLUGIN::saveDIMENTION( const DIMENSION* me ) const
fmtBIU( me->GetWidth() ).c_str() );
fprintf( m_fp, "S1 %d %s %s %s\n", S_SEGMENT,
fmtBIUPair( me->m_arrowD1O.x, me->m_arrowD1O.y ).c_str(),
fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(),
fmtBIUPair( me->m_arrowD1F.x, me->m_arrowD1F.y ).c_str(),
fmtBIU( me->GetWidth() ).c_str() );
fprintf( m_fp, "S2 %d %s %s %s\n", S_SEGMENT,
fmtBIUPair( me->m_arrowD2O.x, me->m_arrowD2O.y ).c_str(),
fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(),
fmtBIUPair( me->m_arrowD2F.x, me->m_arrowD2F.y ).c_str(),
fmtBIU( me->GetWidth() ).c_str() );
fprintf( m_fp, "S3 %d %s %s %s\n", S_SEGMENT,
fmtBIUPair( me->m_arrowG1O.x, me->m_arrowG1O.y ).c_str(),
fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(),
fmtBIUPair( me->m_arrowG1F.x, me->m_arrowG1F.y ).c_str(),
fmtBIU( me->GetWidth() ).c_str() );
fprintf( m_fp, "S4 %d %s %s %s\n", S_SEGMENT,
fmtBIUPair( me->m_arrowG2O.x, me->m_arrowG2O.y ).c_str(),
fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(),
fmtBIUPair( me->m_arrowG2F.x, me->m_arrowG2F.y ).c_str(),
fmtBIU( me->GetWidth() ).c_str() );

View File

@ -292,13 +292,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
_( "Reset text size and width of all module fields to current defaults" ),
KiBitmap( reset_text_xpm ) );
editMenu->AppendSeparator();
AddMenuItem( editMenu, ID_PNS_ROUTER_TOOL,
_( "Interactive router" ),
_( "Interactive router push&shove tool." ),
KiBitmap( ps_router_xpm ) );
//----- View menu -----------------------------------------------------------
wxMenu* viewMenu = new wxMenu;
@ -344,33 +337,36 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
viewMenu->AppendSeparator();
text = AddHotkeyName( _( "&Switch canvas to default" ), g_Pcbnew_Editor_Hokeys_Descr,
HK_CANVAS_DEFAULT, IS_ACCELERATOR );
HK_CANVAS_DEFAULT );
AddMenuItem( viewMenu, ID_MENU_CANVAS_DEFAULT,
text, _( "Switch the canvas implementation to default" ),
KiBitmap( tools_xpm ) );
KiBitmap( tools_xpm ) );
text = AddHotkeyName( _( "&Switch canvas to OpenGL" ), g_Pcbnew_Editor_Hokeys_Descr,
HK_CANVAS_OPENGL, IS_ACCELERATOR );
HK_CANVAS_OPENGL );
AddMenuItem( viewMenu, ID_MENU_CANVAS_OPENGL,
text, _( "Switch the canvas implementation to OpenGL" ),
KiBitmap( tools_xpm ) );
KiBitmap( tools_xpm ) );
text = AddHotkeyName( _( "&Switch canvas to Cairo" ), g_Pcbnew_Editor_Hokeys_Descr,
HK_CANVAS_CAIRO, IS_ACCELERATOR );
HK_CANVAS_CAIRO );
AddMenuItem( viewMenu, ID_MENU_CANVAS_CAIRO,
text, _( "Switch the canvas implementation to Cairo" ),
KiBitmap( tools_xpm ) );
KiBitmap( tools_xpm ) );
//----- Place Menu ----------------------------------------------------------
wxMenu* placeMenu = new wxMenu;
text = AddHotkeyName( _( "&Module" ), g_Pcbnew_Editor_Hokeys_Descr,
HK_ADD_MODULE, IS_ACCELERATOR );
HK_ADD_MODULE );
AddMenuItem( placeMenu, ID_PCB_MODULE_BUTT, text,
_( "Add modules" ), KiBitmap( module_xpm ) );
text = AddHotkeyName( _( "&Track" ), g_Pcbnew_Editor_Hokeys_Descr,
HK_ADD_NEW_TRACK, IS_ACCELERATOR );
HK_ADD_NEW_TRACK );
AddMenuItem( placeMenu, ID_TRACK_BUTT, text,
_( "Add tracks and vias" ), KiBitmap( add_tracks_xpm ) );

View File

@ -27,9 +27,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <boost/bind.hpp>
#include <fctsys.h>
#include <pgm_base.h>
#include <class_drawpanel.h>
#include <class_draw_panel_gal.h>
#include <confirm.h>
#include <dialog_helpers.h>
#include <wxPcbStruct.h>
@ -59,6 +61,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
wxString msg;
NETLIST netlist;
NETLIST_READER* netlistReader;
KIGFX::VIEW* view = GetGalCanvas()->GetView();
netlist.SetIsDryRun( aIsDryRun );
netlist.SetFindByTimeStamp( aSelectByTimeStamp );
@ -93,6 +96,16 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
if( !netlist.IsDryRun() )
GetScreen()->ClearUndoRedoList();
if( !netlist.IsDryRun() )
{
// Remove old modules
for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
}
}
netlist.SortByReference();
GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter );
@ -104,6 +117,13 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
SetCurItem( NULL );
// Reload modules
for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
GetGalCanvas()->GetView()->Add( module );
}
if( aDeleteUnconnectedTracks && GetBoard()->m_Track )
{
// Remove erroneous tracks. This should probably pushed down to the #BOARD object.

View File

@ -244,7 +244,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
if( GetToolId() == ID_PCB_ARC_BUTT )
shape = S_ARC;
if( IsCopperLayer( getActiveLayer() ) )
if( IsCopperLayer( GetActiveLayer() ) )
{
DisplayError( this, _( "Graphic not allowed on Copper layers" ) );
break;
@ -268,7 +268,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
break;
case ID_TRACK_BUTT:
if( !IsCopperLayer( getActiveLayer() ) )
if( !IsCopperLayer( GetActiveLayer() ) )
{
DisplayError( this, _( "Tracks on Copper layers only " ) );
break;
@ -326,7 +326,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
break;
case ID_PCB_ADD_TEXT_BUTT:
if( IsLayerInList( EDGE_LAYER, getActiveLayer() ) )
if( IsLayerInList( EDGE_LAYER, GetActiveLayer() ) )
{
DisplayError( this,
_( "Texts not allowed on Edge Cut layer" ) );
@ -376,7 +376,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
break;
case ID_PCB_DIMENSION_BUTT:
if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, getActiveLayer() ) )
if( IsLayerInList( EDGE_LAYER|ALL_CU_LAYERS, GetActiveLayer() ) )
{
DisplayError( this,
_( "Dimension not allowed on Copper or Edge Cut layers" ) );

View File

@ -34,9 +34,8 @@
#include <class_marker_pcb.h>
#include <class_dimension.h>
#include <class_mire.h>
#include <pcbstruct.h>
#include <class_marker_pcb.h>
#include <view/view.h>
#include <pcb_painter.h>
#include <gal/graphics_abstraction_layer.h>
@ -47,7 +46,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
// By default everything should be displayed as filled
for( unsigned int i = 0; i < END_PCB_VISIBLE_LIST; ++i )
{
m_sketchModeSelect[i] = false;
m_sketchMode[i] = false;
}
update();
@ -67,15 +66,16 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings
}
// Default colors for specific layers
m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 1.0 );
m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 1.0 );
m_layerColors[ITEM_GAL_LAYER( VIAS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 );
m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 1.0 );
m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 );
m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.7 );
m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 1.0 );
m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 0.8 );
m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 0.8 );
m_layerColors[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.8 );
m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.8 );
m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 0.8 );
m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 0.8 );
// Netnames for copper layers
for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; ++layer )
@ -94,9 +94,9 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const DISPLAY_OPTIONS& aOptions )
m_padNumbers = aOptions.DisplayPadNum;
// Whether to draw tracks, vias & pads filled or as outlines
m_sketchModeSelect[PADS_VISIBLE] = !aOptions.DisplayPadFill;
m_sketchModeSelect[VIAS_VISIBLE] = !aOptions.DisplayViaFill;
m_sketchModeSelect[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill;
m_sketchMode[PADS_VISIBLE] = !aOptions.DisplayPadFill;
m_sketchMode[VIA_THROUGH_VISIBLE] = !aOptions.DisplayViaFill;
m_sketchMode[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill;
switch( aOptions.DisplayNetNamesMode )
{
@ -175,23 +175,15 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer
void PCB_RENDER_SETTINGS::update()
{
RENDER_SETTINGS::update();
// Calculate darkened/highlighted variants of layer colors
for( int i = 0; i < TOTAL_LAYER_COUNT; i++ )
{
m_layerColors[i].a = m_layerOpacity;
m_layerColorsHi[i] = m_layerColors[i].Brightened( m_highlightFactor );
m_layerColorsDark[i] = m_layerColors[i].Darkened( 1.0 - m_highlightFactor );
m_layerColorsSel[i] = m_layerColors[i].Brightened( m_selectFactor );
}
m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_hiContrastFactor,
m_layerOpacity );
}
const COLOR4D& PCB_RENDER_SETTINGS::GetLayerColor( int aLayer ) const
{
return m_layerColors[aLayer];
}
@ -246,6 +238,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
draw( (PCB_TARGET*) aItem );
break;
case PCB_MARKER_T:
draw( (MARKER_PCB*) aItem );
break;
default:
// Painter does not know how to draw the object
return false;
@ -261,14 +257,11 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
VECTOR2D start( aTrack->GetStart() );
VECTOR2D end( aTrack->GetEnd() );
int width = aTrack->GetWidth();
COLOR4D color;
if( m_pcbSettings->m_netNamesOnTracks && IsNetnameLayer( aLayer ) )
{
int netCode = aTrack->GetNetCode();
// If there is a net name - display it on the track
if( netCode > 0 )
if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED )
{
VECTOR2D line = ( end - start );
double length = line.EuclideanNorm();
@ -277,17 +270,13 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
if( length < 10 * width )
return;
NETINFO_ITEM* net = aTrack->GetNet();
if( !net )
return;
const wxString& netName = aTrack->GetShortNetname();
VECTOR2D textPosition = start + line / 2.0; // center of the track
double textOrientation = -atan( line.y / line.x );
double textSize = std::min( static_cast<double>( width ), length / netName.length() );
// Set a proper color for the label
color = m_pcbSettings->GetColor( aTrack, aTrack->GetLayer() );
const COLOR4D& color = m_pcbSettings->GetColor( aTrack, aTrack->GetLayer() );
COLOR4D labelColor = m_pcbSettings->GetColor( NULL, aLayer );
if( color.GetBrightness() > 0.5 )
@ -308,11 +297,11 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
else if( IsCopperLayer( aLayer ) )
{
// Draw a regular track
color = m_pcbSettings->GetColor( aTrack, aLayer );
const COLOR4D& color = m_pcbSettings->GetColor( aTrack, aLayer );
m_gal->SetStrokeColor( color );
m_gal->SetIsStroke( true );
if( m_pcbSettings->m_sketchModeSelect[TRACKS_VISIBLE] )
if( m_pcbSettings->m_sketchMode[TRACKS_VISIBLE] )
{
// Outline mode
m_gal->SetLineWidth( m_pcbSettings->m_outlineWidth );
@ -333,10 +322,9 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
{
VECTOR2D center( aVia->GetStart() );
double radius;
COLOR4D color;
// Choose drawing settings depending on if we are drawing via's pad or hole
if( aLayer == ITEM_GAL_LAYER( VIAS_VISIBLE ) )
if( aLayer == ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) )
{
radius = aVia->GetWidth() / 2.0;
}
@ -347,9 +335,9 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
else
return;
color = m_pcbSettings->GetColor( aVia, aLayer );
const COLOR4D& color = m_pcbSettings->GetColor( aVia, aLayer );
if( m_pcbSettings->m_sketchModeSelect[VIAS_VISIBLE] )
if( m_pcbSettings->m_sketchMode[VIA_THROUGH_VISIBLE] )
{
// Outline mode
m_gal->SetIsFill( false );
@ -371,7 +359,6 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
COLOR4D color;
VECTOR2D size;
VECTOR2D position( aPad->GetPosition() );
PAD_SHAPE_T shape;
@ -386,7 +373,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
if( m_pcbSettings->m_netNamesOnPads || m_pcbSettings->m_padNumbers )
{
// Min char count to calculate string size
#define MIN_CHAR_COUNT 3
const int MIN_CHAR_COUNT = 3;
bool displayNetname = ( m_pcbSettings->m_netNamesOnPads &&
!aPad->GetNetname().empty() );
@ -406,9 +393,6 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
// If the text is displayed on a symmetrical pad, do not rotate it
orientation = 0.0;
}
else
{
}
// Font size limits
if( size > maxSize )
@ -429,7 +413,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m_gal->SetMirrored( false );
// Set a proper color for the label
color = m_pcbSettings->GetColor( aPad, aPad->GetLayer() );
const COLOR4D& color = m_pcbSettings->GetColor( aPad, aPad->GetLayer() );
COLOR4D labelColor = m_pcbSettings->GetColor( NULL, aLayer );
if( color.GetBrightness() > 0.5 )
@ -457,8 +441,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
VECTOR2D namesize( tsize, tsize );
m_gal->SetGlyphSize( namesize );
m_gal->SetLineWidth( namesize.x / 12.0 );
m_gal->StrokeText( std::wstring( aPad->GetShortNetname().wc_str() ),
textpos, 0.0 );
m_gal->StrokeText( aPad->GetShortNetname(), textpos, 0.0 );
}
if( m_pcbSettings->m_padNumbers )
@ -475,7 +458,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m_gal->SetGlyphSize( numsize );
m_gal->SetLineWidth( numsize.x / 12.0 );
m_gal->StrokeText( std::wstring( aPad->GetPadName().wc_str() ), textpos, 0.0 );
m_gal->StrokeText( aPad->GetPadName(), textpos, 0.0 );
}
m_gal->Restore();
@ -484,8 +467,8 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
}
// Pad drawing
color = m_pcbSettings->GetColor( aPad, aLayer );
if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] )
const COLOR4D& color = m_pcbSettings->GetColor( aPad, aLayer );
if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] )
{
// Outline mode
m_gal->SetIsFill( false );
@ -548,7 +531,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m = ( size.y - size.x );
n = size.x;
if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] )
if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] )
{
// Outline mode
m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 );
@ -569,7 +552,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m = ( size.x - size.y );
n = size.y;
if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] )
if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] )
{
// Outline mode
m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
@ -605,7 +588,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
pointList.push_back( VECTOR2D( corners[2] ) );
pointList.push_back( VECTOR2D( corners[3] ) );
if( m_pcbSettings->m_sketchModeSelect[PADS_VISIBLE] )
if( m_pcbSettings->m_sketchMode[PADS_VISIBLE] )
{
// Add the beginning point to close the outline
pointList.push_back( pointList.front() );
@ -629,7 +612,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
{
COLOR4D color = m_pcbSettings->GetColor( aSegment, aSegment->GetLayer() );
const COLOR4D& color = m_pcbSettings->GetColor( aSegment, aSegment->GetLayer() );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
@ -709,7 +692,7 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer )
if( aText->GetText().Length() == 0 )
return;
COLOR4D strokeColor = m_pcbSettings->GetColor( aText, aText->GetLayer() );
const COLOR4D& strokeColor = m_pcbSettings->GetColor( aText, aText->GetLayer() );
VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y );
double orientation = aText->GetOrientation() * M_PI / 1800.0;
@ -725,7 +708,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
if( aText->GetLength() == 0 )
return;
COLOR4D strokeColor = m_pcbSettings->GetColor( aText, aLayer );
const COLOR4D& strokeColor = m_pcbSettings->GetColor( aText, aLayer );
VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y );
double orientation = aText->GetDrawRotation() * M_PI / 1800.0;
@ -738,7 +721,7 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone )
{
COLOR4D color = m_pcbSettings->GetColor( aZone, aZone->GetLayer() );
const COLOR4D& color = m_pcbSettings->GetColor( aZone, aZone->GetLayer() );
std::deque<VECTOR2D> corners;
PCB_RENDER_SETTINGS::DisplayZonesMode displayMode = m_pcbSettings->m_displayZoneMode;
@ -811,7 +794,7 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone )
void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
{
COLOR4D strokeColor = m_pcbSettings->GetColor( aDimension, aLayer );
const COLOR4D& strokeColor = m_pcbSettings->GetColor( aDimension, aLayer );
m_gal->SetStrokeColor( strokeColor );
m_gal->SetIsFill( false );
@ -824,10 +807,10 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
VECTOR2D( aDimension->m_featureLineGF ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_featureLineDO ),
VECTOR2D( aDimension->m_featureLineDF ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_arrowD1O ), VECTOR2D( aDimension->m_arrowD1F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_arrowD2O ), VECTOR2D( aDimension->m_arrowD2F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_arrowG1O ), VECTOR2D( aDimension->m_arrowG1F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_arrowG2O ), VECTOR2D( aDimension->m_arrowG2F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD1F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD2F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG1F ) );
m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG2F ) );
// Draw text
TEXTE_PCB& text = aDimension->Text();
@ -836,13 +819,13 @@ void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
m_gal->SetLineWidth( text.GetThickness() );
m_gal->SetTextAttributes( &text );
m_gal->StrokeText( std::wstring( text.GetText().wc_str() ), position, orientation );
m_gal->StrokeText( text.GetText(), position, orientation );
}
void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
{
COLOR4D strokeColor = m_pcbSettings->GetColor( aTarget, aTarget->GetLayer() );
const COLOR4D& strokeColor = m_pcbSettings->GetColor( aTarget, aTarget->GetLayer() );
VECTOR2D position( aTarget->GetPosition() );
double size, radius;
@ -876,4 +859,23 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
}
void PCB_PAINTER::draw( const MARKER_PCB* aMarker )
{
const BOARD_ITEM* item = aMarker->GetItem();
if( item ) // By default draw an item in a different color
{
Draw( item, ITEM_GAL_LAYER( DRC_VISIBLE ) );
}
else // If there is no item associated - draw a circle marking the DRC error
{
m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( 10000 );
m_gal->DrawCircle( VECTOR2D( aMarker->GetPosition() ), 200000 );
}
}
const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 );

View File

@ -48,6 +48,7 @@ class TEXTE_PCB;
class TEXTE_MODULE;
class DIMENSION;
class PCB_TARGET;
class MARKER_PCB;
namespace KIGFX
{
@ -96,7 +97,51 @@ public:
* Returns the color used to draw a layer.
* @param aLayer is the layer number.
*/
const COLOR4D& GetLayerColor( int aLayer ) const;
const COLOR4D& GetLayerColor( int aLayer ) const
{
return m_layerColors[aLayer];
}
/**
* Function SetLayerColor
* Changes the color used to draw a layer.
* @param aLayer is the layer number.
* @param aColor is the new color.
*/
void SetLayerColor( int aLayer, const COLOR4D& aColor )
{
m_layerColors[aLayer] = aColor;
update(); // recompute other shades of the color
}
/**
* Function SetSketchMode
* Turns on/off sketch mode for given item layer.
* @param aItemLayer is the item layer that is changed.
* @param aEnabled decides if it is drawn in sketch mode (true for sketched mode,
* false for filled mode).
*/
void SetSketchMode( int aItemLayer, bool aEnabled )
{
// It is supposed to work only with item layers
assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) );
m_sketchMode[aItemLayer] = aEnabled;
}
/**
* Function GetSketchMode
* Returns sketch mode setting for a given item layer.
* @param aItemLayer is the item layer that is changed.
*/
bool GetSketchMode( int aItemLayer ) const
{
// It is supposed to work only with item layers
assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) );
return m_sketchMode[aItemLayer];
}
protected:
///> @copydoc RENDER_SETTINGS::Update()
@ -114,8 +159,8 @@ protected:
///> Colors for all layers (darkened)
COLOR4D m_layerColorsDark[TOTAL_LAYER_COUNT];
///> Flag determining if items on a given layer should be drawn as an outline or a full item
bool m_sketchModeSelect[TOTAL_LAYER_COUNT];
///> Flag determining if items on a given layer should be drawn as an outline or a filled item
bool m_sketchMode[TOTAL_LAYER_COUNT];
///> Flag determining if pad numbers should be visible
bool m_padNumbers;
@ -169,6 +214,7 @@ protected:
void draw( const ZONE_CONTAINER* aZone );
void draw( const DIMENSION* aDimension, int aLayer );
void draw( const PCB_TARGET* aTarget );
void draw( const MARKER_PCB* aMarker );
};
} // namespace KIGFX

View File

@ -1438,6 +1438,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
dimension->UpdateHeight();
NeedRIGHT();
NeedRIGHT();
break;
@ -1451,6 +1452,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
dimension->UpdateHeight();
NeedRIGHT();
NeedRIGHT();
break;
@ -1465,6 +1467,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
dimension->UpdateHeight();
NeedRIGHT();
NeedRIGHT();
break;
@ -1476,7 +1479,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
if( token != T_pts )
Expecting( T_pts );
parseXY( &dimension->m_arrowD1O.x, &dimension->m_arrowD1O.y );
parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
NeedRIGHT();
NeedRIGHT();
@ -1489,7 +1492,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
if( token != T_pts )
Expecting( T_pts );
parseXY( &dimension->m_arrowD2O.x, &dimension->m_arrowD2O.y );
parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
NeedRIGHT();
NeedRIGHT();
@ -1502,7 +1505,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
if( token != T_pts )
Expecting( T_pts );
parseXY( &dimension->m_arrowG1O.x, &dimension->m_arrowG1O.y );
parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
NeedRIGHT();
NeedRIGHT();
@ -1515,7 +1518,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
if( token != T_pts )
Expecting( T_pts );
parseXY( &dimension->m_arrowG2O.x, &dimension->m_arrowG2O.y );
parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
NeedRIGHT();
NeedRIGHT();

View File

@ -57,6 +57,7 @@
#include <dialog_plot.h>
#include <convert_from_iu.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <painter.h>
#include <class_track.h>
@ -73,7 +74,8 @@
#include <python_scripting.h>
#endif
#include <class_drawpanel_gal.h>
#include <class_draw_panel_gal.h>
#include <boost/bind.hpp>
// Keys used in read/write config
#define OPTKEY_DEFAULT_LINEWIDTH_VALUE wxT( "PlotLineWidth_mm" )
@ -127,12 +129,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
// menu Config
/* Tom's hacks start */
EVT_MENU ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand )
EVT_TOOL ( ID_PNS_ROUTER_TOOL, PCB_EDIT_FRAME::onGenericCommand )
/* Tom's hacks end */
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config )
EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config )
@ -492,17 +488,14 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
{
PCB_BASE_FRAME::SetBoard( aBoard );
if( GetGalCanvas() )
if( IsGalCanvasActive() )
{
ViewReloadBoard( aBoard );
// update the tool manager with the new board and its view.
if( m_toolManager )
{
m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
}
m_toolManager.SetEnvironment( aBoard, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
m_toolManager.ResetTools( TOOL_BASE::MODEL_RELOAD );
}
}
@ -517,51 +510,26 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
// Load zones
for( int i = 0; i < aBoard->GetAreaCount(); ++i )
{
view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) );
}
// Load drawings
for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load tracks
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
view->Add( track );
}
// Load modules and its additional elements
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
// Load module's pads
for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
view->Add( pad );
}
// Load module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing;
drawing = drawing->Next() )
{
view->Add( drawing );
}
// Load module's texts (name and value)
view->Add( &module->Reference() );
view->Add( &module->Value() );
// Add the module itself
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
}
// Segzones (equivalent of ZONE_CONTAINER for legacy boards)
for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
{
view->Add( zone );
}
KIGFX::WORKSHEET_VIEWITEM* worksheet = aBoard->GetWorksheetViewItem();
worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );
@ -578,7 +546,7 @@ void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const
view->Add( aBoard->GetRatsnestViewItem() );
// Limit panning to the size of worksheet frame
view->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() );
GetGalCanvas()->GetViewControls()->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() );
view->RecacheAllItems( true );
if( IsGalCanvasActive() )
@ -701,16 +669,16 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
{
EDA_DRAW_FRAME::UseGalCanvas( aEnable );
ViewReloadBoard( m_Pcb );
if( aEnable )
{
ViewReloadBoard( m_Pcb );
// Update potential changes in the ratsnest
m_Pcb->GetRatsnest()->Recalculate();
m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
m_toolManager.SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
m_toolManager.ResetTools( TOOL_BASE::GAL_SWITCH );
}
}
@ -722,6 +690,7 @@ void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
switch( id )
{
case ID_MENU_CANVAS_DEFAULT:
Compile_Ratsnest( NULL, true );
UseGalCanvas( false );
break;
@ -832,7 +801,7 @@ void PCB_EDIT_FRAME::SetGridColor(EDA_COLOR_T aColor)
bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
{
int copperlayercnt = GetBoard()->GetCopperLayerCount( );
LAYER_NUM currLayer = getActiveLayer();
LAYER_NUM currLayer = GetActiveLayer();
if( !GetDesignSettings().m_MicroViasAllowed )
return false; // Obvious..
@ -850,13 +819,13 @@ bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
}
void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
void PCB_EDIT_FRAME::SetHighContrastLayer( LAYER_NUM aLayer )
{
// Set display settings for high contrast mode
KIGFX::VIEW* view = GetGalCanvas()->GetView();
KIGFX::RENDER_SETTINGS* rSettings = view->GetPainter()->GetSettings();
setTopLayer( aLayer );
SetTopLayer( aLayer );
rSettings->ClearActiveLayers();
rSettings->SetActiveLayer( aLayer );
@ -867,7 +836,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
// fixme do not like the idea of storing the list of layers here,
// should be done in some other way I guess..
LAYER_NUM layers[] = {
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ),
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE )
@ -893,7 +862,7 @@ void PCB_EDIT_FRAME::setHighContrastLayer( LAYER_NUM aLayer )
}
void PCB_EDIT_FRAME::setTopLayer( LAYER_NUM aLayer )
void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer )
{
// Set display settings for high contrast mode
KIGFX::VIEW* view = GetGalCanvas()->GetView();
@ -907,10 +876,11 @@ void PCB_EDIT_FRAME::setTopLayer( LAYER_NUM aLayer )
// fixme do not like the idea of storing the list of layers here,
// should be done in some other way I guess..
LAYER_NUM layers[] = {
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIAS_VISIBLE ),
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N,
ITEM_GAL_LAYER( DRC_VISIBLE )
};
for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
@ -935,11 +905,11 @@ void PCB_EDIT_FRAME::setTopLayer( LAYER_NUM aLayer )
}
void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate )
void PCB_EDIT_FRAME::SetActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate )
{
( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer;
setHighContrastLayer( aLayer );
SetHighContrastLayer( aLayer );
if( doLayerWidgetUpdate )
syncLayerWidgetLayer();
@ -951,7 +921,7 @@ void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate
void PCB_EDIT_FRAME::syncLayerWidgetLayer()
{
m_Layers->SelectLayer( getActiveLayer() );
m_Layers->SelectLayer( GetActiveLayer() );
m_Layers->OnLayerSelected();
}
@ -1008,6 +978,7 @@ bool PCB_EDIT_FRAME::IsElementVisible( int aElement ) const
void PCB_EDIT_FRAME::SetElementVisibility( int aElement, bool aNewState )
{
GetGalCanvas()->GetView()->SetLayerVisible( ITEM_GAL_LAYER( aElement ), aNewState );
GetBoard()->SetElementVisibility( aElement, aNewState );
m_Layers->SetRenderState( aElement, aNewState );
}

View File

@ -370,9 +370,7 @@ enum pcbnew_ids
ID_FOOTPRINT_WIZARD_PAGES_WINDOW,
ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW,
ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
ID_PNS_ROUTER_TOOL
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD
};
#endif // PCBNEW_ID_H_

View File

@ -275,19 +275,19 @@ void BRDITEMS_PLOTTER::PlotDimension( DIMENSION* aDim )
draw.SetEnd( aDim->m_featureLineDF );
PlotDrawSegment( &draw );
draw.SetStart( aDim->m_arrowD1O );
draw.SetStart( aDim->m_crossBarF );
draw.SetEnd( aDim->m_arrowD1F );
PlotDrawSegment( &draw );
draw.SetStart( aDim->m_arrowD2O );
draw.SetStart( aDim->m_crossBarF );
draw.SetEnd( aDim->m_arrowD2F );
PlotDrawSegment( &draw );
draw.SetStart( aDim->m_arrowG1O );
draw.SetStart( aDim->m_crossBarO );
draw.SetEnd( aDim->m_arrowG1F );
PlotDrawSegment( &draw );
draw.SetStart( aDim->m_arrowG2O );
draw.SetStart( aDim->m_crossBarO );
draw.SetEnd( aDim->m_arrowG2F );
PlotDrawSegment( &draw );
}

View File

@ -68,7 +68,7 @@ bool sortDistance( const RN_NODE_PTR& aOrigin, const RN_NODE_PTR& aNode1,
bool sortWeight( const RN_EDGE_PTR& aEdge1, const RN_EDGE_PTR& aEdge2 )
{
return aEdge1->getWeight() < aEdge2->getWeight();
return aEdge1->GetWeight() < aEdge2->GetWeight();
}
@ -92,7 +92,7 @@ bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond )
bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode )
{
return aEdge->getSourceNode() == aNode || aEdge->getTargetNode() == aNode;
return aEdge->GetSourceNode() == aNode || aEdge->GetTargetNode() == aNode;
}
@ -125,8 +125,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
{
RN_EDGE_PTR& dt = *aEdges.begin();
int srcTag = tags[dt->getSourceNode()];
int trgTag = tags[dt->getTargetNode()];
int srcTag = tags[dt->GetSourceNode()];
int trgTag = tags[dt->GetTargetNode()];
// Check if by adding this edge we are going to join two different forests
if( srcTag != trgTag )
@ -139,7 +139,7 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
// Move nodes that were marked with old tag to the list marked with the new tag
cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
if( dt->getWeight() == 0 ) // Skip already existing connections (weight == 0)
if( dt->GetWeight() == 0 ) // Skip already existing connections (weight == 0)
{
mstExpectedSize--;
}
@ -148,9 +148,9 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
// Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
// RN_EDGE_MST saves both source and target node and does not require any other
// edges to exist for getting source/target nodes
RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->getSourceNode(),
dt->getTargetNode(),
dt->getWeight() );
RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->GetSourceNode(),
dt->GetTargetNode(),
dt->GetWeight() );
mst->push_back( newEdge );
++mstSize;
}
@ -169,8 +169,8 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
void RN_NET::validateEdge( RN_EDGE_PTR& aEdge )
{
RN_NODE_PTR source = aEdge->getSourceNode();
RN_NODE_PTR target = aEdge->getTargetNode();
RN_NODE_PTR source = aEdge->GetSourceNode();
RN_NODE_PTR target = aEdge->GetTargetNode();
bool valid = true;
// If any of nodes belonging to the edge has the flag set,
@ -280,13 +280,13 @@ void RN_NET::compute()
std::partial_sort_copy( boardNodes.begin(), boardNodes.end(), nodes.begin(), nodes.end() );
TRIANGULATOR triangulator;
triangulator.createDelaunay( nodes.begin(), nodes.end() );
boost::scoped_ptr<RN_LINKS::RN_EDGE_LIST> triangEdges( triangulator.getEdges() );
triangulator.CreateDelaunay( nodes.begin(), nodes.end() );
boost::scoped_ptr<RN_LINKS::RN_EDGE_LIST> triangEdges( triangulator.GetEdges() );
// Compute weight/distance for edges resulting from triangulation
RN_LINKS::RN_EDGE_LIST::iterator eit, eitEnd;
for( eit = (*triangEdges).begin(), eitEnd = (*triangEdges).end(); eit != eitEnd; ++eit )
(*eit)->setWeight( getDistance( (*eit)->getSourceNode(), (*eit)->getTargetNode() ) );
(*eit)->SetWeight( getDistance( (*eit)->GetSourceNode(), (*eit)->GetTargetNode() ) );
// Add the currently existing connections list to the results of triangulation
std::copy( boardEdges.begin(), boardEdges.end(), std::front_inserter( *triangEdges ) );
@ -508,8 +508,8 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
RN_EDGE_PTR& edge = m_tracks.at( aTrack );
// Save nodes, so they can be cleared later
RN_NODE_PTR aBegin = edge->getSourceNode();
RN_NODE_PTR aEnd = edge->getTargetNode();
RN_NODE_PTR aBegin = edge->GetSourceNode();
RN_NODE_PTR aEnd = edge->GetTargetNode();
m_links.RemoveConnection( edge );
// Remove nodes associated with the edge. It is done in a safe way, there is a check
@ -696,8 +696,8 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
const TRACK* track = static_cast<const TRACK*>( aItem );
RN_EDGE_PTR edge = m_tracks.at( track );
nodes.push_back( edge->getSourceNode() );
nodes.push_back( edge->getTargetNode() );
nodes.push_back( edge->GetSourceNode() );
nodes.push_back( edge->GetTargetNode() );
}
break;
@ -982,6 +982,7 @@ void RN_DATA::ProcessBoard()
for( int i = 0; i < m_board->GetAreaCount(); ++i )
{
ZONE_CONTAINER* zone = m_board->GetArea( i );
netCode = zone->GetNetCode();
if( netCode > 0 )
@ -1023,7 +1024,7 @@ void RN_DATA::updateNet( int aNetCode )
{
assert( aNetCode < (int) m_nets.size() );
if( aNetCode < 1 )
if( aNetCode < 1 || aNetCode > (int) m_nets.size() )
return;
m_nets[aNetCode].ClearSimple();

View File

@ -50,13 +50,13 @@ class ZONE_CONTAINER;
class CPolyPt;
// Preserve KiCad coding style policy
typedef hed::Node RN_NODE;
typedef hed::NodePtr RN_NODE_PTR;
typedef hed::Edge RN_EDGE;
typedef hed::EdgePtr RN_EDGE_PTR;
typedef hed::EdgeMST RN_EDGE_MST;
typedef boost::shared_ptr<hed::EdgeMST> RN_EDGE_MST_PTR;
typedef hed::Triangulation TRIANGULATOR;
typedef hed::NODE RN_NODE;
typedef hed::NODE_PTR RN_NODE_PTR;
typedef hed::EDGE RN_EDGE;
typedef hed::EDGE_PTR RN_EDGE_PTR;
typedef hed::EDGE_MST RN_EDGE_MST;
typedef hed::TRIANGULATION TRIANGULATOR;
typedef boost::shared_ptr<hed::EDGE_MST> RN_EDGE_MST_PTR;
bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );
bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );

View File

@ -97,8 +97,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
BOOST_FOREACH( const RN_EDGE_PTR& edge, *edges )
{
const RN_NODE_PTR& sourceNode = edge->getSourceNode();
const RN_NODE_PTR& targetNode = edge->getTargetNode();
const RN_NODE_PTR& sourceNode = edge->GetSourceNode();
const RN_NODE_PTR& targetNode = edge->GetTargetNode();
VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() );
VECTOR2D target( targetNode->GetX(), targetNode->GetY() );

Some files were not shown because too many files have changed in this diff Show More