From d79eadc0ae526c6574c47a524a5c822b9585f30a Mon Sep 17 00:00:00 2001 From: Insineer Date: Sat, 21 Sep 2019 04:50:51 +0300 Subject: [PATCH] [CLT] add(SpawnWindow) --- OSS13 Client/OSS13 Client.vcxproj | 2 + OSS13 Client/OSS13 Client.vcxproj.filters | 6 + OSS13 Client/Sources/Graphics/Sprite.cpp | 6 +- OSS13 Client/Sources/Graphics/Sprite.hpp | 1 + .../Graphics/UI/UIModule/GameProcessUI.cpp | 14 ++ .../Graphics/UI/UIModule/GameProcessUI.hpp | 5 + .../Graphics/UI/Widget/SpawnWindow.cpp | 131 ++++++++++++++++++ .../Sources/Graphics/UI/Widget/SpawnWindow.h | 27 ++++ OSS13 Client/Sources/Network.cpp | 14 ++ 9 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.cpp create mode 100644 OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.h diff --git a/OSS13 Client/OSS13 Client.vcxproj b/OSS13 Client/OSS13 Client.vcxproj index 7b10080..ae27e50 100644 --- a/OSS13 Client/OSS13 Client.vcxproj +++ b/OSS13 Client/OSS13 Client.vcxproj @@ -150,6 +150,7 @@ + @@ -183,6 +184,7 @@ + diff --git a/OSS13 Client/OSS13 Client.vcxproj.filters b/OSS13 Client/OSS13 Client.vcxproj.filters index fb5ba67..d676386 100644 --- a/OSS13 Client/OSS13 Client.vcxproj.filters +++ b/OSS13 Client/OSS13 Client.vcxproj.filters @@ -96,6 +96,9 @@ Файлы исходного кода + + Файлы исходного кода + @@ -191,5 +194,8 @@ Заголовочные файлы + + Заголовочные файлы + \ No newline at end of file diff --git a/OSS13 Client/Sources/Graphics/Sprite.cpp b/OSS13 Client/Sources/Graphics/Sprite.cpp index 977ec68..bb3b4c2 100644 --- a/OSS13 Client/Sources/Graphics/Sprite.cpp +++ b/OSS13 Client/Sources/Graphics/Sprite.cpp @@ -75,4 +75,8 @@ void Sprite::updateSpriteVariables() { sfSprite.setTexture(*texture->GetSFMLTexture()); sfSprite.setTextureRect(rect); -} \ No newline at end of file +} + +const sf::Sprite &Sprite::GetSfmlSprite() const { + return sfSprite; +} diff --git a/OSS13 Client/Sources/Graphics/Sprite.hpp b/OSS13 Client/Sources/Graphics/Sprite.hpp index 6a91ef0..10b42e2 100644 --- a/OSS13 Client/Sources/Graphics/Sprite.hpp +++ b/OSS13 Client/Sources/Graphics/Sprite.hpp @@ -27,6 +27,7 @@ class Sprite { bool IsValid() const; bool IsAnimated() const; bool PixelTransparent(uf::vec2u pixel) const; + const sf::Sprite &GetSfmlSprite() const; private: mutable sf::Sprite sfSprite; diff --git a/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.cpp b/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.cpp index 6a3ee33..d0cb675 100644 --- a/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.cpp +++ b/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -115,6 +116,19 @@ void GameProcessUI::HandleEvent(sf::Event event) { UIModule::HandleEvent(event); } +void GameProcessUI::OpenSpawnWindow() { + for (auto &widget : widgets) + if (dynamic_cast(widget.get())) + return; + widgets.push_back(std::make_unique()); +} + +void GameProcessUI::UpdateSpawnWindow(std::vector &&types) { + for (auto &widget : widgets) + if (auto *spawnWidget = dynamic_cast(widget.get())) + spawnWidget->UpdateTypes(std::forward>(types)); +} + InfoLabel *GameProcessUI::GetInfoLabel() const { return infoLabel.get(); } TileGrid *GameProcessUI::GetTileGrid() const { return tileGrid; } diff --git a/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.hpp b/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.hpp index 2bef4d8..cf4720e 100644 --- a/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.hpp +++ b/OSS13 Client/Sources/Graphics/UI/UIModule/GameProcessUI.hpp @@ -7,6 +7,8 @@ #include "Graphics/UI/Widget/FormattedTextField.hpp" #include "UIModule.hpp" +#include + class UI; class TileGrid; @@ -27,6 +29,9 @@ class GameProcessUI : public UIModule { void Update(sf::Time timeElapsed) override final; void HandleEvent(sf::Event event) override; + void OpenSpawnWindow(); + void UpdateSpawnWindow(std::vector &&types); + InfoLabel *GetInfoLabel() const; TileGrid *GetTileGrid() const; diff --git a/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.cpp b/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.cpp new file mode 100644 index 0000000..b58da05 --- /dev/null +++ b/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.cpp @@ -0,0 +1,131 @@ +#include "SpawnWindow.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +void SpawnWindow::Update(sf::Time timeElapsed) { + std::unique_lock lock(guard); + + ImGui::SetNextWindowPos(ImVec2(60, 60), ImGuiCond_Once); + ImGui::SetNextWindowSize(ImVec2(300, 300), ImGuiCond_Once); + + if (!ImGui::Begin("Object Spawner")) { + ImGui::End(); + return; + } + + drawHeader(); + drawBody(); + + ImGui::End(); +} + +void SpawnWindow::UpdateTypes(std::vector &&types) { + std::unique_lock lock(guard); + + this->types = std::forward>(types); + noQueriesYet = false; +} + +void searchTypesAndDropBuffer(std::string &searchBuffer) { + auto command = std::make_unique(); + std::swap(command->searchBuffer, searchBuffer); + Connection::commandQueue.Push(command.release()); +} + +void drawHeaderInput(std::string &searchBuffer) { + if (ImGui::InputTextWithHint("", "all object types", &searchBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) { + searchTypesAndDropBuffer(searchBuffer); + } +} + +void drawHeaderSearchButton(std::string &searchBuffer) { + ImGui::SameLine(); + if (ImGui::Button("Search")) { + searchTypesAndDropBuffer(searchBuffer); + } +} + +void SpawnWindow::drawHeader() { + drawHeaderInput(searchBuffer); + drawHeaderSearchButton(searchBuffer); +} + +void drawTypesListItemTooltip(const network::protocol::ObjectType &type) { + if (type.sprite) { + auto sprite = CC::Get()->RM.CreateSprite(type.sprite); + ImGui::Image(sprite.GetSfmlSprite()); + ImGui::SameLine(); + } + + ImGui::BeginGroup(); + ImGui::Text(type.name.c_str()); + ImGui::Text(type.typeKey.c_str()); + ImGui::Text(type.description.c_str()); + ImGui::EndGroup(); +} + +void drawTypesListItem(const network::protocol::ObjectType &type, bool &selected) { + ImGui::Selectable(type.typeKey.c_str(), &selected); + + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + drawTypesListItemTooltip(type); + ImGui::EndTooltip(); + } +} + +void drawTypesListEmptySearchResultText() { + ImGui::Text("No types were found!"); +} + +void drawTypesListContent(const std::vector &types, size_t &selectedIndex) { + size_t counter = 0; + for (auto &type : types) { + counter++; + bool selected = (counter == selectedIndex); + drawTypesListItem(type, selected); + if (selected) + selectedIndex = counter; + } +} + +void SpawnWindow::drawTypesList() { + const float footerHeightToReserve = ImGui::GetFrameHeightWithSpacing(); + ImGui::BeginChild("types list", ImVec2(0, -footerHeightToReserve), true); + + if (!types.size() && !noQueriesYet) + drawTypesListEmptySearchResultText(); + else + drawTypesListContent(types, selectedIndex); + + ImGui::EndChild(); +} + +void spawnObject(const std::string &typeKey) { + auto command = std::make_unique(); + command->typeKey = typeKey; + Connection::commandQueue.Push(command.release()); +} + +void SpawnWindow::drawSpawnButton() { + bool disabled = (selectedIndex == 0); + if (ImGui::Button("Spawn", disabled)) { + spawnObject(types[selectedIndex - 1].typeKey); + } +} + +void SpawnWindow::drawBody() { + drawTypesList(); + drawSpawnButton(); +} diff --git a/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.h b/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.h new file mode 100644 index 0000000..21d916b --- /dev/null +++ b/OSS13 Client/Sources/Graphics/UI/Widget/SpawnWindow.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include + +#include + +class SpawnWindow : public ImGuiWidget { +public: + void Update(sf::Time timeElapsed) final; + + void UpdateTypes(std::vector &&types); + +private: + void drawHeader(); + void drawBody(); + void drawTypesList(); + void drawSpawnButton(); + +private: + std::vector types; + size_t selectedIndex{0}; + std::string searchBuffer; + std::mutex guard; + bool noQueriesYet{true}; +}; diff --git a/OSS13 Client/Sources/Network.cpp b/OSS13 Client/Sources/Network.cpp index 76cac63..1a3b3f5 100644 --- a/OSS13 Client/Sources/Network.cpp +++ b/OSS13 Client/Sources/Network.cpp @@ -255,6 +255,20 @@ bool Connection::parsePacket(Packet &packet) { return true; } + if (auto *command = dynamic_cast(p.get())) { + GameProcessUI *gameProcessUI = dynamic_cast(CC::Get()->GetWindow()->GetUI()->GetCurrentUIModule()); + EXPECT(gameProcessUI); + gameProcessUI->OpenSpawnWindow(); + return true; + } + + if (auto *command = dynamic_cast(p.get())) { + GameProcessUI *gameProcessUI = dynamic_cast(CC::Get()->GetWindow()->GetUI()->GetCurrentUIModule()); + EXPECT(gameProcessUI); + gameProcessUI->UpdateSpawnWindow(std::forward>(command->types)); + return true; + } + if (auto *command = dynamic_cast(p.get())) { UIModule *uiModule = CC::Get()->GetWindow()->GetUI()->GetCurrentUIModule(); EXPECT(uiModule);