32 , symbolManager(manager.getReactor().getSymbolManager())
45 for (
const auto& file : symbolManager.
getFiles()) {
46 buf.appendf(
"symbolfile=%s\n", file.filename.c_str());
49 for (
const auto& [file, error, type] : fileError) {
50 buf.appendf(
"symbolfile=%s\n", file.c_str());
65 }
else if (name ==
"symbolfile") {
66 fileError.emplace_back(std::string{value},
69 }
else if (name ==
"symbolfiletype") {
70 if (!fileError.empty()) {
71 fileError.back().type =
79 std::vector<FileInfo> tmp;
80 std::swap(tmp, fileError);
81 for (
const auto& info : tmp) {
89 auto it =
ranges::find(fileError, filename, &FileInfo::filename);
91 if (!symbolManager.
reloadFile(filename, loadEmpty, type)) {
92 cliComm.printWarning(
"Symbol file \"", filename,
93 "\" doesn't contain any symbols");
95 if (it != fileError.end()) fileError.erase(it);
96 }
catch (MSXException& e) {
98 "Couldn't load symbol file \"", filename,
"\": ",
e.getMessage());
99 if (it != fileError.end()) {
100 it->error =
e.getMessage();
103 fileError.emplace_back(filename,
e.getMessage(), type);
108static void checkSort(
const SymbolManager& manager, std::vector<SymbolRef>& symbols)
110 auto* sortSpecs = ImGui::TableGetSortSpecs();
111 if (!sortSpecs->SpecsDirty)
return;
113 sortSpecs->SpecsDirty =
false;
114 assert(sortSpecs->SpecsCount == 1);
115 assert(sortSpecs->Specs);
116 assert(sortSpecs->Specs->SortOrder == 0);
118 switch (sortSpecs->Specs->ColumnIndex) {
120 sortUpDown_String(symbols, sortSpecs, [&](
const auto& sym) {
return sym.name(manager); });
123 sortUpDown_T(symbols, sortSpecs, [&](
const auto& sym) {
return sym.value(manager); });
126 sortUpDown_String(symbols, sortSpecs, [&](
const auto& sym) {
return sym.file(manager); });
132template<
bool FILTER_FILE>
133static void drawTable(ImGuiManager& manager,
const SymbolManager& symbolManager, std::vector<SymbolRef>& symbols,
const std::string& file = {})
135 assert(FILTER_FILE == !file.empty());
137 int flags = ImGuiTableFlags_RowBg |
138 ImGuiTableFlags_BordersV |
139 ImGuiTableFlags_BordersOuter |
140 ImGuiTableFlags_ContextMenuInBody |
141 ImGuiTableFlags_Resizable |
142 ImGuiTableFlags_Reorderable |
143 ImGuiTableFlags_Sortable |
144 ImGuiTableFlags_SizingStretchProp |
145 (FILTER_FILE ? ImGuiTableFlags_ScrollY : 0);
146 im::Table(file.c_str(), FILTER_FILE ? 2 : 3, flags, {0, 100}, [&]{
147 ImGui::TableSetupScrollFreeze(0, 1);
148 ImGui::TableSetupColumn(
"name");
149 ImGui::TableSetupColumn(
"value", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed);
151 ImGui::TableSetupColumn(
"file");
153 ImGui::TableHeadersRow();
154 checkSort(symbolManager, symbols);
156 for (
const auto& sym : symbols) {
157 if (FILTER_FILE && (sym.file(symbolManager) != file))
continue;
159 if (ImGui::TableNextColumn()) {
163 if (ImGui::TableNextColumn()) {
167 if (!FILTER_FILE && ImGui::TableNextColumn()) {
178 ImGui::SetNextWindowSize(
gl::vec2{24, 18} * ImGui::GetFontSize(), ImGuiCond_FirstUseEver);
180 if (ImGui::Button(
"Load symbol file...")) {
182 "Select symbol file",
184 [
this](
const std::string& filename) {
190 im::TreeNode(
"Symbols per file", ImGuiTreeNodeFlags_DefaultOpen, [&]{
191 auto drawFile = [&](
const FileInfo& info) {
193 auto title =
strCat(
"File: ", info.filename);
195 if (!info.error.empty()) {
196 ImGui::TextUnformatted(info.error);
199 if (ImGui::Button(
"Reload")) {
203 if (ImGui::Button(
"Remove")) {
204 symbolManager.removeFile(info.filename);
205 if (
auto it =
ranges::find(fileError, info.filename, &FileInfo::filename);
206 it != fileError.end()) {
210 drawTable<true>(
manager, symbolManager, symbols, info.filename);
218 return FileInfo{file.filename, std::string{}, file.type};
220 append(infos, fileError);
221 for (
const auto& info : infos) {
227 if (ImGui::Button(
"Reload all")) {
229 return FileInfo{file.filename, std::string{}, file.type};
231 append(tmp, std::move(fileError));
233 for (
const auto& info : tmp) {
238 if (ImGui::Button(
"Remove all")) {
239 symbolManager.removeAllFiles();
242 drawTable<false>(manager, symbolManager, symbols);
247void ImGuiSymbols::notifySymbolsChanged()
250 for (
const auto& [fileIdx, file] :
enumerate(symbolManager.getFiles())) {
251 for (
auto symbolIdx :
xrange(file.symbols.
size())) {
255 symbols.push_back(SymbolRef{narrow<unsigned>(fileIdx),
256 narrow<unsigned>(symbolIdx)});
260 manager.breakPoints->refreshSymbols();
261 manager.watchExpr->refreshSymbols();
std::unique_ptr< ImGuiOpenFile > openFile
static std::string getLastFilter()
void loadLine(std::string_view name, zstring_view value) override
void save(ImGuiTextBuffer &buf) override
void loadStart() override
void paint(MSXMotherBoard *motherBoard) override
ImGuiSymbols(ImGuiManager &manager)
const auto & getFiles() const
bool reloadFile(const std::string &filename, LoadEmpty loadEmpty, SymbolFile::Type type)
static std::string getFileFilters()
static SymbolFile::Type getTypeForFilter(std::string_view filter)
void setObserver(SymbolObserver *observer_)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr const char * c_str() const
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
void TextUnformatted(const std::string &str)
void Table(const char *str_id, int column, ImGuiTableFlags flags, const ImVec2 &outer_size, float inner_width, std::invocable<> auto next)
void Window(const char *name, bool *p_open, ImGuiWindowFlags flags, std::invocable<> auto next)
bool TreeNode(const char *label, ImGuiTreeNodeFlags flags, std::invocable<> auto next)
void StyleColor(bool active, Args &&...args)
This file implemented 3 utility functions:
bool loadOnePersistent(std::string_view name, zstring_view value, C &c, const std::tuple< Elements... > &tup)
void sortUpDown_String(Range &range, const ImGuiTableSortSpecs *sortSpecs, Projection proj)
void savePersistent(ImGuiTextBuffer &buf, C &c, const std::tuple< Elements... > &tup)
void sortUpDown_T(Range &range, const ImGuiTableSortSpecs *sortSpecs, Projection proj)
ImU32 getColor(imColor col)
auto find(InputRange &&range, const T &value)
size_t size(std::string_view utf8)
constexpr auto transform(Range &&range, UnaryOp op)
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))> >
static std::optional< Type > parseType(std::string_view str)
static zstring_view toString(Type type)
constexpr auto xrange(T e)