Support wire & bus drawing from selection tool.

This commit is contained in:
Jeff Young 2019-05-02 11:59:36 +01:00
parent f95f202f81
commit 20b63174dc
7 changed files with 271 additions and 261 deletions

View File

@ -61,7 +61,7 @@ TOOL_ACTION SCH_ACTIONS::placePower( "eeschema.InteractiveDrawing.placePowerPort
TOOL_ACTION SCH_ACTIONS::startWire( "eeschema.InteractiveDrawing.startWire",
AS_GLOBAL, 0,
_( "Begin Wire" ), _( "Start drawing a wire" ),
_( "Start Wire" ), _( "Start drawing a wire" ),
add_line_xpm, AF_ACTIVATE );
TOOL_ACTION SCH_ACTIONS::drawWire( "eeschema.InteractiveDrawing.drawWire",
@ -71,7 +71,7 @@ TOOL_ACTION SCH_ACTIONS::drawWire( "eeschema.InteractiveDrawing.drawWire",
TOOL_ACTION SCH_ACTIONS::startBus( "eeschema.InteractiveDrawing.startBus",
AS_GLOBAL, 0,
_( "Begin Bus" ), _( "Start drawing a bus" ),
_( "Start Bus" ), _( "Start drawing a bus" ),
add_bus_xpm, AF_ACTIVATE );
TOOL_ACTION SCH_ACTIONS::drawBus( "eeschema.InteractiveDrawing.drawBus",
@ -214,76 +214,67 @@ bool SCH_DRAWING_TOOL::Init()
m_frame = getEditFrame<SCH_EDIT_FRAME>();
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
auto activeTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED );
};
auto wireToolCondition = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_WIRE_BUTT );
auto wireOrBusTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_WIRE_BUTT || m_frame->GetToolId() == ID_BUS_BUTT );
};
auto busToolCondition = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_BUS_BUTT );
};
auto lineToolCondition = [ this ] ( const SELECTION& aSel ) {
auto lineTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_LINE_COMMENT_BUTT );
};
auto sheetToolCondition = [ this ] ( const SELECTION& aSel ) {
auto sheetTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_SHEET_SYMBOL_BUTT );
};
auto idleCondition = [] ( const SELECTION& aSel ) {
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
return ( !item || !item->GetEditFlags() );
};
auto idleBusOrLineToolCondition = ( busToolCondition || lineToolCondition ) && idleCondition;
auto wireOrBusSelectionCondition = SELECTION_CONDITIONS::MoreThan( 0 )
&& SELECTION_CONDITIONS::OnlyTypes( wireOrBusTypes );
auto drawingSegmentsCondition = [] ( const SELECTION& aSel ) {
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
return ( item && item->Type() == SCH_LINE_T && item->IsNew() );
};
auto singleSheetCondition = SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyType( SCH_SHEET_T );
auto& ctxMenu = m_menu.GetMenu();
// cancel current tool goes in main context menu at the top if present
ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
//
// Build the drawing tool menu
//
ctxMenu.AddItem( ACTIONS::cancelInteractive, activeTool, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startWire, wireToolCondition && idleCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startBus, busToolCondition && idleCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startLines, lineToolCondition && idleCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishWire, wireToolCondition && drawingSegmentsCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishBus, busToolCondition && drawingSegmentsCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishLine, lineToolCondition && drawingSegmentsCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startWire, wireOrBusTool && SCH_CONDITIONS::Idle, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startBus, wireOrBusTool && SCH_CONDITIONS::Idle, 1 );
ctxMenu.AddItem( SCH_ACTIONS::startLines, lineTool && SCH_CONDITIONS::Idle, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishWire, IsDrawingWire, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishBus, IsDrawingBus, 1 );
ctxMenu.AddItem( SCH_ACTIONS::finishLine, IsDrawingLine, 1 );
// TODO(JE): add menu access to unfold bus...
ctxMenu.AddItem( SCH_ACTIONS::resizeSheet, sheetToolCondition && idleCondition, 1 );
ctxMenu.AddItem( SCH_ACTIONS::resizeSheet, sheetTool && SCH_CONDITIONS::Idle, 1 );
ctxMenu.AddSeparator( idleBusOrLineToolCondition, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addJunction, idleBusOrLineToolCondition, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addLabel, idleBusOrLineToolCondition, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addGlobalLabel, idleBusOrLineToolCondition, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addHierLabel, idleBusOrLineToolCondition, 100 );
ctxMenu.AddSeparator( wireOrBusTool && SCH_CONDITIONS::Idle, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addJunction, wireOrBusTool && SCH_CONDITIONS::Idle, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addLabel, wireOrBusTool && SCH_CONDITIONS::Idle, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addGlobalLabel, wireOrBusTool && SCH_CONDITIONS::Idle, 100 );
ctxMenu.AddItem( SCH_ACTIONS::addHierLabel, wireOrBusTool && SCH_CONDITIONS::Idle, 100 );
ctxMenu.AddSeparator( activeToolCondition, 1000 );
ctxMenu.AddSeparator( activeTool, 1000 );
m_menu.AddStandardSubMenus( m_frame );
// Add editing actions to the selection tool menu
//
// Add drawing actions to the selection tool menu
//
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
// TODO(JE): add menu access to unfold bus on busSelectionCondition...
selToolMenu.AddItem( SCH_ACTIONS::resizeSheet, singleSheetCondition, 1 );
selToolMenu.AddItem( SCH_ACTIONS::startWire, SCH_CONDITIONS::Empty, 1 );
selToolMenu.AddItem( SCH_ACTIONS::startBus, SCH_CONDITIONS::Empty, 1 );
selToolMenu.AddItem( SCH_ACTIONS::finishWire, IsDrawingWire, 1 );
selToolMenu.AddItem( SCH_ACTIONS::finishBus, IsDrawingBus, 1 );
selToolMenu.AddItem( SCH_ACTIONS::addJunction, wireOrBusSelectionCondition, 100 );
selToolMenu.AddItem( SCH_ACTIONS::addLabel, wireOrBusSelectionCondition, 100 );
selToolMenu.AddItem( SCH_ACTIONS::addGlobalLabel, wireOrBusSelectionCondition, 100 );
@ -303,6 +294,42 @@ void SCH_DRAWING_TOOL::Reset( RESET_REASON aReason )
}
static bool isNewSegment( SCH_ITEM* aItem )
{
return aItem && aItem->IsNew() && aItem->Type() == SCH_LINE_T;
}
bool SCH_DRAWING_TOOL::IsDrawingLine( const SELECTION& aSelection )
{
static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && !aSelection.Front()->IsType( wireOrBusTypes );
}
bool SCH_DRAWING_TOOL::IsDrawingWire( const SELECTION& aSelection )
{
static KICAD_T wireType[] = { SCH_LINE_LOCATE_WIRE_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( wireType );
}
bool SCH_DRAWING_TOOL::IsDrawingBus( const SELECTION& aSelection )
{
static KICAD_T busType[] = { SCH_LINE_LOCATE_BUS_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( busType );
}
bool SCH_DRAWING_TOOL::IsDrawingLineWireOrBus( const SELECTION& aSelection )
{
// NOTE: for immediate hotkeys, it is NOT required that the line, wire or bus tool
// be selected
SCH_ITEM* item = (SCH_ITEM*) aSelection.Front();
return isNewSegment( item );
}
int SCH_DRAWING_TOOL::AddJunction( const TOOL_EVENT& aEvent )
{
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
@ -315,42 +342,21 @@ int SCH_DRAWING_TOOL::AddJunction( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::AddLabel( const TOOL_EVENT& aEvent )
{
return doAddItem( SCH_LABEL_T );
}
int SCH_DRAWING_TOOL::AddGlobalLabel( const TOOL_EVENT& aEvent )
{
return doAddItem( SCH_GLOBAL_LABEL_T );
}
int SCH_DRAWING_TOOL::AddHierLabel( const TOOL_EVENT& aEvent )
{
return doAddItem( SCH_HIER_LABEL_T );
}
int SCH_DRAWING_TOOL::doAddItem( KICAD_T aType )
{
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
SCH_ITEM* item = nullptr;
int layer = LAYER_NOTES;
switch( aType )
{
case SCH_LABEL_T: item = m_frame->CreateNewText( LAYER_LOCLABEL ); break;
case SCH_GLOBAL_LABEL_T: item = m_frame->CreateNewText( LAYER_GLOBLABEL ); break;
case SCH_HIER_LABEL_T: item = m_frame->CreateNewText( LAYER_HIERLABEL ); break;
case SCH_TEXT_T: item = m_frame->CreateNewText( LAYER_NOTES ); break;
default: wxFAIL_MSG( "doAddItem(): unknown type" );
}
if( aEvent.IsAction( &SCH_ACTIONS::addLabel ) )
layer = LAYER_LOCLABEL;
else if( aEvent.IsAction( &SCH_ACTIONS::addGlobalLabel ) )
layer = LAYER_GLOBLABEL;
else if( aEvent.IsAction( &SCH_ACTIONS::addHierLabel ) )
layer = LAYER_HIERLABEL;
SCH_ITEM* item = m_frame->CreateNewText( layer );
m_frame->AddItemToScreenAndUndoList( item );
m_frame->SetNoToolSelected();
return 0;
}
@ -886,7 +892,6 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
int SCH_DRAWING_TOOL::StartWire( const TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _( "Add wire" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
@ -911,7 +916,6 @@ int SCH_DRAWING_TOOL::DrawWire( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::StartBus( const TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_BUS_BUTT, wxCURSOR_PENCIL, _( "Add bus" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
@ -977,7 +981,6 @@ int SCH_DRAWING_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::StartLines( const TOOL_EVENT& aEvent)
{
m_frame->SetToolID( ID_LINE_COMMENT_BUTT, wxCURSOR_PENCIL, _( "Add lines" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
@ -1155,6 +1158,9 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
finishSegments();
aSegment = nullptr;
}
if( m_frame->GetToolId() == ID_NO_TOOL_SELECTED )
break;
}
else if( evt->IsClick( BUT_RIGHT ) )
{
@ -1189,6 +1195,9 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
{
finishSegments();
aSegment = nullptr;
if( m_frame->GetToolId() == ID_NO_TOOL_SELECTED )
break;
}
else
{
@ -1208,6 +1217,9 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
{
finishSegments();
aSegment = nullptr;
if( m_frame->GetToolId() == ID_NO_TOOL_SELECTED )
break;
}
}
else if( evt->IsMotion() )
@ -1413,11 +1425,13 @@ void SCH_DRAWING_TOOL::finishSegments()
// Add the new wires
while( s_wires.GetFirst() )
{
s_wires.GetFirst()->ClearFlags( IS_NEW | IS_MOVED );
m_frame->AddToScreen( s_wires.PopFront() );
}
m_view->ClearPreview();
m_view->ShowPreview( false );
m_view->ClearHiddenFlags();
m_controls->CaptureCursor( false );
m_controls->SetAutoPan( false );
@ -1651,6 +1665,6 @@ void SCH_DRAWING_TOOL::setTransitions()
Go( &SCH_DRAWING_TOOL::StartLines, SCH_ACTIONS::startLines.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddJunction, SCH_ACTIONS::addJunction.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddLabel, SCH_ACTIONS::addLabel.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddGlobalLabel, SCH_ACTIONS::addGlobalLabel.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddHierLabel, SCH_ACTIONS::addHierLabel.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddLabel, SCH_ACTIONS::addGlobalLabel.MakeEvent() );
Go( &SCH_DRAWING_TOOL::AddLabel, SCH_ACTIONS::addHierLabel.MakeEvent() );
}

View File

@ -79,9 +79,6 @@ public:
int StartLines( const TOOL_EVENT& aEvent );
int AddJunction( const TOOL_EVENT& aEvent );
int AddLabel( const TOOL_EVENT& aEvent );
int AddGlobalLabel( const TOOL_EVENT& aEvent );
int AddHierLabel( const TOOL_EVENT& aEvent );
int ImportHierLable( const TOOL_EVENT& aEvent );
int PlaceSymbol( const TOOL_EVENT& aEvent );
int PlacePower( const TOOL_EVENT& aEvent );
@ -103,6 +100,12 @@ public:
int DrawLines( const TOOL_EVENT& aEvent );
int PlaceImage( const TOOL_EVENT& aEvent );
// SELECTION_CONDITIONs:
static bool IsDrawingLine( const SELECTION& aSelection );
static bool IsDrawingWire( const SELECTION& aSelection );
static bool IsDrawingBus( const SELECTION& aSelection );
static bool IsDrawingLineWireOrBus( const SELECTION& aSelection );
private:
int doAddItem( KICAD_T aType );

View File

@ -204,26 +204,27 @@ bool SCH_EDIT_TOOL::Init()
return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED );
};
auto noActiveToolCondition = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_NO_TOOL_SELECTED );
auto moveCondition = [] ( const SELECTION& aSel ) {
if( aSel.Empty() )
return false;
if( SCH_DRAWING_TOOL::IsDrawingLineWireOrBus( aSel ) )
return false;
return true;
};
auto orientatableCondition = [ this ] ( const SELECTION& aSel ) {
auto orientCondition = [] ( const SELECTION& aSel ) {
if( aSel.Empty() )
return false;
if( SCH_DRAWING_TOOL::IsDrawingLineWireOrBus( aSel ) )
return false;
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
if( aSel.GetSize() > 1 )
{
// In general a group is orientatable, except when we're drawing wires/busses
if( m_frame->GetToolId() == ID_WIRE_BUTT || m_frame->GetToolId() == ID_BUS_BUTT )
{
if( item->Type() == SCH_LINE_T && item->IsNew() )
return false;
}
return true;
}
switch( item->Type() )
{
@ -241,7 +242,7 @@ bool SCH_EDIT_TOOL::Init()
}
};
auto hasPropertiesCondition = [] ( const SELECTION& aSel ) {
auto propertiesCondition = [] ( const SELECTION& aSel ) {
if( aSel.GetSize() != 1 )
return false;
@ -261,93 +262,45 @@ bool SCH_EDIT_TOOL::Init()
}
};
auto notJustMarkersCondition = SELECTION_CONDITIONS::MoreThan( 0 )
&& ! SELECTION_CONDITIONS::OnlyType( SCH_MARKER_T );
KICAD_T toLabelTypes[] = { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
auto toLabelCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyTypes( toLabelTypes );
auto toLabelCondition = SELECTION_CONDITIONS::Count( 1 )
&& ( SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) );
KICAD_T toHLableTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_TEXT_T, EOT };
auto toHLabelCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyTypes( toHLableTypes);
auto toHLabelCondition = SELECTION_CONDITIONS::Count( 1 )
&& ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) );
KICAD_T toGLableTypes[] = { SCH_LABEL_T, SCH_HIER_LABEL_T, SCH_TEXT_T, EOT };
auto toGLabelCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyTypes( toGLableTypes);
auto toGLabelCondition = SELECTION_CONDITIONS::Count( 1 )
&& ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) );
KICAD_T toTextTypes[] = { SCH_LABEL_T, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, EOT };
auto toTextlCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyTypes( toTextTypes);
auto toTextlCondition = SELECTION_CONDITIONS::Count( 1 )
&& ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T )
|| SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T ) );
KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT };
auto entryCondition = SCH_CONDITIONS::MoreThan( 0 )
&& SCH_CONDITIONS::OnlyTypes( entryTypes );
auto entryCondition = SELECTION_CONDITIONS::HasType( SCH_BUS_WIRE_ENTRY_T )
|| SELECTION_CONDITIONS::HasType( SCH_BUS_BUS_ENTRY_T );
auto singleComponentCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyType( SCH_COMPONENT_T );
auto singleComponentCondition = SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyType( SCH_COMPONENT_T );
auto wireSelectionCondition = SCH_CONDITIONS::MoreThan( 0 )
&& SCH_CONDITIONS::OnlyType( SCH_LINE_LOCATE_WIRE_T );
auto singleSheetCondition = SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyType( SCH_SHEET_T );
auto busSelectionCondition = SCH_CONDITIONS::MoreThan( 0 )
&& SCH_CONDITIONS::OnlyType( SCH_LINE_LOCATE_BUS_T );
auto singleSymbolCondition = [] ( const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
auto singleSheetCondition = SCH_CONDITIONS::Count( 1 )
&& SCH_CONDITIONS::OnlyType( SCH_SHEET_T );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return !partRef || !partRef->IsPower();
}
}
return false;
auto wireOrBusTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_WIRE_BUTT
|| m_frame->GetToolId() == ID_BUS_BUTT
|| m_frame->GetToolId() == ID_JUNCTION_BUTT );
};
auto singleDeMorganSymbolCondition = [] ( const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return partRef && partRef->HasConversion();
}
}
return false;
};
auto wireTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_WIRE_BUTT );
};
auto busTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_BUS_BUTT );
};
auto junctionTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_JUNCTION_BUTT );
};
auto idleCondition = [] ( const SELECTION& aSel ) {
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
return ( !item || !item->GetEditFlags() );
};
auto idleWireOrBusTool = ( wireTool || busTool || junctionTool ) && idleCondition;
auto wireSelectionCondition = SELECTION_CONDITIONS::MoreThan( 0 )
&& SELECTION_CONDITIONS::OnlyType( SCH_LINE_LOCATE_WIRE_T );
auto busSelectionCondition = SELECTION_CONDITIONS::MoreThan( 0 )
&& SELECTION_CONDITIONS::OnlyType( SCH_LINE_LOCATE_BUS_T );
//
// Build the edit tool menu (shown when moving or dragging)
//
CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
@ -355,42 +308,43 @@ bool SCH_EDIT_TOOL::Init()
ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition );
ctxMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition );
ctxMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition );
ctxMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition );
ctxMenu.AddItem( SCH_ACTIONS::duplicate, notJustMarkersCondition );
ctxMenu.AddItem( SCH_ACTIONS::doDelete, SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::rotateCCW, orientCondition );
ctxMenu.AddItem( SCH_ACTIONS::rotateCW, orientCondition );
ctxMenu.AddItem( SCH_ACTIONS::mirrorX, orientCondition );
ctxMenu.AddItem( SCH_ACTIONS::mirrorY, orientCondition );
ctxMenu.AddItem( SCH_ACTIONS::duplicate, moveCondition );
ctxMenu.AddItem( SCH_ACTIONS::doDelete, SCH_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::properties, hasPropertiesCondition );
ctxMenu.AddItem( SCH_ACTIONS::properties, propertiesCondition );
ctxMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition );
ctxMenu.AddItem( SCH_ACTIONS::convertDeMorgan, SCH_CONDITIONS::SingleDeMorganSymbol );
// JEY TODO: add menu access for changing symbol unit
ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::copy, SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddSeparator( SCH_CONDITIONS::IdleSelection );
ctxMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection );
ctxMenu.AddItem( SCH_ACTIONS::copy, SCH_CONDITIONS::IdleSelection );
ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 );
m_menu.AddStandardSubMenus( m_frame );
//
// Add editing actions to the drawing tool menu
//
CONDITIONAL_MENU& drawingMenu = drawingTool->GetToolMenu().GetMenu();
ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 200 );
drawingMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition, 200 );
ctxMenu.AddSeparator( SCH_CONDITIONS::NotEmpty, 200 );
drawingMenu.AddItem( SCH_ACTIONS::rotateCCW, orientCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::rotateCW, orientCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::mirrorX, orientCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::mirrorY, orientCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::properties, hasPropertiesCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::properties, propertiesCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::convertDeMorgan, SCH_CONDITIONS::SingleDeMorganSymbol, 200 );
// JEY TODO: add menu access for changing symbol unit
drawingMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 );
@ -398,32 +352,33 @@ bool SCH_EDIT_TOOL::Init()
drawingMenu.AddItem( SCH_ACTIONS::toHLabel, toHLabelCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toGLabel, toGLabelCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toText, toTextlCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::selectNode, idleWireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::selectConnection, idleWireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::breakWire, idleWireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::breakBus, idleWireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::selectNode, SCH_CONDITIONS::Idle && wireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::selectConnection, SCH_CONDITIONS::Idle && wireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::breakWire, SCH_CONDITIONS::Idle && wireOrBusTool, 200 );
drawingMenu.AddItem( SCH_ACTIONS::breakBus, SCH_CONDITIONS::Idle && wireOrBusTool, 200 );
//
// Add editing actions to the selection tool menu
//
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
selToolMenu.AddItem( SCH_ACTIONS::move, SELECTION_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::drag, SELECTION_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::duplicate, notJustMarkersCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::doDelete, SELECTION_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::move, moveCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::drag, moveCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, orientCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::rotateCW, orientCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::mirrorX, orientCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::mirrorY, orientCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::duplicate, moveCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::doDelete, SCH_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::properties, hasPropertiesCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editReference, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editValue, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editFootprint, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::properties, propertiesCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editReference, SCH_CONDITIONS::SingleSymbol, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editValue, SCH_CONDITIONS::SingleSymbol, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editFootprint, SCH_CONDITIONS::SingleSymbol, 200 );
selToolMenu.AddItem( SCH_ACTIONS::autoplaceFields, singleComponentCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::convertDeMorgan, SCH_CONDITIONS::SingleSymbol, 200 );
// JEY TODO: add menu access for changing symbol unit
selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, SCH_CONDITIONS::SingleSymbol, 200 );
selToolMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::toLabel, toLabelCondition, 200 );
@ -434,12 +389,10 @@ bool SCH_EDIT_TOOL::Init()
selToolMenu.AddItem( SCH_ACTIONS::breakBus, busSelectionCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::cleanupSheetPins, singleSheetCondition, 200 );
selToolMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty, 200 );
selToolMenu.AddItem( SCH_ACTIONS::copy, SELECTION_CONDITIONS::NotEmpty, 200 );
// Selection tool handles the context menu for some other tools, such as the Picker.
// Don't add things like Paste when another tool is active.
selToolMenu.AddItem( SCH_ACTIONS::paste, noActiveToolCondition, 200 );
selToolMenu.AddSeparator( SCH_CONDITIONS::Idle, 200 );
selToolMenu.AddItem( SCH_ACTIONS::cut, SCH_CONDITIONS::IdleSelection, 200 );
selToolMenu.AddItem( SCH_ACTIONS::copy, SCH_CONDITIONS::IdleSelection, 200 );
selToolMenu.AddItem( SCH_ACTIONS::paste, SCH_CONDITIONS::Idle, 200 );
return true;
}

