#include "GUI.h" #include "Rect.hpp" #include "interpreter/Interpreter.hpp" #include "imgui.h" #include "imgui_internal.h" using namespace tp; using namespace obj; namespace ImGui { bool SubMenuBegin(const char* desc, int level); void SubMenuEnd(int level); void ToolTip(const char* desc); struct PopupData { bool opened = false; bool ishovered = false; tp::Vec2F p1; tp::Vec2F p2; operator bool() { return opened; } }; PopupData HoverPopupBegin(const char* id, tp::Vec2F size, tp::Vec2F pos = tp::Vec2F(-1), int flags = 0); void HoverPopupEnd(PopupData& in); void ApplyStyle(tp::halnf dpmm, float font_size_mm = 5, float ui_scale = 1); }; ImGui::PopupData ImGui::HoverPopupBegin(const char* str_id, tp::Vec2F size, tp::Vec2F pos_p, ImGuiPopupFlags popup_flags) { ImGui::PopupData out; out.ishovered = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup); if (out.ishovered) { ImVec2 pos; if (pos_p == tp::Vec2F(-1)) { pos = GImGui->CurrentWindow->DC.CursorPos; } else { pos.x = pos_p.x; pos.y = pos_p.y; } ImGui::SetNextWindowPos(pos); out.p1 = { pos.x, pos.y }; ImGui::OpenPopup(str_id); out.p2 = out.p1; out.p2.x += ImGui::GetWindowWidth(); } if (BeginPopup(str_id, ImGuiWindowFlags_NoMove)) { out.opened = true; auto pos = GetWindowPos(); out.p1 = { pos.x, pos.y }; out.p2 = out.p1; out.p2.x += ImGui::GetWindowWidth(); } return out; } void ImGui::HoverPopupEnd(ImGui::PopupData& in) { if (!in.opened) { return; } in.ishovered |= IsWindowHovered( ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ChildWindows ); tp::Vec2F mousepos = { ImGui::GetMousePos().x, ImGui::GetMousePos().y }; tp::halnf tollerance = 10; tp::RectF tollerace_rect(tp::Vec2F(in.p1.x, in.p1.y - tollerance), tp::Vec2F(in.p2.x - in.p1.x, tollerance * 2.f)); bool is_tollerance = tollerace_rect.isInside(mousepos); if (!(in.ishovered || is_tollerance)) { CloseCurrentPopup(); } EndPopup(); } obj::ObjectsGUI::~ObjectsGUI() { if (mClipboard) { obj::NDO->destroy(mClipboard); } for (auto iter : mViewStack) { obj::NDO->destroy(iter->obj); } } void obj::ObjectsGUI::setClipboard(obj::Object* obj) { if (mClipboard) { obj::NDO->destroy(mClipboard); } mClipboard = obj; if (mClipboard) { obj::NDO->increaseReferenceCount(obj); } } obj::Object* obj::ObjectsGUI::getClipboard() { return mClipboard; } obj::Object* imgui_object_create_menu(obj::TypeGroups* type_group = nullptr) { obj::Object* newo = nullptr; if (!type_group) { type_group = &obj::NDO->type_groups; } for (auto childo : *type_group->getChilds()) { if (childo->val->isGroup()) { if (ImGui::BeginMenu((childo->key).c_str())) { newo = imgui_object_create_menu(childo->val); ImGui::EndMenu(); } continue; } if (ImGui::Button((childo->key).c_str(), { 100, 0 })) { if (childo->key == "null") { newo = NDO_NULL; } else { newo = obj::NDO->create(childo->key); } } } return newo; } obj::ObjectsGUI::ObjectsGUI() { assert(obj::NDO && "Objects library is not initialized"); } void obj::ObjectsGUI::cd(obj::Object* child, const std::string& name) { mActive = child; mViewStack.pushBack({ mActive, name }); obj::NDO->increaseReferenceCount(child); } void obj::ObjectsGUI::cdup() { if (mViewStack.length() > 1) { obj::NDO->destroy(mViewStack.last()->data.obj); mViewStack.popBack(); mActive = mViewStack.last()->data.obj; } } void obj::ObjectsGUI::preview(obj::Object* obj) { if (objects_api::cast(obj)) { auto linko = objects_api::cast(obj); bool no_link_preview = !linko->getLink(); tp::alni max_depth = 5; tp::alni depth_count = 0; tp::Map link_lookup; obj::LinkObject* link_iter = linko; while (link_iter && link_iter->getLink() && !no_link_preview) { link_iter = objects_api::cast(link_iter->getLink()); depth_count++; if (link_lookup.presents(tp::alni(link_iter))) { no_link_preview = true; } else { link_lookup.put(tp::alni(link_iter), 0); } no_link_preview |= max_depth < depth_count; } if (linko->getLink()) { if (!no_link_preview) { ImGui::Text("=> "); ImGui::SameLine(); preview(linko->getLink()); } else { ImGui::Text("Max preview depth exceeded"); } } else { ImGui::Text("Link Is Null"); } } else if (objects_api::cast(obj)) { tp::alni& val = objects_api::cast(obj)->val; int gui_val = int(val); ImGui::InputInt(" ", &gui_val); val = tp::alni(gui_val); } else if (objects_api::cast(obj)) { auto stringo = objects_api::cast(obj); static char val[2048] = { " " }; if (stringo->val != val) { assert(stringo->val.size() < 2048); tp::memCopy(val, stringo->val.c_str(), stringo->val.size() + 1); } ImGui::InputText("", val, 2048); if (stringo->val != val) { stringo->val = val; } } else if (objects_api::cast(obj)) { boolView((obj::BoolObject*) obj); } else if (objects_api::cast(obj)) { tp::alnf& val = objects_api::cast(obj)->val; auto gui_val = float(val); ImGui::InputFloat(" ", &gui_val); val = tp::alnf(gui_val); } else if (objects_api::cast(obj)) { enumView((obj::EnumObject*) obj); } else if (objects_api::cast(obj)) { colorView((obj::ColorObject*) obj); } else { ImGui::Text(obj->type->name); ImGui::SameLine(); ImGui::Text(" (No Preview) "); } } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::interpreterView(obj::InterpreterObject* self) { using namespace ImGui; auto& interp = self->mInterpreter; // not running state if (interp.finished()) { Text("State: Not Runnig"); if (Selectable("Debug")) { self->debug(); } auto res = ObjectsGUI::classView(self); if (res) { return res; } return {}; } // running state BeginChild("dockable"); { auto id = ImGui::GetCurrentWindow()->ID; DockSpace(id); } EndChild(); Begin("ByteCodeView"); { if (Button("Step")) { interp.stepBytecode(); if (interp.finished()) { End(); return {}; } } SameLine(); if (Button("Step In")) { interp.stepBytecodeIn(); if (interp.finished()) { End(); return {}; } } SameLine(); if (Button("Step out")) { interp.stepBytecodeOut(); if (interp.finished()) { End(); return {}; } } BeginChild("frame", { 0, 0 }, 0, ImGuiWindowFlags_NoBackground); const auto bytecode = interp.mCallStack.getBytecode(); tp::halni idx = 0; for (auto ip = 0; ip < bytecode->mInstructions.size();) { auto opcode = bytecode->mInstructions[ip]; auto info = obj::gOpcodeInfos.fetch(opcode); PushID(info.name); TextColored(ImVec4(1.f, 1.f, 1.f, 0.5f), "%i", idx); SameLine(); if (bytecode->mInstructionIdx == ip) { TextColored(ImVec4(1.f, 0.5f, 0.5f, 1.f), info.name); } else { Text(info.name); } // INFO auto hd = HoverPopupBegin(std::to_string((tp::alni) ip).c_str(), { 400, 250 }); if (hd) { Text(info.desc); if (info.operands.len) { Text("Operands :"); for (auto i = 0; i < info.operands.len; i++) { auto op = info.operands.buff[i]; Text(" %i : %s : %s", i, op.obj_type, op.desc); } } if (info.params.len) { Text("Params : "); for (auto i = 0; i < info.params.len; i++) { auto param = info.params.buff[i]; Text(" %i : %i bytes : %s ", i, param.bytes, param.desc); } } } HoverPopupEnd(hd); PopID(); ip += info.opsize(); idx++; } EndChild(); } End(); Begin("SourceCodeView"); { stringView(interp.mCallStack.mStack.last().mMethod->mScript->mReadable); } End(); Begin("OperandStack"); { if (!interp.mOperandsStack.mIdx) { Text("No Operands"); } for (auto i = 0; i < interp.mOperandsStack.mIdx; i++) { auto operand = interp.mOperandsStack.mBuff[i]; tp::alni operand_val = (tp::alni) operand; if (operand_val == 0) { Text("nullptr"); } else if (tp::uint2(operand_val) == 0) { Text("2 BYTE VAL : %i", tp::uint2(operand_val)); } else { if (Selectable(operand->type->name, false, 0, ImVec2(100, 0))) { End(); return { operand, "operand" }; } SameLine(); PushID((tp::alni) operand); preview(operand); PopID(); } } } End(); Begin("ScopeStack"); { for (auto i = 0; i < interp.mScopeStack.mIdx; i++) { if (TreeNode(std::to_string((tp::alni) i).c_str())) { auto& scope = interp.mScopeStack.mBuff[i]; if (TreeNode("Locals")) { for (auto local : scope.mLocals) { if (Selectable(local->key.c_str(), false, 0, ImVec2(100, 0))) { TreePop(); TreePop(); End(); return { local->val, local->key }; } PushID(local->key.c_str()); SameLine(); preview(local->val); PopID(); } TreePop(); } if (TreeNode("Temps")) { tp::alni idx = 0; for (auto tmp : scope.mTemps) { if (Selectable(std::to_string(idx).c_str(), false, 0, ImVec2(100, 0))) { TreePop(); TreePop(); End(); return { tmp.data(), "temp" }; } idx++; } TreePop(); } TreePop(); } } } End(); Begin("CallStack"); { for (auto i = 0; i < interp.mCallStack.mStack.size(); i++) { auto method = interp.mCallStack.mStack[i].mMethod; PushID(i); if (Selectable("method")) { PopID(); End(); return { method, "call stack method" }; } PopID(); } } End(); Begin("ConstPool"); { auto bc = interp.mCallStack.getBytecode(); tp::alni idx = 0; for (auto const_obj : bc->mConstants) { PushID(idx); if (Button(const_obj.data()->type->name)) { End(); PopID(); return { const_obj.data(), std::to_string(idx) }; } SameLine(); preview(const_obj.data()); PopID(); idx++; } } End(); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::colorView(obj::ColorObject* in) { ImGui::ColorEdit4(" ", &in->mCol.r); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::enumView(obj::EnumObject* obj) { if (!obj->entries) { ImGui::Text("enum is uninitialized"); return {}; } if (ImGui::BeginCombo(" ", obj->getActiveName())) { for (tp::uhalni idx = 0; idx < obj->nentries; idx++) { if (ImGui::Selectable(obj->getItemName(idx))) { obj::NDO->set(obj, tp::alni(idx)); } } ImGui::EndCombo(); } return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::boolView(obj::BoolObject* obj) { tp::alni& val = obj->val; bool gui_val = bool(val); ImGui::Checkbox(gui_val ? "True" : "False", &gui_val); val = tp::alni(gui_val); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::floatView(obj::FloatObject* obj) { tp::alnf& val = obj->val; float gui_val = float(val); ImGui::InputFloat("Value", &gui_val); val = tp::alnf(gui_val); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::nullView(obj::NullObject* in) { ImGui::Text("Null Object."); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::linkoView(obj::LinkObject* obj) { if (obj->getLink()) { ImGui::Text("%s at %x", obj->getLink()->type->name, obj->getLink()); if (ImGui::Selectable("View")) { return { obj->getLink(), "adress" }; } } else { ImGui::Text("Link Is Null"); } if (ImGui::Selectable("Set from clipboard")) { obj->setLink(mClipboard); } if (ImGui::Selectable("Copy value")) { setClipboard(obj->getLink()); } if (ImGui::Selectable("Set Null")) { obj->setLink(nullptr); } return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::intoView(obj::IntObject* obj) { ImGui::Text("Int Value: "); ImGui::SameLine(); int val = (int) obj->val; ImGui::InputInt(" ", &val); obj->val = (tp::alni) val; return {}; } void obj::ObjectsGUI::dictViewDrawCreate(obj::DictObject* dict) { if (ImGui::BeginPopupContextItem("child_2", ImGuiPopupFlags_MouseButtonRight)) { if (mClipboard) { if (ImGui::Selectable("Paste")) { tp::alni idx = 1; auto name_base = std::string("clipboard ") + std::string(mClipboard->type->name) + " "; auto name_out = name_base; while (dict->presents(name_out)) { name_out = name_base + std::to_string(idx); idx++; } dict->put(name_out, mClipboard); } } if (ImGui::BeginMenu("Create")) { obj::Object* newo = imgui_object_create_menu(); if (newo) { tp::alni idx = 1; auto name_base = std::string("new ") + std::string(newo->type->name) + " "; auto name_out = name_base; while (dict->presents(name_out)) { name_out = name_base + std::to_string(idx); idx++; } dict->put(name_out, newo); } ImGui::EndMenu(); } ImGui::EndPopup(); } } void obj::ObjectsGUI::dictViewEdit(obj::DictObject* dict, const std::string& key, obj::Object* obj, bool& popup) { if (ImGui::BeginPopupContextItem(key.c_str(), ImGuiPopupFlags_MouseButtonRight)) { popup = true; ImGui::Text("%s at %x", obj->type->name, obj); if (key.size() > 100) { ImGui::Text("name is too large"); } else { if (mLastNameEditObject != obj) { tp::memCopy(mNameEdit, key.c_str(), key.size() + 1); mLastNameEditObject = obj; } if (ImGui::InputTextEx(" ", "new name", mNameEdit, 100, { 140, 30 }, ImGuiInputTextFlags_EnterReturnsTrue)) { auto idx = dict->presents(mNameEdit); if (bool(idx)) { // Notify("Object with such name Already Exists"); } else { obj::NDO->increaseReferenceCount(obj); dict->remove(key); auto id = std::string(mNameEdit); dict->put(id, obj); obj::NDO->destroy(obj); } } } if (ImGui::Selectable("Remove")) { dict->remove(key); } if (ImGui::Selectable("Copy Link")) { setClipboard(obj); } ImGui::EndPopup(); } } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::dictView(obj::DictObject* obj) { bool popup = false; auto table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable; ImGui::BeginChild("frame", { 0, 0 }, 0, ImGuiWindowFlags_NoBackground); { if (!obj->getItems().size()) { ImGui::Text("Dictinary Is Empty. "); } if (ImGui::BeginTable("Members", 2, table_flags)) { ImGui::TableSetupColumn("name"); ImGui::TableSetupColumn("info"); for (auto childo : obj->getItems()) { ImGui::TableNextRow(0, 30); ImGui::TableSetColumnIndex(0); if (ImGui::Selectable(childo->key.c_str())) { ImGui::EndTable(); ImGui::EndChild(); return { childo->val, { std::string(childo->val->type->name) + " " + childo->key } }; } dictViewEdit(obj, childo->key, childo->val, popup); ImGui::TableSetColumnIndex(1); ImGui::PushID((int) childo->key.c_str()[0]); preview(childo->val); ImGui::PopID(); } ImGui::EndTable(); } } ImGui::EndChild(); if (!popup) { dictViewDrawCreate(obj); } return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::listView(obj::ListObject* obj) { bool popup = false; ViewStackNode out; if (!obj->getItems().length()) { ImGui::Text("List Is Empty. "); } ImGui::BeginChild("frame", { 0, 0 }, 0, ImGuiWindowFlags_NoBackground); if (ImGui::BeginTable("Items", 2)) { ImGui::TableSetupColumn("type", ImGuiTableColumnFlags_WidthFixed, 120.0f); ImGui::TableSetupColumn("info"); tp::alni idx = 0; for (auto childo : obj->getItems()) { ImGui::TableNextRow(0, 36); ImGui::TableSetColumnIndex(0); if (ImGui::Selectable(std::to_string(idx).c_str())) { out = ViewStackNode(childo.data(), { std::string(childo->type->name) + "at" + std::to_string(idx) }); break; } { if (ImGui::BeginPopupContextItem(std::to_string(idx).c_str(), ImGuiPopupFlags_MouseButtonRight)) { popup = true; ImGui::Text("%s at %x", childo->type->name, childo.data()); if (ImGui::Selectable("Remove")) { obj->delNode(childo.node()); ImGui::EndPopup(); break; } if (ImGui::Selectable("Copy Link")) { setClipboard(childo.data()); ImGui::EndPopup(); break; } if (childo.node()->prev && ImGui::Selectable("Move Up")) { tp::swap(childo.node()->prev->data, childo.data()); ImGui::EndPopup(); break; } if (childo.node()->next && ImGui::Selectable("Move Down")) { tp::swap(childo.node()->next->data, childo.data()); ImGui::EndPopup(); break; } ImGui::EndPopup(); } } ImGui::TableSetColumnIndex(1); ImGui::PushID((int) idx); preview(childo.data()); ImGui::PopID(); idx++; } ImGui::EndTable(); } ImGui::EndChild(); if (!popup && ImGui::BeginPopupContextItem("child_2", ImGuiPopupFlags_MouseButtonRight)) { if (ImGui::Selectable("Paste")) { obj->pushBack(mClipboard); } if (ImGui::BeginMenu("Create")) { obj::Object* newo = imgui_object_create_menu(); if (newo) { obj->pushBack(newo); } ImGui::EndMenu(); } ImGui::EndPopup(); } return out; } void drawStrView(std::string& in) { static char val[2048] = { " " }; if (in != val) { assert(in.size() < 2048); tp::memCopy(val, in.c_str(), in.size() + 1); } ImGui::BeginChild("str_edit"); ImGui::InputTextMultiline(" ", val, 2048, { ImGui::GetWindowWidth(), ImGui::GetWindowHeight() }); ImGui::EndChild(); if (in != val) { in = val; } } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::stringView(obj::StringObject* in) { drawStrView(in->val); return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::classView(obj::ClassObject* self) { bool popup = false; auto dict = self->members; ImGui::BeginChild("frame", { 0, 0 }, 0, ImGuiWindowFlags_NoBackground); if (!dict->getItems().size()) { ImGui::Text("No Members"); } auto table_flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable; auto tree_flags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed; ImGuiWindow* window = ImGui::GetCurrentWindow(); auto n_methods = 0; for (auto childo : dict->getItems()) { if (childo->val->type == &obj::MethodObject::TypeData) { n_methods++; } } if (n_methods != dict->getItems().size() && ImGui::TreeNodeBehavior(window->GetID("Members"), tree_flags, "Members", 0)) { if (ImGui::BeginTable("Members", 2, table_flags)) { ImGui::TableSetupColumn("name"); ImGui::TableSetupColumn("info"); tp::alni idx = 0; for (auto childo : dict->getItems()) { if (childo->val->type == &obj::MethodObject::TypeData) { continue; } ImGui::TableNextRow(0, 30); ImGui::TableSetColumnIndex(0); if (ImGui::Selectable(childo->key.c_str())) { ImGui::EndTable(); ImGui::TreePop(); ImGui::EndChild(); return { childo->val, { std::string(childo->val->type->name) + childo->key } }; } dictViewEdit(dict, childo->key, childo->val, popup); ImGui::TableSetColumnIndex(1); ImGui::PushID((int) idx); preview(childo->val); ImGui::PopID(); } ImGui::EndTable(); idx++; } ImGui::TreePop(); } if (n_methods && ImGui::TreeNodeBehavior(window->GetID("Methods"), tree_flags, "Methods", 0)) { for (auto childo : dict->getItems()) { if (childo->val->type == &obj::MethodObject::TypeData) { if (ImGui::Selectable(childo->key.c_str())) { ImGui::TreePop(); ImGui::EndChild(); return { childo->val, { std::string(childo->val->type->name) + childo->key } }; } dictViewEdit(dict, childo->key, childo->val, popup); } } ImGui::TreePop(); } ImGui::EndChild(); if (!popup) { dictViewDrawCreate(dict); } return {}; } obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::methodView(obj::MethodObject* in) { if (in->mScript->mBytecode.mInstructions.size()) { if (ImGui::Button("Recompile")) { in->compile(); } ImGui::SameLine(); if (ImGui::Button("Execute")) { obj::Interpreter interp; interp.execAll(in); } } else { if (ImGui::Button("Compile")) { in->compile(); } } ImGui::SameLine(); auto ret = stringView(in->mScript->mReadable); if (ret.obj) { return ret; } return {}; } void obj::ObjectsGUI::explorer() { if (ImGui::Button("<")) { cdup(); } ImGui::SameLine(); ImGui::BeginChild( "child_path", { 0, 45 }, false, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_HorizontalScrollbar ); tp::List rev_path; for (auto childo = mViewStack.last(); childo; childo = childo->prev) { rev_path.pushBack(&childo->data); } tp::alni idx = 0; for (auto childo = rev_path.last(); childo; childo = childo->prev) { ImGui::PushID((int) idx); bool go_back = false; if (childo == rev_path.last()) { go_back = ImGui::Button(childo->data->id.c_str()); ImGui::SameLine(); } else { go_back = ImGui::Button((childo->data->id).c_str()); ImGui::SameLine(); } ImGui::PopID(); if (ImGui::BeginPopupContextItem(nullptr, ImGuiPopupFlags_MouseButtonRight)) { obj::Object* curretn_object = childo->data->obj; ImGui::Text("%s at %x", curretn_object->type->name, curretn_object); ImGui::Separator(); if (ImGui::Selectable("Copy Link")) { setClipboard(curretn_object); } if (ImGui::Selectable("Instantiate ")) { setClipboard(obj::NDO->instantiate(curretn_object)); // Notify("Object copied to clipboard"); } ImGui::Separator(); static char path_str[100] = { "data.o\0" }; static bool compressed = true; ImGui::InputTextEx(" ", "save path", path_str, 100, { 100, 30 }, 0); bool save_object = ImGui::Button("Save Object"); ImGui::SameLine(); ImGui::Checkbox("Compressed", &compressed); bool load_object = ImGui::Button("Load Object"); if (save_object) { obj::NDO->save(curretn_object, path_str, compressed); // Notify("Object saved"); } if (load_object) { obj::Object* loadedo = obj::NDO->load(path_str); if (loadedo) { setClipboard(loadedo); // Notify("Object copied to clipboard"); } else { // Notify("Can't load Object"); } } ImGui::EndPopup(); } if (go_back) { while (&mViewStack.last()->data != childo->data) { cdup(); } mActive = childo->data->obj; ImGui::EndChild(); return; } idx++; } ImGui::Text(" "); ImGui::EndChild(); ImGui::Separator(); ViewStackNode new_active; if (objects_api::cast(mActive)) { new_active = nullView((obj::NullObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = linkoView((obj::LinkObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = intoView((obj::IntObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = stringView((obj::StringObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = listView((obj::ListObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = dictView((obj::DictObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = interpreterView((obj::InterpreterObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = classView((obj::ClassObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = boolView((obj::BoolObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = floatView((obj::FloatObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = enumView((obj::EnumObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = methodView((obj::MethodObject*) mActive); } else if (objects_api::cast(mActive)) { new_active = colorView((obj::ColorObject*) mActive); } else { ImGui::Text("Preview is Unavailable"); } if (new_active != 0) { cd(new_active.obj, new_active.id); } } void obj::ObjectsGUI::properties(const obj::ObjectType* type, bool top_of_tree_vew) { assert(type); assert(mActive); if (mActive->type != type) return; ImGui::Text(" RefCount : %i", obj::NDO->getReferenceCount(mActive)); ImGui::Text(" Type : %s", type->name); if (ImGui::TreeNode("Description ")) { if (type->description) { ImGui::Text(type->description); } else { ImGui::Text("Description is not given"); } ImGui::TreePop(); } if (ImGui::TreeNode("Size")) { if (0 && ImGui::TreeNode("Top Level Type")) { ImGui::Text("RAM : "); ImGui::Indent(); ImGui::Text("Only Structure : %i bytes", type->size - (type->base ? type->base->size : 0)); ImGui::Text("With Non-Object Links : Not Supported"); ImGui::Unindent(); ImGui::Text("Disk :"); ImGui::Indent(); ImGui::Text("Only Structure : Currently Not Supported"); ImGui::Text("With Object Links : Not Supported"); ImGui::Unindent(); ImGui::TreePop(); } // if (ImGui::TreeNode("Full Type Hierarchy")) { ImGui::Text("RAM : "); ImGui::Indent(); ImGui::Text("Only Structure : %i bytes", type->size); ImGui::Text("With Non-Object Links : %i bytes", obj::NDO->objsize_ram(mActive)); ImGui::Text("Full Size Recursive : %i bytes", obj::NDO->objsize_ram_recursive(mActive)); ImGui::Unindent(); ImGui::Text("Disk :"); ImGui::Indent(); ImGui::Text("Only Structure : %i bytes", obj::NDO->objsize_file(mActive)); ImGui::Text("With Object Links : %i bytes", obj::NDO->objsize_file_recursive(mActive)); ImGui::Unindent(); // ImGui::TreePop(); //} ImGui::TreePop(); } if (ImGui::TreeNode("Base Type")) { if (type->base) { properties(type->base, false); } else { ImGui::Text("No base type"); } ImGui::TreePop(); } } void obj::ObjectsGUI::draw() { if (!mShowDebugInfo) { return; } if (mViewStack.length()) { if (ImGui::Begin("Explorer")) { explorer(); } ImGui::End(); if (ImGui::Begin("Objet Info")) { properties(mActive->type); } ImGui::End(); } else { ImGui::Text("ViewStack is Empty"); } auto& io = ImGui::GetIO(); mCaptureInput = (io.WantCaptureMouse || io.WantCaptureKeyboard); }