-
Notifications
You must be signed in to change notification settings - Fork 214
Developer information and guides
Eknous edited this page Oct 31, 2024
·
2 revisions
(note: this page is a work in progress!)
Adding a UI window
Files to modify:
CMakeLists.txt
src/gui/doAction.cpp
src/gui/gui.cpp
src/gui/gui.h
src/gui/guiConst.cpp
- create a C++ source file in
src/gui/
for your window (e.g.src/gui/myWindow.cpp
) - add that file to the CMakeLists (starting from line 889, in alphabetical order with the other windows)
...
src/gui/mixer.cpp
src/gui/midiMap.cpp
+ src/gui/myWindow.cpp
src/gui/newSong.cpp
...
-
in
src/gui/gui.h
:- add an entry for your window in the
FurnaceGUIWindows
enum (at the end, beforeGUI_WINDOW_SPOILER
)
... GUI_WINDOW_CS_PLAYER, GUI_WINDOW_USER_PRESETS, + GUI_WINDOW_MY_WINDOW, GUI_WINDOW_SPOILER }; ...
- add an entry for your window in the
FurnaceGUIActions
enum (lastGUI_ACTION_WINDOW_*
, beforeGUI_ACTION_COLLAPSE_WINDOW
)
... GUI_ACTION_WINDOW_CS_PLAYER, GUI_ACTION_WINDOW_USER_PRESETS, + GUI_ACTION_WINDOW_MY_WINDOW, GUI_ACTION_COLLAPSE_WINDOW, ...
- add a boolean for the window open state in the
FuranceGUI
class (last*Open
)
... bool subSongsOpen, findOpen, spoilerOpen, patManagerOpen, sysManagerOpen, clockOpen, speedOpen; - bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen, cvOpen, userPresetsOpen; + bool groovesOpen, xyOscOpen, memoryOpen, csPlayerOpen, cvOpen, userPresetsOpen, myWindowOpen; ...
- add the function declaration for drawing your window in the
FurnaceGUI
class (lastvoid draw*()
, beforevoid drawSystemChannelInfo(const DivSysDef* whichDef);
)
... void drawXYOsc(); void drawUserPresets(); + void drawMyWindow(); void drawSystemChannelInfo(const DivSysDef* whichDef); ...
- add an entry for your window in the
-
in
src/gui/doAction.cpp
:- add the case for your window's action in the switch in the
doAction(int what)
function (lastcase GUI_ACTION_WINDOW_*
, beforecase GUI_ACTION_COLLAPSE_WINDOW
)
... case GUI_ACTION_WINDOW_USER_PRESETS: nextWindow=GUI_WINDOW_USER_PRESETS; break; + case GUI_ACTION_WINDOW_MY_WINDOW: + nextWindow=GUI_WINDOW_MY_WINDOW; + break; case GUI_ACTION_COLLAPSE_WINDOW: ...
- add the case for the action of closing your window in the same function but in the nested switch for the
GUI_ACTION_CLOSE_WINDOW
case (lastcase GUI_WINDOW_*
, beforedefault:
)
... case GUI_ACTION_CLOSE_WINDOW: switch (curWindow) { ... case GUI_WINDOW_USER_PRESETS: userPresetsOpen=false; + case GUI_WINDOW_MY_WINDOW: + myWindowOpen=false; default: ...
- add the case for your window's action in the switch in the
-
in
src/gui/guiConst.cpp
add the action definition for your window in theguiAction[GUI_ACTION_MAX]
array (lastD("WINDOW_*
, beforeD("COLLAPSE_WINDOW...
)... D("WINDOW_USER_PRESETS", _N("User Presets"), 0), + D("WINDOW_MY_WINDOW", _N("My Window"), 0), D("COLLAPSE_WINDOW", _N("Collapse/expand current window"), 0), ...
-
in
src/gui/gui.cpp
:- declare your window's metric in the
loop()
function (lastDECLARE_METRIC(*)
, beforeDECLARE_METRIC(popup)
)
... DECLARE_METRIC(userPresets) + DECLARE_METRIC(myWindow) DECLARE_METRIC(popup) ...
- add the
IMPORT_CLOSE
for your window in theif (pendingLayoutImportStep==0) {
statement (lastIMPORT_CLOSE(*)
)
... IMPORT_CLOSE(csPlayerOpen); IMPORT_CLOSE(userPresetsOpen); + IMPORT_CLOSE(myWindowOpen); } else if (pendingLayoutImportStep==1) { ...
- add the menu item for your window
notes:- depending on the type of your window, this may be optional, even unnecessary
- the location of the menu item also may depend on your window type. for this guide the entry is added at the end, in the "window" menu, not belonging to any category)
... if (ImGui::MenuItem(_("piano/input pad"),BIND_FOR(GUI_ACTION_WINDOW_PIANO),pianoOpen)) pianoOpen=!pianoOpen; + if (ImGui::MenuItem(_("my window"),BIND_FOR(GUI_ACTION_MY_WINDOW),myWindowOpen)) myWindowOpen=!myWindowOpen; if (spoilerOpen) if (ImGui::MenuItem(_("spoiler"),NULL,spoilerOpen)) spoilerOpen=!spoilerOpen; ...
- add the metric measurement macros for your window (last
MEASURE(*)
)
note for mobile ui:- if your window belongs to a scene, the
MEASURE(...)
statement should be inside the case for that scene. for this guide, it does not
- if your window belongs to a scene, the
... if (mobileUI) { ... MEASURE(userPresets,drawUserPresets()); MEASURE(patManager,drawPatManager()); + MEASURE(myWindow,drawMyWindow()); ...
... } else { ... MEASURE(effectList,drawEffectList()); MEASURE(userPresets,drawUserPresets()); + MEASURE(myWindow,drawMyWindow()); ...
- get the state of your window from the config (last
*Open=e->getConfBool("*Open",false);
... spoilerOpen=e->getConfBool("spoilerOpen",false); userPresetsOpen=e->getConfBool("userPresetsOpen",false); + myWindowOpen=e->getConfBool("myWindowOpen",false); ...
- set the state of your window in the config (last
conf.set("*Open",*Open);
)
... conf.set("spoilerOpen",spoilerOpen); conf.set("userPresetsOpen",userPresetsOpen); + conf.set("myWindowOpen",myWindowOpen); ...
- initialize the bool for your window state in the class constructor (last
*Open(...)
)
... cvOpen(false), userPresetsOpen(false), + myWindowOpen(false), ...
- declare your window's metric in the
-
in
src/gui/myWindow.cpp
:- add this template code for a generic Furnace window
/** * 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 "imgui.h" void FurnaceGUI::drawMyWindow() { if (nextWindow==GUI_WINDOW_MY_WINDOW) { myWindowOpen=true; ImGui::SetNextWindowFocus(); nextWindow=GUI_WINDOW_NOTHING; } if (!myWindowOpen) return; if (ImGui::Begin("My Window",&myWindowOpen,globalWinFlags,_("My Window"))) { // your window code here } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_MY_WINDOW; ImGui::End(); }
- modify it to add your stuff!