mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Added UI actions to change key of source callbacks and copy-paste
Drag&drop input button keys to change key associated to a list of source callbacks (i.e. move). Copy Paste in context popup menu to remember the input model to copy at another input.
This commit is contained in:
16
Source.cpp
16
Source.cpp
@@ -684,6 +684,22 @@ void Source::addInputCallback(uint input, SourceCallback *callback)
|
|||||||
added->second.model_ = callback;
|
added->second.model_ = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Source::swapInputCallback(uint from, uint to)
|
||||||
|
{
|
||||||
|
std::multimap<uint, InputCallback> swapped_callbacks_;
|
||||||
|
|
||||||
|
for (auto k = input_callbacks_.begin(); k != input_callbacks_.end(); ++k)
|
||||||
|
{
|
||||||
|
if ( k->first == from )
|
||||||
|
swapped_callbacks_.emplace( to, k->second);
|
||||||
|
else
|
||||||
|
swapped_callbacks_.emplace( k->first, k->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_callbacks_.swap(swapped_callbacks_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Source::removeInputCallback(SourceCallback *callback)
|
void Source::removeInputCallback(SourceCallback *callback)
|
||||||
{
|
{
|
||||||
for (auto k = input_callbacks_.begin(); k != input_callbacks_.end(); ++k)
|
for (auto k = input_callbacks_.begin(); k != input_callbacks_.end(); ++k)
|
||||||
|
|||||||
1
Source.h
1
Source.h
@@ -153,6 +153,7 @@ public:
|
|||||||
void removeInputCallback(SourceCallback *callback);
|
void removeInputCallback(SourceCallback *callback);
|
||||||
std::list<SourceCallback *> inputCallbacks(uint input);
|
std::list<SourceCallback *> inputCallbacks(uint input);
|
||||||
std::list<uint> callbackInputs();
|
std::list<uint> callbackInputs();
|
||||||
|
void swapInputCallback(uint from, uint to);
|
||||||
void clearInputCallbacks();
|
void clearInputCallbacks();
|
||||||
|
|
||||||
// update mode
|
// update mode
|
||||||
|
|||||||
@@ -4463,9 +4463,9 @@ void InputMappingInterface::Render()
|
|||||||
Session *ses = Mixer::manager().session();
|
Session *ses = Mixer::manager().session();
|
||||||
|
|
||||||
const ImGuiContext& g = *GImGui;
|
const ImGuiContext& g = *GImGui;
|
||||||
static ImVec2 keyLetterIconSize = ImVec2(60, 60);
|
static ImVec2 keyLetterIconSize = ImVec2(50, 52);
|
||||||
static ImVec2 keyLetterItemSize = keyLetterIconSize + g.Style.ItemSpacing;
|
static ImVec2 keyLetterItemSize = keyLetterIconSize + g.Style.ItemSpacing;
|
||||||
static ImVec2 keyNumpadIconSize = ImVec2(75, 75);
|
static ImVec2 keyNumpadIconSize = ImVec2(65, 66);
|
||||||
static ImVec2 keyNumpadItemSize = keyNumpadIconSize + g.Style.ItemSpacing;
|
static ImVec2 keyNumpadItemSize = keyNumpadIconSize + g.Style.ItemSpacing;
|
||||||
static float fixed_height = keyLetterItemSize.y * 5.f + g.Style.WindowBorderSize + g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y * 2.0f ;
|
static float fixed_height = keyLetterItemSize.y * 5.f + g.Style.WindowBorderSize + g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y * 2.0f ;
|
||||||
static float inputarea_width = keyLetterItemSize.x * 5.f;
|
static float inputarea_width = keyLetterItemSize.x * 5.f;
|
||||||
@@ -4536,6 +4536,7 @@ void InputMappingInterface::Render()
|
|||||||
ImVec2 frame_top = ImGui::GetCursorScreenPos();
|
ImVec2 frame_top = ImGui::GetCursorScreenPos();
|
||||||
|
|
||||||
// create data structures more adapted for display
|
// create data structures more adapted for display
|
||||||
|
static uint copy_input_callback = INPUT_UNDEFINED;
|
||||||
std::multimap< uint, std::pair<Source *, SourceCallback*> > input_sources_callbacks;
|
std::multimap< uint, std::pair<Source *, SourceCallback*> > input_sources_callbacks;
|
||||||
bool input_assigned[INPUT_MAX]{};
|
bool input_assigned[INPUT_MAX]{};
|
||||||
// loop over sources of the session
|
// loop over sources of the session
|
||||||
@@ -4578,10 +4579,34 @@ void InputMappingInterface::Render()
|
|||||||
// draw key button
|
// draw key button
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
if (ImGui::Selectable(Control::manager().inputLabel(ik).c_str(), input_assigned[ik], 0, keyLetterIconSize)) {
|
if (ImGui::Selectable(Control::manager().inputLabel(ik).c_str(), input_assigned[ik], 0, keyLetterIconSize)) {
|
||||||
|
|
||||||
current_input_ = ik;
|
current_input_ = ik;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
|
// if user clics and drags an assigned key icon...
|
||||||
|
if (input_assigned[ik] && ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||||
|
ImGui::SetDragDropPayload("DND_KEYBOARD", &ik, sizeof(uint));
|
||||||
|
ImGui::Text( ICON_FA_CUBE " %s ", Control::manager().inputLabel(ik).c_str());
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
// ...and drops it onto another key icon
|
||||||
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_KEYBOARD")) {
|
||||||
|
if ( payload->DataSize == sizeof(uint) ) {
|
||||||
|
// drop means change key of input callbacks
|
||||||
|
uint previous_input_key = *(const int*)payload->Data;
|
||||||
|
// index of current source changed;
|
||||||
|
auto result = input_sources_callbacks.equal_range(previous_input_key);
|
||||||
|
for (auto kit = result.first; kit != result.second; ++kit)
|
||||||
|
kit->second.first->swapInputCallback(previous_input_key, ik);
|
||||||
|
// switch to this key
|
||||||
|
current_input_ = ik;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5 elements in a row
|
||||||
if ((i % 5) < 4) ImGui::SameLine();
|
if ((i % 5) < 4) ImGui::SameLine();
|
||||||
|
|
||||||
// Draw frame around current keyboard letter
|
// Draw frame around current keyboard letter
|
||||||
@@ -4633,6 +4658,30 @@ void InputMappingInterface::Render()
|
|||||||
current_input_ = ik;
|
current_input_ = ik;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
// if user clics and drags an assigned key icon...
|
||||||
|
if (input_assigned[ik] && ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||||
|
ImGui::SetDragDropPayload("DND_NUMPAD", &ik, sizeof(uint));
|
||||||
|
ImGui::Text( ICON_FA_CUBE " %s ", Control::manager().inputLabel(ik).c_str());
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
// ...and drops it onto another key icon
|
||||||
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_NUMPAD")) {
|
||||||
|
if ( payload->DataSize == sizeof(uint) ) {
|
||||||
|
// drop means change key of input callbacks
|
||||||
|
uint previous_input_key = *(const int*)payload->Data;
|
||||||
|
// index of current source changed;
|
||||||
|
auto result = input_sources_callbacks.equal_range(previous_input_key);
|
||||||
|
for (auto kit = result.first; kit != result.second; ++kit)
|
||||||
|
kit->second.first->swapInputCallback(previous_input_key, ik);
|
||||||
|
// switch to this key
|
||||||
|
current_input_ = ik;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4 elements in a row
|
||||||
if ((p % 4) < 3) ImGui::SameLine();
|
if ((p % 4) < 3) ImGui::SameLine();
|
||||||
|
|
||||||
// Draw frame around current
|
// Draw frame around current
|
||||||
@@ -4693,11 +4742,33 @@ void InputMappingInterface::Render()
|
|||||||
}
|
}
|
||||||
// draw key button
|
// draw key button
|
||||||
ImGui::PushID(ig);
|
ImGui::PushID(ig);
|
||||||
if (ImGui::Selectable(gamepad_labels[b].c_str(), input_assigned[ig], 0, keyLetterIconSize)) {
|
if (ImGui::Selectable(gamepad_labels[b].c_str(), input_assigned[ig], 0, keyLetterIconSize))
|
||||||
|
|
||||||
current_input_ = ig;
|
current_input_ = ig;
|
||||||
}
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
|
// if user clics and drags an assigned key icon...
|
||||||
|
if (input_assigned[ig] && ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||||
|
ImGui::SetDragDropPayload("DND_GAMEPAD", &ig, sizeof(uint));
|
||||||
|
ImGui::Text( ICON_FA_CUBE " %s ", Control::manager().inputLabel(ig).c_str());
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
// ...and drops it onto another key icon
|
||||||
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_GAMEPAD")) {
|
||||||
|
if ( payload->DataSize == sizeof(uint) ) {
|
||||||
|
// drop means change key of input callbacks
|
||||||
|
uint previous_input_key = *(const int*)payload->Data;
|
||||||
|
// index of current source changed;
|
||||||
|
auto result = input_sources_callbacks.equal_range(previous_input_key);
|
||||||
|
for (auto kit = result.first; kit != result.second; ++kit)
|
||||||
|
kit->second.first->swapInputCallback(previous_input_key, ig);
|
||||||
|
// switch to this key
|
||||||
|
current_input_ = ig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
if ((b % 5) < 4) ImGui::SameLine();
|
if ((b % 5) < 4) ImGui::SameLine();
|
||||||
|
|
||||||
// Draw frame around current gamepad button
|
// Draw frame around current gamepad button
|
||||||
@@ -4803,11 +4874,7 @@ void InputMappingInterface::Render()
|
|||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2.f, g.Style.ItemSpacing.y * 2.f) );
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2.f, g.Style.ItemSpacing.y * 2.f) );
|
||||||
ImGui::BeginChild("InputsMappingInterfacePanel", ImVec2(0, 0), true);
|
ImGui::BeginChild("InputsMappingInterfacePanel", ImVec2(0, 0), true);
|
||||||
|
|
||||||
if (input_sources_callbacks.count(current_input_) < 1) {
|
if (input_assigned[current_input_]) {
|
||||||
|
|
||||||
ImGui::Text("No action mapped to this input. Add one with '+'.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
ImGui::Columns(3, "InputMapping", false);
|
ImGui::Columns(3, "InputMapping", false);
|
||||||
auto result = input_sources_callbacks.equal_range(current_input_);
|
auto result = input_sources_callbacks.equal_range(current_input_);
|
||||||
@@ -4866,6 +4933,10 @@ void InputMappingInterface::Render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
ImGui::Text("No action mapped to this input. Add one with '+'.");
|
||||||
|
}
|
||||||
|
|
||||||
// Add a new interface
|
// Add a new interface
|
||||||
static bool temp_new_input = false;
|
static bool temp_new_input = false;
|
||||||
@@ -4917,17 +4988,36 @@ void InputMappingInterface::Render()
|
|||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all button
|
// Custom popup menu for the current input actions (right aligned)
|
||||||
if (input_sources_callbacks.count(current_input_) > 0) {
|
ImGui::SetCursorScreenPos(frame_top + ImVec2(window->Size.x - g.FontSize - g.Style.FramePadding.x * 2.0f - g.Style.WindowPadding.x, g.Style.FramePadding.y));
|
||||||
ImGui::SetCursorScreenPos(frame_top + ImVec2(window->Size.x - g.FontSize - g.Style.FramePadding.x * 2.0f - g.Style.WindowPadding.x, g.Style.FramePadding.y));
|
if (ImGuiToolkit::IconButton(5, 8))
|
||||||
if (ImGuiToolkit::IconButton(ICON_FA_BACKSPACE, "Remove all") ){
|
ImGui::OpenPopup( "MenuInputMapping" );
|
||||||
auto result = input_sources_callbacks.equal_range(current_input_);
|
if (ImGui::BeginPopup( "MenuInputMapping" ))
|
||||||
for (auto kit = result.first; kit != result.second; ++kit) {
|
{
|
||||||
|
// 1) Reset (if there are callbacks assigned)
|
||||||
|
if (ImGui::MenuItem("Reset", NULL, false, input_assigned[current_input_] )) {
|
||||||
|
// remove all source callback of this input
|
||||||
|
auto current_source_callback = input_sources_callbacks.equal_range(current_input_);
|
||||||
|
for (auto kit = current_source_callback.first; kit != current_source_callback.second; ++kit)
|
||||||
kit->second.first->removeInputCallback(kit->second.second);
|
kit->second.first->removeInputCallback(kit->second.second);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// static var for the copy-paste mechanism
|
||||||
|
static uint _copy_current_input = INPUT_UNDEFINED;
|
||||||
|
// 2) Copy (if there are callbacks assigned)
|
||||||
|
if (ImGui::MenuItem("Copy", NULL, false, input_assigned[current_input_] ))
|
||||||
|
// Remember the index of the input to copy
|
||||||
|
_copy_current_input = current_input_;
|
||||||
|
// 3) Paste (if copied input index is assigned)
|
||||||
|
if (ImGui::MenuItem("Paste", NULL, false, input_assigned[_copy_current_input] )) {
|
||||||
|
// create source callbacks at current input cloning those of the copied index
|
||||||
|
auto copy_source_callback = input_sources_callbacks.equal_range(_copy_current_input);
|
||||||
|
for (auto kit = copy_source_callback.first; kit != copy_source_callback.second; ++kit)
|
||||||
|
kit->second.first->addInputCallback(current_input_, kit->second.second->clone());
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user