-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #121 from berdal84/feat/node-search
feat(GraphView): advanced contextual menu, introducing Actions
- Loading branch information
Showing
44 changed files
with
1,483 additions
and
902 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "Action.h" | ||
#include "EventManager.h" | ||
|
||
using namespace fw; | ||
|
||
void IAction::trigger() const | ||
{ | ||
EventManager& event_manager = EventManager::get_instance(); | ||
event_manager.dispatch( make_event() ); | ||
} | ||
|
||
IEvent* IAction::make_event() const | ||
{ | ||
return new IEvent(event_id); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#pragma once | ||
#include "Event.h" | ||
#include "core/types.h" | ||
#include <SDL/include/SDL_keycode.h> | ||
#include <string> | ||
|
||
namespace fw | ||
{ | ||
/** Data describing a shortcut (ex: "Reset": Ctrl + Alt + R) */ | ||
struct Shortcut | ||
{ | ||
SDL_Keycode key = SDLK_UNKNOWN; // a key to be pressed | ||
SDL_Keymod mod = KMOD_NONE; // modifiers (alt, ctrl, etc.) | ||
std::string description; | ||
std::string to_string() const; | ||
}; | ||
|
||
/** | ||
* The purpose of any IAction is to trigger a given basic event (identified by an EventID) | ||
* when a key shortcut is pressed. | ||
*/ | ||
class IAction | ||
{ | ||
public: | ||
explicit IAction( | ||
EventID event_id, | ||
const char* label = "action", | ||
Shortcut&& shortcut = {}, | ||
u64_t userdata = {} | ||
) | ||
: label(label) | ||
, event_id(event_id) | ||
, shortcut(std::move(shortcut)) | ||
, userdata(userdata) | ||
{} | ||
std::string label; | ||
EventID event_id; | ||
Shortcut shortcut; | ||
u64_t userdata; | ||
|
||
void trigger() const; // Trigger action, will dispatch an event with default values | ||
virtual IEvent* make_event() const; // Make a new event with default values | ||
}; | ||
|
||
/** | ||
* The purpose of an Action is similar to IAction for events requiring some data to be constructed | ||
*/ | ||
template<typename EventT> | ||
class Action : public IAction | ||
{ | ||
public: | ||
static_assert( !std::is_base_of_v<EventT, IEvent> ); // Ensure EventT implements IEvent | ||
|
||
using event_t = EventT; // Type of the event triggered by this action | ||
using event_data_t = typename EventT::data_t; // Type of the payload for the events triggered by this action | ||
|
||
event_data_t event_data; // Initial data used when making a new event | ||
|
||
Action( | ||
const char* label, | ||
Shortcut&& shortcut | ||
) | ||
: IAction(EventT::id, label, std::move(shortcut) ) | ||
{} | ||
|
||
Action( | ||
const char* label, // Text to display for this action | ||
Shortcut&& shortcut, // Shortcut able to trigger this action | ||
u64_t userdata // Custom user data (typically to store flags) | ||
) | ||
: IAction(EventT::id, label, std::move(shortcut), userdata) | ||
{} | ||
|
||
Action( | ||
const char* label, // Text to display for this action | ||
Shortcut&& shortcut, // Shortcut able to trigger this action | ||
event_data_t event_data, // Initial data of a default event | ||
u64_t userdata = {} // Custom user data (typically to store flags) | ||
) | ||
: IAction(EventT::id, label, std::move(shortcut), userdata) | ||
, event_data( event_data ) | ||
{} | ||
|
||
EventT* make_event() const override // Make a new event using default event_data | ||
{ return new EventT( event_data ); } | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#include "ActionManager.h" | ||
#include "core/assertions.h" | ||
#include "core/async.h" | ||
#include "core/log.h" | ||
#include "core/reflection/type.h" | ||
#include <SDL/include/SDL_keyboard.h> | ||
#include <future> | ||
#include <thread> | ||
|
||
using namespace fw; | ||
|
||
ActionManager* ActionManager::s_instance = nullptr; | ||
|
||
ActionManager::ActionManager() | ||
{ | ||
LOG_VERBOSE("fw::ActionManager", "Constructor ...\n"); | ||
FW_EXPECT(!s_instance, "cannot have two instances at a time"); | ||
s_instance = this; | ||
LOG_VERBOSE("fw::ActionManager", "Constructor " OK "\n"); | ||
} | ||
|
||
ActionManager::~ActionManager() | ||
{ | ||
LOG_VERBOSE("fw::ActionManager", "Destructor ...\n"); | ||
s_instance = nullptr; | ||
for( auto action : m_actions ) | ||
{ | ||
delete action; | ||
} | ||
LOG_VERBOSE("fw::ActionManager", "Destructor " OK "\n"); | ||
} | ||
|
||
ActionManager& ActionManager::get_instance() | ||
{ | ||
FW_EXPECT(s_instance, "No instance found."); | ||
return *s_instance; | ||
} | ||
|
||
const IAction* ActionManager::get_action_with_id(EventID id) | ||
{ | ||
auto found = m_actions_by_id.find(id); | ||
if ( found == m_actions_by_id.end() ) | ||
{ | ||
string128 str; | ||
str.append_fmt("Unable to find an action bound to EventId %i\n", id); | ||
FW_EXPECT(false, str.c_str() ); | ||
} | ||
return found->second; | ||
} | ||
|
||
const std::vector<IAction*>& ActionManager::get_actions() const | ||
{ | ||
return m_actions; | ||
} | ||
|
||
void ActionManager::add_action( IAction* _action )// Add a new action (can be triggered via shortcut) | ||
{ | ||
m_actions.push_back( _action ); | ||
m_actions_by_id.insert(std::pair{_action->event_id, _action}); | ||
LOG_MESSAGE("ActionManager", "Action '%s' bound to the event_id %i\n", _action->label.c_str(), _action->event_id); | ||
} | ||
|
||
std::string Shortcut::to_string() const | ||
{ | ||
std::string result; | ||
|
||
if (mod & KMOD_CTRL) result += "Ctrl + "; | ||
if (mod & KMOD_ALT) result += "Alt + "; | ||
if (key) result += SDL_GetKeyName(key); | ||
if (!description.empty()) result += description; | ||
|
||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
|
||
#include <queue> | ||
#include <string> | ||
#include <future> | ||
#include <map> | ||
#include <utility> | ||
|
||
#include "Action.h" | ||
#include "Event.h" | ||
#include "core/reflection/func_type.h" | ||
#include "core/types.h" | ||
|
||
namespace fw | ||
{ | ||
class ActionManager | ||
{ | ||
public: | ||
ActionManager(); | ||
ActionManager(const ActionManager&) = delete; | ||
~ActionManager(); | ||
|
||
const std::vector<IAction*>& get_actions() const; // Get all the actions bound to any event | ||
|
||
template<typename EventT, typename... Args> | ||
Action<EventT>* new_action(Args&&... args) | ||
{ | ||
static_assert(std::is_base_of_v<IEvent, EventT> ); | ||
auto* action = new Action<EventT>(std::forward<Args>(args)...); | ||
add_action(action); | ||
return action; | ||
} | ||
|
||
const IAction* get_action_with_id(EventID id); // Get the action bound to a given event type | ||
static ActionManager& get_instance(); | ||
|
||
template<class ActionT> | ||
static ActionT* get_action() // Helper to get a given action type from the ActionManager instance | ||
{ return s_instance->get_action<ActionT>(); } | ||
|
||
private: | ||
|
||
template<class ActionT> | ||
ActionT* _get_action() const | ||
{ | ||
static_assert( std::is_base_of_v<IAction, ActionT> ); | ||
auto* action = get_action_with_id( ActionT::event_id ); | ||
return dynamic_cast<ActionT*>( action ); | ||
} | ||
|
||
void add_action( IAction* _action); | ||
static ActionManager* s_instance; | ||
std::vector<IAction*> m_actions; | ||
std::unordered_multimap<EventID, IAction*> m_actions_by_id; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "ActionManagerView.h" | ||
#include "ActionManager.h" | ||
#include "imgui.h" | ||
|
||
using namespace fw; | ||
|
||
void ActionManagerView::draw(ActionManager* manager) | ||
{ | ||
if ( ImGui::BeginTable("Actions", 2) ) | ||
{ | ||
ImGui::TableSetupColumn("Action"); | ||
ImGui::TableSetupColumn("Shortcut"); | ||
ImGui::TableHeadersRow(); | ||
|
||
for( auto& action : manager->get_actions()) | ||
{ | ||
ImGui::PushID(action); | ||
ImGui::TableNextRow(); | ||
ImGui::TableNextColumn(); | ||
if( ImGui::SmallButton("trigger") ) | ||
{ | ||
action->trigger(); | ||
} | ||
ImGui::SameLine(); | ||
ImGui::Text("%s", action->label.c_str()); | ||
ImGui::TableNextColumn(); | ||
ImGui::Text("%s", action->shortcut.to_string().c_str()); // TODO: handle shortcut edition | ||
ImGui::PopID(); | ||
} | ||
ImGui::EndTable(); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#pragma once | ||
|
||
namespace fw | ||
{ | ||
// Forward declaration | ||
class ActionManager; | ||
|
||
class ActionManagerView | ||
{ | ||
public: static void draw(ActionManager* manager); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.