diff --git a/assets/included_level/bg.lvl b/assets/included_level/bg.lvl new file mode 100644 index 0000000..66c990d Binary files /dev/null and b/assets/included_level/bg.lvl differ diff --git a/assets/included_level/level.json b/assets/included_level/level.json index 99ab7aa..4204929 100644 --- a/assets/included_level/level.json +++ b/assets/included_level/level.json @@ -5,9 +5,9 @@ "editor-version":1.000000, "entities":[ { - "color":"#CDCDCDCD", - "flip-h":-431602080.000000, - "flip-v":-431602080.000000, + "color":"#C5549AA3", + "flip-h":0.000000, + "flip-v":-0.000000, "height":16.000000, "metadata":null, "name":"Mr Bigg", @@ -25,12 +25,22 @@ "cell-height":16.000000, "cell-width":16.000000, "cols":64.000000, - "name":"0", + "name":"Colliding Tiles", + "order":1.000000, + "rows":64.000000 + }, + { + "binary-path":"bg.lvl", + "cell-height":16.000000, + "cell-width":16.000000, + "cols":64.000000, + "name":"Background", + "order":0.000000, "rows":64.000000 } ], - "map-cols":-842150451.000000, - "map-rows":-842150451.000000, + "map-cols":0.000000, + "map-rows":-962889206.000000, "map-type":true, "name":"Test Level", "tags":[ diff --git a/assets/included_level/test.lvl b/assets/included_level/test.lvl index 22eb218..8d09976 100644 Binary files a/assets/included_level/test.lvl and b/assets/included_level/test.lvl differ diff --git a/include/App/AboutDialog.hpp b/include/App/AboutDialog.hpp index 8ea9a57..cbc6b87 100644 --- a/include/App/AboutDialog.hpp +++ b/include/App/AboutDialog.hpp @@ -4,6 +4,14 @@ class AboutDialog : public JUI::Window { public: + AboutDialog() : Window() { + Title("Redacted 2D Map Editor"); + Size({300_px, 375_px}); + } + + explicit AboutDialog(JUI::Widget* parent) : AboutDialog() { + Parent(parent); + } protected: private: diff --git a/include/App/EditorApp.hpp b/include/App/EditorApp.hpp index 9eae71a..50909b4 100644 --- a/include/App/EditorApp.hpp +++ b/include/App/EditorApp.hpp @@ -99,6 +99,10 @@ public: int focus_layer_index = 0; + bool HasLevelFileOpen() const { + return loaded_level != nullptr; + } + JUI::Window * CreateAppInfoDialogWindow(JUI::Widget *parent); Layer* GetLayer(int index) diff --git a/include/App/LayerView.hpp b/include/App/LayerView.hpp index a803d01..377091d 100644 --- a/include/App/LayerView.hpp +++ b/include/App/LayerView.hpp @@ -16,90 +16,27 @@ public: float layer_entry_height = 30; Event LayerVisibilityToggled; Event ActiveLayerSelected; - LayerView() : JUI::Window() - { - this->Title("Layers"); - Name("LayerView"); + Event MoveLayerUp; + Event MoveLayerDown; - scroller = new JUI::ScrollingRect(this->Content()); - scroller->Size({100_percent, 100_percent}); + /// Constructs a new LayerView by assigning it to a child of the given `parent` Widget. + explicit LayerView(Widget* parent); - layout = new JUI::VerticalListLayout(this->Content()); + /// The base constructor initializes the core elements that are persistent in the layer view. + /// This constructor is to be called in a chain from the other constructors. + LayerView(); - } - explicit LayerView(Widget* parent) : LayerView() - { - Parent(parent); - } - void UpdateComponents(const Level* level) - { - for (auto entry : entry_elements) { - entry->Parent(nullptr); - delete entry; - } + /// + void UpdateComponents(const Level* level); - entry_elements.clear(); + void ClearComponents(); - for (auto layer : level->layers) - { - auto* rect = new JUI::Rect(layout); - rect->Size({100_percent, JUI::UDim(layer_entry_height, 0)}); - auto* vis_chk = new JUI::Checkbox(rect); - vis_chk->Size({JUI::UDim(layer_entry_height, 0), JUI::UDim(layer_entry_height, 0)}); - auto* label = new JUI::TextButton(rect); - label->Name("Label"); - label->Position({JUI::UDim(layer_entry_height, 0), 0_px}); - label->Size({100_percent-JUI::UDim(layer_entry_height*2, 0), JUI::UDim(layer_entry_height, 0)}); - label->Content(layer->name); - label->TextColor(Colors::Black); - - label->OnReleaseEvent += [this, label, layer] (auto a, auto b, auto c) mutable { - ActiveLayerSelected.Invoke(layer->name); - label->BaseBGColor(Colors::Gray); - }; - - vis_chk->OnReleaseEvent += [this, layer](auto a, auto b, auto c) mutable { - LayerVisibilityToggled.Invoke(layer->name, !layer->visible); - }; - - auto* layer_order_shift_box = new JUI::Rect(rect); - layer_order_shift_box->Size({JUI::UDim(layer_entry_height, 0), JUI::UDim(layer_entry_height, 0)}); - layer_order_shift_box->Position({100_percent-JUI::UDim(layer_entry_height, 0), 0_px}); +protected: - auto layer_up = new JUI::TextButton(layer_order_shift_box); - layer_up->Size({100_percent, 50_percent}); - layer_up->TextColor(Colors::Black); - layer_up->Content("/\\"); - layer_up->Center(); - - layer_up->OnReleaseEvent += [this, layer] (auto a, auto b, auto c) mutable { - if (layer->order > 0) - layer->order--; - }; - - - auto* layer_down = new JUI::TextButton(layer_order_shift_box); - layer_down->Size({100_percent, 50_percent}); - layer_down->Content("\\/"); - layer_down->TextColor(Colors::Black); - layer_down->Position({0_percent, 50_percent}); - layer_down->Center(); - - layer_down->OnReleaseEvent += [this, level, layer] (auto a, auto b, auto c) mutable { - const int layer_count = level->layers.size(); - if (layer->order <= layer_count) - layer->order++; - }; - - - - entry_elements.push_back(rect); - - } - } - + /// The transient components that will be re-generated when UpdateComponents is called. std::vector entry_elements; JUI::ScrollingRect* scroller = nullptr; JUI::VerticalListLayout* layout = nullptr; + const Level* stored_level_data; }; \ No newline at end of file diff --git a/include/App/NewMapDialog.hpp b/include/App/NewMapDialog.hpp index 2eeffd4..35b28e6 100644 --- a/include/App/NewMapDialog.hpp +++ b/include/App/NewMapDialog.hpp @@ -9,7 +9,6 @@ public: NewMapDialog() : JUI::Window() { Name("NewMapDialog"); - } explicit NewMapDialog(Widget* parent) : NewMapDialog() diff --git a/main.cpp b/main.cpp index a03a40b..973ece9 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,9 @@ #include "cmake-build-debug/_deps/rewindow-src/include/ReWindow/Logger.h" -int main() { +int main(int argc, char** argv) { + + ReWindow::Logger::Debug.EnableConsole(false); diff --git a/src/App/EditorApp.cpp b/src/App/EditorApp.cpp index 51c8117..4294c77 100644 --- a/src/App/EditorApp.cpp +++ b/src/App/EditorApp.cpp @@ -236,7 +236,6 @@ void EditorApp::LoadLevel(const std::filesystem::path& level_meta_path) for (auto layer : loaded_level->layers) layer->Load(); - tileset_view = new TilesetView(loaded_tileset, loaded_tilesheet, scene); tileset_view->TileSelected += [this](int id) mutable { @@ -244,6 +243,7 @@ void EditorApp::LoadLevel(const std::filesystem::path& level_meta_path) }; layer_view->UpdateComponents(loaded_level); + layer_view->Open(); data_ready = true; } @@ -392,8 +392,6 @@ std::string tolower(const std::string& s) { void EditorApp::BindConsoleCallbacks() { - - // TODO: This parsing pattern is duplicated between at least 2 other projects at this point. // TODO: Move up into JUI or a separate package. console->OnInput += [this] (const std::string& input) @@ -451,6 +449,15 @@ void EditorApp::CreateWidgets() { scene = new JUI::Scene(); + + /*auto* blank_text = new JUI::TextRect(scene); + blank_text->Content("Open or create a new level file to get started!"); + blank_text->Center(); + blank_text->AutoFitSizeToText(true); + blank_text->Position({20_px, 20_px});*/ + + + app_info_dialog = CreateAppInfoDialogWindow(scene); fps_graph = new JUI::FpsGraph(scene); @@ -467,10 +474,10 @@ void EditorApp::CreateWidgets() BindConsoleCallbacks(); nmd = new NewMapDialog(scene); - nmd->Close(); + nmd->Open(); layer_view = new LayerView(scene); - layer_view->Open(); + layer_view->Close(); topbar = new JUI::UtilityBar(scene); @@ -927,8 +934,11 @@ void EditorApp::Draw() auto bruhbruh = camera.CameraToScreenSpace(camera.ScreenToCameraSpace(mouse_v2)); - Tile selected_tile = loaded_tileset->tiles[selected_quad]; - J2D::DrawString(Colors::White, std::format("Selected Tile: {}", selected_tile.name), 16, 48, 16); + if (selected_quad > -1){ + Tile selected_tile = loaded_tileset->tiles[selected_quad]; + J2D::DrawString(Colors::White, std::format("Selected Tile: {}", selected_tile.name), 16, 48, 16); + + } Vector2i cell = GetGridCellFromMouse(); diff --git a/src/App/LayerView.cpp b/src/App/LayerView.cpp new file mode 100644 index 0000000..5695780 --- /dev/null +++ b/src/App/LayerView.cpp @@ -0,0 +1,104 @@ +#include + +LayerView::LayerView(): JUI::Window() { + this->Title("Layers"); + Name("LayerView"); + + scroller = new JUI::ScrollingRect(this->Content()); + scroller->Size({100_percent, 100_percent}); + + layout = new JUI::VerticalListLayout(this->Content()); + layout->LayoutOrder(JUI::LayoutOrder::V::TOP); +} + +LayerView::LayerView(Widget *parent): LayerView() { + Parent(parent); +} + +void LayerView::ClearComponents() { + for (auto entry : entry_elements) { + entry->Parent(nullptr); + delete entry; + } + + entry_elements.clear(); +} + +void LayerView::UpdateComponents(const Level *level) { + stored_level_data = level; + + ClearComponents(); + + for (auto layer : level->layers) + { + bool is_bottom_layer_in_stack = false; + bool is_top_layer_in_stack = false; + + if (layer->order == 0) is_top_layer_in_stack = true; + if (layer->order == level->layers.size()-1) is_bottom_layer_in_stack = true; + + auto* rect = new JUI::Rect(layout); + rect->LayoutOrder(layer->order); + rect->Size({100_percent, JUI::UDim(layer_entry_height, 0)}); + auto* vis_chk = new JUI::Checkbox(rect); + vis_chk->Size({JUI::UDim(layer_entry_height, 0), JUI::UDim(layer_entry_height, 0)}); + auto* label = new JUI::TextButton(rect); + label->Name("Label"); + label->Position({JUI::UDim(layer_entry_height, 0), 0_px}); + label->Size({100_percent-JUI::UDim(layer_entry_height*2, 0), JUI::UDim(layer_entry_height, 0)}); + label->Content(layer->name); + label->TextColor(Colors::Black); + + label->OnReleaseEvent += [this, label, layer] (auto a, auto b, auto c) mutable { + ActiveLayerSelected.Invoke(layer->name); + label->BaseBGColor(Colors::Gray); + }; + + vis_chk->OnReleaseEvent += [this, layer](auto a, auto b, auto c) mutable { + LayerVisibilityToggled.Invoke(layer->name, !layer->visible); + }; + + auto* layer_order_shift_box = new JUI::Rect(rect); + layer_order_shift_box->Size({JUI::UDim(layer_entry_height, 0), JUI::UDim(layer_entry_height, 0)}); + layer_order_shift_box->Position({100_percent-JUI::UDim(layer_entry_height, 0), 0_px}); + + + auto layer_up = new JUI::TextButton(layer_order_shift_box); + layer_up->Size({100_percent, 50_percent}); + layer_up->TextColor(Colors::Black); + layer_up->Content("/\\"); + layer_up->Center(); + + layer_up->OnReleaseEvent += [this, layer] (auto a, auto b, auto c) mutable { + if (layer->order > 0) + layer->order--; + }; + + if (is_top_layer_in_stack) + layer_up->Disable(); + + + auto* layer_down = new JUI::TextButton(layer_order_shift_box); + layer_down->Size({100_percent, 50_percent}); + layer_down->Content("\\/"); + layer_down->TextColor(Colors::Black); + layer_down->Position({0_percent, 50_percent}); + layer_down->Center(); + + layer_down->OnReleaseEvent += [this, level, layer] (auto a, auto b, auto c) mutable { + const int layer_count = level->layers.size(); + if (layer->order <= layer_count) + layer->order++; + }; + + if (is_bottom_layer_in_stack) + layer_down->Disable(); + + + + entry_elements.push_back(rect); + + } +} + + diff --git a/src/Data/Layer.cpp b/src/Data/Layer.cpp index 24f6433..0f608b3 100644 --- a/src/Data/Layer.cpp +++ b/src/Data/Layer.cpp @@ -1,6 +1,6 @@ #include -Layer::Layer(): rows(0), cols(0), cell_width(0), cell_height(0), parallax_x(0), parallax_y(0), cells(nullptr), visible(true) +Layer::Layer(): rows(0), cols(0), cell_width(0), cell_height(0), parallax_x(0), parallax_y(0), cells(nullptr), visible(true), order(0) { } Layer::Layer(int rows, int cols, int cell_width, int cell_height): cells(nullptr), parallax_x(0), parallax_y(0) @@ -38,7 +38,7 @@ json::value Layer::Serialize() const data["cols"] = (float)cols; data["cell-width"] = (float)cell_width; data["cell-height"] = (float)cell_height; - + data["order"] = (float)order; return data; } @@ -51,7 +51,7 @@ void Layer::Deserialize(const json::value& json) cols = json["cols"].number.value(); cell_width = json["cell-width"].number.value(); cell_height = json["cell-height"].number.value(); - + order = json["order"].number.value_or(0); } void Layer::InitGrid()