54#include <imgui_impl_opengl3.h>
55#include <imgui_impl_sdl2.h>
56#include <imgui_internal.h>
57#include <CustomFont.ii>
63using namespace std::literals;
65ImFont* ImGuiManager::addFont(
zstring_view filename,
int fontSize)
67 auto& io = ImGui::GetIO();
68 if (!filename.
empty()) {
73 auto fileSize = file.getSize();
74 auto ttfData = std::span(
75 static_cast<uint8_t*
>(ImGui::MemAlloc(fileSize)), fileSize);
78 static const std::array<ImWchar, 2*6 + 1>
ranges = {
94 return io.Fonts->AddFontFromMemoryTTF(
96 narrow<int>(ttfData.size()), narrow<float>(fontSize),
98 }
catch (MSXException& e) {
100 ". Reverted to builtin font");
103 return io.Fonts->AddFontDefault();
106void ImGuiManager::loadFont()
108 ImGuiIO& io = ImGui::GetIO();
114 static constexpr std::array<ImWchar, 3> icons_ranges = {ICON_MIN_IGFD, ICON_MAX_IGFD, 0};
115 ImFontConfig icons_config; icons_config.MergeMode =
true; icons_config.PixelSnapH =
true;
116 io.Fonts->AddFontFromMemoryCompressedBase85TTF(FONT_ICON_BUFFER_NAME_IGFD, 15.0f, &icons_config, icons_ranges.data());
124void ImGuiManager::reloadFont()
130 ImGuiIO& io = ImGui::GetIO();
138void ImGuiManager::initializeImGui()
141 IMGUI_CHECKVERSION();
142 ImGui::CreateContext();
143 ImGuiIO& io = ImGui::GetIO();
144 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard |
146 ImGuiConfigFlags_DockingEnable |
147 ImGuiConfigFlags_ViewportsEnable;
149 io.IniFilename = iniFilename.c_str();
154static void cleanupImGui()
156 ImGui::DestroyContext();
162 , fontPropFilename(reactor.getCommandController(),
"gui_font_default_filename",
"TTF font filename for the default GUI font",
"DejaVuSans.ttf.gz")
163 , fontMonoFilename(reactor.getCommandController(),
"gui_font_mono_filename",
"TTF font filename for the monospaced GUI font",
"DejaVuSansMono.ttf.gz")
164 , fontPropSize(reactor.getCommandController(),
"gui_font_default_size",
"size for the default GUI font", 13, 9, 72)
165 , fontMonoSize(reactor.getCommandController(),
"gui_font_mono_size",
"size for the monospaced GUI font", 13, 9, 72)
166 , windowPos{SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED}
168 parts.push_back(
this);
171 machine = std::make_unique<ImGuiMachine>(*
this);
172 media = std::make_unique<ImGuiMedia>(*
this);
173 connector = std::make_unique<ImGuiConnector>(*
this);
174 reverseBar = std::make_unique<ImGuiReverseBar>(*
this);
175 tools = std::make_unique<ImGuiTools>(*
this);
176 settings = std::make_unique<ImGuiSettings>(*
this);
177 debugger = std::make_unique<ImGuiDebugger>(*
this);
178 help = std::make_unique<ImGuiHelp>(*
this);
180 breakPoints = std::make_unique<ImGuiBreakPoints>(*
this);
181 symbols = std::make_unique<ImGuiSymbols>(*
this);
182 watchExpr = std::make_unique<ImGuiWatchExpr>(*
this);
183 bitmap = std::make_unique<ImGuiBitmapViewer>(*
this);
184 character = std::make_unique<ImGuiCharacter>(*
this);
185 sprite = std::make_unique<ImGuiSpriteViewer>(*
this);
186 vdpRegs = std::make_unique<ImGuiVdpRegs>(*
this);
187 palette = std::make_unique<ImGuiPalette>(*
this);
188 osdIcons = std::make_unique<ImGuiOsdIcons>(*
this);
189 openFile = std::make_unique<ImGuiOpenFile>(*
this);
190 trainer = std::make_unique<ImGuiTrainer>(*
this);
191 cheatFinder = std::make_unique<ImGuiCheatFinder>(*
this);
192 sccViewer = std::make_unique<ImGuiSCCViewer>(*
this);
193 waveViewer = std::make_unique<ImGuiWaveViewer>(*
this);
195 soundChip = std::make_unique<ImGuiSoundChip>(*
this);
196 keyboard = std::make_unique<ImGuiKeyboard>(*
this);
197 console = std::make_unique<ImGuiConsole>(*
this);
198 messages = std::make_unique<ImGuiMessages>(*
this);
201 ImGuiSettingsHandler ini_handler;
202 ini_handler.TypeName =
"openmsx";
203 ini_handler.TypeHash =
ImHashStr(
"openmsx");
204 ini_handler.UserData =
this;
209 ini_handler.ReadInitFn = [](ImGuiContext*, ImGuiSettingsHandler* handler) {
211 static_cast<ImGuiManager*
>(handler->UserData)->iniReadInit();
213 ini_handler.ReadOpenFn = [](ImGuiContext*, ImGuiSettingsHandler* handler,
const char* name) ->
void* {
215 return static_cast<ImGuiManager*
>(handler->UserData)->iniReadOpen(name);
217 ini_handler.ReadLineFn = [](ImGuiContext*, ImGuiSettingsHandler* handler,
void* entry,
const char* line) {
219 static_cast<ImGuiManager*
>(handler->UserData)->loadLine(entry, line);
221 ini_handler.ApplyAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler) {
223 static_cast<ImGuiManager*
>(handler->UserData)->iniApplyAll();
225 ini_handler.WriteAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf) {
227 static_cast<ImGuiManager*
>(handler->UserData)->iniWriteAll(*out_buf);
229 ImGui::AddSettingsHandler(&ini_handler);
266 assert(!
contains(toBeAddedParts, part));
267 toBeAddedParts.push_back(part);
272 if (
auto it1 =
ranges::find(parts, part); it1 != parts.end()) {
275 }
else if (
auto it2 =
ranges::find(toBeAddedParts, part); it2 != toBeAddedParts.end()) {
276 toBeAddedParts.erase(it2);
280void ImGuiManager::updateParts()
287 append(parts, toBeAddedParts);
288 toBeAddedParts.clear();
291void ImGuiManager::save(ImGuiTextBuffer& buf)
299void ImGuiManager::loadLine(std::string_view name,
zstring_view value)
306 auto windowTL = windowPos;
307 auto windowBR = windowTL + windowSize;
308 auto overlaps = [&](
const ImGuiPlatformMonitor& monitor) {
310 auto monitorBR = monitorTL +
trunc(
gl::vec2(monitor.MainSize));
311 return windowTL.x < monitorBR.x &&
312 windowBR.x > monitorTL.x &&
313 windowTL.y < monitorBR.y &&
314 windowBR.y > monitorTL.y;
317 const auto& monitors = ImGui::GetPlatformIO().Monitors;
321 return gl::ivec2(SDL_WINDOWPOS_CENTERED);
326void ImGuiManager::loadEnd()
329 windowPos = ensureVisible(windowPos, display.getWindowSize());
330 display.setWindowPosition(windowPos);
355 delayedActionQueue.push_back(std::move(action));
360 const std::function<
void(
const TclObject&)>& ok,
361 const std::function<
void(
const std::string&)>& error)
368 if (error) error(e.getMessage());
374 const std::function<
void(
const TclObject&)>& ok)
377 [
this](
const std::string& message) { this->
printError(message); });
385bool ImGuiManager::signalEvent(
const Event& event)
387 if (
auto* evt = get_event_if<SdlEvent>(event)) {
388 const ImGuiIO& io = ImGui::GetIO();
389 if (!io.BackendPlatformUserData) {
393 const SDL_Event& sdlEvent = evt->getSdlEvent();
395 if ((io.WantCaptureMouse &&
396 sdlEvent.type ==
one_of(SDL_MOUSEMOTION, SDL_MOUSEWHEEL,
397 SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP)) ||
398 (io.WantCaptureKeyboard &&
399 sdlEvent.type ==
one_of(SDL_KEYDOWN, SDL_KEYUP, SDL_TEXTINPUT))) {
405 for (
auto& action : delayedActionQueue) {
408 delayedActionQueue.clear();
412 const auto& fde = get_event<FileDropEvent>(event);
413 droppedFile = fde.getFileName();
414 handleDropped =
true;
433void ImGuiManager::update(
const Setting& )
noexcept
435 needReloadFont =
true;
439static std::vector<std::string> getDrives(MSXMotherBoard* motherBoard)
441 std::vector<std::string> result;
442 if (!motherBoard)
return result;
444 std::string driveName =
"diskX";
447 if (!(*drivesInUse)[i])
continue;
448 driveName[4] = char(
'a' + i);
449 result.push_back(driveName);
454static std::vector<std::string> getSlots(MSXMotherBoard* motherBoard)
456 std::vector<std::string> result;
457 if (!motherBoard)
return result;
459 const auto& slotManager = motherBoard->getSlotManager();
460 std::string cartName =
"cartX";
461 for (
auto slot :
xrange(CartridgeSlotManager::MAX_SLOTS)) {
462 if (!slotManager.slotExists(slot))
continue;
463 cartName[4] = char(
'a' + slot);
464 result.push_back(cartName);
472 ImGui::LoadIniSettingsFromDisk(
loadIniFile.c_str());
481static bool hoverMenuBar()
483 const auto* viewport = ImGui::GetMainViewport();
485 gl::vec2 bottomRight = topLeft +
gl::vec2(viewport->Size.x, ImGui::GetFrameHeight());
486 gl::vec2 mouse = ImGui::GetMousePos();
487 return mouse.x >= topLeft.x && mouse.x <= bottomRight.x &&
488 mouse.y >= topLeft.y && mouse.y <= bottomRight.y;
498 if (
auto* keyb = motherBoard->getKeyboard()) {
500 keyb->setFocus(!ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow), time);
504 for (
auto* part : parts) {
505 part->paint(motherBoard);
512 for (
auto* part : parts) {
513 part->showMenu(motherBoard);
516 if (mainMenuBarUndocked) {
517 im::Window(
"openMSX main menu", &mainMenuBarUndocked, ImGuiWindowFlags_MenuBar, [&]{
519 if (ImGui::ArrowButton(
"re-dock-button", ImGuiDir_Down)) {
520 mainMenuBarUndocked =
false;
522 simpleToolTip(
"Dock the menu bar in the main openMSX window.");
527 bool active = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) ||
528 ImGui::IsWindowFocused(ImGuiHoveredFlags_AnyWindow) ||
530 if (active != guiActive) {
537 auto target = active ? 1.0f : 0.0f;
538 auto period = active ? 0.5f : 5.0f;
543 if (ImGui::ArrowButton(
"undock-button", ImGuiDir_Up)) {
544 mainMenuBarUndocked =
true;
546 simpleToolTip(
"Undock the menu bar from the main openMSX window.");
555 auto insert2 = [&](std::string_view displayName,
TclObject cmd) {
556 auto message =
strCat(
"Inserted ", droppedFile,
" in ", displayName);
558 insertedInfo = message;
559 openInsertedInfo =
true;
560 media->addRecent(cmd);
563 auto insert = [&](std::string_view displayName, std::string_view cmd) {
564 insert2(displayName,
makeTclList(cmd,
"insert", droppedFile));
567 handleDropped =
false;
568 insertedInfo.clear();
570 auto category =
execute(
makeTclList(
"openmsx_info",
"file_type_category", droppedFile))->getString();
575 auto error = [&](
auto&& ...message) {
578 auto cantHandle = [&](
auto&& ...message) {
579 error(
"Can't handle dropped file ", droppedFile,
": ", message...);
581 auto notPresent = [&](
const auto& mediaType) {
582 cantHandle(
"no ", mediaType,
" present.");
585 auto testMedia = [&](std::string_view displayName, std::string_view cmd) {
587 insert(displayName, cmd);
589 notPresent(displayName);
593 if (category ==
"disk") {
594 auto list = getDrives(motherBoard);
596 notPresent(
"disk drive");
597 }
else if (list.size() == 1) {
598 const auto& drive = list.front();
599 insert(
strCat(
"disk drive ",
char(drive.back() -
'a' +
'A')), drive);
601 selectList = std::move(list);
602 ImGui::OpenPopup(
"select-drive");
604 }
else if (category ==
"rom") {
605 auto list = getSlots(motherBoard);
607 notPresent(
"cartridge slot");
610 selectedMedia = list.front();
611 selectList = std::move(list);
617 selectedRomType = romInfo ? romInfo->
getRomType()
619 ImGui::OpenPopup(
"select-cart");
620 }
else if (category ==
"cassette") {
621 testMedia(
"casette port",
"cassetteplayer");
622 }
else if (category ==
"laserdisc") {
623 testMedia(
"laser disc player",
"laserdiscplayer");
624 }
else if (category ==
"savestate") {
626 }
else if (category ==
"replay") {
628 }
else if (category ==
"script") {
633 cantHandle(
"unknown file type");
638 auto n = std::min(3.5f, narrow<float>(selectList.size()));
639 auto height = n * ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y;
640 im::ListBox(
"##select-media", {-FLT_MIN, height}, [&]{
641 for (
const auto& item : selectList) {
642 auto drive = item.back() -
'a';
643 auto display =
strCat(
char(
'A' + drive),
": ",
media->displayNameForDriveContent(drive,
true));
644 if (ImGui::Selectable(display.c_str())) {
645 insert(
strCat(
"disk drive ",
char(drive +
'A')), item);
646 ImGui::CloseCurrentPopup();
660 ImGui::TableSetupColumn(
"description", ImGuiTableColumnFlags_WidthFixed);
661 ImGui::TableSetupColumn(
"value", ImGuiTableColumnFlags_WidthStretch);
666 if (ImGui::TableNextColumn()) {
667 ImGui::AlignTextToFramePadding();
670 if (ImGui::TableNextColumn()) {
676 if (selectList.size() > 1) {
677 const auto& slotManager = motherBoard->getSlotManager();
679 auto n = std::min(3.5f, narrow<float>(selectList.size()));
680 auto height = n * ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y;
681 im::ListBox(
"##select-media", {-FLT_MIN, height}, [&]{
682 for (
const auto& item : selectList) {
683 auto slot = item.back() -
'a';
686 " (", slotManager.getPsSsString(slot),
"): ",
687 media->displayNameForSlotContent(slotManager, slot,
true));
689 if (ImGui::Selectable(display.c_str(), item == selectedMedia)) {
690 selectedMedia = item;
696 ImGui::Checkbox(
"Reset MSX on inserting ROM", &
media->resetOnInsertRom);
698 if (ImGui::Button(
"Insert ROM")) {
699 auto cmd =
makeTclList(selectedMedia,
"insert", droppedFile);
703 insert2(
strCat(
"cartridge slot ",
char(selectedMedia.back() -
'a' +
'A')), cmd);
704 if (
media->resetOnInsertRom) {
707 ImGui::CloseCurrentPopup();
710 if (ImGui::Button(
"Cancel")) {
711 ImGui::CloseCurrentPopup();
714 if (openInsertedInfo) {
715 openInsertedInfo =
false;
716 insertedInfoTimeout = 3.0f;
717 ImGui::OpenPopup(
"inserted-info");
720 insertedInfoTimeout -= ImGui::GetIO().DeltaTime;
721 if (insertedInfoTimeout <= 0.0f || insertedInfo.empty()) {
722 ImGui::CloseCurrentPopup();
732 if (ImGui::BeginViewportSideBar(
"##MainStatusBar",
nullptr, ImGuiDir_Down, ImGui::GetFrameHeight(),
733 ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar)) {
735 auto frameTime = ImGui::GetIO().DeltaTime;
738 fpsDrawTimeOut -= frameTime;
739 if (fpsDrawTimeOut < 0.0f) {
740 fpsDrawTimeOut = 0.1f;
743 std::stringstream ssFps;
744 ssFps << std::fixed << std::setprecision(1) << fps <<
" fps";
749 auto [modeStr, extendedStr] = [&] {
750 if (!motherBoard)
return std::pair{
"-",
""};
751 const auto* vdp =
dynamic_cast<const VDP*
>(motherBoard->
findDevice(
"VDP"));
752 if (!vdp)
return std::pair{
"-",
""};
754 auto mode = vdp->getDisplayMode();
755 auto base = mode.getBase();
767 ? (mode.getByte() &
DisplayMode::YAE) ? std::pair{
"11",
"GRAPHIC 7 (YJK/YAE mode)"} : std::pair{
"12",
"GRAPHIC 7 (YJK mode)"}
768 : std::pair{
"8",
"GRAPHIC 7"};
772 std::string result =
"screen mode as used in MSX-BASIC";
773 if (extendedStr[0]) {
774 strAppend(result,
", corresponds to VDP mode ", extendedStr);
780 auto timeStr = motherBoard
789 speedDrawTimeOut -= frameTime;
790 if (speedDrawTimeOut < 0.0f) {
791 auto realTimePassed = 1.0f - speedDrawTimeOut;
792 speedDrawTimeOut = 1.0f;
795 auto boardTimePassed = (boardTime < prevBoardTime)
797 : (boardTime - prevBoardTime).toDouble();
798 prevBoardTime = boardTime;
800 speed = 100.0f * boardTimePassed / realTimePassed;
804 prevBoardTime = EmuTime::zero();
811 if (
const HardwareConfig* machineConfig = motherBoard->
getMachineConfig()) {
812 if (
const auto* info = machineConfig->getConfig().findChild(
"info")) {
813 auto manuf = info->getChildData(
"manufacturer",
"?");
814 auto code = info->getChildData(
"code",
"?");
817 auto type = info->getChildData(
"type",
"");
818 auto desc = info->getChildData(
"description",
"");
819 return strCat((type.empty() ?
"" :
strCat(
"Machine type: ", type,
'\n')), desc);
826 if (
auto result =
execute(TclObject(
"guess_title"))) {
836void ImGuiManager::iniReadInit()
839 for (
auto* part : parts) {
846void* ImGuiManager::iniReadOpen(std::string_view name)
849 for (
auto* part : parts) {
850 if (part->iniName() == name)
return part;
855void ImGuiManager::loadLine(
void* entry,
const char* line_)
const
858 auto pos = line.
find(
'=');
860 std::string_view name = line.
substr(0, pos);
864 static_cast<ImGuiPartInterface*
>(entry)->loadLine(name, value);
867void ImGuiManager::iniApplyAll()
870 for (
auto* part : parts) {
875void ImGuiManager::iniWriteAll(ImGuiTextBuffer& buf)
878 for (
auto* part : parts) {
879 if (
auto name = part->iniName(); !name.empty()) {
880 buf.appendf(
"[openmsx][%s]\n", name.c_str());
void printError(std::string_view message)
void printWarning(std::string_view message)
static constexpr uint8_t GRAPHIC3
static constexpr uint8_t MULTICOLOR
static constexpr uint8_t GRAPHIC4
static constexpr uint8_t GRAPHIC5
static constexpr uint8_t GRAPHIC1
static constexpr uint8_t GRAPHIC7
static constexpr uint8_t TEXT2
static constexpr byte YAE
Encoding of YAE flag.
static constexpr uint8_t GRAPHIC6
static constexpr byte YJK
Encoding of YJK flag.
static constexpr uint8_t GRAPHIC2
static constexpr uint8_t TEXT1
void unregisterEventListener(EventType type, EventListener &listener)
Unregisters a previously registered event listener.
void distributeEvent(Event &&event)
Schedule the given event for delivery.
void registerEventListener(EventType type, EventListener &listener, Priority priority=Priority::OTHER)
Registers a given object to receive certain events.
std::string resolveCreate(std::string_view filename) const
Sha1Sum getSha1Sum(File &file)
Calculate sha1sum for the given File object.
zstring_view getString() const noexcept
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
std::unique_ptr< ImGuiHelp > help
IntegerSetting fontPropSize
std::unique_ptr< ImGuiSpriteViewer > sprite
Interpreter & getInterpreter()
std::unique_ptr< ImGuiConsole > console
std::unique_ptr< ImGuiSoundChip > soundChip
ImGuiManager(Reactor &reactor_)
std::unique_ptr< ImGuiReverseBar > reverseBar
std::unique_ptr< ImGuiMedia > media
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< ImGuiSCCViewer > sccViewer
std::unique_ptr< ImGuiCharacter > character
void unregisterPart(ImGuiPartInterface *part)
std::unique_ptr< ImGuiTools > tools
void executeDelayed(std::function< void()> action)
FilenameSetting fontMonoFilename
std::unique_ptr< ImGuiSymbols > symbols
int getInt() const noexcept
EmuTime::param getCurrentTime() const
Convenience method: This is the same as getScheduler().getCurrentTime().
const HardwareConfig * getMachineConfig() const
MSXDevice * findDevice(std::string_view name)
Find a MSXDevice by name.
Contains the main loop of openMSX.
MSXMotherBoard * getMotherBoard() const
Interpreter & getInterpreter()
EventDistributor & getEventDistributor()
RomDatabase & getSoftwareDatabase()
static std::shared_ptr< DrivesInUse > getDrivesInUse(MSXMotherBoard &motherBoard)
const RomInfo * fetchRomInfo(const Sha1Sum &sha1sum) const
Lookup an entry in the database by sha1sum.
static std::string_view romTypeToName(RomType type)
RomType getRomType() const
void detach(Observer< T > &observer)
void attach(Observer< T > &observer)
TclObject executeCommand(Interpreter &interp, bool compile=false)
Interpret this TclObject as a command and execute it.
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
static constexpr auto npos
constexpr auto find(char c, size_type pos=0) const
constexpr zstring_view substr(size_type pos) const
constexpr auto empty() const
ImGuiID ImHashStr(const char *data_p, size_t data_size, ImGuiID seed)
bool ImGui_ImplOpenGL3_CreateFontsTexture()
void ImGui_ImplOpenGL3_DestroyFontsTexture()
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event *event)
void TextUnformatted(const std::string &str)
void RightAlignText(std::string_view text, std::string_view maxWidthText)
constexpr vecN< N, int > trunc(const vecN< N, T > &x)
std::optional< Context > context
void Table(const char *str_id, int column, ImGuiTableFlags flags, const ImVec2 &outer_size, float inner_width, std::invocable<> auto next)
void MainMenuBar(std::invocable<> auto next)
void MenuBar(std::invocable<> auto next)
void Window(const char *name, bool *p_open, ImGuiWindowFlags flags, std::invocable<> auto next)
void StyleVar(ImGuiStyleVar idx, float val, std::invocable<> auto next)
void ListBox(const char *label, const ImVec2 &size, std::invocable<> auto next)
void TextWrapPos(float wrap_local_pos_x, std::invocable<> auto next)
void Popup(const char *str_id, ImGuiWindowFlags flags, std::invocable<> auto next)
string_view getExtension(string_view path)
Returns the extension portion of a path.
bool isDirectory(const Stat &st)
string join(string_view part1, string_view part2)
Join two paths.
This file implemented 3 utility functions:
const FileContext & systemFileContext()
bool loadOnePersistent(std::string_view name, zstring_view value, C &c, const std::tuple< Elements... > &tup)
void simpleToolTip(std::string_view desc)
void savePersistent(ImGuiTextBuffer &buf, C &c, const std::tuple< Elements... > &tup)
EventType getType(const Event &event)
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
std::string formatTime(std::optional< double > time)
float calculateFade(float current, float target, float period)
TclObject makeTclList(Args &&... args)
auto remove(ForwardRange &&range, const T &value)
constexpr bool none_of(InputRange &&range, UnaryPredicate pred)
auto find(InputRange &&range, const T &value)
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
TemporaryString tmpStrCat(Ts &&... ts)
void strAppend(std::string &result, Ts &&...ts)
constexpr auto xrange(T e)