From 231853cd9403d7241a1b818c75fbb09bbe931f3f Mon Sep 17 00:00:00 2001 From: YohananDiamond Date: Thu, 15 Jun 2023 02:04:45 -0300 Subject: [PATCH] Command palette - part 1 --- CMakeLists.txt | 1 + src/gui/commandPalette.cpp | 115 +++++++++++++++++++++++++++++++++++++ src/gui/doAction.cpp | 4 +- src/gui/gui.cpp | 17 ++++++ src/gui/gui.h | 10 +++- src/gui/guiConst.cpp | 1 + src/gui/settings.cpp | 1 + 7 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/gui/commandPalette.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a5e91fb00..a58190c69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -674,6 +674,7 @@ src/gui/log.cpp src/gui/mixer.cpp src/gui/midiMap.cpp src/gui/newSong.cpp +src/gui/commandPalette.cpp src/gui/orders.cpp src/gui/osc.cpp src/gui/patManager.cpp diff --git a/src/gui/commandPalette.cpp b/src/gui/commandPalette.cpp new file mode 100644 index 000000000..d0d61c39a --- /dev/null +++ b/src/gui/commandPalette.cpp @@ -0,0 +1,115 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gui.h" +#include "guiConst.h" +#include "misc/cpp/imgui_stdlib.h" +#include +#include +#include +#include "../ta-log.h" + +static std::vector paletteItems; + +static inline bool matchFuzzy(const char* haystack, const char* needle) { + // TODO: case insensitivity + size_t h_i=0; // haystack idx + size_t n_i=0; // needle idx + while (needle[n_i]!='\0') { + for (; std::tolower(haystack[h_i])!=std::tolower(needle[n_i]); h_i++) { + if (haystack[h_i]=='\0') + return false; + } + n_i+=1; + } + return true; +} + +void FurnaceGUI::drawPalette() { + bool accepted=false; + + if (paletteFirstFrame) { + paletteItems.clear(); + for (int i=0; i0) { + curPaletteChoice-=1; + navigated=true; + } + if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) { + curPaletteChoice+=1; + navigated=true; + } + + for (size_t i=0; i=paletteSearchResults.size()) { + curPaletteChoice=paletteSearchResults.size()-1; + } + if (ImGui::IsKeyPressed(ImGuiKey_Enter)) { + accepted=true; + } + } + + if (ImGui::Button("Cancel") || ImGui::IsKeyPressed(ImGuiKey_Escape)) { + ImGui::CloseCurrentPopup(); + } + + if (accepted) { + int action=paletteSearchResults[curPaletteChoice]; + logD("Chose: %s", guiActions[action].friendlyName); + doAction(action); + ImGui::CloseCurrentPopup(); + } + + paletteFirstFrame=false; +} diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 87d74e6cf..8d08f01db 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -184,7 +184,9 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_CLEAR: showWarning("Are you sure you want to clear... (cannot be undone!)",GUI_WARN_CLEAR); break; - + case GUI_ACTION_COMMAND_PALETTE: + displayPalette=true; + break; case GUI_ACTION_WINDOW_EDIT_CONTROLS: nextWindow=GUI_WINDOW_EDIT_CONTROLS; break; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 8c14f977f..ae19b8ec9 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4156,6 +4156,8 @@ bool FurnaceGUI::loop() { ImGui::EndMenu(); } if (ImGui::BeginMenu("window")) { + if (ImGui::MenuItem("command palette",BIND_FOR(GUI_ACTION_COMMAND_PALETTE))) + displayPalette=true; if (ImGui::MenuItem("song information",BIND_FOR(GUI_ACTION_WINDOW_SONG_INFO),songInfoOpen)) songInfoOpen=!songInfoOpen; if (ImGui::MenuItem("subsongs",BIND_FOR(GUI_ACTION_WINDOW_SUBSONGS),subSongsOpen)) subSongsOpen=!subSongsOpen; if (ImGui::MenuItem("speed",BIND_FOR(GUI_ACTION_WINDOW_SPEED),speedOpen)) speedOpen=!speedOpen; @@ -5079,6 +5081,14 @@ bool FurnaceGUI::loop() { ImGui::OpenPopup("New Song"); } + if (displayPalette) { + paletteQuery=""; + paletteFirstFrame=true; + curPaletteChoice=0; + displayPalette=false; + ImGui::OpenPopup("Command Palette"); + } + if (displayEditString) { ImGui::OpenPopup("EditString"); } @@ -5118,6 +5128,11 @@ bool FurnaceGUI::loop() { ImGui::EndPopup(); } + if (ImGui::BeginPopup("Command Palette",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings)) { + drawPalette(); + ImGui::EndPopup(); + } + if (ImGui::BeginPopupModal("Error",NULL,ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("%s",errorString.c_str()); if (ImGui::Button("OK")) { @@ -6561,6 +6576,7 @@ FurnaceGUI::FurnaceGUI(): oldWantCaptureKeyboard(false), displayMacroMenu(false), displayNew(false), + displayPalette(false), fullScreen(false), preserveChanPos(false), wantScrollList(false), @@ -6657,6 +6673,7 @@ FurnaceGUI::FurnaceGUI(): oldBar(-1), curGroove(-1), exitDisabledTimer(0), + curPaletteChoice(0), soloTimeout(0.0f), exportFadeOut(5.0), editControlsOpen(true), diff --git a/src/gui/gui.h b/src/gui/gui.h index 3d91e4058..d3868d762 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -487,6 +487,7 @@ enum FurnaceGUIActions { GUI_ACTION_PANIC, GUI_ACTION_CLEAR, + GUI_ACTION_COMMAND_PALETTE, GUI_ACTION_WINDOW_EDIT_CONTROLS, GUI_ACTION_WINDOW_ORDERS, GUI_ACTION_WINDOW_INS_LIST, @@ -1280,7 +1281,7 @@ class FurnaceGUI { int sampleTexW, sampleTexH; bool updateSampleTex; - String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery; + String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery; String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport; String workingDirVGMExport, workingDirZSMExport, workingDirROMExport, workingDirFont, workingDirColors, workingDirKeybinds; String workingDirLayout, workingDirROM, workingDirTest; @@ -1290,6 +1291,7 @@ class FurnaceGUI { std::vector sysSearchResults; std::vector newSongSearchResults; + std::vector paletteSearchResults; std::deque recentFile; std::vector makeInsTypeList; std::vector availRenderDrivers; @@ -1298,7 +1300,7 @@ class FurnaceGUI { bool vgmExportDirectStream, displayInsTypeList; bool portrait, injectBackUp, mobileMenuOpen; bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu; - bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly; + bool displayNew, displayPalette, fullScreen, preserveChanPos, wantScrollList, noteInputPoly; bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; bool mobileEdit; bool willExport[DIV_MAX_CHIPS]; @@ -1694,11 +1696,12 @@ class FurnaceGUI { int loopOrder, loopRow, loopEnd, isClipping, extraChannelButtons, newSongCategory, latchTarget; int wheelX, wheelY, dragSourceX, dragSourceXFine, dragSourceY, dragDestinationX, dragDestinationXFine, dragDestinationY, oldBeat, oldBar; int curGroove, exitDisabledTimer; + size_t curPaletteChoice; float soloTimeout; double exportFadeOut; - bool newSongFirstFrame; + bool newSongFirstFrame, paletteFirstFrame; bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen; bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen; bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen; @@ -2139,6 +2142,7 @@ class FurnaceGUI { void drawSettings(); void drawDebug(); void drawNewSong(); + void drawPalette(); void drawLog(); void drawEffectList(); void drawSubSongs(bool asChild=false); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 9fcf78a33..0c81ff814 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -492,6 +492,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={ D("PANIC", "Panic", SDLK_F12), D("CLEAR", "Clear song data", 0), + D("COMMAND_PALETTE", "Command Palette", FURKMOD_CMD|SDLK_p), D("WINDOW_EDIT_CONTROLS", "Edit Controls", 0), D("WINDOW_ORDERS", "Orders", 0), D("WINDOW_INS_LIST", "Instrument List", 0), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 5e57640d5..33257f440 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -2227,6 +2227,7 @@ void FurnaceGUI::drawSettings() { if (ImGui::TreeNode("Window activation")) { KEYBIND_CONFIG_BEGIN("keysWindow"); + UI_KEYBIND_CONFIG(GUI_ACTION_COMMAND_PALETTE); UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_EDIT_CONTROLS); UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_ORDERS); UI_KEYBIND_CONFIG(GUI_ACTION_WINDOW_INS_LIST);