OXYGENHUB
◆ main openmsx / src / imgui / ImGuiMessages.hh
4.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef IMGUI_MESSAGES_HH
2
#define IMGUI_MESSAGES_HH
3
4
#include "ImGuiCpp.hh"
5
#include "ImGuiPart.hh"
6
7
#include "CliListener.hh"
8
9
#include "circular_buffer.hh"
10
#include "stl.hh"
11
12
#include <array>
13
#include <cstdint>
14
#include <string>
15
16
namespace openmsx {
17
18
class ImGuiManager;
19
20
class ImGuiMessages final : public ImGuiPart
21
{
22
public:
23
	struct Message {
24
		CliComm::LogLevel level;
25
		std::string text;
26
		uint64_t timestamp; // us
27
	};
28
public:
29
	explicit ImGuiMessages(ImGuiManager& manager_);
30
	~ImGuiMessages();
31
32
	[[nodiscard]] zstring_view iniName() const override { return "messages"; }
33
	void save(ImGuiTextBuffer& buf) override;
34
	void loadLine(std::string_view name, zstring_view value) override;
35
	void paint(MSXMotherBoard* motherBoard) override;
36
37
public:
38
	im::WindowStatus logWindow;
39
	im::WindowStatus configureWindow;
40
41
private:
42
	void paintModal();
43
	void paintPopup();
44
	void paintProgress();
45
	void paintOSD();
46
	void paintLog();
47
	void paintConfigure();
48
	[[nodiscard]] bool paintButtons();
49
50
	void log(CliComm::LogLevel level, std::string_view message, float fraction);
51
52
private:
53
	enum PopupAction : int { NO_POPUP, POPUP, MODAL_POPUP };
54
	enum OpenLogAction : int { NO_OPEN_LOG, OPEN_LOG, OPEN_LOG_FOCUS };
55
	enum OsdAction : int { NO_OSD, SHOW_OSD };
56
	array_with_enum_index<CliComm::LogLevel, int /*PopupAction*/  > popupAction;
57
	array_with_enum_index<CliComm::LogLevel, int /*OpenLogAction*/> openLogAction;
58
	array_with_enum_index<CliComm::LogLevel, int /*OsdAction*/    > osdAction;
59
60
	circular_buffer<Message> modalMessages;
61
	circular_buffer<Message> popupMessages;
62
	circular_buffer<Message> allMessages;
63
	std::string filterLog;
64
	bool doOpenModal = false;
65
	size_t doOpenPopup = 0;
66
67
	std::string progressMessage;
68
	float progressFraction = 0.0f;;
69
	float progressTime = 0.0f;
70
	bool doOpenProgress = false;
71
72
	struct Colors {
73
		uint32_t text;
74
		uint32_t background;
75
	};
76
	struct Step {
77
		float start;
78
		Colors colors;
79
	};
80
	using ColorSequence = std::array<Step, 4>;
81
	array_with_enum_index<CliComm::LogLevel, ColorSequence> colorSequence = {
82
		ColorSequence{ // Info                     AA'BB'GG'RR
83
			Step{.start = 0.0f, .colors = Colors{.text = 0xff'00'ff'ff, .background = 0x80'ff'ff'ff}}, // start of flash
84
			Step{.start = 0.5f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'80'80'80}}, // start of stable colors
85
			Step{.start = 5.0f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'80'80'80}}, // end of stable colors
86
			Step{.start = 1.5f, .colors = Colors{.text = 0x00'ff'ff'ff, .background = 0x00'80'80'80}}, // end of fade-out
87
		},
88
		ColorSequence{ // warning
89
			Step{.start = 0.0f, .colors = Colors{.text = 0xff'00'ff'ff, .background = 0x80'ff'ff'ff}}, // start of flash
90
			Step{.start = 0.5f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'00'60'A0}}, // start of stable colors
91
			Step{.start = 5.0f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'00'60'A0}}, // end of stable colors
92
			Step{.start = 1.5f, .colors = Colors{.text = 0x00'ff'ff'ff, .background = 0x00'00'60'A0}}, // end of fade-out
93
		},
94
		ColorSequence{ // error
95
			Step{.start = 0.0f, .colors = Colors{.text = 0xff'00'ff'ff, .background = 0x80'ff'ff'ff}}, // start of flash
96
			Step{.start = 0.5f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'00'00'C0}}, // start of stable colors
97
			Step{.start = 5.0f, .colors = Colors{.text = 0xff'ff'ff'ff, .background = 0x80'00'00'C0}}, // end of stable colors
98
			Step{.start = 1.5f, .colors = Colors{.text = 0x00'ff'ff'ff, .background = 0x00'00'00'C0}}, // end of fade-out
99
		},
100
		ColorSequence{ /*dummy*/ } // progress
101
	};
102
	struct OsdMessage {
103
		std::string text;
104
		float time;
105
		CliComm::LogLevel level;
106
	};
107
	std::vector<OsdMessage> osdMessages;
108
109
	struct Listener : CliListener {
110
		ImGuiMessages& messages;
111
		explicit Listener(ImGuiMessages& m) : messages(m) {}
112
113
		void log(CliComm::LogLevel level, std::string_view message, float fraction) noexcept override {
114
			messages.log(level, message, fraction);
115
		}
116
		void update(CliComm::UpdateType /*type*/, std::string_view /*machine*/,
117
		            std::string_view /*name*/, std::string_view /*value*/) noexcept override {
118
			// nothing
119
		}
120
	};
121
	CliListener* listenerHandle;
122
123
	static constexpr auto persistentElements = std::tuple{
124
		PersistentElement{"showLog",       &ImGuiMessages::logWindow},
125
		PersistentElement{"showConfigure", &ImGuiMessages::configureWindow}
126
		// 'popupAction', 'openLogAction', 'osdAction' handled elsewhere
127
	};
128
};
129
130
} // namespace openmsx
131
132
#endif