Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
#5231: Start refactoring event manager with the goal to decouple the …
…low-level code from the event management.

The goal is to let all modules register their named commands to the CommandSystem only, without even knowing about the event manager with its accelerator bindings.
  • Loading branch information
codereader committed May 4, 2020
1 parent 2ae15a4 commit 7c96905
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 23 deletions.
13 changes: 10 additions & 3 deletions include/ieventmanager.h
Expand Up @@ -47,6 +47,12 @@ class IAccelerator
// Get/Set the modifier flags
virtual void setModifiers(const unsigned int modifiers) = 0;
virtual unsigned int getModifiers() const = 0;

// Returns a string representation of this accelerator.
// forMenu == true: returns the localised modifier strings
// and is using a different separator to prevent wxWidgets
// from assigning accelerators on its own.
virtual std::string getString(bool forMenu) const = 0;
};

class IEvent
Expand Down Expand Up @@ -100,15 +106,16 @@ class IEvent
typedef std::shared_ptr<IEvent> IEventPtr;

// Event visitor class
class IEventVisitor {
class IEventVisitor
{
public:
// destructor
virtual ~IEventVisitor() {}

virtual void visit(const std::string& eventName, const IEventPtr& event) = 0;
virtual void visit(const std::string& eventName, const IAccelerator& accel) = 0;
};

const std::string MODULE_EVENTMANAGER("EventManager");
const char* const MODULE_EVENTMANAGER("EventManager");

// The function object invoked when a ToggleEvent is changing states
// The passed boolean indicates the new toggle state (true = active/toggled)
Expand Down
2 changes: 1 addition & 1 deletion libs/wxutil/Modifier.h
Expand Up @@ -139,7 +139,7 @@ class Modifier
return mod;
}