View File

@ -69,26 +69,11 @@ bool SCH_INSPECTION_TOOL::Init()
auto singleMarkerCondition = SELECTION_CONDITIONS::OnlyType( SCH_MARKER_T )
&& SELECTION_CONDITIONS::Count( 1 );
auto singleSymbolCondition = [] (const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return !partRef || !partRef->IsPower();
}
}
return false;
};
// Add inspection actions to the selection tool menu
//
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, singleSymbolCondition, 400 );
selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, SCH_CONDITIONS::SingleSymbol, 400 );
selToolMenu.AddItem( SCH_ACTIONS::showMarkerInfo, singleMarkerCondition, 400 );
return true;

View File

@ -75,6 +75,58 @@ TOOL_ACTION SCH_ACTIONS::clearSelection( "eeschema.InteractiveSelection.ClearSel
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
SELECTION_CONDITION SCH_CONDITIONS::Empty = [] (const SELECTION& aSelection )
{
return aSelection.Empty();
};
SELECTION_CONDITION SCH_CONDITIONS::Idle = [] (const SELECTION& aSelection )
{
return ( !aSelection.Front() || aSelection.Front()->GetEditFlags() == 0 );
};
SELECTION_CONDITION SCH_CONDITIONS::IdleSelection = [] (const SELECTION& aSelection )
{
return ( aSelection.Front() && aSelection.Front()->GetEditFlags() == 0 );
};
SELECTION_CONDITION SCH_CONDITIONS::SingleSymbol = [] (const SELECTION& aSel )
{
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return !partRef || !partRef->IsPower();
}
}
return false;
};
SELECTION_CONDITION SCH_CONDITIONS::SingleDeMorganSymbol = [] ( const SELECTION& aSel )
{
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return partRef && partRef->HasConversion();
}
}
return false;
};
SCH_SELECTION_TOOL::SCH_SELECTION_TOOL() :
TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
m_frame( nullptr ),
@ -95,25 +147,15 @@ SCH_SELECTION_TOOL::~SCH_SELECTION_TOOL()
bool SCH_SELECTION_TOOL::Init()
{
static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
m_frame = getEditFrame<SCH_BASE_FRAME>();
auto wireOrBusSelectionCondition = [] ( const SELECTION& aSel ) {
for( unsigned i = 0; i < aSel.GetSize(); ++i )
{
SCH_ITEM* item = (SCH_ITEM*) aSel.GetItem( i );
if( !item->IsType( wireOrBusTypes ) || item->IsNew() )
return false;
}
return aSel.GetSize() >= 1;
};
static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
auto wireOrBusSelection = SCH_CONDITIONS::MoreThan( 0 )
&& SCH_CONDITIONS::OnlyTypes( wireOrBusTypes );
auto& ctxMenu = m_menu.GetMenu();
ctxMenu.AddItem( SCH_ACTIONS::selectConnection, wireOrBusSelectionCondition, 200 );
ctxMenu.AddItem( SCH_ACTIONS::selectConnection, wireOrBusSelection && SCH_CONDITIONS::Idle, 200 );
ctxMenu.AddSeparator( SELECTION_CONDITIONS::ShowAlways, 1000 );
m_menu.AddStandardSubMenus( m_frame );

View File

@ -29,6 +29,7 @@
#include <tool/selection.h>
#include <tool/tool_menu.h>
#include <sch_collectors.h>
#include <sch_component.h>
class SCH_BASE_FRAME;
class SCH_ITEM;
@ -40,6 +41,18 @@ namespace KIGFX
}
class SCH_CONDITIONS : public SELECTION_CONDITIONS
{
public:
static SELECTION_CONDITION Empty;
static SELECTION_CONDITION Idle;
static SELECTION_CONDITION IdleSelection;
static SELECTION_CONDITION SingleSymbol;
static SELECTION_CONDITION SingleDeMorganSymbol;
};
class SCH_SELECTION_TOOL : public TOOL_INTERACTIVE
{
public:

View File

@ -154,7 +154,7 @@ public:
EDA_ITEM* Front() const
{
return m_items.front();
return m_items.size() ? m_items.front() : nullptr;
}
std::deque<EDA_ITEM*>& Items()