Merge pull request #1160 from YohananDiamond/command-palette
undefined WAHAHA nice one GitHub see? that's why I hate JavaScript. couldn't you throw exception on out of bounds/undefined result, like EVERY normal language?
This commit is contained in:
commit
a6aa4b66d1
|
@ -807,6 +807,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
|
||||
|
|
253
src/gui/commandPalette.cpp
Normal file
253
src/gui/commandPalette.cpp
Normal file
|
@ -0,0 +1,253 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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 "commandPalette.h"
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include <fmt/printf.h>
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include "../ta-log.h"
|
||||
|
||||
static inline bool matchFuzzy(const char* haystack, const char* needle) {
|
||||
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)
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
|
||||
int width=ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetNextItemWidth(width);
|
||||
|
||||
const char* hint="Search...";
|
||||
switch (curPaletteType) {
|
||||
case CMDPAL_TYPE_RECENT:
|
||||
hint="Search recent files...";
|
||||
break;
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
hint="Search instruments...";
|
||||
break;
|
||||
case CMDPAL_TYPE_SAMPLES:
|
||||
hint="Search samples...";
|
||||
break;
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
hint="Search instruments (to change to)...";
|
||||
break;
|
||||
case CMDPAL_TYPE_ADD_CHIP:
|
||||
hint="Search chip (to add)...";
|
||||
break;
|
||||
}
|
||||
|
||||
if (ImGui::InputTextWithHint("##CommandPaletteSearch",hint,&paletteQuery) || paletteFirstFrame) {
|
||||
paletteSearchResults.clear();
|
||||
|
||||
switch (curPaletteType) {
|
||||
case CMDPAL_TYPE_MAIN:
|
||||
for (int i=0; i<GUI_ACTION_MAX; i++) {
|
||||
if (guiActions[i].defaultBind==-1) continue;
|
||||
if (matchFuzzy(guiActions[i].friendlyName,paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_RECENT:
|
||||
for (int i=0; i<(int)recentFile.size(); i++) {
|
||||
if (matchFuzzy(recentFile[i].c_str(),paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
if (matchFuzzy("- None -",paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(0);
|
||||
}
|
||||
for (int i=0; i<e->song.insLen; i++) {
|
||||
String s=fmt::sprintf("%02X: %s", i, e->song.ins[i]->name.c_str());
|
||||
if (matchFuzzy(s.c_str(),paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(i+1); // because over here ins=0 is 'None'
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_SAMPLES:
|
||||
for (int i=0; i<e->song.sampleLen; i++) {
|
||||
if (matchFuzzy(e->song.sample[i]->name.c_str(),paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_ADD_CHIP:
|
||||
for (int i=0; availableSystems[i]; i++) {
|
||||
int ds=availableSystems[i];
|
||||
const char* sysname=getSystemName((DivSystem)ds);
|
||||
if (matchFuzzy(sysname,paletteQuery.c_str())) {
|
||||
paletteSearchResults.push_back(ds);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
ImGui::CloseCurrentPopup();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
ImVec2 avail=ImGui::GetContentRegionAvail();
|
||||
avail.y-=ImGui::GetFrameHeightWithSpacing();
|
||||
|
||||
if (ImGui::BeginChild("CommandPaletteList",avail,false,0)) {
|
||||
bool navigated=false;
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_UpArrow) && curPaletteChoice>0) {
|
||||
curPaletteChoice-=1;
|
||||
navigated=true;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) {
|
||||
curPaletteChoice+=1;
|
||||
navigated=true;
|
||||
}
|
||||
|
||||
if (paletteSearchResults.size()>0 && curPaletteChoice<0) {
|
||||
curPaletteChoice=0;
|
||||
navigated=true;
|
||||
}
|
||||
if (curPaletteChoice>=(int)paletteSearchResults.size()) {
|
||||
curPaletteChoice=paletteSearchResults.size()-1;
|
||||
navigated=true;
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)paletteSearchResults.size(); i++) {
|
||||
bool current=(i==curPaletteChoice);
|
||||
int id=paletteSearchResults[i];
|
||||
|
||||
String s="???";
|
||||
switch (curPaletteType) {
|
||||
case CMDPAL_TYPE_MAIN:
|
||||
s=guiActions[id].friendlyName;
|
||||
break;
|
||||
case CMDPAL_TYPE_RECENT:
|
||||
s=recentFile[id].c_str();
|
||||
break;
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
if (id==0) {
|
||||
s="- None -";
|
||||
} else {
|
||||
s=fmt::sprintf("%02X: %s", id-1, e->song.ins[id-1]->name.c_str());
|
||||
}
|
||||
break;
|
||||
case CMDPAL_TYPE_SAMPLES:
|
||||
s=e->song.sample[id]->name.c_str();
|
||||
break;
|
||||
case CMDPAL_TYPE_ADD_CHIP:
|
||||
s=getSystemName((DivSystem)id);
|
||||
break;
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
break;
|
||||
};
|
||||
|
||||
if (ImGui::Selectable(s.c_str(),current)) {
|
||||
curPaletteChoice=i;
|
||||
accepted=true;
|
||||
}
|
||||
if ((navigated || paletteFirstFrame) && current) ImGui::SetScrollHereY();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (!accepted) {
|
||||
if (curPaletteChoice>=(int)paletteSearchResults.size()) {
|
||||
curPaletteChoice=paletteSearchResults.size()-1;
|
||||
}
|
||||
accepted=ImGui::IsKeyPressed(ImGuiKey_Enter);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Cancel") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
// do not move this to after the resetPalette() calls!
|
||||
// if they are called before and we're jumping from one palette to the next, the paletteFirstFrame won't be true at the start and the setup will not happen.
|
||||
paletteFirstFrame=false;
|
||||
|
||||
if (accepted) {
|
||||
if (paletteSearchResults.size()>0) {
|
||||
int i=paletteSearchResults[curPaletteChoice];
|
||||
switch (curPaletteType) {
|
||||
case CMDPAL_TYPE_MAIN:
|
||||
doAction(i);
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_RECENT:
|
||||
openRecentFile(recentFile[i]);
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_INSTRUMENTS:
|
||||
curIns=i-1;
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_SAMPLES:
|
||||
curSample=i;
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_INSTRUMENT_CHANGE:
|
||||
doChangeIns(i-1);
|
||||
break;
|
||||
|
||||
case CMDPAL_TYPE_ADD_CHIP:
|
||||
if (i!=DIV_SYSTEM_NULL) {
|
||||
if (!e->addSystem((DivSystem)i)) {
|
||||
showError("cannot add chip! ("+e->getLastError()+")");
|
||||
} else {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
}
|
||||
updateWindowTitle();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logE("invalid command palette type");
|
||||
break;
|
||||
};
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
31
src/gui/commandPalette.h
Normal file
31
src/gui/commandPalette.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 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.
|
||||
*/
|
||||
|
||||
enum CommandPaletteType {
|
||||
CMDPAL_TYPE_MAIN = 0,
|
||||
CMDPAL_TYPE_RECENT,
|
||||
CMDPAL_TYPE_INSTRUMENTS,
|
||||
CMDPAL_TYPE_SAMPLES,
|
||||
CMDPAL_TYPE_INSTRUMENT_CHANGE,
|
||||
CMDPAL_TYPE_ADD_CHIP,
|
||||
// a menu to select wavetables is beyond scope (they can't be put as strings)
|
||||
// TODO: are there more?
|
||||
|
||||
CMDPAL_TYPE_MAX,
|
||||
};
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "gui.h"
|
||||
#include "commandPalette.h"
|
||||
#include "../ta-log.h"
|
||||
#include <fmt/printf.h>
|
||||
#include <imgui.h>
|
||||
|
@ -195,7 +196,30 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_CLEAR:
|
||||
showWarning("Select an option: (cannot be undone!)",GUI_WARN_CLEAR);
|
||||
break;
|
||||
|
||||
case GUI_ACTION_COMMAND_PALETTE:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_MAIN;
|
||||
break;
|
||||
case GUI_ACTION_CMDPAL_RECENT:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_RECENT;
|
||||
break;
|
||||
case GUI_ACTION_CMDPAL_INSTRUMENTS:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_INSTRUMENTS;
|
||||
break;
|
||||
case GUI_ACTION_CMDPAL_SAMPLES:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_SAMPLES;
|
||||
break;
|
||||
case GUI_ACTION_CMDPAL_INSTRUMENT_CHANGE:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_INSTRUMENT_CHANGE;
|
||||
break;
|
||||
case GUI_ACTION_CMDPAL_ADD_CHIP:
|
||||
displayPalette=true;
|
||||
curPaletteType=CMDPAL_TYPE_ADD_CHIP;
|
||||
break;
|
||||
case GUI_ACTION_WINDOW_EDIT_CONTROLS:
|
||||
nextWindow=GUI_WINDOW_EDIT_CONTROLS;
|
||||
break;
|
||||
|
|
|
@ -2264,6 +2264,17 @@ int FurnaceGUI::load(String path) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void FurnaceGUI::openRecentFile(String path) {
|
||||
if (modified) {
|
||||
nextFile=path;
|
||||
showWarning("Unsaved changes! Save changes before opening file?",GUI_WARN_OPEN_DROP);
|
||||
} else {
|
||||
if (load(path)>0) {
|
||||
showError(fmt::sprintf("Error while loading file! (%s)",lastError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::pushRecentFile(String path) {
|
||||
if (path.empty()) return;
|
||||
if (path.find(backupPath)==0) return;
|
||||
|
@ -4126,10 +4137,8 @@ bool FurnaceGUI::loop() {
|
|||
} else {
|
||||
recentFile.erase(i);
|
||||
i--;
|
||||
if (load(item)>0) {
|
||||
showError(fmt::sprintf("Error while loading file! (%s)",lastError));
|
||||
}
|
||||
}
|
||||
openRecentFile(item);
|
||||
}
|
||||
}
|
||||
if (recentFile.empty()) {
|
||||
|
@ -4382,6 +4391,8 @@ bool FurnaceGUI::loop() {
|
|||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu(settings.capitalMenuBar?"Window":"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;
|
||||
|
@ -5437,6 +5448,15 @@ bool FurnaceGUI::loop() {
|
|||
}
|
||||
}
|
||||
|
||||
if (displayPalette) {
|
||||
paletteSearchResults.clear();
|
||||
paletteQuery="";
|
||||
paletteFirstFrame=true;
|
||||
curPaletteChoice=0;
|
||||
displayPalette=false;
|
||||
ImGui::OpenPopup("Command Palette");
|
||||
}
|
||||
|
||||
if (displayExport) {
|
||||
displayExport=false;
|
||||
ImGui::OpenPopup("Export");
|
||||
|
@ -5483,6 +5503,14 @@ bool FurnaceGUI::loop() {
|
|||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImVec2 wsize=ImVec2(canvasW*0.9,canvasH*0.4);
|
||||
ImGui::SetNextWindowPos(ImVec2((canvasW-wsize.x)*0.5,50*dpiScale));
|
||||
ImGui::SetNextWindowSize(wsize,ImGuiCond_Always);
|
||||
if (ImGui::BeginPopup("Command Palette",ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings)) {
|
||||
drawPalette();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupModal("Export",NULL,ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::SetWindowPos(ImVec2(((canvasW)-ImGui::GetWindowSize().x)*0.5,((canvasH)-ImGui::GetWindowSize().y)*0.5));
|
||||
drawExport();
|
||||
|
@ -7289,6 +7317,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
oldWantCaptureKeyboard(false),
|
||||
displayMacroMenu(false),
|
||||
displayNew(false),
|
||||
displayPalette(false),
|
||||
fullScreen(false),
|
||||
preserveChanPos(false),
|
||||
wantScrollList(false),
|
||||
|
@ -7409,6 +7438,8 @@ FurnaceGUI::FurnaceGUI():
|
|||
oldBar(-1),
|
||||
curGroove(-1),
|
||||
exitDisabledTimer(0),
|
||||
curPaletteChoice(0),
|
||||
curPaletteType(0),
|
||||
soloTimeout(0.0f),
|
||||
exportFadeOut(5.0),
|
||||
patExtraButtons(false),
|
||||
|
|
|
@ -606,6 +606,15 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_PANIC,
|
||||
GUI_ACTION_CLEAR,
|
||||
|
||||
GUI_ACTION_COMMAND_PALETTE,
|
||||
GUI_ACTION_CMDPAL_MIN,
|
||||
GUI_ACTION_CMDPAL_RECENT,
|
||||
GUI_ACTION_CMDPAL_INSTRUMENTS,
|
||||
GUI_ACTION_CMDPAL_SAMPLES,
|
||||
GUI_ACTION_CMDPAL_INSTRUMENT_CHANGE,
|
||||
GUI_ACTION_CMDPAL_ADD_CHIP,
|
||||
GUI_ACTION_CMDPAL_MAX,
|
||||
|
||||
GUI_ACTION_WINDOW_EDIT_CONTROLS,
|
||||
GUI_ACTION_WINDOW_ORDERS,
|
||||
GUI_ACTION_WINDOW_INS_LIST,
|
||||
|
@ -1452,7 +1461,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;
|
||||
|
@ -1463,6 +1472,7 @@ class FurnaceGUI {
|
|||
|
||||
std::vector<DivSystem> sysSearchResults;
|
||||
std::vector<FurnaceGUISysDef> newSongSearchResults;
|
||||
std::vector<int> paletteSearchResults;
|
||||
FixedQueue<String,32> recentFile;
|
||||
std::vector<DivInstrumentType> makeInsTypeList;
|
||||
std::vector<FurnaceGUIWaveSizeEntry> waveSizeList;
|
||||
|
@ -1473,7 +1483,7 @@ class FurnaceGUI {
|
|||
bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList;
|
||||
bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed;
|
||||
bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
||||
bool displayNew, displayExport, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange;
|
||||
bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange;
|
||||
bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString;
|
||||
bool mobileEdit;
|
||||
bool killGraphics;
|
||||
|
@ -1991,6 +2001,7 @@ class FurnaceGUI {
|
|||
int loopOrder, loopRow, loopEnd, isClipping, newSongCategory, latchTarget;
|
||||
int wheelX, wheelY, dragSourceX, dragSourceXFine, dragSourceY, dragDestinationX, dragDestinationXFine, dragDestinationY, oldBeat, oldBar;
|
||||
int curGroove, exitDisabledTimer;
|
||||
int curPaletteChoice, curPaletteType;
|
||||
float soloTimeout;
|
||||
|
||||
double exportFadeOut;
|
||||
|
@ -1998,7 +2009,7 @@ class FurnaceGUI {
|
|||
bool patExtraButtons, patChannelNames, patChannelPairs;
|
||||
unsigned char patChannelHints;
|
||||
|
||||
bool newSongFirstFrame, oldRowChanged;
|
||||
bool newSongFirstFrame, paletteFirstFrame, oldRowChanged;
|
||||
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
|
||||
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
|
||||
bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen;
|
||||
|
@ -2510,6 +2521,7 @@ class FurnaceGUI {
|
|||
void drawSettings();
|
||||
void drawDebug();
|
||||
void drawNewSong();
|
||||
void drawPalette();
|
||||
void drawExport();
|
||||
void drawLog();
|
||||
void drawEffectList();
|
||||
|
@ -2615,6 +2627,7 @@ class FurnaceGUI {
|
|||
int save(String path, int dmfVersion);
|
||||
int load(String path);
|
||||
int loadStream(String path);
|
||||
void openRecentFile(String path);
|
||||
void pushRecentFile(String path);
|
||||
void pushRecentSys(const char* path);
|
||||
void exportAudio(String path, DivAudioExportModes mode);
|
||||
|
|
|
@ -559,6 +559,15 @@ 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("CMDPAL_MIN", "", NOT_AN_ACTION),
|
||||
D("CMDPAL_RECENT", "Recent files (Palette)", 0),
|
||||
D("CMDPAL_INSTRUMENTS", "Instruments (Palette)", 0),
|
||||
D("CMDPAL_SAMPLES", "Samples (Palette)", 0),
|
||||
D("CMDPAL_INSTRUMENT_CHANGE", "Change instrument (Palette)", 0),
|
||||
D("CMDPAL_ADD_CHIP", "Add chip (Palette)", 0),
|
||||
D("CMDPAL_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("WINDOW_EDIT_CONTROLS", "Edit Controls", 0),
|
||||
D("WINDOW_ORDERS", "Orders", 0),
|
||||
D("WINDOW_INS_LIST", "Instrument List", 0),
|
||||
|
@ -669,111 +678,111 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("PAT_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("INS_LIST_MIN", "---Instrument list", NOT_AN_ACTION),
|
||||
D("INS_LIST_ADD", "Add", SDLK_INSERT),
|
||||
D("INS_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||
D("INS_LIST_OPEN", "Open", 0),
|
||||
D("INS_LIST_OPEN_REPLACE", "Open (replace current)", 0),
|
||||
D("INS_LIST_SAVE", "Save", 0),
|
||||
D("INS_LIST_SAVE_DMP", "Save (.dmp)", 0),
|
||||
D("INS_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("INS_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("INS_LIST_DELETE", "Delete", 0),
|
||||
D("INS_LIST_EDIT", "Edit", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("INS_LIST_UP", "Cursor up", SDLK_UP),
|
||||
D("INS_LIST_DOWN", "Cursor down", SDLK_DOWN),
|
||||
D("INS_LIST_DIR_VIEW", "Toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("INS_LIST_ADD", "Add instrument", SDLK_INSERT),
|
||||
D("INS_LIST_DUPLICATE", "Duplicate instrument", FURKMOD_CMD|SDLK_d),
|
||||
D("INS_LIST_OPEN", "Open instrument", 0),
|
||||
D("INS_LIST_OPEN_REPLACE", "Open instrument (replace current)", 0),
|
||||
D("INS_LIST_SAVE", "Save instrument", 0),
|
||||
D("INS_LIST_SAVE_DMP", "Save instrument (.dmp)", 0),
|
||||
D("INS_LIST_MOVE_UP", "Move instrument up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("INS_LIST_MOVE_DOWN", "Move instrument down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("INS_LIST_DELETE", "Delete instrument", 0),
|
||||
D("INS_LIST_EDIT", "Edit instrument", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("INS_LIST_UP", "Instrument cursor up", SDLK_UP),
|
||||
D("INS_LIST_DOWN", "Instrument cursor down", SDLK_DOWN),
|
||||
D("INS_LIST_DIR_VIEW", "Instruments: toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("INS_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("WAVE_LIST_MIN", "---Wavetable list", NOT_AN_ACTION),
|
||||
D("WAVE_LIST_ADD", "Add", SDLK_INSERT),
|
||||
D("WAVE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||
D("WAVE_LIST_OPEN", "Open", 0),
|
||||
D("WAVE_LIST_OPEN_REPLACE", "Open (replace current)", 0),
|
||||
D("WAVE_LIST_SAVE", "Save", 0),
|
||||
D("WAVE_LIST_SAVE_DMW", "Save (.dmw)", 0),
|
||||
D("WAVE_LIST_SAVE_RAW", "Save (raw)", 0),
|
||||
D("WAVE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("WAVE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("WAVE_LIST_DELETE", "Delete", 0),
|
||||
D("WAVE_LIST_EDIT", "Edit", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("WAVE_LIST_UP", "Cursor up", SDLK_UP),
|
||||
D("WAVE_LIST_DOWN", "Cursor down", SDLK_DOWN),
|
||||
D("WAVE_LIST_DIR_VIEW", "Toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("WAVE_LIST_ADD", "Add wavetable", SDLK_INSERT),
|
||||
D("WAVE_LIST_DUPLICATE", "Duplicate wavetable", FURKMOD_CMD|SDLK_d),
|
||||
D("WAVE_LIST_OPEN", "Open wavetable", 0),
|
||||
D("WAVE_LIST_OPEN_REPLACE", "Open wavetable (replace current)", 0),
|
||||
D("WAVE_LIST_SAVE", "Save wavetable", 0),
|
||||
D("WAVE_LIST_SAVE_DMW", "Save wavetable (.dmw)", 0),
|
||||
D("WAVE_LIST_SAVE_RAW", "Save wavetable (raw)", 0),
|
||||
D("WAVE_LIST_MOVE_UP", "Move wavetable up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("WAVE_LIST_MOVE_DOWN", "Move wavetable down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("WAVE_LIST_DELETE", "Delete wavetable", 0),
|
||||
D("WAVE_LIST_EDIT", "Edit wavetable", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("WAVE_LIST_UP", "Wavetable cursor up", SDLK_UP),
|
||||
D("WAVE_LIST_DOWN", "Wavetable cursor down", SDLK_DOWN),
|
||||
D("WAVE_LIST_DIR_VIEW", "Wavetables: toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("WAVE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_LIST_MIN", "---Sample list", NOT_AN_ACTION),
|
||||
D("SAMPLE_LIST_ADD", "Add", SDLK_INSERT),
|
||||
D("SAMPLE_LIST_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||
D("SAMPLE_LIST_OPEN", "Open", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE", "Open (replace current)", 0),
|
||||
D("SAMPLE_LIST_OPEN_RAW", "Import raw data", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE_RAW", "Import raw data (replace current)", 0),
|
||||
D("SAMPLE_LIST_SAVE", "Save", 0),
|
||||
D("SAMPLE_LIST_SAVE_RAW", "Save (raw)", 0),
|
||||
D("SAMPLE_LIST_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("SAMPLE_LIST_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("SAMPLE_LIST_DELETE", "Delete", 0),
|
||||
D("SAMPLE_LIST_EDIT", "Edit", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("SAMPLE_LIST_UP", "Cursor up", SDLK_UP),
|
||||
D("SAMPLE_LIST_DOWN", "Cursor down", SDLK_DOWN),
|
||||
D("SAMPLE_LIST_PREVIEW", "Preview", 0),
|
||||
D("SAMPLE_LIST_STOP_PREVIEW", "Stop preview", 0),
|
||||
D("SAMPLE_LIST_DIR_VIEW", "Toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_LIST_MAKE_MAP", "Make me a drum kit", 0),
|
||||
D("SAMPLE_LIST_ADD", "Add sample", SDLK_INSERT),
|
||||
D("SAMPLE_LIST_DUPLICATE", "Duplicate sample", FURKMOD_CMD|SDLK_d),
|
||||
D("SAMPLE_LIST_OPEN", "Open sample", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE", "Open sample (replace current)", 0),
|
||||
D("SAMPLE_LIST_OPEN_RAW", "Import raw sample data", 0),
|
||||
D("SAMPLE_LIST_OPEN_REPLACE_RAW", "Import raw sample data (replace current)", 0),
|
||||
D("SAMPLE_LIST_SAVE", "Save sample", 0),
|
||||
D("SAMPLE_LIST_SAVE_RAW", "Save sample (raw)", 0),
|
||||
D("SAMPLE_LIST_MOVE_UP", "Move sample up in list", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("SAMPLE_LIST_MOVE_DOWN", "Move sample down in list", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("SAMPLE_LIST_DELETE", "Delete sample", 0),
|
||||
D("SAMPLE_LIST_EDIT", "Edit sample", FURKMOD_SHIFT|SDLK_RETURN),
|
||||
D("SAMPLE_LIST_UP", "Sample cursor up", SDLK_UP),
|
||||
D("SAMPLE_LIST_DOWN", "Sample cursor down", SDLK_DOWN),
|
||||
D("SAMPLE_LIST_PREVIEW", "Sample preview", 0),
|
||||
D("SAMPLE_LIST_STOP_PREVIEW", "Stop sample preview", 0),
|
||||
D("SAMPLE_LIST_DIR_VIEW", "Samples: Toggle folders/standard view", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_LIST_MAKE_MAP", "Samples: Make me a drum kit", 0),
|
||||
D("SAMPLE_LIST_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("SAMPLE_MIN", "---Sample editor", NOT_AN_ACTION),
|
||||
D("SAMPLE_SELECT", "Edit mode: Select", FURKMOD_SHIFT|SDLK_i),
|
||||
D("SAMPLE_DRAW", "Edit mode: Draw", FURKMOD_SHIFT|SDLK_d),
|
||||
D("SAMPLE_CUT", "Cut", FURKMOD_CMD|SDLK_x),
|
||||
D("SAMPLE_COPY", "Copy", FURKMOD_CMD|SDLK_c),
|
||||
D("SAMPLE_PASTE", "Paste", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_PASTE_REPLACE", "Paste replace", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("SAMPLE_PASTE_MIX", "Paste mix", FURKMOD_CMD|FURKMOD_ALT|SDLK_v),
|
||||
D("SAMPLE_SELECT_ALL", "Select all", FURKMOD_CMD|SDLK_a),
|
||||
D("SAMPLE_RESIZE", "Resize", FURKMOD_CMD|SDLK_r),
|
||||
D("SAMPLE_RESAMPLE", "Resample", FURKMOD_CMD|SDLK_e),
|
||||
D("SAMPLE_AMPLIFY", "Amplify", FURKMOD_CMD|SDLK_b),
|
||||
D("SAMPLE_NORMALIZE", "Normalize", FURKMOD_CMD|SDLK_n),
|
||||
D("SAMPLE_FADE_IN", "Fade in", FURKMOD_CMD|SDLK_i),
|
||||
D("SAMPLE_FADE_OUT", "Fade out", FURKMOD_CMD|SDLK_o),
|
||||
D("SAMPLE_SILENCE", "Apply silence", FURKMOD_SHIFT|SDLK_DELETE),
|
||||
D("SAMPLE_INSERT", "Insert silence", SDLK_INSERT),
|
||||
D("SAMPLE_DELETE", "Delete", SDLK_DELETE),
|
||||
D("SAMPLE_TRIM", "Trim", FURKMOD_CMD|SDLK_DELETE),
|
||||
D("SAMPLE_REVERSE", "Reverse", FURKMOD_CMD|SDLK_t),
|
||||
D("SAMPLE_INVERT", "Invert", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_t),
|
||||
D("SAMPLE_SIGN", "Signed/unsigned exchange", FURKMOD_CMD|SDLK_u),
|
||||
D("SAMPLE_FILTER", "Apply filter", FURKMOD_CMD|SDLK_f),
|
||||
D("SAMPLE_CROSSFADE_LOOP", "Crossfade loop points", NOT_AN_ACTION),
|
||||
D("SAMPLE_PREVIEW", "Preview sample", 0),
|
||||
D("SAMPLE_STOP_PREVIEW", "Stop sample preview", 0),
|
||||
D("SAMPLE_ZOOM_IN", "Zoom in", FURKMOD_CMD|SDLK_EQUALS),
|
||||
D("SAMPLE_ZOOM_OUT", "Zoom out", FURKMOD_CMD|SDLK_MINUS),
|
||||
D("SAMPLE_ZOOM_AUTO", "Toggle auto-zoom", FURKMOD_CMD|SDLK_0),
|
||||
D("SAMPLE_MAKE_INS", "Create instrument from sample", 0),
|
||||
D("SAMPLE_SET_LOOP", "Set loop to selection", FURKMOD_CMD|SDLK_l),
|
||||
D("SAMPLE_CREATE_WAVE", "Create wavetable from selection", FURKMOD_CMD|SDLK_w),
|
||||
D("SAMPLE_SELECT", "Sample editor mode: Select", FURKMOD_SHIFT|SDLK_i),
|
||||
D("SAMPLE_DRAW", "Sample editor mode: Draw", FURKMOD_SHIFT|SDLK_d),
|
||||
D("SAMPLE_CUT", "Sample editor: Cut", FURKMOD_CMD|SDLK_x),
|
||||
D("SAMPLE_COPY", "Sample editor: Copy", FURKMOD_CMD|SDLK_c),
|
||||
D("SAMPLE_PASTE", "Sample editor: Paste", FURKMOD_CMD|SDLK_v),
|
||||
D("SAMPLE_PASTE_REPLACE", "Sample editor: Paste replace", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_v),
|
||||
D("SAMPLE_PASTE_MIX", "Sample editor: Paste mix", FURKMOD_CMD|FURKMOD_ALT|SDLK_v),
|
||||
D("SAMPLE_SELECT_ALL", "Sample editor: Select all", FURKMOD_CMD|SDLK_a),
|
||||
D("SAMPLE_RESIZE", "Sample editor: Resize", FURKMOD_CMD|SDLK_r),
|
||||
D("SAMPLE_RESAMPLE", "Sample editor: Resample", FURKMOD_CMD|SDLK_e),
|
||||
D("SAMPLE_AMPLIFY", "Sample editor: Amplify", FURKMOD_CMD|SDLK_b),
|
||||
D("SAMPLE_NORMALIZE", "Sample editor: Normalize", FURKMOD_CMD|SDLK_n),
|
||||
D("SAMPLE_FADE_IN", "Sample editor: Fade in", FURKMOD_CMD|SDLK_i),
|
||||
D("SAMPLE_FADE_OUT", "Sample editor: Fade out", FURKMOD_CMD|SDLK_o),
|
||||
D("SAMPLE_SILENCE", "Sample editor: Apply silence", FURKMOD_SHIFT|SDLK_DELETE),
|
||||
D("SAMPLE_INSERT", "Sample editor: Insert silence", SDLK_INSERT),
|
||||
D("SAMPLE_DELETE", "Sample editor: Delete", SDLK_DELETE),
|
||||
D("SAMPLE_TRIM", "Sample editor: Trim", FURKMOD_CMD|SDLK_DELETE),
|
||||
D("SAMPLE_REVERSE", "Sample editor: Reverse", FURKMOD_CMD|SDLK_t),
|
||||
D("SAMPLE_INVERT", "Sample editor: Invert", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_t),
|
||||
D("SAMPLE_SIGN", "Sample editor: Signed/unsigned exchange", FURKMOD_CMD|SDLK_u),
|
||||
D("SAMPLE_FILTER", "Sample editor: Apply filter", FURKMOD_CMD|SDLK_f),
|
||||
D("SAMPLE_CROSSFADE_LOOP", "Sample editor: Crossfade loop points", NOT_AN_ACTION),
|
||||
D("SAMPLE_PREVIEW", "Sample editor: Preview sample", 0),
|
||||
D("SAMPLE_STOP_PREVIEW", "Sample editor: Stop sample preview", 0),
|
||||
D("SAMPLE_ZOOM_IN", "Sample editor: Zoom in", FURKMOD_CMD|SDLK_EQUALS),
|
||||
D("SAMPLE_ZOOM_OUT", "Sample editor: Zoom out", FURKMOD_CMD|SDLK_MINUS),
|
||||
D("SAMPLE_ZOOM_AUTO", "Sample editor: Toggle auto-zoom", FURKMOD_CMD|SDLK_0),
|
||||
D("SAMPLE_MAKE_INS", "Sample editor: Create instrument from sample", 0),
|
||||
D("SAMPLE_SET_LOOP", "Sample editor: Set loop to selection", FURKMOD_CMD|SDLK_l),
|
||||
D("SAMPLE_CREATE_WAVE", "Sample editor: Create wavetable from selection", FURKMOD_CMD|SDLK_w),
|
||||
D("SAMPLE_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("ORDERS_MIN", "---Orders", NOT_AN_ACTION),
|
||||
D("ORDERS_UP", "Previous order", SDLK_UP),
|
||||
D("ORDERS_DOWN", "Next order", SDLK_DOWN),
|
||||
D("ORDERS_LEFT", "Cursor left", SDLK_LEFT),
|
||||
D("ORDERS_RIGHT", "Cursor right", SDLK_RIGHT),
|
||||
D("ORDERS_INCREASE", "Increase value", 0),
|
||||
D("ORDERS_DECREASE", "Decrease value", 0),
|
||||
D("ORDERS_EDIT_MODE", "Switch edit mode", 0),
|
||||
D("ORDERS_LINK", "Toggle alter entire row", FURKMOD_CMD|SDLK_l),
|
||||
D("ORDERS_ADD", "Add", SDLK_INSERT),
|
||||
D("ORDERS_DUPLICATE", "Duplicate", FURKMOD_CMD|SDLK_d),
|
||||
D("ORDERS_DEEP_CLONE", "Deep clone", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("ORDERS_DUPLICATE_END", "Duplicate to end of song", FURKMOD_CMD|SDLK_e),
|
||||
D("ORDERS_DEEP_CLONE_END", "Deep clone to end of song", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_e),
|
||||
D("ORDERS_REMOVE", "Remove", SDLK_DELETE),
|
||||
D("ORDERS_MOVE_UP", "Move up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("ORDERS_MOVE_DOWN", "Move down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("ORDERS_REPLAY", "Replay", 0),
|
||||
D("ORDERS_LEFT", "Order cursor left", SDLK_LEFT),
|
||||
D("ORDERS_RIGHT", "Order cursor right", SDLK_RIGHT),
|
||||
D("ORDERS_INCREASE", "Increase order value", 0),
|
||||
D("ORDERS_DECREASE", "Decrease order value", 0),
|
||||
D("ORDERS_EDIT_MODE", "Switch order edit mode", 0),
|
||||
D("ORDERS_LINK", "Order: toggle alter entire row", FURKMOD_CMD|SDLK_l),
|
||||
D("ORDERS_ADD", "Add order", SDLK_INSERT),
|
||||
D("ORDERS_DUPLICATE", "Duplicate order", FURKMOD_CMD|SDLK_d),
|
||||
D("ORDERS_DEEP_CLONE", "Deep clone order", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_d),
|
||||
D("ORDERS_DUPLICATE_END", "Duplicate order to end of song", FURKMOD_CMD|SDLK_e),
|
||||
D("ORDERS_DEEP_CLONE_END", "Deep clone order to end of song", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_e),
|
||||
D("ORDERS_REMOVE", "Remove order", SDLK_DELETE),
|
||||
D("ORDERS_MOVE_UP", "Move order up", FURKMOD_SHIFT|SDLK_UP),
|
||||
D("ORDERS_MOVE_DOWN", "Move order down", FURKMOD_SHIFT|SDLK_DOWN),
|
||||
D("ORDERS_REPLAY", "Replay order", 0),
|
||||
D("ORDERS_MAX", "", NOT_AN_ACTION),
|
||||
};
|
||||
#undef D
|
||||
|
|
|
@ -1745,6 +1745,11 @@ void FurnaceGUI::drawSettings() {
|
|||
UI_KEYBIND_CONFIG(GUI_ACTION_COLLAPSE_WINDOW);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_CLOSE_WINDOW);
|
||||
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_COMMAND_PALETTE);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_CMDPAL_RECENT);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_CMDPAL_INSTRUMENTS);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_CMDPAL_SAMPLES);
|
||||
|
||||
KEYBIND_CONFIG_END;
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue