From a3a73426bf10f7bbf3b190b5d16a810da5631352 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 27 Sep 2013 18:51:21 +0200 Subject: [PATCH] Even more code comments and reformatting. --- common/geometry/shape_collisions.cpp | 98 ++++++------ common/tool/action_manager.cpp | 3 +- common/tool/context_menu.cpp | 14 +- common/tool/tool_dispatcher.cpp | 8 +- common/tool/tool_event.cpp | 9 +- common/tool/tool_manager.cpp | 95 +++++++---- include/geometry/seg.h | 125 +++++++-------- include/geometry/shape.h | 25 +-- include/geometry/shape_circle.h | 19 ++- include/geometry/shape_index.h | 31 ++-- include/geometry/shape_index_list.h | 165 ++++++++++---------- include/geometry/shape_rect.h | 46 +++--- include/tool/action_manager.h | 6 + include/tool/context_menu.h | 2 +- include/tool/coroutine.h | 2 +- include/tool/tool_action.h | 19 ++- include/tool/tool_dispatcher.h | 5 +- include/tool/tool_event.h | 9 ++ include/tool/tool_manager.h | 29 ++-- include/view/wx_view_controls.h | 9 +- {include/tool => pcbnew/tools}/item_state.h | 14 +- pcbnew/tools/move_tool.cpp | 6 +- pcbnew/tools/move_tool.h | 2 +- pcbnew/tools/selection_tool.cpp | 9 +- 24 files changed, 412 insertions(+), 338 deletions(-) rename {include/tool => pcbnew/tools}/item_state.h (99%) diff --git a/common/geometry/shape_collisions.cpp b/common/geometry/shape_collisions.cpp index b678e0faa2..f4391760b4 100644 --- a/common/geometry/shape_collisions.cpp +++ b/common/geometry/shape_collisions.cpp @@ -31,36 +31,36 @@ typedef VECTOR2I::extended_type ecoord; -static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, - bool needMTV, VECTOR2I& aMTV ) +static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CIRCLE& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) { - ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); + ecoord min_dist = aClearance + aA.GetRadius() + aB.GetRadius(); ecoord min_dist_sq = min_dist * min_dist; - const VECTOR2I delta = b.GetCenter() - a.GetCenter(); + const VECTOR2I delta = aB.GetCenter() - aA.GetCenter(); ecoord dist_sq = delta.SquaredEuclideanNorm(); if ( dist_sq >= min_dist_sq ) return false; - if ( needMTV ) + if ( aNeedMTV ) aMTV = delta.Resize( sqrt ( abs( min_dist_sq - dist_sq ) ) + 1 ); return true; } -static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, - bool needMTV, VECTOR2I& aMTV ) +static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CIRCLE& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) { - const VECTOR2I c = b.GetCenter(); - const VECTOR2I p0 = a.GetPosition(); - const VECTOR2I size = a.GetSize(); - const ecoord r = b.GetRadius(); - const ecoord min_dist = clearance + r; + const VECTOR2I c = aB.GetCenter(); + const VECTOR2I p0 = aA.GetPosition(); + const VECTOR2I size = aA.GetSize(); + const ecoord r = aB.GetRadius(); + const ecoord min_dist = aClearance + r; const ecoord min_dist_sq = min_dist * min_dist; - if ( a.BBox( 0 ).Contains( c ) ) + if ( aA.BBox( 0 ).Contains( c ) ) return true; const VECTOR2I vts[] = { @@ -86,7 +86,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle if( dist_sq < min_dist_sq ) { - if( !needMTV ) + if( !aNeedMTV ) return true; else { @@ -102,7 +102,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle VECTOR2I delta = c - nearest; - if( !needMTV ) + if( !aNeedMTV ) return true; if( inside ) @@ -114,12 +114,12 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle } -static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, - bool needMTV, VECTOR2I& aMTV ) +static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) { - for( int s = 0; s < b.SegmentCount(); s++ ) + for( int s = 0; s < aB.SegmentCount(); s++ ) { - if ( a.Collide( b.CSegment( s ), clearance ) ) + if ( aA.Collide( aB.CSegment( s ), aClearance ) ) return true; } @@ -127,23 +127,23 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, in } -static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, - bool needMTV, VECTOR2I& aMTV ) +static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) { - for( int i = 0; i < b.SegmentCount(); i++ ) - if( a.Collide( b.CSegment(i), clearance ) ) + for( int i = 0; i < aB.SegmentCount(); i++ ) + if( aA.Collide( aB.CSegment(i), aClearance ) ) return true; return false; } -static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, - bool needMTV, VECTOR2I& aMTV ) +static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, int aClearance, + bool aNeedMTV, VECTOR2I& aMTV ) { - for( int s = 0; s < b.SegmentCount(); s++ ) + for( int s = 0; s < aB.SegmentCount(); s++ ) { - SEG seg = b.CSegment( s ); - if( a.Collide( seg, clearance ) ) + SEG seg = aB.CSegment( s ); + if( aA.Collide( seg, aClearance ) ) return true; } @@ -151,58 +151,58 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int } -bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) +bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - switch( a->Type() ) + switch( aA->Type() ) { case SH_RECT: - switch( b->Type() ) + switch( aB->Type() ) { case SH_CIRCLE: - return Collide( *static_cast( a ), - *static_cast( b ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aA ), + *static_cast( aB ), aClearance, aNeedMTV, aMTV ); case SH_LINE_CHAIN: - return Collide( *static_cast( a ), - *static_cast( b ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aA ), + *static_cast( aB ), aClearance, aNeedMTV, aMTV ); default: break; } case SH_CIRCLE: - switch( b->Type() ) + switch( aB->Type() ) { case SH_RECT: - return Collide( *static_cast( b ), - *static_cast( a ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aB ), + *static_cast( aA ), aClearance, aNeedMTV, aMTV ); case SH_CIRCLE: - return Collide( *static_cast( a ), - *static_cast( b ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aA ), + *static_cast( aB ), aClearance, aNeedMTV, aMTV ); case SH_LINE_CHAIN: - return Collide( *static_cast( a ), - *static_cast( b ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aA ), + *static_cast( aB ), aClearance, aNeedMTV, aMTV ); default: break; } case SH_LINE_CHAIN: - switch( b->Type() ) + switch( aB->Type() ) { case SH_RECT: - return Collide( *static_cast( b ), - *static_cast( a ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aB ), + *static_cast( aA ), aClearance, aNeedMTV, aMTV ); case SH_CIRCLE: - return Collide( *static_cast( b ), - *static_cast( a ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aB ), + *static_cast( aA ), aClearance, aNeedMTV, aMTV ); case SH_LINE_CHAIN: - return Collide( *static_cast( a ), - *static_cast( b ), clearance, needMTV, aMTV ); + return Collide( *static_cast( aA ), + *static_cast( aB ), aClearance, aNeedMTV, aMTV ); default: break; diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index fcd5318852..78fbefd2da 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -99,6 +99,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const void ACTION_MANAGER::runAction( const TOOL_ACTION* aAction ) const { - TOOL_EVENT event = aAction->GetEvent(); + TOOL_EVENT event = aAction->MakeEvent(); + m_toolMgr->ProcessEvent( event ); } diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index d01bc3f0ef..96a877abf8 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -151,24 +151,28 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent ) TOOL_EVENT evt; wxEventType type = aEvent.GetEventType(); + // When the currently chosen item in the menu is changed, an update event is issued. + // For example, the selection tool can use this to dynamically highlight the current item + // from selection clarification popup. if( type == wxEVT_MENU_HIGHLIGHT ) evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() ); + // One of menu entries was selected.. else if( type == wxEVT_COMMAND_MENU_SELECTED ) { - if( aEvent.GetId() > m_actionId ) + // Check if there is a TOOL_ACTION for the given ID + if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 ) { - // Handling TOOL_ACTIONs - if( m_menu->m_toolActions.count( aEvent.GetId() ) == 1 ) - evt = m_menu->m_toolActions[aEvent.GetId()]->GetEvent(); + evt = m_menu->m_toolActions[aEvent.GetId()]->MakeEvent(); } else { - // Handling common menu entries + // Handling non-action menu entries (e.g. items in clarification list) evt = TOOL_EVENT( TC_Command, TA_ContextMenuChoice, aEvent.GetId() ); } } + // forward the action/update event to the TOOL_MANAGER if( m_menu->m_tool ) m_menu->m_tool->GetManager()->ProcessEvent( evt ); } diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 09847b8518..9d2ad52482 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -39,6 +39,7 @@ using boost::optional; +///> Stores information about a mouse button state struct TOOL_DISPATCHER::ButtonState { ButtonState( TOOL_MouseButtons aButton, const wxEventType& aDownEvent, @@ -217,6 +218,8 @@ 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 || + // Event issued whem mouse retains position in screen coordinates, + // but changes in world coordinates (eg. autopanning) type == KiGfx::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE ) { VECTOR2D screenPos = m_toolMgr->GetViewControls()->GetCursorPosition(); @@ -247,7 +250,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( type == wxEVT_KEY_UP ) { - if( key == WXK_ESCAPE ) + if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools evt = TOOL_EVENT( TC_Command, TA_CancelTool ); else evt = TOOL_EVENT( TC_Keyboard, TA_KeyUp, key | mods ); @@ -261,6 +264,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( evt ) m_toolMgr->ProcessEvent( *evt ); + // pass the event to the GUI, it might still be interested in it aEvent.Skip(); } @@ -270,6 +274,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent ) bool activateTool = false; std::string toolName; + // fixme: use TOOL_ACTIONs here switch( aEvent.GetId() ) { case ID_PNS_ROUTER_TOOL: @@ -282,6 +287,7 @@ void TOOL_DISPATCHER::DispatchWxCommand( const wxCommandEvent& aEvent ) break; } + // do nothing if the legacy view is active if( activateTool && m_editFrame->IsGalCanvasActive() ) m_toolMgr->InvokeTool( toolName ); } diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 00397f8ee4..2db95231d0 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -25,9 +25,8 @@ #include #include -//#include - #include +#include #include #include @@ -55,6 +54,12 @@ static const std::string flag2string( int flag, const FlagString* exps ) } +bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const +{ + return Matches( aAction->MakeEvent() ); +} + + const std::string TOOL_EVENT::Format() const { std::string ev; diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 4e4985ad52..2350994b6b 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -3,6 +3,7 @@ * * Copyright (C) 2013 CERN * @author Tomasz Wlostowski + * @author Maciej Suminski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,6 +40,7 @@ #include #include #include +#include #include #include @@ -46,37 +48,38 @@ using boost::optional; using namespace std; -/// Struct describing the current state of a TOOL +/// Struct describing the current execution state of a TOOL struct TOOL_MANAGER::TOOL_STATE { /// The tool itself TOOL_BASE* theTool; - /// Is the tool active or idle at the moment + /// Is the tool active (pending execution) or disabled at the moment bool idle; - /// Flag defining if the tool is waiting for any event + /// Flag defining if the tool is waiting for any event (i.e. if it + /// issued a Wait() call). bool pendingWait; - /// Is there a context menu to be displayed + /// Is there a context menu being displayed bool pendingContextMenu; - /// Context menu used by the tool + /// Context menu currently used by the tool CONTEXT_MENU* contextMenu; - /// Defines when a context menu is opened + /// Defines when the context menu is opened CONTEXT_MENU_TRIGGER contextMenuTrigger; - /// Coroutine launched upon an event trigger + /// Tool execution context COROUTINE* cofunc; - /// The event that triggered the coroutine + /// The event that triggered the execution/wakeup of the tool after Wait() call TOOL_EVENT wakeupEvent; - /// List of events that are triggering the coroutine + /// List of events the tool is currently waiting for TOOL_EVENT_LIST waitEvents; - /// List of possible transitions (ie. association of events and functions that are executed + /// List of possible transitions (ie. association of events and state handlers that are executed /// upon the event reception std::vector transitions; @@ -93,8 +96,9 @@ struct TOOL_MANAGER::TOOL_STATE TOOL_MANAGER::TOOL_MANAGER() : - m_actionMgr( this ), m_model( NULL ), m_view( NULL ) + m_model( NULL ), m_view( NULL ) { + m_actionMgr = new ACTION_MANAGER( this ); } @@ -108,6 +112,8 @@ TOOL_MANAGER::~TOOL_MANAGER() delete it->second; // delete TOOL_STATE delete it->first; // delete the tool itself } + + delete m_actionMgr; } @@ -154,7 +160,7 @@ bool TOOL_MANAGER::InvokeTool( TOOL_ID aToolId ) if( tool && tool->GetType() == TOOL_Interactive ) return invokeTool( tool ); - return false; + return false; // there is no tool with the given id } @@ -165,7 +171,19 @@ bool TOOL_MANAGER::InvokeTool( const std::string& aToolName ) if( tool && tool->GetType() == TOOL_Interactive ) return invokeTool( tool ); - return false; + return false; // there is no tool with the given name +} + + +void TOOL_MANAGER::RegisterAction( TOOL_ACTION* aAction ) +{ + m_actionMgr->RegisterAction( aAction ); +} + + +void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) +{ + m_actionMgr->UnregisterAction( aAction ); } @@ -187,7 +205,7 @@ bool TOOL_MANAGER::runTool( TOOL_ID aToolId ) if( tool && tool->GetType() == TOOL_Interactive ) return runTool( tool ); - return false; + return false; // there is no tool with the given id } @@ -198,7 +216,7 @@ bool TOOL_MANAGER::runTool( const std::string& aToolName ) if( tool && tool->GetType() == TOOL_Interactive ) return runTool( tool ); - return false; + return false; // there is no tool with the given name } @@ -260,8 +278,12 @@ optional TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool, { TOOL_STATE* st = m_toolState[aTool]; + // indicate to the manager that we are going to sleep and we shall be + // woken up when an event matching aConditions arrive st->pendingWait = true; st->waitEvents = aConditions; + + // switch context back to event dispatcher loop st->cofunc->Yield(); return st->wakeupEvent; @@ -300,7 +322,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values ) { - // the tool state handler is waiting for events (i.e. called Wait() method) + // the tool scheduled next state(s) by calling Go() if( !st->pendingWait ) { // no state handler in progress - check if there are any transitions (defined by @@ -313,6 +335,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) { st->transitions.clear(); + // no tool context allocated yet? Create one. if( !st->cofunc ) st->cofunc = new COROUTINE( tr.second ); else @@ -322,7 +345,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) st->cofunc->Call( aEvent ); if( !st->cofunc->Running() ) - finishTool( st ); // The couroutine has finished + finishTool( st ); // The couroutine has finished immediately? } } } @@ -331,8 +354,27 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) } +bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) +{ + if( aEvent.Action() == TA_KeyUp ) + { + // Check if there is a hotkey associated + if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) ) + return false; // hotkey event was handled so it does not go any further + } + else if( aEvent.Category() == TC_Command ) // it may be a tool activation event + { + dispatchActivation( aEvent ); + // do not return false, as the event has to go on to the destined tool + } + + return true; +} + + bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent ) { + // Look for the tool that has the same name as parameter in the processed command TOOL_EVENT BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values ) { if( st->theTool->GetName() == aEvent.m_commandStr ) @@ -359,7 +401,7 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) if( it != m_activeTools.end() ) m_activeTools.erase( it ); else - wxLogWarning( wxT( "Tried to finish not active tool" ) ); + wxLogWarning( wxT( "Tried to finish inactive tool" ) ); aState->idle = true; delete aState->cofunc; @@ -371,22 +413,19 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) { // wxLogDebug( "event: %s", aEvent.Format().c_str() ); - if( aEvent.Action() == TA_KeyUp ) - { - // Check if there is a hotkey associated - if( m_actionMgr.RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) ) - return false; // hotkey event was handled so it does not go any further - } else if( aEvent.Category() == TC_Command ) // it may be a tool activation event - { - dispatchActivation( aEvent ); - } + // Early dispatch of events destined for the TOOL_MANAGER + if( !dispatchStandardEvents( aEvent ) ) + return false; dispatchInternal( aEvent ); + // popup menu handling BOOST_FOREACH( TOOL_ID toolId, m_activeTools ) { TOOL_STATE* st = m_toolIdIndex[toolId]; + // the tool requested a context menu. The menu is activated on RMB click (CMENU_BUTTON mode) + // or immediately (CMENU_NOW) mode. The latter is used for clarification lists. if( st->contextMenuTrigger != CMENU_OFF ) { if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) ) @@ -401,6 +440,7 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) boost::scoped_ptr menu( new CONTEXT_MENU( *st->contextMenu ) ); GetEditFrame()->PopupMenu( menu->GetMenu() ); + // TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice ); dispatchInternal( evt ); @@ -426,6 +466,7 @@ void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu, st->contextMenu = aMenu; st->contextMenuTrigger = aTrigger; + // the tool wants the menu immediately? Preempt it and do so :) if( aTrigger == CMENU_NOW ) st->cofunc->Yield(); } diff --git a/include/geometry/seg.h b/include/geometry/seg.h index 7b5f64ac2f..c5a93dbe19 100644 --- a/include/geometry/seg.h +++ b/include/geometry/seg.h @@ -34,8 +34,8 @@ typedef boost::optional OPT_VECTOR2I; -class SEG { - +class SEG +{ private: typedef VECTOR2I::extended_type ecoord; @@ -52,7 +52,7 @@ class SEG { /** Default constructor * Creates an empty (0, 0) segment, locally-referenced */ - SEG(): a(m_a), b(m_b) + SEG() : a( m_a ), b( m_b ) { a = m_a; b = m_b; @@ -62,12 +62,12 @@ class SEG { /** * Constructor - * Creates a segment between (x1, y1) and (x2, y2), locally referenced + * Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced */ - SEG ( int x1, int y1, int x2, int y2 ) : a(m_a), b(m_b) + SEG( int aX1, int aY1, int aX2, int aY2 ) : a( m_a ), b( m_b ) { - m_a = VECTOR2I(x1, y1); - m_b = VECTOR2I(x2, y2); + m_a = VECTOR2I( aX1, aY1 ); + m_b = VECTOR2I( aX2, aY2 ); a = m_a; b = m_b; m_is_local = true; @@ -78,7 +78,7 @@ class SEG { * Constructor * Creates a segment between (aA) and (aB), locally referenced */ - SEG ( const VECTOR2I& aA, const VECTOR2I& aB ): a(m_a), b(m_b), m_a(aA), m_b(aB) + SEG( const VECTOR2I& aA, const VECTOR2I& aB ) : a( m_a ), b( m_b ), m_a( aA ), m_b( aB ) { a = m_a; b = m_b; @@ -93,7 +93,7 @@ class SEG { * @param aB reference to the end point in the parent shape * @param aIndex index of the segment within the parent shape */ - SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ): a(aA), b(aB) + SEG ( VECTOR2I& aA, VECTOR2I& aB, int aIndex ) : a( aA ), b( aB ) { m_is_local = false; m_index = aIndex; @@ -102,32 +102,32 @@ class SEG { /** * Copy constructor */ - SEG ( const SEG& seg ): a(m_a), b(m_b) + SEG ( const SEG& aSeg ) : a( m_a ), b( m_b ) { - if (seg.m_is_local) + if (aSeg.m_is_local) { - m_a = seg.m_a; - m_b = seg.m_b; + m_a = aSeg.m_a; + m_b = aSeg.m_b; a = m_a; b = m_b; m_is_local = true; m_index = -1; } else { - a = seg.a; - b = seg.b; - m_index = seg.m_index; + a = aSeg.a; + b = aSeg.b; + m_index = aSeg.m_index; m_is_local = false; } } - SEG& operator=(const SEG& seg) + SEG& operator=( const SEG& aSeg ) { - a = seg.a; - b = seg.b; - m_a = seg.m_a; - m_b = seg.m_b; - m_index = seg.m_index; - m_is_local = seg.m_is_local; + a = aSeg.a; + b = aSeg.b; + m_a = aSeg.m_a; + m_b = aSeg.m_b; + m_index = aSeg.m_index; + m_is_local = aSeg.m_is_local; return *this; } @@ -150,8 +150,9 @@ class SEG { */ int Side( const VECTOR2I& aP ) const { - const ecoord det = (b - a).Cross(aP - a); - return det < 0 ? -1 : (det > 0 ? 1 : 0); + const ecoord det = ( b - a ).Cross( aP - a ); + + return det < 0 ? -1 : ( det > 0 ? 1 : 0 ); } /** @@ -173,7 +174,6 @@ class SEG { */ const VECTOR2I NearestPoint( const VECTOR2I &aP ) const; - /** * Function Intersect() * @@ -186,8 +186,6 @@ class SEG { */ OPT_VECTOR2I Intersect( const SEG& aSeg, bool aIgnoreEndpoints = false, bool aLines = false ) const; - - /** * Function IntersectLines() * @@ -195,9 +193,9 @@ class SEG { * @param aSeg segment defining the line to intersect with * @return intersection point, if exists */ - OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const + OPT_VECTOR2I IntersectLines( const SEG& aSeg ) const { - return Intersect ( aSeg, false, true ); + return Intersect( aSeg, false, true ); } bool Collide( const SEG& aSeg, int aClearance ) const; @@ -210,14 +208,13 @@ class SEG { * @return minimum distance */ - ecoord SquaredDistance( const SEG& aSeg ) const ; + ecoord SquaredDistance( const SEG& aSeg ) const; int Distance( const SEG& aSeg ) const { - return sqrt ( SquaredDistance(aSeg) ); + return sqrt( SquaredDistance( aSeg ) ); } - /** * Function Distance() * @@ -225,18 +222,16 @@ class SEG { * @param aP the point * @return minimum distance */ - ecoord SquaredDistance( const VECTOR2I& aP ) const { - return (NearestPoint(aP) - aP).SquaredEuclideanNorm(); + return ( NearestPoint( aP ) - aP ).SquaredEuclideanNorm(); } int Distance( const VECTOR2I& aP ) const { - return sqrt ( SquaredDistance( aP) ); + return sqrt( SquaredDistance( aP ) ); } - /** * Function Collinear() * @@ -244,7 +239,6 @@ class SEG { * @param aSeg the segment to chech colinearity with * @return true, when segments are collinear. */ - bool Collinear( const SEG& aSeg ) const { ecoord qa1 = a.y - b.y; @@ -254,7 +248,7 @@ class SEG { ecoord qb2 = aSeg.b.x - aSeg.a.x; ecoord qc2 = -qa2 * aSeg.a.x - qb2 * aSeg.a.y; - return (qa1 == qa2) && (qb1 == qb2) && (qc1 == qc2); + return ( qa1 == qa2 ) && ( qb1 == qb2 ) && ( qc1 == qc2 ); } /** @@ -265,15 +259,14 @@ class SEG { */ int Length() const { - return (a - b).EuclideanNorm(); + return ( a - b ).EuclideanNorm(); } - ecoord SquaredLength() const + ecoord SquaredLength() const { - return (a - b).SquaredEuclideanNorm(); + return ( a - b ).SquaredEuclideanNorm(); } - /** * Function Index() * @@ -285,20 +278,20 @@ class SEG { return m_index; } + bool Contains( const VECTOR2I& aP ) const; - bool Contains(const VECTOR2I& aP) const; - - bool PointCloserThan ( const VECTOR2I& aP, int dist) const; + bool PointCloserThan( const VECTOR2I& aP, int aDist ) const; // friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg ); private: - - bool ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const; + bool ccw( const VECTOR2I& aA, const VECTOR2I& aB, const VECTOR2I &aC ) const; ///> locally stored start/end coordinates (used when m_is_local == true) VECTOR2I m_a, m_b; + ///> index withing the parent shape (used when m_is_local == false) int m_index; + ///> locality flag bool m_is_local; }; @@ -306,49 +299,47 @@ class SEG { inline VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const { // fixme: numerical errors for large integers - assert(false); - return VECTOR2I(0, 0); + assert( false ); + return VECTOR2I( 0, 0 ); } - - inline int SEG::LineDistance( const VECTOR2I& aP, bool aDetermineSide ) const { - ecoord p = a.y - b.y; - ecoord q = b.x - a.x; - ecoord r = -p * a.x - q * a.y; + ecoord p = a.y - b.y; + ecoord q = b.x - a.x; + ecoord r = -p * a.x - q * a.y; - ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q ); - return aDetermineSide ? dist : abs(dist); + ecoord dist = ( p * aP.x + q * aP.y + r ) / sqrt( p * p + q * q ); + + return aDetermineSide ? dist : abs( dist ); } - - -inline const VECTOR2I SEG::NearestPoint(const VECTOR2I& aP) const +inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const { - VECTOR2I d = b - a; - ecoord l_squared = d.Dot(d); + VECTOR2I d = b - a; + ecoord l_squared = d.Dot( d ); if( l_squared == 0 ) return a; - ecoord t = d.Dot(aP - a); + ecoord t = d.Dot( aP - a ); if( t < 0 ) return a; else if( t > l_squared ) return b; - int xp = rescale(t, (ecoord)d.x, l_squared); - int yp = rescale(t, (ecoord)d.y, l_squared); + int xp = rescale( t, (ecoord)d.x, l_squared ); + int yp = rescale( t, (ecoord)d.y, l_squared ); - return a + VECTOR2I(xp, yp); + return a + VECTOR2I( xp, yp ); } inline std::ostream& operator<<( std::ostream& aStream, const SEG& aSeg ) { - if(aSeg.m_is_local) + if( aSeg.m_is_local ) aStream << "[ local " << aSeg.a << " - " << aSeg.b << " ]"; + return aStream; } diff --git a/include/geometry/shape.h b/include/geometry/shape.h index 18895553ef..2a42659c20 100644 --- a/include/geometry/shape.h +++ b/include/geometry/shape.h @@ -45,7 +45,7 @@ enum ShapeType { /** * Class SHAPE * - * Represents an abstract shape on 2D plane. All SHAPEs implement SHAPE interface. + * Represents an abstract shape on 2D plane. */ class SHAPE { protected: @@ -58,7 +58,7 @@ class SHAPE { * Creates an empty shape of type aType */ - SHAPE ( ShapeType aType ): m_type( aType ) { }; + SHAPE ( ShapeType aType ) : m_type( aType ) { }; // Destructor virtual ~SHAPE() {}; @@ -78,7 +78,7 @@ class SHAPE { * @retval copy of the shape */ virtual SHAPE* Clone() const { - assert(false); + assert( false ); return NULL; }; @@ -89,9 +89,9 @@ class SHAPE { * a collision. * @return true, if there is a collision. */ - virtual bool Collide ( const VECTOR2I& aP, int aClearance = 0 ) const + virtual bool Collide( const VECTOR2I& aP, int aClearance = 0 ) const { - return Collide(SEG(aP, aP), aClearance); + return Collide( SEG( aP, aP ), aClearance ); } /** @@ -99,10 +99,13 @@ class SHAPE { * * Checks if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating * a collision. + * @param aShape shape to check collision against + * @param aClearance minimum clearance + * @param aMTV minimum translation vector * @return true, if there is a collision. */ - virtual bool Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const; - virtual bool Collide ( const SHAPE *aShape, int aClerance = 0 ) const; + virtual bool Collide( const SHAPE* aShape, int aClerance, VECTOR2I& aMTV ) const; + virtual bool Collide( const SHAPE* aShape, int aClerance = 0 ) const; /** * Function Collide() * @@ -110,7 +113,7 @@ class SHAPE { * a collision. * @return true, if there is a collision. */ - virtual bool Collide ( const SEG& aSeg, int aClearance = 0) const = 0; + virtual bool Collide( const SEG& aSeg, int aClearance = 0 ) const = 0; /** * Function Collide() @@ -120,7 +123,7 @@ class SHAPE { * @aClearance how much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape. * @return the bounding box. */ - virtual const BOX2I BBox ( int aClearance = 0 ) const = 0; + virtual const BOX2I BBox( int aClearance = 0 ) const = 0; /** * Function Centre() @@ -130,7 +133,7 @@ class SHAPE { */ virtual VECTOR2I Centre() const { - return BBox(0).Centre(); // if nothing better is available.... + return BBox( 0 ).Centre(); // if nothing better is available.... } private: @@ -139,6 +142,6 @@ class SHAPE { }; -bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV, VECTOR2I& aMTV ); +bool CollideShapes( const SHAPE *aA, const SHAPE *aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ); #endif // __SHAPE_H diff --git a/include/geometry/shape_circle.h b/include/geometry/shape_circle.h index 3e5a7ba89b..d6732a0c64 100644 --- a/include/geometry/shape_circle.h +++ b/include/geometry/shape_circle.h @@ -31,32 +31,31 @@ class SHAPE_CIRCLE : public SHAPE { public: SHAPE_CIRCLE(): - SHAPE( SH_CIRCLE ), m_radius (0) {}; + SHAPE( SH_CIRCLE ), m_radius( 0 ) {}; SHAPE_CIRCLE( const VECTOR2I& aCenter, int aRadius ): - SHAPE( SH_CIRCLE ), m_radius (aRadius), m_center(aCenter) {}; + SHAPE( SH_CIRCLE ), m_radius( aRadius ), m_center( aCenter ) {}; ~SHAPE_CIRCLE() {}; - const BOX2I BBox(int aClearance = 0) const + const BOX2I BBox( int aClearance = 0 ) const { - const VECTOR2I rc (m_radius + aClearance, m_radius + aClearance); - return BOX2I (m_center - rc, rc * 2); + const VECTOR2I rc( m_radius + aClearance, m_radius + aClearance ); + return BOX2I( m_center - rc, rc * 2 ); } - - bool Collide(const SEG& aSeg, int aClearance = 0) const + bool Collide( const SEG& aSeg, int aClearance = 0 ) const { int rc = aClearance + m_radius; - return aSeg.Distance(m_center) <= rc; + return aSeg.Distance( m_center ) <= rc; } - void SetRadius(int aRadius) + void SetRadius( int aRadius ) { m_radius = aRadius; } - void SetCenter (const VECTOR2I& aCenter) + void SetCenter( const VECTOR2I& aCenter ) { m_center = aCenter; } diff --git a/include/geometry/shape_index.h b/include/geometry/shape_index.h index 578c237685..956829ae87 100644 --- a/include/geometry/shape_index.h +++ b/include/geometry/shape_index.h @@ -62,9 +62,9 @@ const SHAPE* shapeFunctor( SHAPE* aItem ); * @return a BOX2I object containing the bounding box of the T object. */ template -BOX2I boundingBox( T object ) +BOX2I boundingBox( T aObject ) { - return shapeFunctor(object)->BBox(); + return shapeFunctor( aObject )->BBox(); } /** @@ -77,9 +77,9 @@ BOX2I boundingBox( T object ) * @param visitor V visitor object */ template -void acceptVisitor( T object, V visitor ) +void acceptVisitor( T aObject, V aVisitor ) { - visitor(object); + aVisitor( aObject ); } /** @@ -94,22 +94,23 @@ void acceptVisitor( T object, V visitor ) * @return if object and anotherObject collide */ template -bool collide( T object, U anotherObject, int minDistance ) +bool collide( T aObject, U aAnotherObject, int aMinDistance ) { - return shapeFunctor( object )->Collide( anotherObject, minDistance ); + return shapeFunctor( aObject )->Collide( aAnotherObject, aMinDistance ); } template -bool queryCallback(T shape, void* context) +bool queryCallback( T aShape, void* aContext ) { - V* visitor = (V*) context; - acceptVisitor( shape, *visitor ); + V* visitor = (V*) aContext; + acceptVisitor( aShape, *visitor ); return true; } template -class SHAPE_INDEX { +class SHAPE_INDEX +{ public: class Iterator { @@ -123,9 +124,9 @@ class SHAPE_INDEX { * Setup the internal tree iterator. * @param tree pointer to a RTREE object */ - void Init( RTree* tree ) + void Init( RTree* aTree ) { - tree->GetFirst( iterator ); + aTree->GetFirst( iterator ); } public: @@ -135,9 +136,9 @@ class SHAPE_INDEX { * Creates an iterator for the index object * @param index SHAPE_INDEX object to iterate */ - Iterator( SHAPE_INDEX* index ) + Iterator( SHAPE_INDEX* aIndex ) { - Init( index->m_tree ); + Init( aIndex->m_tree ); } /** @@ -321,7 +322,7 @@ void SHAPE_INDEX::Add( T aShape ) } template -void SHAPE_INDEX::Remove(T aShape) +void SHAPE_INDEX::Remove( T aShape ) { BOX2I box = boundingBox( aShape ); int min[2] = { box.GetX(), box.GetY() }; diff --git a/include/geometry/shape_index_list.h b/include/geometry/shape_index_list.h index 47c5d98c97..fc210f80a6 100644 --- a/include/geometry/shape_index_list.h +++ b/include/geometry/shape_index_list.h @@ -27,30 +27,29 @@ #include -template const SHAPE *defaultShapeFunctor( const T aItem ) +template const SHAPE* defaultShapeFunctor( const T aItem ) { return aItem->GetShape(); } -template > +template > class SHAPE_INDEX_LIST { struct ShapeEntry { - ShapeEntry(T aParent) + ShapeEntry( T aParent ) { - shape = ShapeFunctor(aParent); - bbox = shape->BBox(0); + shape = ShapeFunctor( aParent ); + bbox = shape->BBox( 0 ); parent = aParent; } ~ShapeEntry() { - } T parent; - const SHAPE *shape; + const SHAPE* shape; BOX2I bbox; }; @@ -58,18 +57,16 @@ class SHAPE_INDEX_LIST { typedef typename std::vector::iterator ShapeVecIter; public: - -// "Normal" iterator interface, for STL algorithms. + // "Normal" iterator interface, for STL algorithms. class iterator { - public: iterator() {}; - iterator( ShapeVecIter aCurrent) - : m_current(aCurrent) {}; + iterator( ShapeVecIter aCurrent ) + : m_current( aCurrent ) {}; - iterator(const iterator &b) : - m_current(b.m_current) {}; + iterator( const iterator &aB ) : + m_current( aB.m_current ) {}; T operator*() const { @@ -81,25 +78,25 @@ public: ++m_current; } - iterator& operator++(int dummy) + iterator& operator++( int aDummy ) { ++m_current; return *this; } - bool operator ==( const iterator& rhs ) const + bool operator==( const iterator& aRhs ) const { - return m_current == rhs.m_current; + return m_current == aRhs.m_current; } - bool operator !=( const iterator& rhs ) const + bool operator!=( const iterator& aRhs ) const { - return m_current != rhs.m_current; + return m_current != aRhs.m_current; } - const iterator& operator=(const iterator& rhs) + const iterator& operator=( const iterator& aRhs ) { - m_current = rhs.m_current; + m_current = aRhs.m_current; return *this; } @@ -107,40 +104,37 @@ public: ShapeVecIter m_current; }; -// "Query" iterator, for iterating over a set of spatially matching shapes. + // "Query" iterator, for iterating over a set of spatially matching shapes. class query_iterator { public: - query_iterator() { - } - query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE *aShape, int aMinDistance, bool aExact) - : m_end(aEnd), - m_current(aCurrent), - m_shape(aShape), - m_minDistance(aMinDistance), - m_exact(aExact) + query_iterator( ShapeVecIter aCurrent, ShapeVecIter aEnd, SHAPE* aShape, + int aMinDistance, bool aExact ) : + m_end( aEnd ), + m_current( aCurrent ), + m_shape( aShape ), + m_minDistance( aMinDistance ), + m_exact( aExact ) { - if(aShape) + if( aShape ) { m_refBBox = aShape->BBox(); next(); } } - query_iterator(const query_iterator &b) - : m_end(b.m_end), - m_current(b.m_current), - m_shape(b.m_shape), - m_minDistance(b.m_minDistance), - m_exact(b.m_exact), - m_refBBox(b.m_refBBox) + query_iterator( const query_iterator &aB ) : + m_end( aB.m_end ), + m_current( aB.m_current ), + m_shape( aB.m_shape ), + m_minDistance( aB.m_minDistance ), + m_exact( aB.m_exact ), + m_refBBox( aB.m_refBBox ) { - } - T operator*() const { @@ -154,45 +148,45 @@ public: return *this; } - query_iterator& operator++(int dummy) + query_iterator& operator++( int aDummy ) { ++m_current; next(); return *this; } - bool operator ==( const query_iterator& rhs ) const + bool operator==( const query_iterator& aRhs ) const { - return m_current == rhs.m_current; + return m_current == aRhs.m_current; } - bool operator !=( const query_iterator& rhs ) const + bool operator!=( const query_iterator& aRhs ) const { - return m_current != rhs.m_current; + return m_current != aRhs.m_current; } - const query_iterator& operator=(const query_iterator& rhs) + const query_iterator& operator=( const query_iterator& aRhs ) { - m_end = rhs.m_end; - m_current = rhs.m_current; - m_shape = rhs.m_shape; - m_minDistance = rhs.m_minDistance; - m_exact = rhs.m_exact; - m_refBBox = rhs.m_refBBox; + m_end = aRhs.m_end; + m_current = aRhs.m_current; + m_shape = aRhs.m_shape; + m_minDistance = aRhs.m_minDistance; + m_exact = aRhs.m_exact; + m_refBBox = aRhs.m_refBBox; return *this; } private: - void next() { - while(m_current != m_end) + while( m_current != m_end ) { - if (m_refBBox.Distance(m_current->bbox) <= m_minDistance) + if( m_refBBox.Distance( m_current->bbox ) <= m_minDistance ) { - if(!m_exact || m_current->shape->Collide(m_shape, m_minDistance)) + if( !m_exact || m_current->shape->Collide( m_shape, m_minDistance ) ) return; } + ++m_current; } } @@ -205,27 +199,27 @@ public: int m_minDistance; }; - void Add(T aItem) + void Add( T aItem ) { - ShapeEntry s (aItem); + ShapeEntry s( aItem ); m_shapes.push_back(s); } - void Remove(const T aItem) + void Remove( const T aItem ) { ShapeVecIter i; - for(i=m_shapes.begin(); i!=m_shapes.end();++i) + for( i = m_shapes.begin(); i != m_shapes.end(); ++i ) { - if(i->parent == aItem) + if( i->parent == aItem ) break; } - if(i == m_shapes.end()) + if( i == m_shapes.end() ) return; - m_shapes.erase(i); + m_shapes.erase( i ); } int Size() const @@ -234,37 +228,37 @@ public: } template - int Query( const SHAPE *aShape, int aMinDistance, Visitor &v, bool aExact = true) //const - { - ShapeVecIter i; - int n = 0; - VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance; + int Query( const SHAPE *aShape, int aMinDistance, Visitor &aV, bool aExact = true ) //const + { + ShapeVecIter i; + int n = 0; + VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance; - BOX2I refBBox = aShape->BBox(); + BOX2I refBBox = aShape->BBox(); - for(i = m_shapes.begin(); i!=m_shapes.end(); ++i) - { - if (refBBox.SquaredDistance(i->bbox) <= minDistSq) - { - if(!aExact || i->shape->Collide(aShape, aMinDistance)) - { - n++; - if(!v( i->parent )) - return n; - } - } - } - return n; - } + for( i = m_shapes.begin(); i != m_shapes.end(); ++i ) + { + if( refBBox.SquaredDistance( i->bbox ) <= minDistSq ) + { + if( !aExact || i->shape->Collide( aShape, aMinDistance ) ) + { + n++; + if( !aV( i->parent ) ) + return n; + } + } + } + return n; + } void Clear() { m_shapes.clear(); } - query_iterator qbegin( SHAPE *aShape, int aMinDistance, bool aExact ) + query_iterator qbegin( SHAPE* aShape, int aMinDistance, bool aExact ) { - return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact); + return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact ); } const query_iterator qend() @@ -283,7 +277,6 @@ public: } private: - ShapeVec m_shapes; }; diff --git a/include/geometry/shape_rect.h b/include/geometry/shape_rect.h index eee04ae956..6784d6b27e 100644 --- a/include/geometry/shape_rect.h +++ b/include/geometry/shape_rect.h @@ -36,28 +36,28 @@ class SHAPE_RECT : public SHAPE { * Constructor * Creates an empty (0-sized) rectangle */ - SHAPE_RECT(): - SHAPE( SH_RECT ), m_w (0), m_h(0) {}; + SHAPE_RECT() : + SHAPE( SH_RECT ), m_w( 0 ), m_h( 0 ) {}; /** * Constructor - * Creates a rectangle defined by top-left corner (x0, y0), width w and height h. + * Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH. */ - SHAPE_RECT( int x0, int y0, int w, int h ): - SHAPE(SH_RECT), m_p0(x0, y0), m_w(w), m_h(h) {}; + SHAPE_RECT( int aX0, int aY0, int aW, int aH ) : + SHAPE( SH_RECT ), m_p0( aX0, aY0 ), m_w( aW ), m_h( aH ) {}; /** * Constructor - * Creates a rectangle defined by top-left corner p0, width w and height h. + * Creates a rectangle defined by top-left corner aP0, width aW and height aH. */ - SHAPE_RECT( const VECTOR2I &p0, int w, int h ): - SHAPE(SH_RECT), m_p0(p0), m_w(w), m_h(h) {}; + SHAPE_RECT( const VECTOR2I &aP0, int aW, int aH ) : + SHAPE( SH_RECT ), m_p0( aP0 ), m_w( aW ), m_h( aH ) {}; /// @copydoc SHAPE::BBox() const BOX2I BBox(int aClearance = 0) const { - BOX2I bbox( VECTOR2I (m_p0.x - aClearance, m_p0.y - aClearance ), - VECTOR2I (m_w + 2 * aClearance, m_h + 2 * aClearance )); + BOX2I bbox( VECTOR2I( m_p0.x - aClearance, m_p0.y - aClearance ), + VECTOR2I( m_w + 2 * aClearance, m_h + 2 * aClearance ) ); //printf("bb : %s\n",bbox.Format().c_str()); return bbox; } @@ -70,11 +70,11 @@ class SHAPE_RECT : public SHAPE { */ int Diagonal() const { - return VECTOR2I(m_w, m_h).EuclideanNorm(); + return VECTOR2I( m_w, m_h ).EuclideanNorm(); } /// @copydoc SHAPE::Collide() - bool Collide(const SEG& aSeg, int aClearance = 0) const + bool Collide( const SEG& aSeg, int aClearance = 0 ) const { //VECTOR2I pmin = VECTOR2I(std::min(aSeg.a.x, aSeg.b.x), std::min(aSeg.a.y, aSeg.b.y)); //VECTOR2I pmax = VECTOR2I(std::max(aSeg.a.x, aSeg.b.x), std::max(aSeg.a.y, aSeg.b.y)); @@ -83,19 +83,19 @@ class SHAPE_RECT : public SHAPE { //if (BBox(0).SquaredDistance(r) > aClearance * aClearance) // return false; - if(BBox(0).Contains(aSeg.a) || BBox(0).Contains(aSeg.b)) + if( BBox( 0 ).Contains( aSeg.a ) || BBox( 0 ).Contains( aSeg.b ) ) return true; - VECTOR2I vts[] = { VECTOR2I(m_p0.x, m_p0.y), - VECTOR2I(m_p0.x, m_p0.y + m_h), - VECTOR2I(m_p0.x + m_w, m_p0.y + m_h), - VECTOR2I(m_p0.x + m_w, m_p0.y), - VECTOR2I(m_p0.x, m_p0.y) }; + VECTOR2I vts[] = { VECTOR2I( m_p0.x, m_p0.y ), + VECTOR2I( m_p0.x, m_p0.y + m_h ), + VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ), + VECTOR2I( m_p0.x + m_w, m_p0.y ), + VECTOR2I( m_p0.x, m_p0.y ) }; - for (int i = 0; i < 4; i++) + for( int i = 0; i < 4; i++ ) { - SEG s(vts[i], vts[i+1], i); - if(s.Distance(aSeg) <= aClearance) + SEG s( vts[i], vts[i + 1], i ); + if( s.Distance( aSeg ) <= aClearance ) return true; } @@ -114,7 +114,7 @@ class SHAPE_RECT : public SHAPE { * * @return size of the rectangle */ - const VECTOR2I GetSize() const { return VECTOR2I(m_w, m_h); } + const VECTOR2I GetSize() const { return VECTOR2I( m_w, m_h ); } /** * Function GetWidth() @@ -133,8 +133,10 @@ class SHAPE_RECT : public SHAPE { private: ///> Top-left corner VECTOR2I m_p0; + ///> Width int m_w; + ///> Height int m_h; }; diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index 9f54c1f305..6d2a408a8a 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -32,6 +32,12 @@ class TOOL_BASE; class TOOL_MANAGER; class TOOL_ACTION; +/** + * Class ACTION_MANAGER + * + * Takes care of TOOL_ACTION objects. Registers them and allows to run them using associated + * hot keys, names or ids. + */ class ACTION_MANAGER { public: diff --git a/include/tool/context_menu.h b/include/tool/context_menu.h index d4d5e2b532..c707088be2 100644 --- a/include/tool/context_menu.h +++ b/include/tool/context_menu.h @@ -140,7 +140,7 @@ private: /// Menu items with ID higher than that are considered TOOL_ACTIONs static const int m_actionId = 10000; - /// Stores tool actions that are choosable from the menu. Does not take the ownership. + /// Associates tool actions with menu item IDs. Non-owning. std::map m_toolActions; }; diff --git a/include/tool/coroutine.h b/include/tool/coroutine.h index f38029a9c8..8a398685b2 100644 --- a/include/tool/coroutine.h +++ b/include/tool/coroutine.h @@ -181,7 +181,7 @@ public: } private: - static const int c_defaultStackSize = 2000000; + static const int c_defaultStackSize = 2000000; // fixme: make configurable /* real entry point of the coroutine */ static void callerStub( intptr_t data ) diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index cc1559983d..10ca6f6c6e 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -3,6 +3,7 @@ * * Copyright (C) 2013 CERN * @author Tomasz Wlostowski + * @author Maciej Suminski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,10 +32,16 @@ #include #include -// TOOL_ACTION - represents a single action. For instance: -// - changing layer to top by pressing PgUp -// - running the DRC from the menu -// and so on, and so forth.... +/** + * Class TOOL_ACTION + * + * Represents a single user action. For instance: + * - changing layer to top by pressing PgUp + * - running the DRC from the menu + * and so on, and so forth.... + * Action class groups all necessary properties of an action, including explanation, + * icons, hotkeys,.menu items, etc. + */ class TOOL_ACTION { public: @@ -133,13 +140,13 @@ public: } /** - * Function GetEvent() + * Function MakeEvent() * Returns the event associated with the action (ie. the event that will be sent after * activating the action). * * @return The event associated with the action. */ - TOOL_EVENT GetEvent() const + TOOL_EVENT MakeEvent() const { return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope ); } diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index ac298226ae..15c0b73eb4 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -42,10 +42,10 @@ namespace KiGfx { * Class TOOL_DISPATCHER * * - takes wx events, - * - fixes all wx quirks (mouse warping, etc) + * - fixes all wx quirks (mouse warping, panning, ordering problems, etc) * - translates coordinates to world space * - low-level input conditioning (drag/click threshold), updating mouse position during view auto-scroll/pan. - * - issues TOOL_EVENTS to the manager + * - issues TOOL_EVENTS to the tool manager */ class TOOL_DISPATCHER @@ -100,6 +100,7 @@ private: ///> Saves the state of key modifiers (Alt, Ctrl and so on). int decodeModifiers( const wxKeyboardState* aState ) const; + ///> Stores all the informations regarding a mouse button state. struct ButtonState; diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 609b72326a..434156d343 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -33,6 +33,7 @@ #include +class TOOL_ACTION; class TOOL_MANAGER; /** @@ -313,6 +314,14 @@ public: return true; } + /** + * Function IsAction() + * Tests if the event contains an action issued upon activation of the given TOOL_ACTION. + * @param aAction is the TOOL_ACTION to be checked against. + * @return True if it matches the given TOOL_ACTION. + */ + bool IsAction( const TOOL_ACTION* aAction ) const; + boost::optional GetCommandId() { return m_commandId; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index eac8371268..ace86ee5eb 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -3,6 +3,7 @@ * * Copyright (C) 2013 CERN * @author Tomasz Wlostowski + * @author Maciej Suminski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,11 +31,10 @@ #include -#include #include -#include class TOOL_BASE; +class ACTION_MANAGER; class CONTEXT_MENU; class wxWindow; @@ -89,10 +89,7 @@ public: * * @param aAction is the action to be registered. */ - void RegisterAction( TOOL_ACTION* aAction ) - { - m_actionMgr.RegisterAction( aAction ); - } + void RegisterAction( TOOL_ACTION* aAction ); /** * Function UnregisterAction() @@ -100,10 +97,7 @@ public: * * @param aAction is the action to be unregistered. */ - void UnregisterAction( TOOL_ACTION* aAction ) - { - m_actionMgr.UnregisterAction( aAction ); - } + void UnregisterAction( TOOL_ACTION* aAction ); /** * Function FindTool() @@ -205,6 +199,14 @@ private: void dispatchInternal( TOOL_EVENT& aEvent ); + /** + * Function dispatchStandardEvents() + * Handles specific events, that are intended for TOOL_MANAGER rather than tools. + * @aEvent is the event to be processed. + * @return False if the event was processed and should not go any further. + */ + bool dispatchStandardEvents( TOOL_EVENT& aEvent ); + /** * Function dispatchActivation() * Checks if it is a valid activation event and invokes a proper tool. @@ -215,7 +217,8 @@ private: /** * Function invokeTool() - * Invokes a tool by sending a proper event. + * Invokes a tool by sending a proper event (in contrary to runTool, which makes the tool run + * for real). * @param aTool is the tool to be invoked. */ bool invokeTool( TOOL_BASE* aTool ); @@ -291,7 +294,9 @@ private: /// Stack of the active tools std::deque m_activeTools; - ACTION_MANAGER m_actionMgr; + /// Instance of ACTION_MANAGER that handles TOOL_ACTIONs + ACTION_MANAGER* m_actionMgr; + EDA_ITEM* m_model; KiGfx::VIEW* m_view; KiGfx::VIEW_CONTROLS* m_viewControls; diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h index fd80e90d76..1c2ef1ea0f 100644 --- a/include/view/wx_view_controls.h +++ b/include/view/wx_view_controls.h @@ -84,15 +84,16 @@ public: /// @copydoc VIEW_CONTROLS::GetCursorPosition() virtual const VECTOR2D GetCursorPosition() const; - /// Event that forces mouse move event in the dispatcher + /// 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) static const wxEventType EVT_REFRESH_MOUSE; private: /// Possible states for WX_VIEW_CONTROLS enum State { - IDLE = 1, - DRAG_PANNING, - AUTO_PANNING, + IDLE = 1, /// Nothing is happening + DRAG_PANNING, /// Panning with mouse button pressed + AUTO_PANNING, /// Panning on approaching borders of the frame }; /** diff --git a/include/tool/item_state.h b/pcbnew/tools/item_state.h similarity index 99% rename from include/tool/item_state.h rename to pcbnew/tools/item_state.h index 8226d6e66c..72270afe1a 100644 --- a/include/tool/item_state.h +++ b/pcbnew/tools/item_state.h @@ -22,6 +22,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifndef ITEM_STATE_H_ +#define ITEM_STATE_H_ + +#include +#include + /** * Class ITEM_STATE * @@ -29,13 +35,6 @@ * the introduced changes. Does not take ownership of modified items, neither takes care of * refreshing. */ - -#ifndef ITEM_STATE_H_ -#define ITEM_STATE_H_ - -#include -#include - class ITEM_STATE { public: @@ -278,4 +277,3 @@ private: }; #endif /* ITEM_STATE_H_ */ - diff --git a/pcbnew/tools/move_tool.cpp b/pcbnew/tools/move_tool.cpp index 69d2d00dba..768785f7f3 100644 --- a/pcbnew/tools/move_tool.cpp +++ b/pcbnew/tools/move_tool.cpp @@ -53,7 +53,7 @@ MOVE_TOOL::~MOVE_TOOL() void MOVE_TOOL::Reset() { // The tool launches upon reception of action event ("pcbnew.InteractiveMove") - Go( &MOVE_TOOL::Main, m_activate.GetEvent() ); + Go( &MOVE_TOOL::Main, m_activate.MakeEvent() ); } @@ -115,12 +115,12 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) { VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - if( evt->Matches( m_rotate.GetEvent() ) ) // got rotation event? + if( evt->IsAction( &m_rotate ) ) // got rotation event? { m_state.Rotate( cursorPos, 900.0 ); m_items.ViewUpdate( VIEW_ITEM::GEOMETRY ); } - else if( evt->Matches( m_flip.GetEvent() ) ) // got flip event? + else if( evt->IsAction( &m_flip ) ) // got flip event? { m_state.Flip( cursorPos ); m_items.ViewUpdate( VIEW_ITEM::GEOMETRY ); diff --git a/pcbnew/tools/move_tool.h b/pcbnew/tools/move_tool.h index fdb0e2e450..d96a7ca023 100644 --- a/pcbnew/tools/move_tool.h +++ b/pcbnew/tools/move_tool.h @@ -27,8 +27,8 @@ #include #include -#include #include +#include "item_state.h" class BOARD_ITEM; class SELECTION_TOOL; diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index c1133de729..995a380417 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -68,7 +68,7 @@ void SELECTION_TOOL::Reset() m_selectedItems.clear(); // The tool launches upon reception of action event ("pcbnew.InteractiveSelection") - Go( &SELECTION_TOOL::Main, m_activate.GetEvent() ); + Go( &SELECTION_TOOL::Main, m_activate.MakeEvent() ); } @@ -266,7 +266,7 @@ bool SELECTION_TOOL::selectMultiple() VIEW* view = getView(); getViewControls()->SetAutoPan( true ); - // Those 2 lines remove the blink-in-the-random-place effect + // These 2 lines remove the blink-in-the-random-place effect m_selArea->SetOrigin( VECTOR2I( 0, 0 ) ); m_selArea->SetEnd( VECTOR2I( 0, 0 ) ); view->Add( m_selArea ); @@ -467,7 +467,6 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const break; } - // All other items are selected only if the layer on which they exist is visible return board->IsLayerVisible( aItem->GetLayer() ); } @@ -475,12 +474,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const { + const unsigned GRIP_MARGIN = 500000; + // Check if the point is located within any of the currently selected items bounding boxes std::set::iterator it, it_end; for( it = m_selectedItems.begin(), it_end = m_selectedItems.end(); it != it_end; ++it ) { BOX2I itemBox = (*it)->ViewBBox(); - itemBox.Inflate( 500000 ); // Give some margin for gripping an item + itemBox.Inflate( GRIP_MARGIN ); // Give some margin for gripping an item if( itemBox.Contains( aPoint ) ) return true;