#include "gui/imgui/imgui.h" #include "types.hpp" #include "ig001.hpp" #include "gui/imgui/imgui_stdlib.h" #include #include #include #include class EntityBase { public: virtual ~EntityBase() {} virtual std::string type() = 0; virtual std::string to_file() = 0; virtual void from_strtok() = 0; // Pointer to the entity base is pushed outside virtual void imgui() {} virtual void draw_prev(Vec2 offset, bool selected) {} virtual void draw(Vec2 offset, bool selected) {} virtual EntityBase *setpos(Vec2 pos) { return this; } }; inline static void draw_box2(Box2 box, bool selected, ImU32 color) { ImDrawList *list = ig::GetBackgroundDrawList(); list->AddRect(box.lefttop.im(), (box.lefttop + box.size).im(), color); if (selected) { list->AddLine(box.lefttop.im(), (box.lefttop + box.size).im(), color); list->AddLine((box.lefttop + Vec2(box.size.x, 0)).im(), (box.lefttop + Vec2(0, box.size.y)).im(), color); } } inline static void draw_vec2(Vec2 vec, bool selected, ImU32 color) { ImDrawList *list = ig::GetBackgroundDrawList(); list->AddLine((vec + Vec2(-10, -10)).im(), (vec + Vec2(10, 10)).im(), color); list->AddLine((vec + Vec2(-10, 10)).im(), (vec + Vec2(10, -10)).im(), color); if (selected) list->AddCircle(vec.im(), 7.0f, color); } #define TOKEN (strtok(NULL, " ")) #define TOKEN_INT (atoi(TOKEN)) #define TOKEN_DOUBLE (strtod(TOKEN, NULL)) // Defined in bundle.cpp extern char buf[1024]; class Hitbox: public EntityBase { public: std::string type() override { return "hitbox"; } std::string to_file() override { snprintf(buf, sizeof(buf), "HITBOX %.0lf %.0lf %.0lf %.0lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); return buf; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); } void imgui() override { DragBox2("", &box); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(0, 255, 0, 255)); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } Box2 box; }; class Player: public EntityBase { public: std::string type() override { return "player"; } std::string to_file() override { snprintf(buf, sizeof(buf), "PLAYER %.0lf %.0lf\n", pos.x, pos.y); return buf; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; pos = Vec2(a, b); } void imgui() override { DragVec2("Player Spawn", &pos); } void draw(Vec2 offset, bool selected) override { draw_vec2(pos + offset, selected, IM_COL32_WHITE); } EntityBase *setpos(Vec2 pos) override { this->pos = pos; return this; } Vec2 pos; }; class HazardRespawn: public EntityBase { public: std::string type() override { return "hazard_respawn"; } std::string to_file() override { snprintf(buf, sizeof(buf), "HAZARD_RESPAWN %.0lf %.0lf %.0lf %.0lf %.0lf %.0lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y, pos.x, pos.y); return buf; } void from_strtok() override { double a, b, c, d, e, f; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; e = TOKEN_DOUBLE; f = TOKEN_DOUBLE; box = Box2(a, b, c, d); pos = Vec2(e, f); } void imgui() override { DragBox2("", &box); DragVec2("Respawn", &pos); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(255, 0, 255, 255)); draw_vec2(pos + offset, selected, IM_COL32(255, 0, 255, 255)); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; this->pos = pos; return this; } Box2 box; Vec2 pos; }; class Hazard: public EntityBase { public: std::string type() override { return "hazard"; } std::string to_file() override { snprintf(buf, sizeof(buf), "HAZARD %.0lf %.0lf %.0lf %.0lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); return buf; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); } void imgui() override { DragBox2("", &box); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(255, 0, 0, 255)); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } Box2 box; }; class Textbox: public EntityBase { public: std::string type() override { return "textbox"; } std::string to_file() override { std::string str; snprintf(buf, sizeof(buf), "TEXTBOX %.0lf %.0lf %.0lf %.0lf %s ", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y, render_bundle.c_str()); str += buf; // Escape all the whitespaces for (char c: text) { switch (c) { case '\t': str += "\\t"; break; case ' ': str += "\\s"; break; case '\n': str += "\\n"; break; default: str.push_back(c); } } str += "\n"; return str; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); char *t = TOKEN; render_bundle = (t ? t : ""); t = TOKEN; std::string temp = (t ? t : ""); text.clear(); for (int i = 0; i < temp.size(); i++) { if (temp[i] == '\\') { if (i == temp.size() - 1) text.push_back('\\'); // Weird case else { if (temp[i + 1] == 's') text.push_back(' '); else if (temp[i + 1] == 'n') text.push_back('\n'); else if (temp[i + 1] == 't') text.push_back('\t'); i++; } } else text.push_back(temp[i]); } } void imgui() override { DragBox2("", &box); ig::InputText("Render Bundle", &render_bundle); ig::InputTextMultiline("##Text", &text, ImVec2(-1, 0)); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(0, 0, 255, 255)); // Draw text ImDrawList *list = ig::GetBackgroundDrawList(); list->AddText((box.lefttop + offset).im(), IM_COL32_WHITE, text.c_str()); list->AddText((box.lefttop + offset + Vec2(0, box.size.y)).im(), IM_COL32_WHITE, render_bundle.c_str()); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } std::string text; std::string render_bundle; Box2 box; }; class LevelTransition: public EntityBase { public: std::string type() override { return "level_transition"; } std::string to_file() override { snprintf(buf, sizeof(buf), "LEVEL_TRANSITION %.0lf %.0lf %.0lf %.0lf %s\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y, next_level.c_str()); return buf; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); char *t = TOKEN; if (t != NULL) next_level = t; else next_level.clear(); } void imgui() override { DragBox2("", &box); ig::InputText("Next Level", &next_level); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(255, 255, 0, 255)); // Draw text ImDrawList *list = ig::GetBackgroundDrawList(); list->AddText((box.lefttop + offset).im(), IM_COL32_WHITE, next_level.c_str()); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } Box2 box; std::string next_level; }; class CameraFocus: public EntityBase { public: std::string type() override { return "camera_focus"; } std::string to_file() override { snprintf(buf, sizeof(buf), "CAMERA_FOCUS %.0lf %.0lf %.0lf %.0lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); return buf; } void from_strtok() override { double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); } void imgui() override { DragBox2("", &box); } void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(0, 255, 255, 255)); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } Box2 box; }; class FillBox: public EntityBase { public: std::string type() override { return "fill_box"; } std::string to_file() override { snprintf(buf, sizeof(buf), "FILL_BOX %.0f %.0f %.0f %.0lf %.0lf %.0lf %.0lf\n", color[0] * 255, color[1] * 255, color[2] * 255, box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); return buf; } void from_strtok() override { color[0] = TOKEN_DOUBLE / 255.0; color[1] = TOKEN_DOUBLE / 255.0; color[2] = TOKEN_DOUBLE / 255.0; double a, b, c, d; a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; box = Box2(a, b, c, d); } void imgui() override { ig::ColorEdit3("Fill", color, ImGuiColorEditFlags_PickerHueWheel); DragBox2("", &box); } void draw_prev(Vec2 offset, bool selected) override { ImDrawList *d = ig::GetBackgroundDrawList(); Box2 world = box.offset(offset); d->AddRectFilled(world.lefttop.im(), (world.lefttop + world.size).im(), ImColor(color[0], color[1], color[2])); } EntityBase *setpos(Vec2 pos) override { box.lefttop = pos; return this; } Box2 box; float color[3]; };