#include "../muscles.h"#include "../ui.h"#include "dialog.h" #include <algorithm>#include <numeric> void View_Definitions::update_ui(Camera& camera) { reposition_box_buttons(cross, maxm, box.w, cross_size); float w = title.font->render.text_width(title.text.c_str()) / camera.scale; float max_title_w = box.w - 5 * cross_size; w = w < max_title_w ? w : max_title_w; title.pos = { (box.w - w) / 2, 2, w, title.font->render.text_height() * 1.1f / camera.scale }; float y = 2*cross.pos.y + cross.pos.h; tabs.pos = { border, y, box.w - 2*border, tabs.font->render.text_height() * 1.4f / camera.scale }; y += tabs.pos.h; view.pos = { tabs.pos.x, y, tabs.pos.w, box.h - border - y };} void View_Definitions::update_tables(Workspace *ws) { types.clear_data(); enums.clear_data(); auto& types_vec = (std::vector<s64>&)types.columns[0]; std::vector<s64> enum_name_idxs; if (!ws) ws = parent; auto& defs = ws->definitions; int n_buckets = defs.size(); for (int i = 0; i < n_buckets; i++) { u32 flags = defs.data[i].flags; if ((flags & FLAG_OCCUPIED) == 0) continue; int name_idx = defs.data[i].name_idx; char *name = defs.sv->at(name_idx); if (flags & FLAG_PRIMITIVE) types_vec.push_back(name_idx); else if (flags & FLAG_ENUM) enum_name_idxs.push_back(name_idx); } String_Vector *sv = defs.sv; auto sort_names = [sv](s64 a, s64 b) { return strcmp(sv->at(a), sv->at(b)) < 0; }; std::sort(types_vec.begin(), types_vec.end(), sort_names); std::sort(enum_name_idxs.begin(), enum_name_idxs.end(), sort_names); int n_types = types_vec.size(); types.resize(n_types); for (int i = 0; i < n_types; i++) { char *name = defs.sv->at(types_vec[i]); types.columns[0][i] = (void*)name; Bucket& buck = defs[name]; if (buck.flags & FLAG_EXTERNAL) { const u32 mask = FLAG_OCCUPIED | FLAG_EXTERNAL | FLAG_PRIMITIVE; while ((buck.flags & mask) == mask) buck = defs[defs.sv->at(buck.value)]; if ((buck.flags & (FLAG_EXTERNAL | FLAG_PRIMITIVE)) != FLAG_PRIMITIVE) continue; } // Size types.columns[1][i] = (void*)buck.value; // Big Endian, Float, Signed types.set_checkbox(2, i, buck.flags & FLAG_BIG_ENDIAN); types.set_checkbox(3, i, buck.flags & FLAG_FLOAT); types.set_checkbox(4, i, buck.flags & FLAG_SIGNED); } enums.branches.clear(); enums.branch_name_vector.head = 0; int n_elems = 0; int n_enums = enum_name_idxs.size(); for (int i = 0; i < n_enums; i++) { char *name = defs.sv->at(enum_name_idxs[i]); if (!name) continue; Bucket& buck = defs[name]; const u32 mask = FLAG_OCCUPIED | FLAG_ENUM; if ((buck.flags & mask) != mask || !buck.pointer) continue; int *data = (int*)buck.pointer; int size = *data++ / sizeof(int); enums.resize(enums.row_count() + size); int name_idx = enums.branch_name_vector.add_string(name); enums.branches.push_back({ n_elems, size, name_idx, false }); for (int j = 0; j < size; j++) { char *elem = defs.sv->at(data[j]); if (elem) { enums.columns[0][n_elems] = elem; enums.columns[1][n_elems] = (void*)defs[elem].value; } n_elems++; } } enums.update_tree(); require_redraw();} void View_Definitions::handle_zoom(Workspace& ws, float new_scale) { cross.img = ws.cross; maxm.img = ws.maxm; sdl_destroy_texture(&view.icon_plus); sdl_destroy_texture(&view.icon_minus); int len = view.font->render.text_height() + 0.5; RGBA color = {1, 1, 1, 0.8}; view.icon_plus = make_plus_minus_icon(color, len, true); view.icon_minus = make_plus_minus_icon(color, len, false);} View_Definitions::View_Definitions(Workspace& ws, MenuType mtype) { float scale = get_default_camera().scale; cross.action = get_delete_box(); cross.img = ws.cross; ui.push_back(&cross); maxm.action = get_maximize_box(); maxm.img = ws.maxm; ui.push_back(&maxm); title.font = ws.default_font; title.text = "Definitions"; title.padding = 0; ui.push_back(&title); const char *tab_names[] = { "Types", "Enums", "Constants", "All" }; Column type_cols[] = { {ColumnString, 0, 0.5, 0, 0, "Name"}, {ColumnDec, 0, 0.2, 3, 5, "Size"}, {ColumnCheckbox, 0, 0.1, 1.5, 1.5, "BE"}, {ColumnCheckbox, 0, 0.1, 1.5, 1.5, "FP"}, {ColumnCheckbox, 0, 0.1, 1.5, 1.5, "S"} }; types.init(type_cols, nullptr, nullptr, nullptr, 5, 0); Column enum_cols[] = { {ColumnString, 0, 0.7, 0, 0, "Name"}, {ColumnDec, 0, 0.3, 0, 0, "Value"} }; enums.init(enum_cols, nullptr, nullptr, nullptr, 2, 0); tables.push_back(&types); tables.push_back(&enums); tables.push_back(&constants); tables.push_back(nullptr); update_tables(&ws); tabs.add(tab_names, 4); tabs.font = ws.default_font; tabs.default_color = ws.colors.dark; tabs.sel_color = ws.colors.scroll_back; tabs.hl_color = ws.colors.hl; tabs.event = [](Tabs *tabs) { if (tabs->sel >= 0) { auto ui = dynamic_cast<View_Definitions*>(tabs->parent); ui->view.data = ui->tables[tabs->sel]; } }; ui.push_back(&tabs); vscroll.back_color = ws.colors.scroll_back; vscroll.default_color = ws.colors.scroll; vscroll.hl_color = ws.colors.scroll_hl; vscroll.sel_color = ws.colors.scroll_sel; hscroll.back_color = ws.colors.scroll_back; hscroll.default_color = ws.colors.scroll; hscroll.hl_color = ws.colors.scroll_hl; hscroll.sel_color = ws.colors.scroll_sel; hscroll.vertical = false; view.show_column_names = true; view.font = ws.make_font(11, ws.colors.text, scale); view.default_color = ws.colors.scroll_back; view.hl_color = ws.colors.hl; view.sel_color = ws.colors.hl; view.back_color = ws.colors.scroll_back; view.hscroll = &hscroll; view.hscroll->content = &view; view.vscroll = &vscroll; view.vscroll->content = &view; arena.set_rewind_point(); Column cols[] = { {ColumnString, 0, 0.5, 0, 0, "Name"}, {ColumnString, 0, 0.5, 0, 0, "Value"} }; constants.init(cols, &arena, nullptr, nullptr, 0, 2); view.data = &constants; tabs.sel = 2; ui.push_back(&view); ui.push_back(&vscroll); ui.push_back(&hscroll); initial_width = 400; initial_height = 450;}