11using ImGui::BeginChild;
16using ImGui::Selectable;
22 ImVec2 canvas_p0, ImVec2 scrolling) {
24 const ImGuiIO &io = ImGui::GetIO();
25 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
26 const ImVec2 mouse_pos(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
29 if (mouse_pos.x >= entity.
x_ && mouse_pos.x <= entity.
x_ + 16 &&
30 mouse_pos.y >= entity.
y_ && mouse_pos.y <= entity.
y_ + 16) {
37 ImVec2 scrolling,
bool free_movement) {
39 const ImGuiIO &io = ImGui::GetIO();
40 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
41 const ImVec2 mouse_pos(io.MousePos.x - origin.x, io.MousePos.y - origin.y);
44 int new_x =
static_cast<int>(mouse_pos.x) / 16 * 16;
45 int new_y =
static_cast<int>(mouse_pos.y) / 16 * 16;
47 new_x =
static_cast<int>(mouse_pos.x) / 8 * 8;
48 new_y =
static_cast<int>(mouse_pos.y) / 8 * 8;
57 ImVec2 scrolling,
bool &is_dragging_entity,
61 std::string entity_type =
"Entity";
66 entity_type =
"Entrance";
68 entity_type =
"Sprite";
72 const auto is_hovering =
75 const auto drag_or_clicked = ImGui::IsMouseDragging(ImGuiMouseButton_Left) ||
76 ImGui::IsMouseClicked(ImGuiMouseButton_Left);
78 if (is_hovering && drag_or_clicked && !is_dragging_entity) {
79 dragged_entity = entity;
80 is_dragging_entity =
true;
81 }
else if (is_hovering && ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
82 current_entity = entity;
83 ImGui::OpenPopup(absl::StrFormat(
"%s editor", entity_type.c_str()).c_str());
84 }
else if (is_dragging_entity && dragged_entity == entity &&
85 ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
88 is_dragging_entity =
false;
89 dragged_entity =
nullptr;
90 }
else if (is_dragging_entity && dragged_entity == entity) {
91 if (ImGui::BeginDragDropSource()) {
92 ImGui::SetDragDropPayload(
"ENTITY_PAYLOAD", &entity,
94 Text(
"Moving %s ID: %s", entity_type.c_str(),
96 ImGui::EndDragDropSource();
99 entity->
x_ = dragged_entity->
x_;
100 entity->
y_ = dragged_entity->
y_;
106 bool set_done =
false;
110 if (ImGui::BeginPopup(
"Entrance Inserter")) {
111 static int entrance_id = 0;
116 ImGui::CloseCurrentPopup();
121 ImGui::CloseCurrentPopup();
131 static bool set_done =
false;
135 if (ImGui::BeginPopupModal(
"Entrance editor", NULL,
136 ImGuiWindowFlags_AlwaysAutoResize)) {
144 ImGui::CloseCurrentPopup();
149 ImGui::CloseCurrentPopup();
154 ImGui::CloseCurrentPopup();
163 if (ImGui::BeginPopup(
"Exit Inserter")) {
164 static int exit_id = 0;
168 ImGui::CloseCurrentPopup();
173 ImGui::CloseCurrentPopup();
181 static bool set_done =
false;
185 if (ImGui::BeginPopupModal(
"Exit editor", NULL,
186 ImGuiWindowFlags_AlwaysAutoResize)) {
196 static int centerY = 0;
197 static int centerX = 0;
200 static int linkPosture = 0;
201 static int spriteGFX = 0;
202 static int bgGFX = 0;
203 static int palette = 0;
204 static int sprPal = 0;
206 static int bottom = 0;
208 static int right = 0;
209 static int leftEdgeOfMap = 0;
232 static bool show_properties =
false;
233 Checkbox(
"Show properties", &show_properties);
234 if (show_properties) {
235 Text(
"Deleted? %s", exit.
deleted_ ?
"true" :
"false");
236 Text(
"Hole? %s", exit.
is_hole_ ?
"true" :
"false");
237 Text(
"Large Map? %s", exit.
large_map_ ?
"true" :
"false");
242 ImGui::RadioButton(
"None", &doorType, 0);
244 ImGui::RadioButton(
"Wooden", &doorType, 1);
246 ImGui::RadioButton(
"Bombable", &doorType, 2);
253 ImGui::RadioButton(
"None##Fancy", &fancyDoorType, 0);
255 ImGui::RadioButton(
"Sanctuary", &fancyDoorType, 1);
257 ImGui::RadioButton(
"Palace", &fancyDoorType, 2);
259 if (fancyDoorType != 0) {
266 static bool special_exit =
false;
267 Checkbox(
"Special exit", &special_exit);
290 ImGui::CloseCurrentPopup();
297 ImGui::CloseCurrentPopup();
303 ImGui::CloseCurrentPopup();
314 if (ImGui::BeginPopup(
"Item Inserter")) {
315 static size_t new_item_id = 0;
317 BeginChild(
"ScrollRegion", ImVec2(150, 150),
true,
318 ImGuiWindowFlags_AlwaysVerticalScrollbar);
329 ImGui::CloseCurrentPopup();
334 ImGui::CloseCurrentPopup();
343 static bool set_done =
false;
347 if (ImGui::BeginPopupModal(
"Item editor", NULL,
348 ImGuiWindowFlags_AlwaysAutoResize)) {
349 BeginChild(
"ScrollRegion", ImVec2(150, 150),
true,
350 ImGuiWindowFlags_AlwaysVerticalScrollbar);
364 ImGui::CloseCurrentPopup();
369 ImGui::CloseCurrentPopup();
380 static ImGuiTextFilter filter;
381 static int selected_id = 0;
382 static std::vector<SpriteItem> items;
386 for (
int i = 0; i < 256; ++i) {
387 items.push_back(
SpriteItem{i, zelda3::kSpriteDefaultNames[i].data()});
391 filter.Draw(
"Filter", 180);
393 if (ImGui::BeginTable(
"##sprites", 2,
394 ImGuiTableFlags_Sortable | ImGuiTableFlags_Resizable)) {
395 ImGui::TableSetupColumn(
"ID", ImGuiTableColumnFlags_DefaultSort, 0.0f,
398 ImGui::TableHeadersRow();
401 if (ImGuiTableSortSpecs *sort_specs = ImGui::TableGetSortSpecs()) {
402 if (sort_specs->SpecsDirty) {
404 sort_specs->SpecsDirty =
false;
409 for (
const auto &item : items) {
410 if (filter.PassFilter(item.name)) {
411 ImGui::TableNextRow();
412 ImGui::TableSetColumnIndex(0);
414 ImGui::TableSetColumnIndex(1);
416 if (Selectable(item.name, selected_id == item.id,
417 ImGuiSelectableFlags_SpanAllColumns)) {
418 selected_id = item.id;
419 onSpriteSelect(item.id);
429 if (ImGui::BeginPopup(
"Sprite Inserter")) {
430 static int new_sprite_id = 0;
432 BeginChild(
"ScrollRegion", ImVec2(250, 250),
true,
433 ImGuiWindowFlags_AlwaysVerticalScrollbar);
440 ImGui::CloseCurrentPopup();
445 ImGui::CloseCurrentPopup();
453 static bool set_done =
false;
457 if (ImGui::BeginPopupModal(
"Sprite editor", NULL,
458 ImGuiWindowFlags_AlwaysAutoResize)) {
459 BeginChild(
"ScrollRegion", ImVec2(350, 350),
true,
460 ImGuiWindowFlags_AlwaysVerticalScrollbar);
462 Text(
"%s", sprite.
name().c_str());
465 sprite.
set_id(selected_id);
475 ImGui::CloseCurrentPopup();
480 ImGui::CloseCurrentPopup();
Base class for all overworld and dungeon entities.
enum yaze::zelda3::GameEntity::EntityType entity_type_
virtual void UpdateMapProperties(uint16_t map_id)=0
A class for managing sprites in the overworld and underworld.
void UpdateMapProperties(uint16_t map_id) override
auto set_deleted(bool deleted)
Editors are the view controllers for the application.
void DrawExitInserterPopup()
void MoveEntityOnGrid(zelda3::GameEntity *entity, ImVec2 canvas_p0, ImVec2 scrolling, bool free_movement)
bool DrawSpriteEditorPopup(zelda3::Sprite &sprite)
void DrawItemInsertPopup()
bool DrawEntranceInserterPopup()
void DrawSpriteInserterPopup()
void DrawSpriteTable(std::function< void(int)> onSpriteSelect)
void HandleEntityDragging(zelda3::GameEntity *entity, ImVec2 canvas_p0, ImVec2 scrolling, bool &is_dragging_entity, zelda3::GameEntity *&dragged_entity, zelda3::GameEntity *¤t_entity, bool free_movement)
bool DrawOverworldEntrancePopup(zelda3::OverworldEntrance &entrance)
bool IsMouseHoveringOverEntity(const zelda3::GameEntity &entity, ImVec2 canvas_p0, ImVec2 scrolling)
bool DrawItemEditorPopup(zelda3::OverworldItem &item)
constexpr float kInputFieldSize
bool DrawExitEditorPopup(zelda3::OverworldExit &exit)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
bool InputHex(const char *label, uint64_t *data)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
void TextWithSeparators(const absl::string_view &text)
std::string HexByte(uint8_t byte, HexStringParams params)
const std::vector< std::string > kSecretItemNames
Main namespace for the application.
static const ImGuiTableSortSpecs * s_current_sort_specs
static void SortWithSortSpecs(ImGuiTableSortSpecs *sort_specs, std::vector< SpriteItem > &items)