Commit f0251ebd authored by Maciej Suminski's avatar Maciej Suminski Committed by Wayne Stambaugh

Merge selection tool branch.

parents 5feddb8c 5ed0980d
......@@ -149,6 +149,13 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" )
endif()
find_package( OpenMP QUIET )
if( OPENMP_FOUND )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
add_definitions( -DUSE_OPENMP )
endif()
if( MINGW )
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
......
......@@ -219,6 +219,8 @@ set( PCB_COMMON_SRCS
../pcbnew/class_zone.cpp
../pcbnew/class_zone_settings.cpp
../pcbnew/classpcb.cpp
../pcbnew/ratsnest_data.cpp
../pcbnew/ratsnest_viewitem.cpp
../pcbnew/collectors.cpp
../pcbnew/netlist_reader.cpp
../pcbnew/legacy_netlist_reader.cpp
......
......@@ -50,7 +50,7 @@ PICKED_ITEMS_LIST::~PICKED_ITEMS_LIST()
}
void PICKED_ITEMS_LIST::PushItem( ITEM_PICKER& aItem )
void PICKED_ITEMS_LIST::PushItem( const ITEM_PICKER& aItem )
{
m_ItemsList.push_back( aItem );
}
......@@ -70,7 +70,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::PopItem()
}
bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const
bool PICKED_ITEMS_LIST::ContainsItem( const EDA_ITEM* aItem ) const
{
for( size_t i = 0; i < m_ItemsList.size(); i++ )
{
......@@ -82,6 +82,18 @@ bool PICKED_ITEMS_LIST::ContainsItem( EDA_ITEM* aItem ) const
}
int PICKED_ITEMS_LIST::FindItem( const EDA_ITEM* aItem ) const
{
for( size_t i = 0; i < m_ItemsList.size(); i++ )
{
if( m_ItemsList[i].GetItem() == aItem )
return i;
}
return -1;
}
void PICKED_ITEMS_LIST::ClearItemsList()
{
m_ItemsList.clear();
......@@ -157,7 +169,7 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
}
ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx )
ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx ) const
{
ITEM_PICKER picker;
......@@ -168,7 +180,7 @@ ITEM_PICKER PICKED_ITEMS_LIST::GetItemWrapper( unsigned int aIdx )
}
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx )
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx ) const
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetItem();
......@@ -177,7 +189,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItem( unsigned int aIdx )
}
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx )
EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx ) const
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetLink();
......@@ -186,7 +198,7 @@ EDA_ITEM* PICKED_ITEMS_LIST::GetPickedItemLink( unsigned int aIdx )
}
UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx )
UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx ) const
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetStatus();
......@@ -195,7 +207,7 @@ UNDO_REDO_T PICKED_ITEMS_LIST::GetPickedItemStatus( unsigned int aIdx )
}
STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx )
STATUS_FLAGS PICKED_ITEMS_LIST::GetPickerFlags( unsigned aIdx ) const
{
if( aIdx < m_ItemsList.size() )
return m_ItemsList[aIdx].GetFlags();
......
......@@ -78,18 +78,21 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
/* Generic events for the Tool Dispatcher */
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, 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_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_LEFT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_RIGHT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this );
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_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 );
......
......@@ -57,15 +57,18 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) );
// Mouse events are skipped to the parent
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#endif
SetSize( aParent->GetSize() );
......
......@@ -34,11 +34,11 @@
#include <typeinfo>
#include <wx/msgdlg.h>
#include <confirm.h>
#ifdef __WXDEBUG__
#ifdef PROFILE
#include <profile.h>
#include <wx/debug.h>
#include <wx/log.h>
#endif
#endif /* PROFILE */
using namespace KIGFX;
......@@ -187,10 +187,10 @@ void GPU_CACHED_MANAGER::EndDrawing()
void GPU_CACHED_MANAGER::uploadToGpu()
{
#ifdef __WXDEBUG__
#ifdef PROFILE
prof_counter totalTime;
prof_start( &totalTime );
#endif /* __WXDEBUG__ */
#endif /* PROFILE */
if( !m_buffersInitialized )
Initialize();
......@@ -207,15 +207,13 @@ void GPU_CACHED_MANAGER::uploadToGpu()
m_indices.reset( new GLuint[bufferSize] );
if( glGetError() != GL_NO_ERROR )
{
DisplayError( NULL, wxT( "Error during data upload to the GPU memory" ) );
}
#ifdef __WXDEBUG__
#ifdef PROFILE
prof_end( &totalTime );
wxLogDebug( wxT( "Uploading %d vertices to GPU / %.1f ms" ), bufferSize, totalTime.msecs() );
#endif /* __WXDEBUG__ */
#endif /* PROFILE */
}
......
......@@ -70,15 +70,18 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::onPaint ) );
// Mouse events are skipped to the parent
Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MOTION, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#if defined _WIN32 || defined _WIN64
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) );
#endif
SetSize( aParent->GetSize() );
......
This diff is collapsed.
......@@ -34,9 +34,18 @@ ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) :
}
ACTION_MANAGER::~ACTION_MANAGER()
{
while( !m_actionIdIndex.empty() )
UnregisterAction( m_actionIdIndex.begin()->second );
}
void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
{
assert( aAction->GetId() == -1 ); // Check if the TOOL_ACTION was not registered before
assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() );
assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() );
aAction->setId( MakeActionId( aAction->m_name ) );
......@@ -44,7 +53,13 @@ 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 );
}
......@@ -52,13 +67,13 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
{
m_actionNameIndex.erase( aAction->m_name );
m_actionIdIndex.erase( aAction->m_id );
// Indicate that the ACTION_MANAGER no longer care about the object
aAction->setActionMgr( NULL );
aAction->setId( -1 );
m_actionNameIndex.erase( aAction->m_name );
m_actionIdIndex.erase( aAction->m_id );
if( aAction->HasHotKey() )
m_actionHotKeys.erase( aAction->m_currentHotKey );
}
......@@ -98,6 +113,12 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
}
void ACTION_MANAGER::ClearHotKey( int aHotKey )
{
m_actionHotKeys.erase( aHotKey );
}
void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const
{
TOOL_EVENT event = aAction->MakeEvent();
......
......@@ -29,7 +29,7 @@
#include <cassert>
CONTEXT_MENU::CONTEXT_MENU() :
m_titleSet( false ), m_handler( this ), m_tool( NULL )
m_titleSet( false ), m_selected( -1 ), m_handler( this ), m_tool( NULL )
{
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
......@@ -43,7 +43,7 @@ CONTEXT_MENU::CONTEXT_MENU() :
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
m_titleSet( aMenu.m_titleSet ), m_handler( this ), m_tool( aMenu.m_tool )
m_titleSet( aMenu.m_titleSet ), m_selected( -1 ), m_handler( this ), m_tool( aMenu.m_tool )
{
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
NULL, &m_handler );
......@@ -164,6 +164,9 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
// One of menu entries was selected..
else if( type == wxEVT_COMMAND_MENU_SELECTED )
{
// Store the selected position
m_menu->m_selected = aEvent.GetId();
// Check if there is a TOOL_ACTION for the given ID
if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 )
{
......
......@@ -43,10 +43,11 @@ using boost::optional;
struct TOOL_DISPATCHER::BUTTON_STATE
{
BUTTON_STATE( TOOL_MOUSE_BUTTONS aButton, const wxEventType& aDownEvent,
const wxEventType& aUpEvent ) :
const wxEventType& aUpEvent, const wxEventType& aDblClickEvent ) :
button( aButton ),
downEvent( aDownEvent ),
upEvent( aUpEvent )
upEvent( aUpEvent ),
dblClickEvent( aDblClickEvent )
{};
///> Flag indicating that dragging is active for the given button.
......@@ -74,6 +75,9 @@ struct TOOL_DISPATCHER::BUTTON_STATE
///> The type of wxEvent that determines mouse button release.
wxEventType upEvent;
///> The type of wxEvent that determines mouse button double click.
wxEventType dblClickEvent;
///> Time stamp for the last mouse button press event.
wxLongLong downTimestamp;
......@@ -89,9 +93,12 @@ struct TOOL_DISPATCHER::BUTTON_STATE
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) :
m_toolMgr( aToolMgr ), m_editFrame( aEditFrame )
{
m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP ) );
m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP ) );
m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP ) );
m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN,
wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) );
m_buttons.push_back( new BUTTON_STATE( BUT_RIGHT, wxEVT_RIGHT_DOWN,
wxEVT_RIGHT_UP, wxEVT_RIGHT_DCLICK ) );
m_buttons.push_back( new BUTTON_STATE( BUT_MIDDLE, wxEVT_MIDDLE_DOWN,
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DCLICK ) );
ResetState();
}
......@@ -126,6 +133,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
bool up = type == st->upEvent;
bool down = type == st->downEvent;
bool dblClick = type == st->dblClickEvent;
int mods = decodeModifiers<wxMouseEvent>( static_cast<wxMouseEvent*>( &aEvent ) );
int args = st->button | mods;
......@@ -139,7 +147,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
st->pressed = true;
evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DOWN, args );
}
else if( up ) // Handle mouse button release
else if( up ) // Handle mouse button release
{
st->pressed = false;
......@@ -162,6 +170,10 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
st->dragging = false;
}
else if( dblClick )
{
evt = TOOL_EVENT( TC_MOUSE, TA_MOUSE_DBLCLICK, args );
}
if( st->pressed && aMotion )
{
......@@ -204,14 +216,15 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
type == wxEVT_LEFT_DOWN || type == wxEVT_LEFT_UP ||
type == wxEVT_MIDDLE_DOWN || type == wxEVT_MIDDLE_UP ||
type == wxEVT_RIGHT_DOWN || type == wxEVT_RIGHT_UP ||
type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK ||
// Event issued whem mouse retains position in screen coordinates,
// but changes in world coordinates (eg. autopanning)
// but changes in world coordinates (e.g. autopanning)
type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
{
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition();
VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetMousePosition();
VECTOR2D pos = getView()->ToWorld( screenPos );
if( pos != m_lastMousePos || type == KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE )
if( pos != m_lastMousePos )
{
motion = true;
m_lastMousePos = pos;
......@@ -267,11 +280,6 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent )
toolName = "pcbnew.InteractiveRouter";
activateTool = true;
break;
case ID_SELECTION_TOOL:
toolName = "pcbnew.InteractiveSelection";
activateTool = true;
break;
}
// do nothing if the legacy view is active
......
......@@ -75,6 +75,7 @@ const std::string TOOL_EVENT::Format() const
const FlagString actions[] =
{
{ TA_MOUSE_CLICK, "click" },
{ TA_MOUSE_DBLCLICK, "double click" },
{ TA_MOUSE_UP, "button-up" },
{ TA_MOUSE_DOWN, "button-down" },
{ TA_MOUSE_DRAG, "drag" },
......@@ -90,6 +91,7 @@ const std::string TOOL_EVENT::Format() const
{ TA_CANCEL_TOOL, "cancel-tool" },
{ TA_CONTEXT_MENU_UPDATE, "context-menu-update" },
{ TA_CONTEXT_MENU_CHOICE, "context-menu-choice" },
{ TA_UNDO_REDO, "undo-redo" },
{ TA_ACTION, "action" },
{ 0, "" }
};
......@@ -100,7 +102,7 @@ const std::string TOOL_EVENT::Format() const
{ BUT_LEFT, "left" },
{ BUT_RIGHT, "right" },
{ BUT_MIDDLE, "middle" },
{ 0, "" }
{ 0, "" }
};
const FlagString modifiers[] =
......
......@@ -96,7 +96,7 @@ struct TOOL_MANAGER::TOOL_STATE
TOOL_MANAGER::TOOL_MANAGER() :
m_model( NULL ), m_view( NULL )
m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL )
{
m_actionMgr = new ACTION_MANAGER( this );
}
......@@ -119,10 +119,14 @@ TOOL_MANAGER::~TOOL_MANAGER()
void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
{
wxASSERT_MSG( m_toolNameIndex.find( aTool->GetName() ) == m_toolNameIndex.end(),
wxT( "Adding two tools with the same name may result in unexpected behaviour.") );
wxASSERT_MSG( m_toolIdIndex.find( aTool->GetId() ) == m_toolIdIndex.end(),
wxT( "Adding two tools with the same ID may result in unexpected behaviour.") );
TOOL_STATE* st = new TOOL_STATE;
st->theTool = aTool;
st->idle = true;
st->pendingWait = false;
st->pendingContextMenu = false;
st->cofunc = NULL;
......@@ -134,22 +138,20 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool )
aTool->m_toolMgr = this;
if( aTool->GetType() == INTERACTIVE )
if( !aTool->Init() )
{
if( !static_cast<TOOL_INTERACTIVE*>( aTool )->Init() )
{
std::string msg = StrPrintf( "Initialization of the %s tool failed", aTool->GetName().c_str() );
std::string msg = StrPrintf( "Initialization of the %s tool failed",
aTool->GetName().c_str() );
DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) );
DisplayError( NULL, wxString::FromUTF8( msg.c_str() ) );
// Unregister the tool
m_toolState.erase( aTool );
m_toolNameIndex.erase( aTool->GetName() );
m_toolIdIndex.erase( aTool->GetId() );
// Unregister the tool
m_toolState.erase( aTool );
m_toolNameIndex.erase( aTool->GetName() );
m_toolIdIndex.erase( aTool->GetId() );
delete st;
delete aTool;
}
delete st;
delete aTool;
}
}
......@@ -188,6 +190,12 @@ void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
}
bool TOOL_MANAGER::RunAction( const std::string& aActionName )
{
return m_actionMgr->RunAction( aActionName );
}
bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool )
{
wxASSERT( aTool != NULL );
......@@ -226,17 +234,16 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
wxASSERT( aTool != NULL );
if( !isRegistered( aTool ) )
{
wxASSERT_MSG( false, wxT( "You cannot run unregistered tools" ) );
return false;
TOOL_STATE* state = m_toolState[aTool];
}
// If the tool is already active, do not invoke it again
if( state->idle == false )
if( isActive( aTool ) )
return false;
state->idle = false;
static_cast<TOOL_INTERACTIVE*>( aTool )->Reset();
aTool->Reset( TOOL_INTERACTIVE::RUN );
// Add the tool on the front of the processing queue (it gets events first)
m_activeTools.push_front( aTool->GetId() );
......@@ -267,6 +274,13 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
}
void TOOL_MANAGER::ResetTools( TOOL_BASE::RESET_REASON aReason )
{
BOOST_FOREACH( TOOL_BASE* tool, m_toolState | boost::adaptors::map_keys )
tool->Reset( aReason );
}
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE* aTool, TOOL_STATE_FUNC& aHandler,
const TOOL_EVENT_LIST& aConditions )
{
......@@ -333,10 +347,11 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
// Go() method that match the event.
if( st->transitions.size() )
{
BOOST_FOREACH( TRANSITION tr, st->transitions )
BOOST_FOREACH( TRANSITION& tr, st->transitions )
{
if( tr.first.Matches( aEvent ) )
{
// as the state changes, the transition table has to be set up again
st->transitions.clear();
// no tool context allocated yet? Create one.
......@@ -350,6 +365,9 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
if( !st->cofunc->Running() )
finishTool( st ); // The couroutine has finished immediately?
// there is no point in further checking, as transitions got cleared
break;
}
}
}
......@@ -394,21 +412,18 @@ bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent )
void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
{
// Find the tool to be deactivated
std::deque<TOOL_ID>::iterator it, it_end;
std::deque<TOOL_ID>::iterator it, itEnd;
for( it = m_activeTools.begin(), it_end = m_activeTools.end(); it != it_end; ++it )
// Find the tool and deactivate it
for( it = m_activeTools.begin(), itEnd = m_activeTools.end(); it != itEnd; ++it )
{
if( aState == m_toolIdIndex[*it] )
{
m_activeTools.erase( it );
break;
}
}
if( it != m_activeTools.end() )
m_activeTools.erase( it );
else
wxLogWarning( wxT( "Tried to finish inactive tool" ) );
aState->idle = true;
delete aState->cofunc;
aState->cofunc = NULL;
}
......@@ -445,9 +460,12 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
GetEditFrame()->PopupMenu( menu->GetMenu() );
//
TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE );
dispatchInternal( evt );
// If nothing was chosen from the context menu, we must notify the tool as well
if( menu->GetSelected() < 0 )
{
TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CHOICE );
dispatchInternal( evt );
}
break;
}
......@@ -456,7 +474,8 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
if( m_view->IsDirty() )
{
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
if( f->IsGalCanvasActive() )
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
}
return false;
......@@ -492,15 +511,6 @@ void TOOL_MANAGER::SetEnvironment( EDA_ITEM* aModel, KIGFX::VIEW* aView,
m_view = aView;
m_viewControls = aViewControls;
m_editFrame = aFrame;
// Reset state of the registered tools
BOOST_FOREACH( TOOL_ID toolId, m_activeTools )
{
TOOL_BASE* tool = m_toolIdIndex[toolId]->theTool;
if( tool->GetType() == INTERACTIVE )
static_cast<TOOL_INTERACTIVE*>( tool )->Reset();
}
}
......@@ -509,5 +519,6 @@ bool TOOL_MANAGER::isActive( TOOL_BASE* aTool )
if( !isRegistered( aTool ) )
return false;
return !m_toolState[aTool]->idle;
// Just check if the tool is on the active tools stack
return std::find( m_activeTools.begin(), m_activeTools.end(), aTool->GetId() ) != m_activeTools.end();
}
......@@ -34,9 +34,9 @@
#include <gal/graphics_abstraction_layer.h>
#include <painter.h>
#ifdef __WXDEBUG__
#ifdef PROFILE
#include <profile.h>
#endif /* __WXDEBUG__ */
#endif /* PROFILE */
using namespace KIGFX;
......@@ -122,6 +122,12 @@ void VIEW::Remove( VIEW_ITEM* aItem )
{
VIEW_LAYER& l = m_layers[layers[i]];
l.items->Remove( aItem );
MarkTargetDirty( l.target );
// Clear the GAL cache
int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
}
}
......@@ -833,7 +839,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 )
......@@ -944,6 +950,12 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
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( prevGroup >= 0 )
m_gal->DeleteGroup( prevGroup );
}
// Add the item to new layer set
......@@ -983,10 +995,10 @@ void VIEW::RecacheAllItems( bool aImmediately )
r.SetMaximum();
#ifdef __WXDEBUG__
#ifdef PROFILE
prof_counter totalRealTime;
prof_start( &totalRealTime );
#endif /* __WXDEBUG__ */
#endif /* PROFILE */
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
{
......@@ -1002,12 +1014,12 @@ void VIEW::RecacheAllItems( bool aImmediately )
}
}
#ifdef __WXDEBUG__
#ifdef PROFILE
prof_end( &totalRealTime );
wxLogDebug( wxT( "RecacheAllItems::immediately: %u %.1f ms" ),
aImmediately, totalRealTime.msecs() );
#endif /* __WXDEBUG__ */
#endif /* PROFILE */
}
......
......@@ -34,17 +34,13 @@ 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 )
{
ViewUpdate( APPEARANCE );
}
}
......@@ -53,16 +49,14 @@ void VIEW_ITEM::ViewUpdate( int aUpdateFlags )
if( !m_view )
return;
m_view->invalidateItem( this, aUpdateFlags );
m_view->InvalidateItem( this, aUpdateFlags );
}
void VIEW_ITEM::ViewRelease()
{
if( m_view && m_view->IsDynamic() )
{
m_view->Remove( this );
}
}
......
......@@ -73,19 +73,12 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
m_mousePosition.x = aEvent.GetX();
m_mousePosition.y = aEvent.GetY();
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;
updateCursor();
bool isAutoPanning = false;
if( m_autoPanEnabled )
{
isAutoPanning = handleAutoPanning( aEvent );
}
if( !isAutoPanning && aEvent.Dragging() )
{
......@@ -168,17 +161,13 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
}
if( aEvent.LeftUp() )
{
m_state = IDLE; // Stop autopanning when user release left mouse button
}
break;
case DRAG_PANNING:
if( aEvent.MiddleUp() )
{
m_state = IDLE;
}
break;
}
......@@ -210,8 +199,23 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
dir = m_view->ToWorld( dir, false );
m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
updateCursor();
// Notify tools that the cursor position has changed in the world coordinates
wxCommandEvent moveEvent( EVT_REFRESH_MOUSE );
wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
// Set the modifiers state
#if wxCHECK_VERSION( 3, 0, 0 )
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT) );
#else
// wx <3.0 do not have accessors, but the fields are exposed
moveEvent.m_controlDown = wxGetKeyState( WXK_CONTROL );
moveEvent.m_shiftDown = wxGetKeyState( WXK_SHIFT );
moveEvent.m_altDown = wxGetKeyState( WXK_ALT );
#endif
wxPostEvent( m_parentPanel, moveEvent );
}
break;
......@@ -225,7 +229,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
void WX_VIEW_CONTROLS::SetGrabMouse( bool aEnabled )
{
m_grabMouse = aEnabled;
VIEW_CONTROLS::SetGrabMouse( aEnabled );
if( aEnabled )
m_parentPanel->CaptureMouse();
......@@ -243,15 +247,6 @@ const VECTOR2D WX_VIEW_CONTROLS::GetMousePosition() const
}
const VECTOR2D WX_VIEW_CONTROLS::GetCursorPosition() const
{
if( m_snappingEnabled )
return m_view->GetGAL()->GetGridPoint( GetMousePosition() );
else
return GetMousePosition();
}
bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
{
VECTOR2D p( aEvent.GetX(), aEvent.GetY() );
......@@ -309,3 +304,14 @@ 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;
}
......@@ -36,10 +36,8 @@
using namespace KIGFX;
WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName,
const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) :
WORKSHEET_VIEWITEM::WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ) :
EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type
m_fileName( aFileName ), m_sheetName( aSheetName ),
m_titleBlock( aTitleBlock ), m_pageInfo( aPageInfo ), m_sheetNumber( 1 ), m_sheetCount( 1 ) {}
......
......@@ -124,7 +124,7 @@ public:
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
{
......
......@@ -160,7 +160,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
}
void SCH_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
......
......@@ -676,7 +676,7 @@ public:
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
{
......
......@@ -83,8 +83,7 @@ protected:
public:
BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
EDA_ITEM( aParent, idtype )
, m_Layer( FIRST_LAYER )
EDA_ITEM( aParent, idtype ), m_Layer( FIRST_LAYER )
{
}
......@@ -94,6 +93,16 @@ public:
virtual void SetPosition( const wxPoint& aPos ) = 0;
/**
* Function IsConnected()
* Returns information if the object is derived from BOARD_CONNECTED_ITEM.
* @return True if the object is of BOARD_CONNECTED_ITEM type, false otherwise.
*/
virtual bool IsConnected() const
{
return false;
}
/**
* A value of wxPoint(0,0) which can be passed to the Draw() functions.
*/
......
......@@ -111,7 +111,7 @@ public:
void SetStatus( UNDO_REDO_T aStatus ) { m_undoRedoStatus = aStatus; }
UNDO_REDO_T GetStatus() { return m_undoRedoStatus; }
UNDO_REDO_T GetStatus() const { return m_undoRedoStatus; }
void SetFlags( STATUS_FLAGS aFlags ) { m_pickerFlags = aFlags; }
......@@ -148,7 +148,7 @@ public:
* pushes \a aItem to the top of the list
* @param aItem Picker to push on to the list.
*/
void PushItem( ITEM_PICKER& aItem );
void PushItem( const ITEM_PICKER& aItem );
/**
* Function PopItem
......@@ -160,7 +160,14 @@ public:
* Function IsItemInList
* @return True if \a aItem is found in the pick list.
*/
bool ContainsItem( EDA_ITEM* aItem ) const;
bool ContainsItem( const EDA_ITEM* aItem ) const;
/**
* Function FindItem
* @return Index of the searched item. If the item is not stored in the list, negative value
* is returned.
*/
int FindItem( const EDA_ITEM* aItem ) const;
/**
* Function ClearItemsList
......@@ -201,21 +208,21 @@ public:
* if this picker does not exist, a picker is returned,
* with its members set to 0 or NULL
*/
ITEM_PICKER GetItemWrapper( unsigned int aIdx );
ITEM_PICKER GetItemWrapper( unsigned int aIdx ) const;
/**
* Function GetPickedItem
* @return A pointer to the picked item
* @param aIdx Index of the picked item in the picked list
*/
EDA_ITEM* GetPickedItem( unsigned int aIdx );
EDA_ITEM* GetPickedItem( unsigned int aIdx ) const;
/**
* Function GetPickedItemLink
* @return link of the picked item, or null if does not exist
* @param aIdx Index of the picked item in the picked list
*/
EDA_ITEM* GetPickedItemLink( unsigned int aIdx );
EDA_ITEM* GetPickedItemLink( unsigned int aIdx ) const;
/**
* Function GetPickedItemStatus
......@@ -223,7 +230,7 @@ public:
* or UR_UNSPECIFIED if does not exist
* @param aIdx Index of the picked item in the picked list
*/
UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx );
UNDO_REDO_T GetPickedItemStatus( unsigned int aIdx ) const;
/**
* Function GetPickerFlags
......@@ -231,7 +238,7 @@ public:
* @param aIdx Index of the picker in the picked list
* @return The value stored in the picker, if the picker exists, or 0 if does not exist
*/
STATUS_FLAGS GetPickerFlags( unsigned aIdx );
STATUS_FLAGS GetPickerFlags( unsigned aIdx ) const;
/**
* Function SetPickedItem
......
......@@ -136,7 +136,7 @@ public:
* Function Brightened
* Returns a color that is brighter by a given factor, without modifying object.
* @param aFactor Specifies how bright the color should become (valid values: 0.0 .. 1.0).
* @return COLOR4D Highlightedd color.
* @return COLOR4D Highlighted color.
*/
COLOR4D Brightened( double aFactor ) const
{
......
......@@ -98,6 +98,24 @@ struct fnv_1a
};
/// Hash function for wxString, counterpart of std::string hash
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
{
std::size_t operator()( const wxString& aString ) const
{
std::size_t hash = 2166136261u;
for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it )
{
hash ^= (unsigned char) *it;
hash *= 16777619;
}
return hash;
}
};
/**
* Type KEYWORD_MAP
* is a hashtable made of a const char* and an int. Note that use of this
......
......@@ -31,6 +31,7 @@
#include <climits>
#include <iostream>
#include <sstream>
#include <cmath>
#include <math/math_util.h>
......
......@@ -47,6 +47,12 @@ public:
*/
ACTION_MANAGER( TOOL_MANAGER* aToolManager );
/**
* Destructor.
* Unregisters every registered action.
*/
~ACTION_MANAGER();
/**
* Function RegisterAction()
* Adds a tool action to the manager and sets it up. After that is is possible to invoke
......@@ -75,18 +81,21 @@ public:
*/
bool RunAction( const std::string& aActionName ) const;
// TODO to be considered
// bool RunAction( int aActionId ) const;
// bool RunAction( TOOL_ACTION* aAction ) const;
/**
* Function RunHotKey()
* Runs an action associated with a hotkey (if there is one available).
* @param aHotKey is the hotkey to be served.
* @param aHotKey is the hotkey to be handled.
* @return True if there was an action associated with the hotkey, false otherwise.
*/
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;
......
......@@ -78,6 +78,17 @@ public:
*/
void Clear();
/**
* Function GetSelected()
* Returns the position of selected item. If the returned value is negative, that means that
* menu was dismissed.
* @return The position of selected item in the context menu.
*/
int GetSelected() const
{
return m_selected;
}
/**
* Function GetMenu()
* Returns the instance of wxMenu object used to display the menu.
......@@ -131,6 +142,9 @@ private:
///> Instance of wxMenu used for display of the context menu.
wxMenu m_menu;
///> Stores the id number of selected item.
int m_selected;
///> Instance of menu event handler.
CMEventHandler m_handler;
......
......@@ -70,6 +70,33 @@ public:
virtual ~TOOL_BASE() {};
///> Determines the reason of reset for a tool
enum RESET_REASON
{
RUN, ///< Tool is invoked after being inactive
MODEL_RELOAD, ///< Model changes
GAL_SWITCH ///< Rendering engine changes
};
/**
* Function Init()
* Init() is called once upon a registration of the tool.
*
* @return True if the initialization went fine, false - otherwise.
*/
virtual bool Init()
{
return true;
}
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
* @param aReason contains information about the reason of tool reset.
*/
virtual void Reset( RESET_REASON aReason ) = 0;
/**
* Function GetType()
* Returns the type of the tool.
......
......@@ -54,39 +54,46 @@ enum TOOL_EVENT_CATEGORY
enum TOOL_ACTIONS
{
// UI input events
TA_NONE = 0x0000,
TA_MOUSE_CLICK = 0x0001,
TA_MOUSE_UP = 0x0002,
TA_MOUSE_DOWN = 0x0004,
TA_MOUSE_DRAG = 0x0008,
TA_MOUSE_MOTION = 0x0010,
TA_MOUSE_WHEEL = 0x0020,
TA_MOUSE = 0x003f,
TA_KEY_UP = 0x0040,
TA_KEY_DOWN = 0x0080,
TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN,
TA_NONE = 0x0000,
TA_MOUSE_CLICK = 0x0001,
TA_MOUSE_DBLCLICK = 0x0002,
TA_MOUSE_UP = 0x0004,
TA_MOUSE_DOWN = 0x0008,
TA_MOUSE_DRAG = 0x0010,
TA_MOUSE_MOTION = 0x0020,
TA_MOUSE_WHEEL = 0x0040,
TA_MOUSE = 0x007f,
TA_KEY_UP = 0x0080,
TA_KEY_DOWN = 0x0100,
TA_KEYBOARD = TA_KEY_UP | TA_KEY_DOWN,
// View related events
TA_VIEW_REFRESH = 0x0100,
TA_VIEW_ZOOM = 0x0200,
TA_VIEW_PAN = 0x0400,
TA_VIEW_DIRTY = 0x0800,
TA_CHANGE_LAYER = 0x1000,
TA_VIEW_REFRESH = 0x0200,
TA_VIEW_ZOOM = 0x0400,
TA_VIEW_PAN = 0x0800,
TA_VIEW_DIRTY = 0x1000,
TA_VIEW = 0x1e00,
TA_CHANGE_LAYER = 0x2000,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CANCEL_TOOL = 0x2000,
TA_CANCEL_TOOL = 0x4000,
// 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 = 0x4000,
TA_CONTEXT_MENU_UPDATE = 0x8000,
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_CONTEXT_MENU_CHOICE = 0x8000,
TA_CONTEXT_MENU_CHOICE = 0x10000,
// This event is sent *before* undo/redo command is performed.
TA_UNDO_REDO = 0x20000,
// Tool action (allows to control tools)
TA_ACTION = 0x10000,
TA_ACTION = 0x40000,
TA_ANY = 0xffffffff
};
......@@ -233,6 +240,12 @@ public:
&& ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
}
bool IsDblClick( int aButtonMask = BUT_ANY ) const
{
return ( m_actions == TA_MOUSE_DBLCLICK )
&& ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
}
bool IsDrag( int aButtonMask = BUT_ANY ) const
{
return ( m_actions == TA_MOUSE_DRAG ) && ( ( m_mouseButtons & aButtonMask ) == aButtonMask );
......@@ -277,7 +290,7 @@ public:
void SetMouseDragOrigin( const VECTOR2D& aP )
{
m_mouseDragOrigin = aP;
}
}
void SetMousePosition( const VECTOR2D& aP )
{
......@@ -311,6 +324,9 @@ public:
if( m_commandId && aEvent.m_commandId )
return *m_commandId == *aEvent.m_commandId;
// Command-type event has to contain either id or string
assert( false );
}
return true;
......
......@@ -48,24 +48,6 @@ public:
TOOL_INTERACTIVE( const std::string& aName );
virtual ~TOOL_INTERACTIVE();
/**
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
*/
virtual void Reset() = 0;
/**
* Function Init()
* Init() is called once upon a registration of the tool.
*
* @return True if the initialization went fine, false - otherwise.
*/
virtual bool Init()
{
return true;
}
/**
* Function SetContextMenu()
*
......
......@@ -99,6 +99,15 @@ public:
*/
void UnregisterAction( TOOL_ACTION* aAction );
/**
* Function RunAction()
* Runs the specified action. The common format 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 FindTool()
* Searches for a tool with given ID.
......@@ -118,10 +127,10 @@ public:
TOOL_BASE* FindTool( const std::string& aName ) const;
/**
* Resets the state of a given tool by clearing its wait and
* transition lists and calling tool's internal Reset() method.
* Function ResetTools()
* Resets all tools (i.e. calls their Reset() method).
*/
void ResetTool( TOOL_BASE* aTool );
void ResetTools( TOOL_BASE::RESET_REASON aReason );
/**
* Takes an event from the TOOL_DISPATCHER and propagates it to
......
......@@ -69,9 +69,6 @@ namespace hed {
struct TTLtraits {
// The actual triangulation object
static Triangulation* triang_;
/** The floating point type used in calculations
* involving scalar products and cross products.
*/
......@@ -172,127 +169,6 @@ namespace hed {
}
//@} // End of Geometric Predicates Group
// A rationale for directing these functions to traits is:
// e.g., constraints
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be swapped
* according to the Delaunay criterion.<br>
*
* \note
* This function is also present in the TTL as ttl::swapTestDelaunay.<br>
* Thus, the function can be implemented simply as:
* \code
* { return ttl::swapTestDelaunay<TTLtraits>(dart); }
* \endcode
*/
//static bool swapTestDelaunay(const Dart& dart) {
// return ttl::swapTestDelaunay<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart can be swapped, i.e.,
* if the edge is a diagonal in a (strictly) convex quadrilateral.
* This function is also present as ttl::swappableEdge.
*/
//static bool swappableEdge(const Dart& dart) {
// return ttl::swappableEdge<TTLtraits>(dart);
//}
//----------------------------------------------------------------------------------------------
/* Checks if the edge associated with \e dart should be \e fixed, meaning
* that it should never be swapped. ??? Use when constraints.
*/
//static bool fixedEdge(const Dart& dart) {
// return dart.getEdge()->isConstrained();
//}
//----------------------------------------------------------------------------------------------
// ----------------------- Functions for Delaunay Triangulation Group -------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for Delaunay Triangulation */
//@{
//----------------------------------------------------------------------------------------------
/** 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.
*/
static void swapEdge(Dart& dart) {
if (!dart.getEdge()->isConstrained()) triang_->swapEdge(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** 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.
*/
static void splitTriangle(Dart& dart, NodePtr point) {
EdgePtr edge = triang_->splitTriangle(dart.getEdge(), point);
dart.init(edge);
}
//@} // End of Functions for Delaunay Triangulation group
//----------------------------------------------------------------------------------------------
// --------------------------- Functions for removing nodes Group -----------------------------
//----------------------------------------------------------------------------------------------
/** @name Functions for removing nodes */
//@{
//----------------------------------------------------------------------------------------------
/** The reverse operation of TTLtraits::splitTriangle.
* This function is only required for functions that involve
* removal of interior nodes; see for example ttl::removeInteriorNode.
*
* <center>
* \image html reverse_splitTriangle.gif
* </center>
*/
static void reverse_splitTriangle(Dart& dart) {
triang_->reverse_splitTriangle(dart.getEdge());
}
//----------------------------------------------------------------------------------------------
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
static void removeBoundaryTriangle(Dart& d) {
triang_->removeTriangle(d.getEdge());
}
//@} // End of Functions for removing nodes Group
};
}; // End of hed namespace
......
......@@ -51,9 +51,13 @@
#include <vector>
#include <iostream>
#include <fstream>
#include <ttl/ttl.h>
#include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace ttl {
class TriangulationHelper;
};
//--------------------------------------------------------------------------------------------------
// The half-edge data structure
......@@ -65,6 +69,7 @@ namespace hed {
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;
//------------------------------------------------------------------------------------------------
......@@ -151,8 +156,7 @@ public:
class Edge {
public:
/// Constructor
Edge() : weight_(0)
{ flags_.isLeadingEdge_ = false; flags_.isConstrained_ = false; }
Edge() : weight_(0), isLeadingEdge_(false) {}
/// Destructor
virtual ~Edge() {}
......@@ -167,49 +171,52 @@ public:
void setTwinEdge(const EdgePtr& edge) { twinEdge_ = edge; }
/// Sets the edge as a leading edge
void setAsLeadingEdge(bool val=true) { flags_.isLeadingEdge_ = val; }
void setAsLeadingEdge(bool val=true) { isLeadingEdge_ = val; }
/// Checks if an edge is a leading edge
bool isLeadingEdge() const { return flags_.isLeadingEdge_; }
/// Sets the edge as a constrained edge
void setConstrained(bool val=true) { flags_.isConstrained_ = val;
if (twinEdge_) twinEdge_->flags_.isConstrained_ = val; }
/// Checks if an edge is constrained
bool isConstrained() const { return flags_.isConstrained_; }
bool isLeadingEdge() const { return isLeadingEdge_; }
/// Returns the twin edge
const EdgePtr& getTwinEdge() const { return twinEdge_; };
EdgePtr getTwinEdge() const { return twinEdge_.lock(); };
void clearTwinEdge() { twinEdge_.reset(); }
/// Returns the next edge in face
const EdgePtr& getNextEdgeInFace() const { return nextEdgeInFace_; }
/// Retuns the source node
virtual const NodePtr& getSourceNode() const { return sourceNode_; }
const NodePtr& getSourceNode() const { return sourceNode_; }
/// Returns the target node
virtual const NodePtr& getTargetNode() const { return getNextEdgeInFace()->getSourceNode(); }
virtual const NodePtr& getTargetNode() const { return nextEdgeInFace_->getSourceNode(); }
void setWeight( unsigned int weight ) { weight_ = weight; }
unsigned int getWeight() const { return weight_; }
void clear()
{
sourceNode_.reset();
nextEdgeInFace_.reset();
if( !twinEdge_.expired() )
{
twinEdge_.lock()->clearTwinEdge();
twinEdge_.reset();
}
}
protected:
NodePtr sourceNode_;
EdgePtr twinEdge_;
EdgeWeakPtr twinEdge_;
EdgePtr nextEdgeInFace_;
unsigned int weight_;
struct {
bool isLeadingEdge_;
bool isConstrained_;
} flags_;
bool isLeadingEdge_;
}; // End of class Edge
/** \class EdgeMST
* \brief \b %Specialization of Edge class to be used for Minimum Spanning Tree algorithm.
* \brief \b Specialization of %Edge class to be used for Minimum Spanning Tree algorithm.
*/
class EdgeMST : public Edge
{
......@@ -221,10 +228,17 @@ public:
target_(target)
{ sourceNode_ = source; weight_ = weight; }
EdgeMST( const Edge& edge )
{
sourceNode_ = edge.getSourceNode();
target_ = edge.getTargetNode();
weight_ = edge.getWeight();
}
~EdgeMST() {};
/// @copydoc Edge::setSourceNode()
const NodePtr& getTargetNode() const { return target_; }
virtual const NodePtr& getTargetNode() const { return target_; }
};
......@@ -242,26 +256,75 @@ public:
class Triangulation {
protected:
list<EdgePtr> leadingEdges_; // one half-edge for each arc
std::list<EdgePtr> leadingEdges_; // one half-edge for each arc
ttl::TriangulationHelper* helper;
void addLeadingEdge(EdgePtr& edge) {
edge->setAsLeadingEdge();
leadingEdges_.push_front( edge );
}
bool removeLeadingEdgeFromList(EdgePtr& leadingEdge);
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);
/** 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);
/** 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);
/** Removes a triangle with an edge at the boundary of the triangulation
* in the actual data structure
*/
void removeBoundaryTriangle(Dart& d);
public:
/// Default constructor
Triangulation() {}
Triangulation();
/// Copy constructor
Triangulation(const Triangulation& tr) {
std::cout << "Triangulation: Copy constructor not present - EXIT.";
exit(-1);
}
Triangulation(const Triangulation& tr);
/// Destructor
~Triangulation() { cleanAll(); }
~Triangulation();
/// Creates a Delaunay triangulation from a set of points
void createDelaunay(NodesContainer::iterator first,
......@@ -280,7 +343,7 @@ public:
void swapEdge(EdgePtr& diagonal);
/// Splits the triangle associated with edge into three new triangles joining at point
EdgePtr splitTriangle(EdgePtr& edge, NodePtr& point);
EdgePtr splitTriangle(EdgePtr& edge, const NodePtr& point);
// Functions required by TTL for removing nodes in a Delaunay triangulation
......@@ -295,20 +358,20 @@ public:
Dart createDart();
/// Returns a list of "triangles" (one leading half-edge for each triangle)
const list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
const std::list<EdgePtr>& getLeadingEdges() const { return leadingEdges_; }
/// Returns the number of triangles
int noTriangles() const { return (int)leadingEdges_.size(); }
int noTriangles() const { return (int)leadingEdges_.size(); }
/// Returns a list of half-edges (one half-edge for each arc)
list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
std::list<EdgePtr>* getEdges(bool skip_boundary_edges = false) const;
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
void flagNodes(bool flag) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
list<NodePtr>* getNodes() const;
std::list<NodePtr>* getNodes() const;
#endif
/// Swaps edges until the triangulation is Delaunay (constrained edges are not swapped)
......@@ -320,12 +383,16 @@ public:
/// Returns an arbitrary interior node (as the source node of the returned edge)
EdgePtr getInteriorNode() const;
EdgePtr getBoundaryEdgeInTriangle(const EdgePtr& e) const;
/// Returns an arbitrary boundary edge
EdgePtr getBoundaryEdge() const;
/// Print edges for plotting with, e.g., gnuplot
void printEdges(std::ofstream& os) const;
friend class ttl::TriangulationHelper;
}; // End of class Triangulation
......
This diff is collapsed.
......@@ -51,9 +51,6 @@
static ofstream ofile_constr("qweCons.dat");
#endif
//using namespace std;
/** \brief Constrained Delaunay triangulation
*
* Basic generic algorithms in TTL for inserting a constrained edge between two existing nodes.\n
......@@ -61,7 +58,7 @@
* See documentation for the namespace ttl for general requirements and assumptions.
*
* \author
* Øyvind Hjelle, oyvindhj@ifi.uio.no
* yvind Hjelle, oyvindhj@ifi.uio.no
*/
namespace ttl_constr {
......@@ -73,6 +70,9 @@ namespace ttl_constr {
#endif
class ConstrainedTriangulation
{
public:
//------------------------------------------------------------------------------------------------
/* Checks if \e dart has start and end points in \e dstart and \e dend.
*
......@@ -89,14 +89,14 @@ namespace ttl_constr {
* A bool confirming that it's the constraint or not
*
* \using
* ttl::same_0_orbit
* same_0_orbit
*/
template <class DartType>
bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) {
static bool isTheConstraint(const DartType& dart, const DartType& dstart, const DartType& dend) {
DartType d0 = dart;
d0.alpha0(); // CW
if ((ttl::same_0_orbit(dstart, dart) && ttl::same_0_orbit(dend, d0)) ||
(ttl::same_0_orbit(dstart, d0) && ttl::same_0_orbit(dend, dart))) {
if ((ttl::TriangulationHelper::same_0_orbit(dstart, dart) && ttl::TriangulationHelper::same_0_orbit(dend, d0)) ||
(ttl::TriangulationHelper::same_0_orbit(dstart, d0) && ttl::TriangulationHelper::same_0_orbit(dend, dart))) {
return true;
}
return false;
......@@ -123,7 +123,7 @@ namespace ttl_constr {
* TraitsType::orient2d
*/
template <class TraitsType, class DartType>
bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) {
static bool crossesConstraint(DartType& dstart, DartType& dend, DartType& d1, DartType& d2) {
typename TraitsType::real_type orient_1 = TraitsType::orient2d(dstart,d1,dend);
typename TraitsType::real_type orient_2 = TraitsType::orient2d(dstart,d2,dend);
......@@ -156,12 +156,12 @@ namespace ttl_constr {
* The dart \e d making the smallest positive (or == 0) angle
*
* \using
* ttl::isBoundaryNode
* ttl::positionAtNextBoundaryEdge
* isBoundaryNode
* positionAtNextBoundaryEdge
* TraitsType::orient2d
*/
template <class TraitsType, class DartType>
DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) {
static DartType getAtSmallestAngle(const DartType& dstart, const DartType& dend) {
// - Must boundary be convex???
// - Handle the case where the constraint is already present???
......@@ -169,9 +169,9 @@ namespace ttl_constr {
// (dstart and dend may define a boundary edge)
DartType d_iter = dstart;
if (ttl::isBoundaryNode(d_iter)) {
if (ttl::TriangulationHelper::isBoundaryNode(d_iter)) {
d_iter.alpha1(); // CW
ttl::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary)
ttl::TriangulationHelper::positionAtNextBoundaryEdge(d_iter); // CCW (was rotated CW to the boundary)
}
// assume convex boundary; see comments
......@@ -273,7 +273,7 @@ namespace ttl_constr {
* Returns the next "collinear" starting node such that dend is returned when done.
*/
template <class TraitsType, class DartType, class ListType>
DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) {
static DartType findCrossingEdges(const DartType& dstart, const DartType& dend, ListType& elist) {
const DartType my_start = getAtSmallestAngle<TraitsType>(dstart, dend);
DartType my_end = getAtSmallestAngle<TraitsType>(dend, dstart);
......@@ -387,15 +387,16 @@ namespace ttl_constr {
* A list containing all the edges crossing the spesified constraint
*
* \using
* ttl::swappableEdge
* ttl::swapEdgeInList
* ttl::crossesConstraint
* ttl::isTheConstraint
* swappableEdge
* swapEdgeInList
* crossesConstraint
* isTheConstraint
*/
template <class TraitsType, class DartType>
void transformToConstraint(DartType& dstart, DartType& dend, std::list<DartType>& elist) {
void transformToConstraint(ttl::TriangulationHelper helper, DartType& dstart, DartType& dend,
std::list<DartType>& elist) const {
typename list<DartType>::iterator it, used;
typename std::list<DartType>::iterator it, used;
// We may enter in a situation where dstart and dend are altered because of a swap.
// (The general rule is that darts inside the actual quadrilateral can be changed,
......@@ -423,7 +424,7 @@ namespace ttl_constr {
if (counter > dartsInList)
break;
if (ttl::swappableEdge<TraitsType, DartType>(*it, true)) {
if (ttl::TriangulationHelper::swappableEdge<TraitsType, DartType>(*it, true)) {
// Dyn & Goren & Rippa 's notation:
// The node assosiated with dart *it is denoted u_m. u_m has edges crossing the constraint
// named w_1, ... , w_r . The other node to the edge assosiated with dart *it is w_s.
......@@ -456,7 +457,7 @@ namespace ttl_constr {
end = true;
// This is the only place swapping is called when inserting a constraint
ttl::swapEdgeInList<TraitsType, DartType>(it,elist);
helper.swapEdgeInList<TraitsType, DartType>(it,elist);
// If we, during look-ahead, found that dstart and/or dend were in the quadrilateral,
// we update them.
......@@ -512,6 +513,8 @@ namespace ttl_constr {
}
}; // End of ConstrainedTriangulation class
}; // End of ttl_constr namespace scope
......@@ -546,14 +549,14 @@ namespace ttl { // (extension)
* - \ref hed::TTLtraits::swapEdge "TraitsType::swapEdge" (DartType&)
*
* \using
* - ttl::optimizeDelaunay if \e optimize_delaunay is set to \c true
* - optimizeDelaunay if \e optimize_delaunay is set to \c true
*
* \par Assumes:
* - The constrained edge must be inside the existing triangulation (and it cannot
* cross the boundary of the triangulation).
*/
template <class TraitsType, class DartType>
DartType insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) {
DartType TriangulationHelper::insertConstraint(DartType& dstart, DartType& dend, bool optimize_delaunay) {
// Assumes:
// - It is the users responsibility to avoid crossing constraints
......@@ -567,8 +570,8 @@ namespace ttl { // (extension)
// calls itself recursively.
// RECURSION
list<DartType> elist;
DartType next_start = ttl_constr::findCrossingEdges<TraitsType>(dstart, dend, elist);
std::list<DartType> elist;
DartType next_start = ttl_constr::ConstrainedTriangulation::findCrossingEdges<TraitsType>(dstart, dend, elist);
// If there are no crossing edges (elist is empty), we assume that the constraint
// is an existing edge.
......@@ -583,7 +586,7 @@ namespace ttl { // (extension)
// findCrossingEdges stops if it finds a node lying on the constraint.
// A dart with this node as start node is returned
// We call insertConstraint recursivly until the received dart is dend
if (!ttl::same_0_orbit(next_start, dend)) {
if (!same_0_orbit(next_start, dend)) {
#ifdef DEBUG_TTL_CONSTR_PLOT
cout << "RECURSION due to collinearity along constraint" << endl;
......@@ -594,7 +597,7 @@ namespace ttl { // (extension)
// Swap edges such that the constraint edge is present in the transformed triangulation.
if (elist.size() > 0) // by Thomas Sevaldrud
ttl_constr::transformToConstraint<TraitsType>(dstart, next_start, elist);
ttl_constr::ConstrainedTriangulation::transformToConstraint<TraitsType>(dstart, next_start, elist);
#ifdef DEBUG_TTL_CONSTR_PLOT
cout << "size of elist = " << elist.size() << endl;
......@@ -607,13 +610,13 @@ namespace ttl { // (extension)
#endif
// Optimize to constrained Delaunay triangulation if required.
typename list<DartType>::iterator end_opt = elist.end();
typename std::list<DartType>::iterator end_opt = elist.end();
if (optimize_delaunay) {
// Indicate that the constrained edge, which is the last element in the list,
// should not be swapped
--end_opt;
ttl::optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
optimizeDelaunay<TraitsType, DartType>(elist, end_opt);
}
if(elist.size() == 0) // by Thomas Sevaldrud
......
......@@ -493,6 +493,14 @@ public:
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
private:
......@@ -563,11 +571,6 @@ private:
*/
void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const;
///* Manages dirty flags & redraw queueing when updating an item. Called internally
/// via VIEW_ITEM::ViewUpdate()
void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
///* Sorts m_orderedLayers when layer rendering order has changed
void sortLayers();
......
......@@ -60,7 +60,7 @@ public:
*
* @param aEnabled says whether the opion should be enabled or disabled.
*/
void SetSnapping( bool aEnabled )
virtual void SetSnapping( bool aEnabled )
{
m_snappingEnabled = aEnabled;
}
......
......@@ -58,6 +58,13 @@ 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).
......@@ -84,7 +91,10 @@ public:
const VECTOR2D GetMousePosition() const;
/// @copydoc VIEW_CONTROLS::GetCursorPosition()
const VECTOR2D GetCursorPosition() const;
const VECTOR2D GetCursorPosition() const
{
return m_cursorPosition;
}
/// 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)
......@@ -109,6 +119,12 @@ 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;
......
......@@ -47,8 +47,7 @@ class GAL;
class WORKSHEET_VIEWITEM : public EDA_ITEM
{
public:
WORKSHEET_VIEWITEM( const std::string& aFileName, const std::string& aSheetName,
const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock );
WORKSHEET_VIEWITEM( const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock );
/**
* Function SetFileName()
......
......@@ -622,7 +622,7 @@ public:
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) = 0;
......
......@@ -1094,7 +1094,7 @@ public:
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
......
......@@ -680,7 +680,7 @@ public:
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
......@@ -705,7 +705,7 @@ public:
* - Get an old version of the board from Redo list
* @return none
*/
void GetBoardFromRedoList( wxCommandEvent& event );
void GetBoardFromRedoList( wxCommandEvent& aEvent );
/**
* Function GetBoardFromUndoList
......@@ -714,7 +714,7 @@ public:
* - Get an old version of the board from Undo list
* @return none
*/
void GetBoardFromUndoList( wxCommandEvent& event );
void GetBoardFromUndoList( wxCommandEvent& aEvent );
/* Block operations: */
......
......@@ -226,7 +226,6 @@ set( PCBNEW_CLASS_SRCS
print_board_functions.cpp
printout_controler.cpp
ratsnest.cpp
ratsnest_data.cpp
ratsnest_viewitem.cpp
# specctra.cpp #moved in pcbcommon lib
# specctra_export.cpp
......@@ -256,7 +255,7 @@ set( PCBNEW_CLASS_SRCS
tools/selection_tool.cpp
tools/selection_area.cpp
tools/bright_box.cpp
tools/move_tool.cpp
tools/edit_tool.cpp
tools/pcb_tools.cpp
tools/common_actions.cpp
)
......
......@@ -103,7 +103,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On )
{
for( ; Track != NULL; Track = Track->Next() )
{
if( net_code == Track->GetNet() )
if( net_code == Track->GetNetCode() )
break;
}
}
......@@ -112,7 +112,7 @@ void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On )
while( Track ) /* Flag change */
{
if( (net_code >= 0 ) && (net_code != Track->GetNet()) )
if( ( net_code >= 0 ) && ( net_code != Track->GetNetCode() ) )
break;
OnModify();
......
......@@ -499,7 +499,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel )
TRACK TmpSegm( NULL );
TmpSegm.SetLayer( UNDEFINED_LAYER );
TmpSegm.SetNet( -1 );
TmpSegm.SetNetCode( -1 );
TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
EDA_ITEM* PtStruct = aBrd->m_Drawings;
......
......@@ -78,7 +78,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
{
case PCB_PAD_T:
Pad = (D_PAD*) GetScreen()->GetCurItem();
autoroute_net_code = Pad->GetNet();
autoroute_net_code = Pad->GetNetCode();
break;
default:
......
......@@ -215,7 +215,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
{
D_PAD* pad = aPcb->GetPad( i );
if( net_code != pad->GetNet() || (flag & FORCE_PADS) )
if( net_code != pad->GetNetCode() || (flag & FORCE_PADS) )
{
::PlacePad( pad, HOLE, marge, WRITE_CELL );
}
......@@ -247,7 +247,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
tmpSegm.SetShape( edge->GetShape() );
tmpSegm.SetWidth( edge->GetWidth() );
tmpSegm.m_Param = edge->GetAngle();
tmpSegm.SetNet( -1 );
tmpSegm.SetNetCode( -1 );
TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL );
TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
......@@ -284,7 +284,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
tmpSegm.SetShape( DrawSegm->GetShape() );
tmpSegm.SetWidth( DrawSegm->GetWidth() );
tmpSegm.m_Param = DrawSegm->GetAngle();
tmpSegm.SetNet( -1 );
tmpSegm.SetNetCode( -1 );
TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL );
}
......@@ -335,7 +335,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
/* Put tracks and vias on matrix */
for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
{
if( net_code == track->GetNet() )
if( net_code == track->GetNetCode() )
continue;
TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
......@@ -374,7 +374,7 @@ int Build_Work( BOARD* Pcb )
pt_pad = pt_rats->m_PadStart;
current_net_code = pt_pad->GetNet();
current_net_code = pt_pad->GetNetCode();
pt_ch = pt_rats;
r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas )
......
......@@ -1180,7 +1180,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() );
g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType );
g_CurrentTrackSegment->SetNet( current_net_code );
g_CurrentTrackSegment->SetNetCode( current_net_code );
}
else // placement of a standard segment
{
......@@ -1198,7 +1198,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
( RoutingMatrix.m_GridRouting * row ),
pcb->GetBoundingBox().GetY() +
( RoutingMatrix.m_GridRouting * col )));
g_CurrentTrackSegment->SetNet( current_net_code );
g_CurrentTrackSegment->SetNetCode( current_net_code );
if( g_CurrentTrackSegment->Back() == NULL ) /* Start trace. */
{
......@@ -1319,7 +1319,7 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
}
// Insert new segments in real board
int netcode = g_FirstTrackSegment->GetNet();
int netcode = g_FirstTrackSegment->GetNetCode();
TRACK* firstTrack = g_FirstTrackSegment;
int newCount = g_CurrentTrackList.GetCount();
......
......@@ -25,6 +25,7 @@
#include <fctsys.h>
#include <class_drawpanel.h>
#include <class_drawpanel_gal.h>
#include <macros.h>
#include <pcbnew.h>
......@@ -40,6 +41,10 @@
#include <class_zone.h>
#include <class_edge_mod.h>
#include <ratsnest_data.h>
#include <tools/selection_tool.h>
#include <tool/tool_manager.h>
/* Functions to undo and redo edit commands.
* commands to undo are stored in CurrentScreen->m_UndoList
......@@ -292,6 +297,17 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
if( aItem == NULL ) // Nothing to save
return;
// For texts belonging to modules, we need to save state of the parent module
if( aItem->Type() == PCB_MODULE_TEXT_T )
{
aItem = aItem->GetParent();
wxASSERT( aItem->Type() == PCB_MODULE_T );
aCommandType = UR_CHANGED;
if( aItem == NULL )
return;
}
PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
commandToUndo->m_TransformPoint = aTransformPoint;
......@@ -346,7 +362,7 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
}
void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
......@@ -361,6 +377,20 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
{
BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
// For texts belonging to modules, we need to save state of the parent module
if( item->Type() == PCB_MODULE_TEXT_T )
{
item = item->GetParent();
wxASSERT( item->Type() == PCB_MODULE_T );
if( item == NULL )
continue;
commandToUndo->SetPickedItem( item, ii );
commandToUndo->SetPickedItemStatus( UR_CHANGED, ii );
}
UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
if( command == UR_UNSPECIFIED )
......@@ -424,13 +454,15 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
BOARD_ITEM* item;
bool not_found = false;
bool reBuild_ratsnest = false;
KIGFX::VIEW* view = GetGalCanvas()->GetView();
RN_DATA* ratsnest = GetBoard()->GetRatsnest();
// Undo in the reverse order of list creation: (this can allow stacked changes
// like the same item can be changes and deleted in the same complex command
bool build_item_list = true; // if true the list of existing items must be rebuilt
for( int ii = aList->GetCount()-1; ii >= 0 ; ii-- )
for( int ii = aList->GetCount() - 1; ii >= 0 ; ii-- )
{
item = (BOARD_ITEM*) aList->GetPickedItem( ii );
wxASSERT( item );
......@@ -484,37 +516,85 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
case UR_CHANGED: /* Exchange old and new data for each item */
{
BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
// Remove all pads/drawings/texts, as they become invalid
// for the VIEW after SwapData() called for modules
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
}
ratsnest->Remove( item );
item->SwapData( image );
// Update all pads/drawings/texts, as they become invalid
// for the VIEW after SwapData() called for modules
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
}
ratsnest->Add( item );
item->ClearFlags( SELECTED );
item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
}
break;
case UR_NEW: /* new items are deleted */
aList->SetPickedItemStatus( UR_DELETED, ii );
GetBoard()->Remove( item );
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Remove ), view ) );
}
view->Remove( item );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
break;
case UR_DELETED: /* deleted items are put in List, as new items */
aList->SetPickedItemStatus( UR_NEW, ii );
GetBoard()->Add( item );
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind1st( std::mem_fun( &KIGFX::VIEW::Add ), view ) );
}
view->Add( item );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
build_item_list = true;
break;
case UR_MOVED:
item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break;
case UR_ROTATED:
item->Rotate( aList->m_TransformPoint,
aRedoCommand ? m_rotationAngle : -m_rotationAngle );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break;
case UR_ROTATED_CLOCKWISE:
item->Rotate( aList->m_TransformPoint,
aRedoCommand ? -m_rotationAngle : m_rotationAngle );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
ratsnest->Update( item );
break;
case UR_FLIPPED:
item->Flip( aList->m_TransformPoint );
item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
ratsnest->Update( item );
break;
default:
......@@ -533,15 +613,24 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
// Rebuild pointers and ratsnest that can be changed.
if( reBuild_ratsnest && aRebuildRatsnet )
Compile_Ratsnest( NULL, true );
{
if( IsGalCanvasActive() )
ratsnest->Recalculate();
else
Compile_Ratsnest( NULL, true );
}
}
void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event )
void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent )
{
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
/* Undo the command */
......@@ -556,11 +645,14 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& event )
}
void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& event )
void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent )
{
if( GetScreen()->GetRedoCommandCount() == 0 )
return;
// Inform tools that redo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
/* Get the old list */
PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
......
......@@ -43,6 +43,8 @@
#include <reporter.h>
#include <base_units.h>
#include <ratsnest_data.h>
#include <ratsnest_viewitem.h>
#include <worksheet_viewitem.h>
#include <pcbnew.h>
#include <colors_selection.h>
......@@ -104,22 +106,29 @@ BOARD::BOARD() :
SetCurrentNetClass( m_NetClasses.GetDefault()->GetName() );
// Initialize ratsnest
m_ratsnest = new RN_DATA( this );
m_ratsnestViewItem = new KIGFX::RATSNEST_VIEWITEM( m_ratsnest );
// Initialize view item for displaying worksheet frame
m_worksheetViewItem = new KIGFX::WORKSHEET_VIEWITEM( &m_paper, &m_titles );
m_worksheetViewItem->SetFileName( std::string( m_fileName.mb_str() ) );
}
BOARD::~BOARD()
{
delete m_ratsnest;
while( m_ZoneDescriptorList.size() )
{
ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
Delete( area_to_remove );
}
m_FullRatsnest.clear();
delete m_worksheetViewItem;
delete m_ratsnestViewItem;
delete m_ratsnest;
m_FullRatsnest.clear();
m_LocalRatsnest.clear();
DeleteMARKERs();
......@@ -206,7 +215,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, LAYER_MSK aLayerMask, TRACK_
*/
for( ; ; )
{
if( GetPadFast( aPosition, aLayerMask ) != NULL )
if( GetPad( aPosition, aLayerMask ) != NULL )
return;
/* Test for a via: a via changes the layer mask and can connect a lot
......@@ -842,6 +851,8 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
}
break;
}
m_ratsnest->Add( aBoardItem );
}
......@@ -905,6 +916,8 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
}
m_ratsnest->Remove( aBoardItem );
return aBoardItem;
}
......@@ -1341,93 +1354,13 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
// NULL is returned for non valid netcodes
NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode );
#if defined(DEBUG)
if( net && aNetcode != net->GetNet()) // item can be NULL if anetcode is not valid
{
wxLogError( wxT( "FindNet() anetcode %d != GetNet() %d (net: %s)\n" ),
aNetcode, net->GetNet(), TO_UTF8( net->GetNetname() ) );
}
#endif
return net;
}
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
{
// the first valid netcode is 1.
// zero is reserved for "no connection" and is not used.
if( aNetname.IsEmpty() )
return NULL;
int ncount = m_NetInfo.GetNetCount();
// Search for a netname = aNetname
#if 0
// Use a sequential search: easy to understand, but slow
for( int ii = 1; ii < ncount; ii++ )
{
NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii );
if( item && item->GetNetname() == aNetname )
{
return item;
}
}
#else
// Use a fast binary search,
// this is possible because Nets are alphabetically ordered in list
// see NETINFO_LIST::BuildListOfNets() and
// NETINFO_LIST::Build_Pads_Full_List()
int imax = ncount - 1;
int index = imax;
while( ncount > 0 )
{
int ii = ncount;
ncount >>= 1;
if( (ii & 1) && ( ii > 1 ) )
ncount++;
NETINFO_ITEM* item = m_NetInfo.GetNetItem( index );
if( item == NULL )
return NULL;
int icmp = item->GetNetname().Cmp( aNetname );
if( icmp == 0 ) // found !
{
return item;
}
if( icmp < 0 ) // must search after item
{
index += ncount;
if( index > imax )
index = imax;
continue;
}
if( icmp > 0 ) // must search before item
{
index -= ncount;
if( index < 1 )
index = 1;
continue;
}
}
#endif
return NULL;
return m_NetInfo.GetNetItem( aNetname );
}
......@@ -1512,10 +1445,11 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCoun
netBuffer.reserve( m_NetInfo.GetNetCount() );
for( unsigned ii = 1; ii < m_NetInfo.GetNetCount(); ii++ )
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
if( m_NetInfo.GetNetItem( ii )->GetNet() > 0 )
netBuffer.push_back( m_NetInfo.GetNetItem( ii ) );
if( net->GetNet() > 0 )
netBuffer.push_back( *net );
}
// sort the list
......@@ -1582,7 +1516,7 @@ ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos,
if( area->GetState( BUSY ) )
continue;
if( aNetCode >= 0 && area->GetNet() != aNetCode )
if( aNetCode >= 0 && area->GetNetCode() != aNetCode )
continue;
if( area->HitTestFilledArea( aRefPos ) )
......@@ -1601,24 +1535,24 @@ int BOARD::SetAreasNetCodesFromNetNames( void )
{
if( !GetArea( ii )->IsOnCopperLayer() )
{
GetArea( ii )->SetNet( 0 );
GetArea( ii )->SetNetCode( NETINFO_LIST::UNCONNECTED );
continue;
}
if( GetArea( ii )->GetNet() != 0 ) // i.e. if this zone is connected to a net
if( GetArea( ii )->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
{
const NETINFO_ITEM* net = FindNet( GetArea( ii )->GetNetName() );
const NETINFO_ITEM* net = GetArea( ii )->GetNet();
if( net )
{
GetArea( ii )->SetNet( net->GetNet() );
GetArea( ii )->SetNetCode( net->GetNet() );
}
else
{
error_count++;
// keep Net Name and set m_NetCode to -1 : error flag.
GetArea( ii )->SetNet( -1 );
GetArea( ii )->SetNetCode( -1 );
}
}
}
......@@ -2338,7 +2272,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, LAYER_NUM layer, int
{
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
new_area->SetNet( netcode );
new_area->SetNetCode( netcode );
new_area->SetLayer( layer );
new_area->SetTimeStamp( GetNewTimeStamp() );
......@@ -2377,7 +2311,7 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
{
// create new copper area and copy poly into it
CPolyLine* new_p = (*pa)[ip - 1];
NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(),
NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(),
wxPoint(0, 0), CPolyLine::NO_HATCH );
// remove the poly that was automatically created for the new area
......@@ -2618,7 +2552,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
}
if( !aNetlist.IsDryRun() )
pad->SetNetname( wxEmptyString );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
}
else // Footprint pad has a net.
......@@ -2638,7 +2572,17 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
}
if( !aNetlist.IsDryRun() )
pad->SetNetname( net.GetNetName() );
{
NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
if( netinfo == NULL )
{
// It is a new net, we have to add it
netinfo = new NETINFO_ITEM( this, net.GetNetName() );
m_NetInfo.AppendNet( netinfo );
}
pad->SetNetCode( netinfo->GetNet() );
}
}
}
}
......@@ -2710,7 +2654,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
GetChars( previouspad->GetPadName() ) );
aReporter->Report( msg );
}
previouspad->SetNetname( wxEmptyString );
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
netname = pad->GetNetname();
count = 1;
......@@ -2723,7 +2668,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Examine last pad
if( pad && count == 1 )
pad->SetNetname( wxEmptyString );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
// Last step: Some tests:
......@@ -2760,31 +2705,6 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
}
}
}
// Verify zone net names validity:
// After schematic changes, a zone can have a non existing net name.
// It should be reported
if( aReporter && aReporter->ReportErrors() )
{
//Loop through all copper zones
for( i = 0; i < m_ZoneDescriptorList.size(); i++ )
{
ZONE_CONTAINER* zone = m_ZoneDescriptorList[i];
if( zone->GetNet() >= 0 || !zone->IsOnCopperLayer() )
continue;
// Net name not valid, report error
wxString coord;
coord << zone->GetPosition();
msg.Printf( _( "*** Error: Zone '%s' layer '%s'"
" has non-existent net name '%s' ***\n" ),
GetChars( coord ),
GetChars( zone->GetLayerName() ),
GetChars( zone->GetNetName() ) );
aReporter->Report( msg );
}
}
}
/* Extracts the board outlines and build a closed polygon
......
......@@ -58,6 +58,12 @@ class NETLIST;
class REPORTER;
class RN_DATA;
namespace KIGFX
{
class RATSNEST_VIEWITEM;
class WORKSHEET_VIEWITEM;
}
// non-owning container of item candidates when searching for items on the same track.
typedef std::vector< TRACK* > TRACK_PTRS;
......@@ -227,6 +233,8 @@ private:
EDA_RECT m_BoundingBox;
NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
RN_DATA* m_ratsnest;
KIGFX::RATSNEST_VIEWITEM* m_ratsnestViewItem; ///< VIEW_ITEM that draws ratsnest
KIGFX::WORKSHEET_VIEWITEM* m_worksheetViewItem; ///< VIEW_ITEM that draws worksheet frame
BOARD_DESIGN_SETTINGS m_designSettings;
ZONE_SETTINGS m_zoneSettings;
......@@ -367,6 +375,24 @@ public:
return m_ratsnest;
}
/**
* Function GetRatsnestViewItem()
* returns VIEW_ITEM responsible for drawing the ratsnest for the board.
*/
KIGFX::RATSNEST_VIEWITEM* GetRatsnestViewItem() const
{
return m_ratsnestViewItem;
}
/**
* Function GetWorksheetViewItem()
* returns VIEW_ITEM responsible for drawing the worksheet frame.
*/
KIGFX::WORKSHEET_VIEWITEM* GetWorksheetViewItem() const
{
return m_worksheetViewItem;
}
/**
* Function DeleteMARKERs
* deletes ALL MARKERS from the board.
......@@ -845,6 +871,24 @@ public:
m_NetInfo.AppendNet( aNewNet );
}
/**
* Function BeginNets
* @return iterator to the first element of the NETINFO_ITEMs list
*/
NETINFO_LIST::iterator BeginNets() const
{
return m_NetInfo.begin();
}
/**
* Function EndNets
* @return iterator to the last element of the NETINFO_ITEMs list
*/
NETINFO_LIST::iterator EndNets() const
{
return m_NetInfo.end();
}
/**
* Function GetNetCount
* @return the number of nets (NETINFO_ITEM)
......
/**
* @file class_board_connected_item.cpp
* @brief BOARD_CONNECTED_ITEM class functions.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
......@@ -28,76 +23,67 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_board_connected_item.cpp
* @brief BOARD_CONNECTED_ITEM class functions.
*/
#include <fctsys.h>
#include <pcbnew.h>
#include <class_board.h>
#include <class_board_item.h>
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_ITEM( aParent, idtype )
BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED ),
m_Subnet( 0 ), m_ZoneSubnet( 0 )
{
m_NetCode = 0;
m_Subnet = 0;
m_ZoneSubnet = 0;
// The unconnected net is set only in case the item belongs to a BOARD
SetNetCode( NETINFO_LIST::UNCONNECTED );
}
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) :
BOARD_ITEM( aItem )
BOARD_ITEM( aItem ), m_netinfo( aItem.m_netinfo ), m_Subnet( aItem.m_Subnet ),
m_ZoneSubnet( aItem.m_ZoneSubnet )
{
m_NetCode = aItem.m_NetCode;
m_Subnet = aItem.m_Subnet;
m_ZoneSubnet = aItem.m_ZoneSubnet;
}
/**
* Function GetNet
* @return int - the net code.
*/
int BOARD_CONNECTED_ITEM::GetNet() const
int BOARD_CONNECTED_ITEM::GetNetCode() const
{
return m_NetCode;
return m_netinfo->GetNet();
}
void BOARD_CONNECTED_ITEM::SetNet( int aNetCode )
void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
{
m_NetCode = aNetCode;
}
/**
* Function GetSubNet
* @return int - the sub net code.
*/
int BOARD_CONNECTED_ITEM::GetSubNet() const
{
return m_Subnet;
}
BOARD* board = GetBoard();
if( board )
{
m_netinfo = board->FindNet( aNetCode );
void BOARD_CONNECTED_ITEM::SetSubNet( int aSubNetCode )
{
m_Subnet = aSubNetCode;
// The requested net does not exist, mark it as unconnected
if( m_netinfo == NULL )
m_netinfo = board->FindNet( NETINFO_LIST::UNCONNECTED );
}
else
{
// There is no board that contains list of nets, the item is orphaned
m_netinfo = &NETINFO_LIST::ORPHANED;
}
}
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int BOARD_CONNECTED_ITEM::GetZoneSubNet() const
const wxString& BOARD_CONNECTED_ITEM::GetNetname() const
{
return m_ZoneSubnet;
return m_netinfo->GetNetname();
}
void BOARD_CONNECTED_ITEM::SetZoneSubNet( int aSubNetCode )
const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const
{
m_ZoneSubnet = aSubNetCode;
return m_netinfo->GetShortNetname();
}
......@@ -132,11 +118,6 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
}
/** return a pointer to the netclass of the zone
* if the net is not found (can happen when a netlist is reread,
* and the net name is not existant, return the default net class
* So should not return a null pointer
*/
NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
{
// It is important that this be implemented without any sequential searching.
......@@ -155,8 +136,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
}
NETCLASS* netclass = NULL;
int netcode = GetNet();
NETINFO_ITEM* net = board->FindNet( netcode );
NETINFO_ITEM* net = board->FindNet( GetNetCode() );
if( net )
{
......@@ -176,10 +156,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
return board->m_NetClasses.GetDefault();
}
/**
* Function GetNetClassName
* @return the Net Class name of this item
*/
wxString BOARD_CONNECTED_ITEM::GetNetClassName() const
{
wxString name;
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_board_connected_item.h
* @brief Class BOARD_CONNECTED_ITEM.
......@@ -6,9 +31,9 @@
#ifndef BOARD_CONNECTED_ITEM_H
#define BOARD_CONNECTED_ITEM_H
#include <class_board_item.h>
class NETINFO_ITEM;
class NETCLASS;
class TRACK;
class D_PAD;
......@@ -29,41 +54,78 @@ public:
std::vector<TRACK*> m_TracksConnected; // list of other tracks connected to me
std::vector<D_PAD*> m_PadsConnected; // list of other pads connected to me
private:
int m_NetCode; // Net number
int m_Subnet; /* In rastnest routines : for the current net, block number
* (number common to the current connected items found)
*/
int m_ZoneSubnet; // used in rastnest computations : for the current net,
// handle cluster number in zone connection
public:
BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype );
BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem );
///> @copydoc BOARD_ITEM::IsConnected()
bool IsConnected() const
{
return true;
}
/**
* Function GetNet
* Returns NET_INFO object for a given item.
*/
NETINFO_ITEM* GetNet() const
{
return m_netinfo;
}
/**
* Function GetNetCode
* @return int - the net code.
*/
int GetNet() const;
virtual void SetNet( int aNetCode );
int GetNetCode() const;
/**
* Function SetNetCode
* sets net using a net code.
* @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD.
* Otherwise, item is assigned to the unconnected net.
*/
void SetNetCode( int aNetCode );
/**
* Function GetSubNet
* @return int - the sub net code.
*/
int GetSubNet() const;
void SetSubNet( int aSubNetCode );
int GetSubNet() const
{
return m_Subnet;
}
void SetSubNet( int aSubNetCode )
{
m_Subnet = aSubNetCode;
}
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int GetZoneSubNet() const;
void SetZoneSubNet( int aSubNetCode );
int GetZoneSubNet() const
{
return m_ZoneSubnet;
}
void SetZoneSubNet( int aSubNetCode )
{
m_ZoneSubnet = aSubNetCode;
}
/**
* Function GetNetname
* @return wxString - the full netname
*/
const wxString& GetNetname() const;
/**
* Function GetShortNetname
* @return wxString - the short netname
*/
const wxString& GetShortNetname() const;
/**
* Function GetClearance
......@@ -84,9 +146,25 @@ public:
/**
* Function GetNetClassName
* returns a pointer to the netclass of the zone.
* If the net is not found (can happen when a netlist is reread,
* and the net name does not exist, return the default net class
* (should not return a null pointer).
* @return the Net Class name of this item
*/
wxString GetNetClassName() const;
protected:
/// Stores all informations about the net that item belongs to
NETINFO_ITEM* m_netinfo;
private:
int m_Subnet; /* In rastnest routines : for the current net, block number
* (number common to the current connected items found)
*/
int m_ZoneSubnet; // used in rastnest computations : for the current net,
// handle cluster number in zone connection
};
......
......@@ -52,7 +52,7 @@
BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
m_Pad_Master( 0 )
m_Pad_Master( NULL )
{
m_EnabledLayers = ALL_LAYERS; // All layers enabled at first.
// SetCopperLayerCount() will adjust this.
......
......@@ -134,7 +134,7 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const
return endPoint; // after rotation, the end of the arc.
}
const double DRAWSEGMENT::GetArcAngleStart() const
double DRAWSEGMENT::GetArcAngleStart() const
{
// due to the Y axis orient atan2 needs - y value
double angleStart = ArcTangente( GetArcStart().y - GetCenter().y,
......@@ -148,6 +148,7 @@ const double DRAWSEGMENT::GetArcAngleStart() const
return angleStart;
}
void DRAWSEGMENT::SetAngle( double aAngle )
{
NORMALIZE_ANGLE_360( aAngle );
......@@ -379,6 +380,59 @@ const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
wxPoint end = m_End;
RotatePoint( &end, m_Start, -m_Angle );
bbox.Merge( end );
// Determine the starting quarter
// 0 right-bottom
// 1 left-bottom
// 2 left-top
// 3 right-top
unsigned int quarter = 0; // assume right-bottom
if( m_End.y < m_Start.y ) // change to left-top
quarter |= 3;
if( m_End.x < m_Start.x ) // for left side, the LSB is 2nd bit negated
quarter ^= 1;
int radius = GetRadius();
int angle = (int) GetArcAngleStart() % 900 + m_Angle;
bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise?
if( !directionCW )
{
angle = 900 - angle;
quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic
}
while( angle > 900 )
{
switch( quarter )
{
case 0:
bbox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down
break;
case 1:
bbox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left
break;
case 2:
bbox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up
break;
case 3:
bbox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right
break;
}
if( directionCW )
++quarter;
else
quarter += 3; // -1 modulo arithmetic
quarter %= 4;
angle -= 900;
}
}
break;
......
......@@ -30,7 +30,6 @@
#ifndef CLASS_DRAWSEGMENT_H_
#define CLASS_DRAWSEGMENT_H_
#include <class_board_item.h>
#include <PolyLine.h>
#include <math_for_graphics.h>
......@@ -126,9 +125,9 @@ public:
/**
* function GetArcAngleStart()
* @return the angle of the stating point of this arc, between 0 and 3600 in 0.1 deg
* @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg
*/
const double GetArcAngleStart() const;
double GetArcAngleStart() const;
/**
* Function GetRadius
......
......@@ -728,6 +728,41 @@ EDA_ITEM* MODULE::Clone() const
}
void MODULE::RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction )
{
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
aFunction( static_cast<BOARD_ITEM*>( pad ) );
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
aFunction( drawing );
aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
}
void MODULE::ViewUpdate( int aUpdateFlags )
{
if( !m_view )
return;
// Update pads
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
m_view->InvalidateItem( pad, aUpdateFlags );
// Update module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
m_view->InvalidateItem( drawing, 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 );
}
/* Test for validity of the name in a library of the footprint
* ( no spaces, dir separators ... )
* return true if the given name is valid
......
......@@ -41,6 +41,7 @@
#include <PolyLine.h>
#include "zones.h"
#include <boost/function.hpp>
class LINE_READER;
class EDA_3D_CANVAS;
......@@ -453,6 +454,17 @@ public:
EDA_ITEM* Clone() const;
/**
* Function RunOnChildren
*
* Invokes a function on all BOARD_ITEMs that belong to the module (pads, drawings, texts).
* @param aFunction is the function to be invoked.
*/
void RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction );
/// @copydoc VIEW_ITEM::ViewUpdate()
void ViewUpdate( int aUpdateFlags );
/**
* Function CopyNetlistSettings
* copies the netlist settings to \a aModule.
......
......@@ -203,12 +203,10 @@ void BOARD::SynchronizeNetsAndNetClasses()
// set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes.
int count = m_NetInfo.GetNetCount();
for( int i=0; i<count; ++i )
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
NETINFO_ITEM* net = FindNet( i );
if( net )
net->SetClass( m_NetClasses.GetDefault() );
net->SetClass( m_NetClasses.GetDefault() );
}
// Add netclass name and pointer to nets. If a net is in more than one netclass,
......@@ -248,21 +246,18 @@ void BOARD::SynchronizeNetsAndNetClasses()
m_NetClasses.GetDefault()->Clear();
for( int i=0; i<count; ++i )
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
NETINFO_ITEM* net = FindNet( i );
if( net )
{
const wxString& classname = net->GetClassName();
const wxString& classname = net->GetClassName();
// because of the std:map<> this should be fast, and because of
// prior logic, netclass should not be NULL.
NETCLASS* netclass = m_NetClasses.Find( classname );
// because of the std:map<> this should be fast, and because of
// prior logic, netclass should not be NULL.
NETCLASS* netclass = m_NetClasses.Find( classname );
wxASSERT( netclass );
wxASSERT( netclass );
netclass->Add( net->GetNetname() );
}
netclass->Add( net->GetNetname() );
}
// D(printf("stop\n");)
......@@ -337,8 +332,15 @@ void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FMT_IU( GetuViaDiameter() ).c_str() );
aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() );
for( NETCLASS::const_iterator it = begin(); it!= end(); ++it )
aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() );
for( NETCLASS::const_iterator it = begin(); it != end(); ++it )
{
NETINFO_ITEM* netinfo = m_Parent->FindNet( *it );
if( netinfo && netinfo->GetNodesCount() > 0 )
{
aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() );
}
}
aFormatter->Print( aNestLevel, ")\n\n" );
}
This diff is collapsed.
......@@ -49,25 +49,16 @@
/* class NETINFO_ITEM: handle data relative to a given net */
/*********************************************************/
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode )
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) :
m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) )
{
SetNet( aNetCode );
if( aNetName.size() )
SetNetname( aNetName );
m_parent = aParent;
m_NbNodes = 0;
m_NbLink = 0;
m_NbNoconn = 0;
m_Flag = 0;
m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a
// general buffer of ratsnest
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
m_NetClassName = NETCLASS::Default;
m_NetClass = 0;
m_NetClass = NULL;
}
......@@ -77,17 +68,6 @@ NETINFO_ITEM::~NETINFO_ITEM()
}
/**
* Function SetNetname
* @param aNetname : the new netname
*/
void NETINFO_ITEM::SetNetname( const wxString& aNetname )
{
m_Netname = aNetname;
m_ShortNetname = m_Netname.AfterLast( '/' );
}
/**
* Function Draw (TODO)
*/
......@@ -121,7 +101,7 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{
for( pad = module->Pads(); pad != 0; pad = pad->Next() )
{
if( pad->GetNet() == GetNet() )
if( pad->GetNetCode() == GetNet() )
{
count++;
lengthPadToDie += pad->GetPadToDieLength();
......@@ -139,13 +119,13 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{
if( Struct->Type() == PCB_VIA_T )
{
if( ( (SEGVIA*) Struct )->GetNet() == GetNet() )
if( ( (SEGVIA*) Struct )->GetNetCode() == GetNet() )
count++;
}
if( Struct->Type() == PCB_TRACE_T )
{
if( ( (TRACK*) Struct )->GetNet() == GetNet() )
if( ( (TRACK*) Struct )->GetNetCode() == GetNet() )
lengthnet += ( (TRACK*) Struct )->GetLength();
}
}
......
This diff is collapsed.
......@@ -364,13 +364,6 @@ void D_PAD::SetPadName( const wxString& name )
}
void D_PAD::SetNetname( const wxString& aNetname )
{
m_Netname = aNetname;
m_ShortNetname = m_Netname.AfterLast( '/' );
}
void D_PAD::Copy( D_PAD* source )
{
if( source == NULL )
......@@ -380,7 +373,7 @@ void D_PAD::Copy( D_PAD* source )
m_layerMask = source->m_layerMask;
m_NumPadName = source->m_NumPadName;
SetNet( source->GetNet() );
m_netinfo = source->m_netinfo;
m_Drill = source->m_Drill;
m_drillShape = source->m_drillShape;
m_Offset = source->m_Offset;
......@@ -402,8 +395,6 @@ void D_PAD::Copy( D_PAD* source )
SetSubRatsnest( 0 );
SetSubNet( 0 );
m_Netname = source->m_Netname;
m_ShortNetname = source->m_ShortNetname;
}
......@@ -412,7 +403,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad )
// Don't do anything foolish like trying to copy to yourself.
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
aPad->SetNetname( GetNetname() );
aPad->SetNetCode( GetNetCode() );
aPad->SetLocalClearance( m_LocalClearance );
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
......@@ -577,7 +568,7 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) );
}
aList.push_back( MSG_PANEL_ITEM( _( "Net" ), m_Netname, DARKCYAN ) );
aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
/* For test and debug only: display m_physical_connexion and
* m_logical_connexion */
......
......@@ -118,24 +118,6 @@ public:
return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API
}
/**
* Function SetNetname
* @param aNetname: the new netname
*/
void SetNetname( const wxString& aNetname );
/**
* Function GetNetname
* @return const wxString& - the full netname
*/
const wxString& GetNetname() const { return m_Netname; }
/**
* Function GetShortNetname
* @return const wxString& - the short netname
*/
const wxString& GetShortNetname() const { return m_ShortNetname; }
/**
* Function GetShape
* @return the shape of this pad.
......@@ -470,10 +452,6 @@ private:
int m_boundingRadius; ///< radius of the circle containing the pad shape
wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout used by Eeschema
wxString m_ShortNetname; ///< short net name, like vout from /mysheet/mysubsheet/vout
/// Pad name (4 char) or a long identifier (used in pad name
/// comparisons because this is faster than string comparison)
union
......
......@@ -473,7 +473,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );
// Draw "No connect" ( / or \ or cross X ) if necessary
if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark )
if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark )
{
int dx0 = std::min( halfsize.x, halfsize.y );
EDA_COLOR_T nc_color = BLUE;
......@@ -499,7 +499,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
wxPoint tpos0 = shape_pos; // Position of the centre of text
wxPoint tpos = tpos0;
wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x
int shortname_len = m_ShortNetname.Len();
int shortname_len = GetShortNetname().Len();
if( !aDrawInfo.m_Display_netname )
shortname_len = 0;
......@@ -583,7 +583,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
tsize = ( tsize * 7 ) / 10;
DrawGraphicHaloText( clipBox, aDC, tpos,
aDrawInfo.m_Color, BLACK, WHITE,
m_ShortNetname, t_angle,
GetShortNetname(), t_angle,
wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
}
......
......@@ -415,6 +415,18 @@ EDA_ITEM* TEXTE_MODULE::Clone() const
}
const BOX2I TEXTE_MODULE::ViewBBox() const
{
double angle = GetDrawRotation();
EDA_RECT text_area = GetTextBox( -1, -1 );
if( angle )
text_area = text_area.GetBoundingBoxRotated( m_Pos, angle );
return BOX2I( text_area.GetPosition(), text_area.GetSize() );
}
void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
{
if( m_NoShow ) // Hidden text
......
......@@ -165,6 +165,9 @@ public:
EDA_ITEM* Clone() const;
/// @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const;
/// @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
......
This diff is collapsed.
This diff is collapsed.
......@@ -186,31 +186,6 @@ public:
return ( GetLayer() < FIRST_NON_COPPER_LAYER ) ? true : false;
}
/**
* Function SetNet
* sets the netcode and the netname.
*
* @param aNetCode The net code of the zone container if greater than or equal to
* zero. Otherwise the current net code is kept and set the net
* code error flag.
*/
virtual void SetNet( int aNetCode );
/**
* Function SetNetNameFromNetCode
* Find the net name corresponding to the net code.
* @return bool - true if net found, else false
*/
bool SetNetNameFromNetCode( void );
/**
* Function GetNetName
* returns the net name.
* @return const wxString& - The net name.
*/
const wxString& GetNetName() const { return m_Netname; };
void SetNetName( const wxString& aName ) { m_Netname = aName; }
/// How to fill areas: 0 = use filled polygons, 1 => fill with segments.
void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; }
int GetFillMode() const { return m_FillMode; }
......@@ -607,7 +582,6 @@ public:
private:
CPolyLine* m_Poly; ///< Outline of the zone.
wxString m_Netname; ///< Name of the net assigned to the zone.
CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly
int m_cornerSmoothingType;
unsigned int m_cornerRadius;
......
......@@ -76,7 +76,7 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
m_FillMode = aSource.GetFillMode();
m_ZoneClearance = aSource.GetClearance();
m_ZoneMinThickness = aSource.GetMinThickness();
m_NetcodeSelection = aSource.GetNet();
m_NetcodeSelection = aSource.GetNetCode();
m_CurrentZone_Layer = aSource.GetLayer();
m_Zone_HatchingStyle = aSource.GetHatchStyle();
m_ArcToSegmentsCount = aSource.GetArcSegmentCount();
......@@ -113,7 +113,7 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
if( aFullExport )
{
aTarget.SetPriority( m_ZonePriority );
aTarget.SetNet( m_NetcodeSelection );
aTarget.SetNetCode( m_NetcodeSelection );
aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.Outline()->SetLayer( m_CurrentZone_Layer );
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment