diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c8d3939..b47d2a74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -553,6 +553,7 @@ src/gui/subSongs.cpp src/gui/sysConf.cpp src/gui/sysEx.cpp src/gui/sysManager.cpp +src/gui/sysPicker.cpp src/gui/util.cpp src/gui/waveEdit.cpp src/gui/volMeter.cpp diff --git a/src/engine/engine.h b/src/engine/engine.h index 3e75bef6..ccfed7c3 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -627,6 +627,9 @@ class DivEngine { // get japanese system name const char* getSystemNameJ(DivSystem sys); + // get sys definition + const DivSysDef* getSystemDef(DivSystem sys); + // convert sample rate format int fileToDivRate(int frate); int divToFileRate(int drate); diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 0487873b..6dc3a8a4 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -284,6 +284,10 @@ const char* DivEngine::getSystemNameJ(DivSystem sys) { */ } +const DivSysDef* DivEngine::getSystemDef(DivSystem sys) { + return sysDefs[sys]; +} + bool DivEngine::isFMSystem(DivSystem sys) { if (sysDefs[sys]==NULL) return false; return sysDefs[sys]->isFM; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index fb127648..09ecad39 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1941,20 +1941,6 @@ void FurnaceGUI::processDrags(int dragX, int dragY) { } } -#define sysAddOption(x) \ - if (ImGui::MenuItem(getSystemName(x))) { \ - if (!e->addSystem(x)) { \ - showError("cannot add chip! ("+e->getLastError()+")"); \ - } \ - updateWindowTitle(); \ - } - -#define sysChangeOption(x,y) \ - if (ImGui::MenuItem(getSystemName(y),NULL,e->song.system[x]==y)) { \ - e->changeSystem(x,y,preserveChanPos); \ - updateWindowTitle(); \ - } - #define checkExtension(x) \ String lowerCase=fileName; \ for (char& i: lowerCase) { \ @@ -3051,9 +3037,12 @@ bool FurnaceGUI::loop() { } ImGui::Separator(); if (ImGui::BeginMenu("add chip...")) { - for (int j=0; availableSystems[j]; j++) { - if (!settings.hiddenSystems && (availableSystems[j]==DIV_SYSTEM_YMU759 || availableSystems[j]==DIV_SYSTEM_DUMMY)) continue; - sysAddOption((DivSystem)availableSystems[j]); + DivSystem picked=systemPicker(); + if (picked!=DIV_SYSTEM_NULL) { + if (!e->addSystem(picked)) { + showError("cannot add chip! ("+e->getLastError()+")"); + } + updateWindowTitle(); } ImGui::EndMenu(); } @@ -3070,9 +3059,10 @@ bool FurnaceGUI::loop() { ImGui::Checkbox("Preserve channel positions",&preserveChanPos); for (int i=0; isong.systemLen; i++) { if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) { - for (int j=0; availableSystems[j]; j++) { - if (!settings.hiddenSystems && (availableSystems[j]==DIV_SYSTEM_YMU759 || availableSystems[j]==DIV_SYSTEM_DUMMY)) continue; - sysChangeOption(i,(DivSystem)availableSystems[j]); + DivSystem picked=systemPicker(); + if (picked!=DIV_SYSTEM_NULL) { + e->changeSystem(i,picked,preserveChanPos); + updateWindowTitle(); } ImGui::EndMenu(); } diff --git a/src/gui/gui.h b/src/gui/gui.h index a93e59a9..283edc82 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -969,13 +969,15 @@ class FurnaceGUI { int sampleTexW, sampleTexH; bool updateSampleTex; - String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile; + String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery; String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport; String workingDirVGMExport, workingDirROMExport, workingDirFont, workingDirColors, workingDirKeybinds; String workingDirLayout, workingDirROM, workingDirTest; String mmlString[32]; String mmlStringW; + std::vector sysSearchResults; + bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, vgmExportPatternHints; bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu; bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly; @@ -1666,6 +1668,8 @@ class FurnaceGUI { void doReplace(); void doDrag(); void editOptions(bool topMenu); + DivSystem systemPicker(); + bool systemPickerOption(DivSystem sys); void noteInput(int num, int key, int vol=-1); void valueInput(int num, bool direct=false, int target=-1); diff --git a/src/gui/sysManager.cpp b/src/gui/sysManager.cpp index 619345ba..bab348e3 100644 --- a/src/gui/sysManager.cpp +++ b/src/gui/sysManager.cpp @@ -78,6 +78,14 @@ void FurnaceGUI::drawSysManager() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Change"); } + if (ImGui::BeginPopupContextItem("SysPickerC",ImGuiPopupFlags_MouseButtonLeft)) { + DivSystem picked=systemPicker(); + if (picked!=DIV_SYSTEM_NULL) { + e->changeSystem(i,picked,preserveChanPos); + updateWindowTitle(); + } + ImGui::EndPopup(); + } ImGui::SameLine(); ImGui::BeginDisabled(e->song.systemLen<=1); if (ImGui::Button(ICON_FA_TIMES "##SysRemove")) { @@ -95,6 +103,16 @@ void FurnaceGUI::drawSysManager() { ImGui::TableNextColumn(); ImGui::TableNextColumn(); ImGui::Button(ICON_FA_PLUS "##SysAdd"); + if (ImGui::BeginPopupContextItem("SysPickerA",ImGuiPopupFlags_MouseButtonLeft)) { + DivSystem picked=systemPicker(); + if (picked!=DIV_SYSTEM_NULL) { + if (!e->addSystem(picked)) { + showError("cannot add chip! ("+e->getLastError()+")"); + } + updateWindowTitle(); + } + ImGui::EndPopup(); + } } ImGui::EndTable(); } diff --git a/src/gui/sysPicker.cpp b/src/gui/sysPicker.cpp new file mode 100644 index 00000000..bcfc95ae --- /dev/null +++ b/src/gui/sysPicker.cpp @@ -0,0 +1,74 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2022 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 "misc/cpp/imgui_stdlib.h" +#include "IconsFontAwesome4.h" +#include "guiConst.h" +#include + +bool FurnaceGUI::systemPickerOption(DivSystem sys) { + const DivSysDef* sysDef=e->getSystemDef(sys); + if (sysDef==NULL) return false; + bool ret=ImGui::Selectable(sysDef->name); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::TextUnformatted(sysDef->description); + ImGui::EndTooltip(); + } + return ret; +} + +DivSystem FurnaceGUI::systemPicker() { + DivSystem ret=DIV_SYSTEM_NULL; + /* + for (int j=0; availableSystems[j]; j++) { + if (!settings.hiddenSystems && (availableSystems[j]==DIV_SYSTEM_YMU759 || availableSystems[j]==DIV_SYSTEM_DUMMY)) continue; + sysAddOption((DivSystem)availableSystems[j]); + } + */ + if (ImGui::InputTextWithHint("##SysSearch","Search...",&sysSearchQuery)) { + String lowerCase=sysSearchQuery; + for (char& i: lowerCase) { + if (i>='A' && i<='Z') i+='a'-'A'; + } + sysSearchResults.clear(); + for (int j=0; availableSystems[j]; j++) { + String lowerCase1=e->getSystemName((DivSystem)availableSystems[j]); + for (char& i: lowerCase1) { + if (i>='A' && i<='Z') i+='a'-'A'; + } + if (lowerCase1.find(lowerCase)!=String::npos) { + sysSearchResults.push_back((DivSystem)availableSystems[j]); + } + } + } + if (sysSearchQuery.empty()) { + // display chip list + for (int j=0; availableSystems[j]; j++) { + if (systemPickerOption((DivSystem)availableSystems[j])) ret=(DivSystem)availableSystems[j]; + } + } else { + // display search results + for (DivSystem i: sysSearchResults) { + if (systemPickerOption(i)) ret=i; + } + } + return ret; +} \ No newline at end of file