Refactor and fix a few issues with bus unfolding

This commit is contained in:
Jon Evans 2019-05-01 22:29:02 -04:00
parent cbc8faf49b
commit 839f0fbfcf
3 changed files with 76 additions and 98 deletions

View File

@ -784,56 +784,10 @@ void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame )
}
// Bus unfolding menu (only available if bus is properly defined)
auto connection = Bus->Connection( *g_CurrentSheet );
wxMenu* bus_unfold_menu = frame->GetUnfoldBusMenu( Bus );
if( connection && connection->IsBus() && connection->Members().size() > 0 )
{
int idx = 0;
wxMenu* bus_unfolding_menu = new wxMenu;
PopMenu->AppendSubMenu( bus_unfolding_menu, _( "Unfold Bus" ) );
for( const auto& member : connection->Members() )
{
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
auto name = member->Name( true );
if( member->Type() == CONNECTION_BUS )
{
wxMenu* submenu = new wxMenu;
bus_unfolding_menu->AppendSubMenu( submenu, _( name ) );
for( const auto& sub_member : member->Members() )
{
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
submenu->Append( id, sub_member->Name( true ), wxEmptyString );
// See comment in else clause below
auto sub_item_clone = new wxMenuItem();
sub_item_clone->SetItemLabel( sub_member->Name( true ) );
frame->Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
frame, id, id, sub_item_clone );
}
}
else
{
bus_unfolding_menu->Append( id, name, wxEmptyString );
// Because Bind() takes ownership of the user data item, we
// make a new menu item here and set its label. Why create a
// menu item instead of just a wxString or something? Because
// Bind() requires a pointer to wxObject rather than a void
// pointer. Maybe at some point I'll think of a better way...
auto item_clone = new wxMenuItem();
item_clone->SetItemLabel( name );
frame->Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
frame, id, id, item_clone );
}
}
}
if( bus_unfold_menu )
PopMenu->AppendSubMenu( bus_unfold_menu, _( "Unfold Bus" ) );
PopMenu->AppendSeparator();
msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hotkeys_Descr, HK_ADD_JUNCTION );

View File

@ -260,6 +260,11 @@ public:
*/
void OnUnfoldBus( wxCommandEvent& event );
/**
* Builds the context menu for unfolding a bus
*/
wxMenu* GetUnfoldBusMenu( SCH_LINE* aBus );
bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) override;
/**

View File

@ -316,10 +316,14 @@
void SCH_EDIT_FRAME::OnUnfoldBus( wxCommandEvent& event )
{
wxMenuItem* item = static_cast< wxMenuItem* >( event.GetEventUserData() );
static wxString net = item->GetItemLabelText();
wxMenuItem* item = static_cast<wxMenuItem*>( event.GetEventUserData() );
wxString net = item->GetItemLabelText();
GetToolManager()->RunAction( SCH_ACTIONS::unfoldBus, true, &net );
GetToolManager()->RunAction( SCH_ACTIONS::unfoldBus, true, &net );
// Now that we have handled the chosen bus unfold, disconnect all the events so they can be
// recreated with updated data on the next unfold
Unbind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this );
}
@ -1182,57 +1186,72 @@ void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
return;
}
auto connection = item->Connection( *g_CurrentSheet );
if( item->Type() != SCH_LINE_T )
return;
if( connection && connection->IsBus() )
wxMenu* bus_unfold_menu = GetUnfoldBusMenu( static_cast<SCH_LINE*>( item ) );
if( bus_unfold_menu )
{
int idx = 0;
wxMenu* bus_unfolding_menu = new wxMenu;
for( const auto& member : connection->Members() )
{
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
if( member->Type() == CONNECTION_BUS )
{
wxMenu* submenu = new wxMenu;
bus_unfolding_menu->AppendSubMenu( submenu, _( member->Name() ) );
for( const auto& sub_member : member->Members() )
{
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
submenu->Append( id, sub_member->Name(), wxEmptyString );
// See comment in else clause below
auto sub_item_clone = new wxMenuItem();
sub_item_clone->SetItemLabel( sub_member->Name() );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
this, id, id, sub_item_clone );
}
}
else
{
bus_unfolding_menu->Append( id, member->Name(), wxEmptyString );
// Because Bind() takes ownership of the user data item, we
// make a new menu item here and set its label. Why create a
// menu item instead of just a wxString or something? Because
// Bind() requires a pointer to wxObject rather than a void
// pointer. Maybe at some point I'll think of a better way...
auto item_clone = new wxMenuItem();
item_clone->SetItemLabel( member->Name() );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
this, id, id, item_clone );
}
}
auto controls = GetCanvas()->GetViewControls();
auto vmp = controls->GetMousePosition( false );
wxPoint mouse_pos( (int) vmp.x, (int) vmp.y );
GetGalCanvas()->PopupMenu( bus_unfolding_menu, mouse_pos );
GetGalCanvas()->PopupMenu( bus_unfold_menu, mouse_pos );
}
}
wxMenu* SCH_EDIT_FRAME::GetUnfoldBusMenu( SCH_LINE* aBus )
{
auto connection = aBus->Connection( *g_CurrentSheet );
if( !connection || !connection->IsBus() || connection->Members().empty() )
return nullptr;
int idx = 0;
wxMenu* bus_unfolding_menu = new wxMenu;
for( const auto& member : connection->Members() )
{
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
wxString name = member->Name( true );
if( member->Type() == CONNECTION_BUS )
{
wxMenu* submenu = new wxMenu;
bus_unfolding_menu->AppendSubMenu( submenu, _( name ) );
for( const auto& sub_member : member->Members() )
{
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
submenu->Append( id, sub_member->Name( true ), wxEmptyString );
// See comment in else clause below
auto sub_item_clone = new wxMenuItem();
sub_item_clone->SetItemLabel( sub_member->Name( true ) );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this, id, id,
sub_item_clone );
}
}
else
{
bus_unfolding_menu->Append( id, name, wxEmptyString );
// Because Bind() takes ownership of the user data item, we
// make a new menu item here and set its label. Why create a
// menu item instead of just a wxString or something? Because
// Bind() requires a pointer to wxObject rather than a void
// pointer. Maybe at some point I'll think of a better way...
auto item_clone = new wxMenuItem();
item_clone->SetItemLabel( name );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this, id, id,
item_clone );
}
}
return bus_unfolding_menu;
}