Skip to content

Commit

Permalink
#5180: Toolbars are properly unregistering themselves on destruction.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed May 14, 2020
1 parent 1d95fc6 commit 1b58089
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 3 deletions.
29 changes: 27 additions & 2 deletions radiant/eventmanager/EventManager.cpp
Expand Up @@ -550,13 +550,38 @@ void EventManager::removeEvent(const std::string& eventName)

void EventManager::disconnectToolbar(wxToolBar* toolbar)
{
std::for_each(_events.begin(), _events.end(), [&] (EventMap::value_type& pair)
for (std::size_t tool = 0; tool < toolbar->GetToolsCount(); tool++)
{
for (auto it = _toolItems.begin(); it != _toolItems.end(); ++it)
{
auto toolItem = toolbar->GetToolByPos(tool);

if (it->second == toolItem)
{
auto evt = findEvent(it->first);

if (!evt->empty())
{
evt->disconnectToolItem(toolItem);
}
else
{
toolbar->Unbind(wxEVT_TOOL, &EventManager::onToolItemClicked, this, toolItem->GetId());
}

_toolItems.erase(it);
break;
}
}
}

for (EventMap::value_type& pair : _events)
{
for (std::size_t tool = 0; tool < toolbar->GetToolsCount(); tool++)
{
pair.second->disconnectToolItem(const_cast<wxToolBarToolBase*>(toolbar->GetToolByPos(static_cast<int>(tool))));
}
});
}
}

// Loads the default shortcuts from the registry
Expand Down
8 changes: 8 additions & 0 deletions radiant/ui/mainframe/TopLevelFrame.cpp
Expand Up @@ -91,6 +91,14 @@ wxToolBar* TopLevelFrame::getToolbar(IMainFrame::Toolbar type)
return (found != _toolbars.end()) ? found->second.get() : nullptr;
}

bool TopLevelFrame::Destroy()
{
// Clear out any references to toolbars while the modules are still loaded
_toolbars.clear();

return wxFrame::Destroy();
}

wxMenuBar* TopLevelFrame::createMenuBar()
{
// Return the "main" menubar from the UIManager
Expand Down
2 changes: 2 additions & 0 deletions radiant/ui/mainframe/TopLevelFrame.h
Expand Up @@ -35,6 +35,8 @@ class TopLevelFrame :

wxToolBar* getToolbar(IMainFrame::Toolbar type);

virtual bool Destroy() override;

private:
wxMenuBar* createMenuBar();

Expand Down
12 changes: 11 additions & 1 deletion radiant/uimanager/ToolbarManager.cpp
Expand Up @@ -149,11 +149,21 @@ wxToolBar* ToolbarManager::createToolbar(xml::Node& node, wxWindow* parent)
throw std::runtime_error("No elements in toolbar.");
}

// TODO: Subscribe to destroy event to deregister tool items
toolbar->Bind(wxEVT_DESTROY, &ToolbarManager::onToolbarDestroy, this);

return toolbar;
}

void ToolbarManager::onToolbarDestroy(wxWindowDestroyEvent& ev)
{
auto toolbar = wxDynamicCast(ev.GetEventObject(), wxToolBar);

if (toolbar != nullptr)
{
GlobalEventManager().disconnectToolbar(toolbar);
}
}

bool ToolbarManager::toolbarExists(const std::string& toolbarName)
{
return (_toolbars.find(toolbarName) != _toolbars.end());
Expand Down
3 changes: 3 additions & 0 deletions radiant/uimanager/ToolbarManager.h
Expand Up @@ -14,6 +14,7 @@
* Obtain a loaded toolbar by calling getToolbar(<toolbarName>);
*/
class wxToolBarToolBase;
class wxWindowDestroyEvent;

namespace ui {

Expand Down Expand Up @@ -53,6 +54,8 @@ class ToolbarManager :
wxToolBarToolBase* createToolItem(wxToolBar* toolbar, xml::Node& node);

bool toolbarExists(const std::string& toolbarName);

void onToolbarDestroy(wxWindowDestroyEvent& ev);
};

} // namespace ui

0 comments on commit 1b58089

Please sign in to comment.