openMSX
ImGuiManager.hh
Go to the documentation of this file.
1#ifndef IMGUI_MANAGER_HH
2#define IMGUI_MANAGER_HH
3
5#include "ImGuiUtils.hh"
6#include "Shortcuts.hh"
7
8#include "EmuTime.hh"
9#include "EventListener.hh"
10#include "FilenameSetting.hh"
11#include "IntegerSetting.hh"
12#include "Reactor.hh"
13#include "RomTypes.hh"
14#include "TclObject.hh"
15
16#include "Observer.hh"
17#include "strCat.hh"
18#include "StringReplacer.hh"
19
20#include <functional>
21#include <optional>
22#include <string_view>
23#include <vector>
24
25struct ImFont;
26struct ImGuiTextBuffer;
27
28namespace openmsx {
29
30class CliComm;
31class ImGuiBreakPoints;
32class ImGuiCheatFinder;
33class ImGuiConnector;
34class ImGuiConsole;
35class ImGuiDebugger;
36class ImGuiDiskManipulator;
37class ImGuiHelp;
38class ImGuiKeyboard;
39class ImGuiMachine;
40class ImGuiMedia;
41class ImGuiMessages;
42class ImGuiOpenFile;
43class ImGuiOsdIcons;
44class ImGuiPalette;
45class ImGuiReverseBar;
46class ImGuiSCCViewer;
47class ImGuiSettings;
48class ImGuiSoundChip;
49class ImGuiSymbols;
50class ImGuiTools;
51class ImGuiTrainer;
52class ImGuiVdpRegs;
53class ImGuiWatchExpr;
54class ImGuiWaveViewer;
55class RomInfo;
56class SettingsConfig;
57
58class ImGuiManager final : public ImGuiPartInterface, private EventListener, private Observer<Setting>
59{
60public:
61 explicit ImGuiManager(Reactor& reactor_);
62 ImGuiManager(const ImGuiManager&) = delete;
67
70
71 [[nodiscard]] Reactor& getReactor() { return reactor; }
72 [[nodiscard]] Shortcuts& getShortcuts() { return reactor.getShortcuts(); }
73 [[nodiscard]] Interpreter& getInterpreter();
74 [[nodiscard]] CliComm& getCliComm();
75 std::optional<TclObject> execute(TclObject command);
76 void executeDelayed(std::function<void()> action);
77 void executeDelayed(TclObject command,
78 const std::function<void(const TclObject&)>& ok,
79 const std::function<void(const std::string&)>& error);
80 void executeDelayed(TclObject command,
81 const std::function<void(const TclObject&)>& ok = {});
82
83 void printError(std::string_view message);
84 template<typename... Ts> void printError(Ts&&... ts) {
85 printError(static_cast<std::string_view>(tmpStrCat(std::forward<Ts>(ts)...)));
86 }
87
88 void preNewFrame();
89 void paintImGui();
90
91 void storeWindowPosition(gl::ivec2 pos) { windowPos = pos; }
92 [[nodiscard]] gl::ivec2 retrieveWindowPosition() const { return windowPos; }
93
95
96private:
97 void initializeImGui();
98 [[nodiscard]] ImFont* addFont(zstring_view filename, int fontSize);
99 void loadFont();
100 void reloadFont();
101 void drawStatusBar(MSXMotherBoard* motherBoard);
102
103 // ImGuiPartInterface
104 [[nodiscard]] zstring_view iniName() const override { return "manager"; }
105 void save(ImGuiTextBuffer& buf) override;
106 void loadLine(std::string_view name, zstring_view value) override;
107 void loadEnd() override;
108
109 // EventListener
110 bool signalEvent(const Event& event) override;
111
112 // Observer<Setting>
113 void update(const Setting& setting) noexcept override;
114
115 // ini handler callbacks
116 void iniReadInit();
117 void* iniReadOpen(std::string_view name);
118 void loadLine(void* entry, const char* line) const;
119 void iniApplyAll();
120 void iniWriteAll(ImGuiTextBuffer& buf);
121
122 void updateParts();
123
124private:
125 Reactor& reactor;
126 std::vector<ImGuiPartInterface*> parts;
127 std::vector<ImGuiPartInterface*> toBeAddedParts;
128 bool removeParts = false;
129
130public:
135 ImFont* fontProp = nullptr;
136 ImFont* fontMono = nullptr;
137
138 std::unique_ptr<ImGuiMachine> machine;
139 std::unique_ptr<ImGuiDebugger> debugger;
140 std::unique_ptr<ImGuiBreakPoints> breakPoints;
141 std::unique_ptr<ImGuiSymbols> symbols;
142 std::unique_ptr<ImGuiWatchExpr> watchExpr;
143 std::unique_ptr<ImGuiVdpRegs> vdpRegs;
144 std::unique_ptr<ImGuiPalette> palette;
145 std::unique_ptr<ImGuiReverseBar> reverseBar;
146 std::unique_ptr<ImGuiHelp> help;
147 std::unique_ptr<ImGuiOsdIcons> osdIcons;
148 std::unique_ptr<ImGuiOpenFile> openFile;
149 std::unique_ptr<ImGuiMedia> media;
150 std::unique_ptr<ImGuiConnector> connector;
151 std::unique_ptr<ImGuiTools> tools;
152 std::unique_ptr<ImGuiTrainer> trainer;
153 std::unique_ptr<ImGuiSCCViewer> sccViewer;
154 std::unique_ptr<ImGuiWaveViewer> waveViewer;
155 std::unique_ptr<ImGuiCheatFinder> cheatFinder;
156 std::unique_ptr<ImGuiDiskManipulator> diskManipulator;
157 std::unique_ptr<ImGuiSettings> settings;
158 std::unique_ptr<ImGuiSoundChip> soundChip;
159 std::unique_ptr<ImGuiKeyboard> keyboard;
160 std::unique_ptr<ImGuiConsole> console;
161 std::unique_ptr<ImGuiMessages> messages;
162
163 bool menuFade = true;
164 bool needReloadFont = false;
165 bool statusBarVisible = false;
172
173 std::string loadIniFile;
174
175private:
176 std::vector<std::function<void()>> delayedActionQueue;
177 float menuAlpha = 1.0f;
178
179 std::string droppedFile;
180 std::string insertedInfo;
181 std::vector<std::string> selectList;
182 std::string selectedMedia;
183 const RomInfo* romInfo = nullptr;
184 RomType selectedRomType = RomType::UNKNOWN;
185 float insertedInfoTimeout = 0.0f;
186 gl::ivec2 windowPos;
187 bool mainMenuBarUndocked = false;
188 bool handleDropped = false;
189 bool openInsertedInfo = false;
190 bool guiActive = false;
191
192 EmuTime prevBoardTime = EmuTime::zero();
193 float speedDrawTimeOut = 0.0f;
194 float fpsDrawTimeOut = 0.0f;
195 float fps = 0.0f;
196 float speed = 0.0f;
197
198 static constexpr auto persistentElements = std::tuple{
199 PersistentElement{"mainMenuBarUndocked", &ImGuiManager::mainMenuBarUndocked},
200 PersistentElement{"mainMenuBarFade", &ImGuiManager::menuFade},
201 PersistentElement{"windowPos", &ImGuiManager::windowPos},
203 PersistentElement{"statusBarItemvisibility.fps", &ImGuiManager::statusBarItemVisibilityFps},
204 PersistentElement{"statusBarItemVisibility.screenModeInfo", &ImGuiManager::statusBarItemVisibilityScreenModeInfo},
205 PersistentElement{"statusBarItemVisibility.time", &ImGuiManager::statusBarItemVisibilityTime},
206 PersistentElement{"statusBarItemVisibility.actualSpeed", &ImGuiManager::statusBarItemVisibilityActualSpeed},
207 PersistentElement{"statusBarItemVisibility.machine", &ImGuiManager::statusBarItemVisibilityMachine},
208 PersistentElement{"statusBarItemVisibility.runningSoftware", &ImGuiManager::statusBarItemVisibilityRunningSoftware},
209 };
210};
211
212// Parse machine or extension config files:
213// store config-name, display-name and meta-data
214template<typename InfoType>
215std::vector<InfoType> parseAllConfigFiles(ImGuiManager& manager, std::string_view type, std::initializer_list<std::string_view> topics)
216{
217 static constexpr auto replacer = StringReplacer::create(
218 "name", "Name",
219 "manufacturer", "Manufacturer",
220 "code", "Product code",
221 "region", "Region",
222 "release_year", "Release year",
223 "description", "Description",
224 "type", "Type");
225
226 std::vector<InfoType> result;
227
228 const auto& configs = Reactor::getHwConfigs(type);
229 result.reserve(configs.size());
230 for (const auto& config : configs) {
231 auto& info = result.emplace_back();
232 info.configName = config;
233
234 // get machine meta-data
235 auto& configInfo = info.configInfo;
236 if (auto r = manager.execute(makeTclList("openmsx_info", type, config))) {
237 auto first = r->begin();
238 auto last = r->end();
239 while (first != last) {
240 auto desc = *first++;
241 if (first == last) break; // shouldn't happen
242 auto value = *first++;
243 if (!value.empty()) {
244 configInfo.emplace_back(std::string(replacer(desc)),
245 std::string(value));
246 }
247 }
248 }
249
250 // Based on the above meta-data, try to construct a more
251 // readable name Unfortunately this new name is no
252 // longer guaranteed to be unique, we'll address this
253 // below.
254 auto& display = info.displayName;
255 for (const auto topic : topics) {
256 if (const auto* value = getOptionalDictValue(configInfo, topic)) {
257 if (!value->empty()) {
258 if (!display.empty()) strAppend(display, ' ');
259 strAppend(display, *value);
260 }
261 }
262 }
263 if (display.empty()) display = config;
264 }
265
266 ranges::sort(result, StringOp::caseless{}, &InfoType::displayName);
267
268 // make 'displayName' unique again
269 auto sameDisplayName = [](InfoType& x, InfoType& y) {
271 return cmp(x.displayName, y.displayName);
272 };
273 chunk_by(result, sameDisplayName, [](auto first, auto last) {
274 if (std::distance(first, last) == 1) return; // no duplicate name
275 for (auto it = first; it != last; ++it) {
276 strAppend(it->displayName, " (", it->configName, ')');
277 }
278 ranges::sort(first, last, StringOp::caseless{}, &InfoType::displayName);
279 });
280
281 return result;
282}
283
284} // namespace openmsx
285
286#endif
BaseSetting * setting
ImGuiManager & operator=(const ImGuiManager &)=delete
std::unique_ptr< ImGuiMachine > machine
void registerPart(ImGuiPartInterface *part)
std::unique_ptr< ImGuiBreakPoints > breakPoints
void printError(std::string_view message)
std::unique_ptr< ImGuiVdpRegs > vdpRegs
std::unique_ptr< ImGuiCheatFinder > cheatFinder
std::unique_ptr< ImGuiTrainer > trainer
std::unique_ptr< ImGuiDiskManipulator > diskManipulator
IntegerSetting fontMonoSize
std::unique_ptr< ImGuiWatchExpr > watchExpr
std::unique_ptr< ImGuiPalette > palette
std::unique_ptr< ImGuiWaveViewer > waveViewer
std::unique_ptr< ImGuiConnector > connector
std::optional< TclObject > execute(TclObject command)
std::unique_ptr< ImGuiKeyboard > keyboard
bool statusBarItemVisibilityScreenModeInfo
std::unique_ptr< ImGuiHelp > help
IntegerSetting fontPropSize
bool statusBarItemVisibilityRunningSoftware
Interpreter & getInterpreter()
void storeWindowPosition(gl::ivec2 pos)
ImGuiManager(const ImGuiManager &)=delete
ImGuiManager(ImGuiManager &&)=delete
void configStatusBarVisibilityItems()
ImGuiManager & operator=(ImGuiManager &&)=delete
Shortcuts & getShortcuts()
std::unique_ptr< ImGuiConsole > console
std::unique_ptr< ImGuiSoundChip > soundChip
std::unique_ptr< ImGuiReverseBar > reverseBar
std::unique_ptr< ImGuiMedia > media
gl::ivec2 retrieveWindowPosition() const
std::unique_ptr< ImGuiMessages > messages
std::unique_ptr< ImGuiOpenFile > openFile
std::unique_ptr< ImGuiOsdIcons > osdIcons
FilenameSetting fontPropFilename
std::unique_ptr< ImGuiSettings > settings
std::unique_ptr< ImGuiDebugger > debugger
std::unique_ptr< ImGuiSCCViewer > sccViewer
void unregisterPart(ImGuiPartInterface *part)
std::unique_ptr< ImGuiTools > tools
void executeDelayed(std::function< void()> action)
FilenameSetting fontMonoFilename
void printError(Ts &&... ts)
std::unique_ptr< ImGuiSymbols > symbols
A Setting with an integer value.
Generic Gang-of-Four Observer class, templatized edition.
Definition Observer.hh:10
Contains the main loop of openMSX.
Definition Reactor.hh:75
Shortcuts & getShortcuts()
Definition Reactor.hh:87
static std::vector< std::string > getHwConfigs(std::string_view type)
Definition Reactor.cc:348
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr auto create(Args ...args)
This file implemented 3 utility functions:
Definition Autofire.cc:11
PersistentElement(zstring_view, T C::*) -> PersistentElement< C, T >
const std::string * getOptionalDictValue(const std::vector< std::pair< std::string, std::string > > &info, std::string_view key)
std::vector< InfoType > parseAllConfigFiles(ImGuiManager &manager, std::string_view type, std::initializer_list< std::string_view > topics)
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event
Definition Event.hh:445
TclObject makeTclList(Args &&... args)
Definition TclObject.hh:293
constexpr void sort(RandomAccessRange &&range)
Definition ranges.hh:51
TemporaryString tmpStrCat(Ts &&... ts)
Definition strCat.hh:742
void strAppend(std::string &result, Ts &&...ts)
Definition strCat.hh:752