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
7#include "EventListener.hh"
8#include "FilenameSetting.hh"
9#include "IntegerSetting.hh"
10#include "Reactor.hh"
11#include "RomTypes.hh"
12#include "TclObject.hh"
13
14#include "Observer.hh"
15#include "strCat.hh"
16#include "StringReplacer.hh"
17
18#include <functional>
19#include <optional>
20#include <string_view>
21#include <vector>
22
23struct ImFont;
24struct ImGuiTextBuffer;
25
26namespace openmsx {
27
28class CliComm;
29class ImGuiBitmapViewer;
30class ImGuiBreakPoints;
31class ImGuiCharacter;
32class ImGuiCheatFinder;
33class ImGuiConnector;
34class ImGuiConsole;
35class ImGuiDebugger;
36class ImGuiDiskManipulator;
37class ImGuiHelp;
38class ImGuiKeyboard;
39class ImGuiMachine;
40class ImGuiMedia;
41class ImGuiMessages;
42class ImGuiOpenFile;
43class ImGuiPalette;
44class ImGuiOsdIcons;
45class ImGuiReverseBar;
46class ImGuiSettings;
47class ImGuiSoundChip;
48class ImGuiSpriteViewer;
49class ImGuiSymbols;
50class ImGuiTools;
51class ImGuiTrainer;
52class ImGuiVdpRegs;
53class ImGuiWatchExpr;
54class RomInfo;
55
56class ImGuiManager final : public ImGuiPartInterface, private EventListener, private Observer<Setting>
57{
58public:
59 ImGuiManager(const ImGuiManager&) = delete;
61
62 explicit ImGuiManager(Reactor& reactor_);
64
67
68 [[nodiscard]] Reactor& getReactor() { return reactor; }
69 [[nodiscard]] Interpreter& getInterpreter();
70 [[nodiscard]] CliComm& getCliComm();
71 std::optional<TclObject> execute(TclObject command);
72 void executeDelayed(std::function<void()> action);
73 void executeDelayed(TclObject command,
74 std::function<void(const TclObject&)> ok,
75 std::function<void(const std::string&)> error);
76 void executeDelayed(TclObject command,
77 std::function<void(const TclObject&)> ok = {});
78
79 void printError(std::string_view message);
80 template<typename... Ts> void printError(Ts&&... ts) {
81 printError(static_cast<std::string_view>(tmpStrCat(std::forward<Ts>(ts)...)));
82 }
83
84 void preNewFrame();
85 void paintImGui();
86
87 void storeWindowPosition(gl::ivec2 pos) { windowPos = pos; }
88 [[nodiscard]] gl::ivec2 retrieveWindowPosition() const { return windowPos; }
89
90private:
91 void initializeImGui();
92 [[nodiscard]] ImFont* addFont(zstring_view filename, int fontSize);
93 void loadFont();
94 void reloadFont();
95
96 // ImGuiPartInterface
97 [[nodiscard]] zstring_view iniName() const override { return "manager"; }
98 void save(ImGuiTextBuffer& buf) override;
99 void loadLine(std::string_view name, zstring_view value) override;
100 void loadEnd() override;
101
102 // EventListener
103 int signalEvent(const Event& event) override;
104
105 // Observer<Setting>
106 void update(const Setting& setting) noexcept override;
107
108 // ini handler callbacks
109 void iniReadInit();
110 void* iniReadOpen(std::string_view name);
111 void loadLine(void* entry, const char* line);
112 void iniApplyAll();
113 void iniWriteAll(ImGuiTextBuffer& buf);
114
115private:
116 Reactor& reactor;
117 std::vector<ImGuiPartInterface*> parts;
118
119public:
124 ImFont* fontProp = nullptr;
125 ImFont* fontMono = nullptr;
126
127 std::unique_ptr<ImGuiMachine> machine;
128 std::unique_ptr<ImGuiDebugger> debugger;
129 std::unique_ptr<ImGuiBreakPoints> breakPoints;
130 std::unique_ptr<ImGuiSymbols> symbols;
131 std::unique_ptr<ImGuiWatchExpr> watchExpr;
132 std::unique_ptr<ImGuiBitmapViewer> bitmap;
133 std::unique_ptr<ImGuiCharacter> character;
134 std::unique_ptr<ImGuiSpriteViewer> sprite;
135 std::unique_ptr<ImGuiVdpRegs> vdpRegs;
136 std::unique_ptr<ImGuiPalette> palette;
137 std::unique_ptr<ImGuiReverseBar> reverseBar;
138 std::unique_ptr<ImGuiHelp> help;
139 std::unique_ptr<ImGuiOsdIcons> osdIcons;
140 std::unique_ptr<ImGuiOpenFile> openFile;
141 std::unique_ptr<ImGuiMedia> media;
142 std::unique_ptr<ImGuiConnector> connector;
143 std::unique_ptr<ImGuiTools> tools;
144 std::unique_ptr<ImGuiTrainer> trainer;
145 std::unique_ptr<ImGuiCheatFinder> cheatFinder;
146 std::unique_ptr<ImGuiDiskManipulator> diskManipulator;
147 std::unique_ptr<ImGuiSettings> settings;
148 std::unique_ptr<ImGuiSoundChip> soundChip;
149 std::unique_ptr<ImGuiKeyboard> keyboard;
150 std::unique_ptr<ImGuiConsole> console;
151 std::unique_ptr<ImGuiMessages> messages;
152
153 bool menuFade = true;
154 bool needReloadFont = false;
155 std::string loadIniFile;
156
157private:
158 std::vector<std::function<void()>> delayedActionQueue;
159 float menuAlpha = 1.0f;
160
161 std::string droppedFile;
162 std::string insertedInfo;
163 std::vector<std::string> selectList;
164 std::string selectedMedia;
165 const RomInfo* romInfo = nullptr;
166 RomType selectedRomType = ROM_UNKNOWN;
167 float insertedInfoTimeout = 0.0f;
168 gl::ivec2 windowPos;
169 bool mainMenuBarUndocked = false;
170 bool handleDropped = false;
171 bool openInsertedInfo = false;
172 bool guiActive = false;
173
174 static constexpr auto persistentElements = std::tuple{
175 PersistentElement{"mainMenuBarUndocked", &ImGuiManager::mainMenuBarUndocked},
176 PersistentElement{"mainMenuBarFade", &ImGuiManager::menuFade},
177 PersistentElement{"windowPos", &ImGuiManager::windowPos}
178 };
179};
180
181// Parse machine or extension config files:
182// store config-name, display-name and meta-data
183template<typename InfoType>
184std::vector<InfoType> parseAllConfigFiles(ImGuiManager& manager, std::string_view type, std::initializer_list<std::string_view> topics)
185{
186 static constexpr auto replacer = StringReplacer::create(
187 "name", "Name",
188 "manufacturer", "Manufacturer",
189 "code", "Product code",
190 "region", "Region",
191 "release_year", "Release year",
192 "description", "Description",
193 "type", "Type");
194
195 std::vector<InfoType> result;
196
197 const auto& configs = Reactor::getHwConfigs(type);
198 result.reserve(configs.size());
199 for (const auto& config : configs) {
200 auto& info = result.emplace_back();
201 info.configName = config;
202
203 // get machine meta-data
204 auto& configInfo = info.configInfo;
205 if (auto r = manager.execute(makeTclList("openmsx_info", type, config))) {
206 auto first = r->begin();
207 auto last = r->end();
208 while (first != last) {
209 auto desc = *first++;
210 if (first == last) break; // shouldn't happen
211 auto value = *first++;
212 if (!value.empty()) {
213 configInfo.emplace_back(std::string(replacer(desc)),
214 std::string(value));
215 }
216 }
217 }
218
219 // Based on the above meta-data, try to construct a more
220 // readable name Unfortunately this new name is no
221 // longer guaranteed to be unique, we'll address this
222 // below.
223 auto& display = info.displayName;
224 for (const auto topic : topics) {
225 if (const auto* value = getOptionalDictValue(configInfo, topic)) {
226 if (!value->empty()) {
227 if (!display.empty()) strAppend(display, ' ');
228 strAppend(display, *value);
229 }
230 }
231 }
232 if (display.empty()) display = config;
233 }
234
235 ranges::sort(result, StringOp::caseless{}, &InfoType::displayName);
236
237 // make 'displayName' unique again
238 auto sameDisplayName = [](InfoType& x, InfoType& y) {
240 return cmp(x.displayName, y.displayName);
241 };
242 chunk_by(result, sameDisplayName, [](auto first, auto last) {
243 if (std::distance(first, last) == 1) return; // no duplicate name
244 for (auto it = first; it != last; ++it) {
245 strAppend(it->displayName, " (", it->configName, ')');
246 }
247 ranges::sort(first, last, StringOp::caseless{}, &InfoType::displayName);
248 });
249
250 return result;
251}
252
253} // namespace openmsx
254
255#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< ImGuiConnector > connector
std::optional< TclObject > execute(TclObject command)
std::unique_ptr< ImGuiKeyboard > keyboard
std::unique_ptr< ImGuiHelp > help
IntegerSetting fontPropSize
std::unique_ptr< ImGuiSpriteViewer > sprite
Interpreter & getInterpreter()
void storeWindowPosition(gl::ivec2 pos)
ImGuiManager(const ImGuiManager &)=delete
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< ImGuiBitmapViewer > bitmap
std::unique_ptr< ImGuiSettings > settings
std::unique_ptr< ImGuiDebugger > debugger
std::unique_ptr< ImGuiCharacter > character
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:72
static std::vector< std::string > getHwConfigs(std::string_view type)
Definition Reactor.cc:349
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:9
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)
@ ROM_UNKNOWN
Definition RomTypes.hh:94
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:454
TclObject makeTclList(Args &&... args)
Definition TclObject.hh:289
constexpr void sort(RandomAccessRange &&range)
Definition ranges.hh:49
TemporaryString tmpStrCat(Ts &&... ts)
Definition strCat.hh:742
void strAppend(std::string &result, Ts &&...ts)
Definition strCat.hh:752