static std::string GetModifierStringForMenu(unsigned int state, const std::string& separator = "+")
static std::string GetLocalisedModifierString(unsigned int state, const std::string& separator = "+")
{
std::string mod = "";

Expand Down
4 changes: 2 additions & 2 deletions radiant/eventmanager/Accelerator.cpp
Expand Up @@ -71,15 +71,15 @@ void Accelerator::keyDown() {
_event->keyDown();
}

std::string Accelerator::getAcceleratorString(bool forMenu)
std::string Accelerator::getString(bool forMenu) const
{
const std::string keyStr = _key != 0 ? Accelerator::getNameFromKeyCode(_key) : "";

if (!keyStr.empty())
{
// Return a modifier string for a menu
const std::string modifierStr = forMenu ?
wxutil::Modifier::GetModifierStringForMenu(_modifiers) :
wxutil::Modifier::GetLocalisedModifierString(_modifiers) :
wxutil::Modifier::GetModifierString(_modifiers);

const std::string connector = (forMenu) ? "~" : "+";
Expand Down
2 changes: 1 addition & 1 deletion radiant/eventmanager/Accelerator.h
Expand Up @@ -57,7 +57,7 @@ class Accelerator :
void keyUp();
void keyDown();

std::string getAcceleratorString(bool forMenu);
std::string getString(bool forMenu) const override;

/**
* Converts a string representation of a key to the corresponding
Expand Down
4 changes: 2 additions & 2 deletions radiant/eventmanager/Event.h
Expand Up @@ -79,7 +79,7 @@ class Event :
// Cut off any existing accelerators
wxString caption = item->GetItemLabel().BeforeFirst('\t');

wxString accelText = accel.getAcceleratorString(true);
wxString accelText = accel.getString(true);

// greebo: Accelerators seem to globally catch the key events, add a space to fool wxWidgets
item->SetItemLabel(caption + "\t " + accelText);
Expand All @@ -92,7 +92,7 @@ class Event :

static void setToolItemAccelerator(wxToolBarToolBase* tool, Accelerator& accel)
{
wxString accelText = accel.getAcceleratorString(true);
wxString accelText = accel.getString(true);
std::replace(accelText.begin(), accelText.end(), '~', '-');

tool->SetShortHelp(getCleanToolItemHelpText(tool) + " (" + accelText + ")");
Expand Down
15 changes: 8 additions & 7 deletions radiant/eventmanager/EventManager.cpp
Expand Up @@ -165,7 +165,7 @@ std::string EventManager::getAcceleratorStr(const IEventPtr& event, bool forMenu
{
IAccelerator& accelerator = findAccelerator(event);

return static_cast<Accelerator&>(accelerator).getAcceleratorString(forMenu);
return accelerator.getString(forMenu);
}

// Checks if the eventName is already registered and writes to rWarning, if so
Expand Down Expand Up @@ -440,22 +440,23 @@ void EventManager::loadAcceleratorFromList(const xml::NodeList& shortcutList)
void EventManager::foreachEvent(IEventVisitor& eventVisitor)
{
// Cycle through the event and pass them to the visitor class
for (const EventMap::value_type& pair : _events)
for (const auto& pair : _events)
{
eventVisitor.visit(pair.first, pair.second);
auto& accel = findAccelerator(pair.second);
eventVisitor.visit(pair.first, accel);
}
}

// Tries to locate an accelerator, that is connected to the given command
Accelerator& EventManager::findAccelerator(const IEventPtr& event)
{
// Cycle through the accelerators and check for matches
for (AcceleratorList::iterator i = _accelerators.begin(); i != _accelerators.end(); ++i)
for (auto& accel : _accelerators)
{
if (i->match(event))
if (accel.match(event))
{
// Return the reference to the found accelerator
return (*i);
return accel;
}
}

Expand Down Expand Up @@ -577,7 +578,7 @@ std::string EventManager::getEventStr(wxKeyEvent& ev)
const unsigned int modifierFlags = wxutil::Modifier::GetStateForKeyEvent(ev);

// Construct the complete string
returnValue += wxutil::Modifier::GetModifierStringForMenu(modifierFlags);
returnValue += wxutil::Modifier::GetLocalisedModifierString(modifierFlags);
returnValue += (returnValue != "") ? "-" : "";

returnValue += getKeyString(ev);
Expand Down
5 changes: 1 addition & 4 deletions radiant/eventmanager/SaveEventVisitor.h
Expand Up @@ -38,14 +38,11 @@ class SaveEventVisitor :
_shortcutsNode = GlobalRegistry().createKey(_rootKey + "/shortcuts");
}

void visit(const std::string& eventName, const IEventPtr& event)
void visit(const std::string& eventName, const IAccelerator& accelerator) override
{
// Only export events with non-empty name
if (eventName.empty()) return;

// Try to find an accelerator connected to this event
Accelerator& accelerator = _eventManager.findAccelerator(event);

unsigned int keyVal = accelerator.getKey();

const std::string keyStr = keyVal != 0 ? Accelerator::getNameFromKeyCode(keyVal) : "";
Expand Down
6 changes: 3 additions & 3 deletions radiant/ui/commandlist/CommandListPopulator.h
Expand Up @@ -21,19 +21,19 @@ class CommandListPopulator :
const CommandList::Columns& _columns;

public:
CommandListPopulator(wxutil::TreeModel::Ptr listStore,
CommandListPopulator(const wxutil::TreeModel::Ptr& listStore,
const CommandList::Columns& columns) :
_listStore(listStore),
_columns(columns)
{}

void visit(const std::string& eventName, const IEventPtr& ev)
void visit(const std::string& eventName, const IAccelerator& accel) override
{
// Allocate a new list store element
wxutil::TreeModel::Row row = _listStore->AddItem();

row[_columns.command] = eventName;
row[_columns.key] = GlobalEventManager().getAcceleratorStr(ev, true);
row[_columns.key] = accel.getString(true);

row.SendItemAdded();
}
Expand Down

0 comments on commit 7c96905

Please sign in to comment.