diff --git a/apps/openmw/mwmp/GUI/GUICustomWindow.cpp b/apps/openmw/mwmp/GUI/GUICustomWindow.cpp new file mode 100644 index 000000000..171238b38 --- /dev/null +++ b/apps/openmw/mwmp/GUI/GUICustomWindow.cpp @@ -0,0 +1,307 @@ +// +// Created by koncord on 07.11.17. +// + +#include "GUICustomWindow.hpp" + +#include + +#include "apps/openmw/mwbase/environment.hpp" +#include "apps/openmw/mwgui/windowmanagerimp.hpp" +#include "apps/openmw/mwgui/widgets.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace mwmp; +using namespace std; + +GUICustomWindow::GUICustomWindow(const BasePlayer::GUIWindow &guiMessageBox) : WindowModal("tes3mp_custom.layout") +{ + center(); + mMainWidget->setSize(guiMessageBox.width, guiMessageBox.height); + id = guiMessageBox.id; + + //setTitle(title); + + { + MyGUI::Button *button; + getWidget(button, "SendButton"); + auto bsize = button->getSize(); + auto wsize = mMainWidget->getSize(); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &GUICustomWindow::mousePressed); + //button->setCaptionWithReplacing(widget.name); + button->setSize(button->getTextSize().width + 2 * 12, button->getTextSize().height + 2 * 4); + button->setUserData(string("Send")); + button->setPosition(wsize.width - bsize.width - 12, wsize.height - bsize.height - 12); + } + + for (auto &&widget : guiMessageBox.widgets) + { + switch (widget.type) + { + + case BasePlayer::GUIWindow::WidgetType::Button: + addButton(widget); + break; + case BasePlayer::GUIWindow::WidgetType::Editbox: + addEditBox(widget); + break; + case BasePlayer::GUIWindow::WidgetType::Label: + addLabel(widget); + break; + case BasePlayer::GUIWindow::WidgetType::ListBoxActive: + case BasePlayer::GUIWindow::WidgetType::ListBoxPassive: + addListBox(widget); + break; + case BasePlayer::GUIWindow::WidgetType::Slider: + addSlider(widget); + } + } + +} + +void GUICustomWindow::addPassiveData(vector &widgets) +{ + for (const auto &box : boxes) + { + auto name = box->getUserData(false); + if (name != nullptr) + { + BasePlayer::GUIWindow::Widget widget; + widget.name = *name; + widget.type = BasePlayer::GUIWindow::WidgetType::Editbox; + widget.data.push_back(box->getCaption().asUTF8()); + widgets.push_back(widget); + } + } + + for (auto &&list : lists) + { + size_t selected = list->getIndexSelected(); + if (selected != MyGUI::ITEM_NONE) + { + auto name = list->getUserData(false); + if(name != nullptr) + { + BasePlayer::GUIWindow::Widget widget; + widget.name = *name; + widget.type = BasePlayer::GUIWindow::WidgetType::ListBoxPassive; + widget.data.push_back(list->getItemNameAt(selected).asUTF8()); + widgets.push_back(widget); + } + } + } + + for (auto &&slider : sliders) + { + auto name = slider->getUserData(false); + if(name != nullptr) + { + BasePlayer::GUIWindow::Widget widget; + widget.name = *name; + widget.type = BasePlayer::GUIWindow::WidgetType::Slider; + widget.data.push_back(to_string(slider->getScrollPosition())); + widgets.push_back(widget); + } + } +} + +void GUICustomWindow::mousePressed(MyGUI::Widget *pressed) +{ + setVisible(false); + MWBase::Environment::get().getWindowManager()->popGuiMode(); + + auto value = pressed->getUserData(false); + + if (value != nullptr) + { + BasePlayer::GUIWindow::Widget pressedButton; + + pressedButton.name = *value; + pressedButton.type = BasePlayer::GUIWindow::WidgetType::Button; + send(pressedButton); + /*printf("Ret Value: %s\n", value->c_str()); + + for (auto &&list : lists) + { + size_t selected = list->getIndexSelected(); + if (selected != MyGUI::ITEM_NONE) + { + auto value2 = list->getUserData(false); + printf("RetList: %s %s\n", value2->c_str(), list->getItemNameAt(selected).asUTF8_c_str()); + } + } + + for (auto &&box : boxes) + { + auto value2 = box->getUserData(false); + if (value2 != nullptr) + { + printf("\tRetEdit: %s %s\n", value2->c_str(), box->getCaption().asUTF8_c_str()); + } + } + + for (auto &&slider : sliders) + { + printf("Slider: %zu\n", slider->getScrollPosition()); + }*/ + } +} + +void GUICustomWindow::itemActivated(MyGUI::ListPtr sender, size_t index) +{ + /*printf("---------Item Activated---------\n"); + auto str = sender->getUserData(false); + if(str != nullptr) + printf("ID: %s\n", str->c_str()); + printf("item: %zu\n", index); + printf("value of item: %s\n", sender->getItemNameAt(index).asUTF8_c_str()); + printf("--------------------------------\n");*/ + + auto str = sender->getUserData(false); + if(str != nullptr) + { + BasePlayer::GUIWindow::Widget pressedListBox; + pressedListBox.name = *str; + pressedListBox.type = BasePlayer::GUIWindow::WidgetType::ListBoxActive; + pressedListBox.data.push_back(sender->getItemNameAt(index).asUTF8()); + send(pressedListBox); + } +} + +void GUICustomWindow::send(const BasePlayer::GUIWindow::Widget &widget) +{ + auto networking = mwmp::Main::get().getNetworking(); + auto player = networking->getLocalPlayer(); + + player->guiWindow.widgets.clear(); + player->guiWindow.widgets.push_back(widget); + addPassiveData(player->guiWindow.widgets); + + player->guiWindow.id = id; + player->guiWindow.width = 0; + player->guiWindow.height = 0; + auto packet = networking->getPlayerPacket(ID_GUI_WINDOW); + packet->setPlayer(player); + packet->Send(); + + setVisible(false); + MWBase::Environment::get().getWindowManager()->popGuiMode(); +} + +void GUICustomWindow::onFrame(float frameDuration) +{ + +} + +void GUICustomWindow::addButton(const BasePlayer::GUIWindow::Widget &widget) +{ + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + + auto *button = mMainWidget->createWidget( + MyGUI::WidgetStyle::Child, + string("MW_Button"), + dummyCoord, + MyGUI::Align::Default); + + button->eventMouseButtonClick += MyGUI::newDelegate(this, &GUICustomWindow::mousePressed); + button->setPosition(widget.posX, widget.posY); + button->setCaptionWithReplacing(widget.name); + button->setSize(button->getTextSize().width + 2 * 12, button->getTextSize().height + 2 * 4); + button->setUserData(widget.name); + button->setEnabled(!widget.disabled); + +} + +void GUICustomWindow::addEditBox(const BasePlayer::GUIWindow::Widget &widget) +{ + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + auto *editBox = mMainWidget->createWidget( + MyGUI::WidgetStyle::Child, + string("MW_TextEdit"), + dummyCoord, + MyGUI::Align::Default + ); + + editBox->setCaption(widget.name); + + editBox->setPosition(widget.posX, widget.posY); + editBox->setSize(widget.width, widget.height); + editBox->setUserData(string(widget.name)); // ID + editBox->setEnabled(!widget.disabled); + if(!widget.disabled) + boxes.push_back(editBox); +} + +void GUICustomWindow::addLabel(const BasePlayer::GUIWindow::Widget &widget) +{ + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + auto *textBox = mMainWidget->createWidget( + MyGUI::WidgetStyle::Child, + string("ProgressText"), + dummyCoord, + MyGUI::Align::Default + ); + + textBox->setCaption(widget.name); + + textBox->setPosition(widget.posX, widget.posY); + + textBox->setSize(textBox->getTextSize().width, textBox->getTextSize().height); +} + +void GUICustomWindow::addListBox(const BasePlayer::GUIWindow::Widget &widget) +{ + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + auto *lbox = mMainWidget->createWidget( + MyGUI::WidgetStyle::Child, + string("MW_List"), + dummyCoord, + MyGUI::Align::Default + ); + + for(const auto & item : widget.data) + lbox->addItem(item); + + lbox->setUserData(widget.name); + lbox->setScrollPosition(0); + lbox->setPosition(widget.posX, widget.posY); + lbox->setSize(widget.width, widget.height); + lbox->setEnabled(!widget.disabled); + + if(!widget.disabled) + { + if (widget.type == BasePlayer::GUIWindow::WidgetType::ListBoxPassive) + lists.push_back(lbox); + else + lbox->eventListMouseItemActivate += MyGUI::newDelegate(this, &GUICustomWindow::itemActivated); + } +} + +void GUICustomWindow::addSlider(const BasePlayer::GUIWindow::Widget &widget) +{ + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + + auto *slider = mMainWidget->createWidget( + MyGUI::WidgetStyle::Child, + string("MW_HScroll"), + dummyCoord, + MyGUI::Align::Default + ); + + slider->setPosition(widget.posX, widget.posY); + slider->setSize(widget.width, widget.height); + + slider->setScrollRange(10000); + slider->setScrollPage(300); + sliders.push_back(slider); +} diff --git a/apps/openmw/mwmp/GUI/GUICustomWindow.hpp b/apps/openmw/mwmp/GUI/GUICustomWindow.hpp new file mode 100644 index 000000000..06a3437ff --- /dev/null +++ b/apps/openmw/mwmp/GUI/GUICustomWindow.hpp @@ -0,0 +1,38 @@ +// +// Created by koncord on 07.11.17. +// + +#pragma once + + +#include +#include +#include "apps/openmw/mwgui/windowbase.hpp" + +namespace mwmp +{ + + class GUICustomWindow : public MWGui::WindowModal + { + public: + explicit GUICustomWindow(const BasePlayer::GUIWindow &guiMessageBox); + void mousePressed(MyGUI::Widget *_widget); + void itemActivated(MyGUI::ListPtr sender, size_t index); + void onFrame(float frameDuration); + + void addButton(const BasePlayer::GUIWindow::Widget &widget); + void addEditBox(const BasePlayer::GUIWindow::Widget &widget); + void addLabel(const BasePlayer::GUIWindow::Widget &widget); + void addListBox(const BasePlayer::GUIWindow::Widget &widget); + void addSlider(const BasePlayer::GUIWindow::Widget &widget); + + private: + std::vector lists; + std::vector boxes; + std::vector sliders; + int id; + + void addPassiveData(std::vector &widgets); + void send(const BasePlayer::GUIWindow::Widget &widget); + }; +} diff --git a/apps/openmw/mwmp/GUIController.cpp b/apps/openmw/mwmp/GUIController.cpp index 2985141dd..f3dd81568 100644 --- a/apps/openmw/mwmp/GUIController.cpp +++ b/apps/openmw/mwmp/GUIController.cpp @@ -33,12 +33,13 @@ #include "GUI/PlayerMarkerCollection.hpp" #include "GUI/GUIDialogList.hpp" #include "GUI/GUIChat.hpp" +#include "GUI/GUICustomWindow.hpp" #include "LocalPlayer.hpp" #include "DedicatedPlayer.hpp" #include "PlayerList.hpp" -mwmp::GUIController::GUIController(): mInputBox(0), mListBox(0) +mwmp::GUIController::GUIController(): mInputBox(0), mListBox(0), mCustomWindow(0) { mChat = nullptr; keySay = SDL_SCANCODE_Y; @@ -54,8 +55,8 @@ mwmp::GUIController::~GUIController() void mwmp::GUIController::cleanUp() { mPlayerMarkers.clear(); - if (mChat != nullptr) - delete mChat; + + delete mChat; mChat = nullptr; } @@ -158,6 +159,20 @@ void mwmp::GUIController::showInputBox(const BasePlayer::GUIMessageBox &guiMessa mInputBox->setVisible(true); } +void mwmp::GUIController::showCustomWindow(const mwmp::BasePlayer::GUIWindow &guiMessageBox) +{ + MWBase::WindowManager *windowManager = MWBase::Environment::get().getWindowManager(); + if(mCustomWindow != nullptr) + LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Deleting mCustomWindow"); + windowManager->removeDialog(mCustomWindow); + windowManager->pushGuiMode((MWGui::GuiMode)GM_TES3MP_CustomWindow); + mCustomWindow = nullptr; + + mCustomWindow = new GUICustomWindow(guiMessageBox); + + mCustomWindow->setVisible(true); +} + void mwmp::GUIController::onInputBoxDone(MWGui::WindowBase *parWindow) { //MWBase::WindowManager *windowManager = MWBase::Environment::get().getWindowManager(); @@ -193,10 +208,128 @@ bool mwmp::GUIController::pressedKey(int key) mChat->pressedSay(); return true; } + else if (key == SDL_SCANCODE_F4) + { + windowManager->removeDialog(mCustomWindow); + windowManager->pushGuiMode((MWGui::GuiMode)GM_TES3MP_CustomWindow); + mCustomWindow = nullptr; + + + BasePlayer::GUIWindow data; + data.id = 1234; + data.width = 450; + data.height = 250; + BasePlayer::GUIWindow::Widget widget; + { + widget.type = BasePlayer::GUIWindow::WidgetType::Button; + widget.posX = 12; + widget.posY = 12; + widget.name = "My Button"; + widget.disabled = false; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::Editbox; + widget.posX = 12; + widget.posY = 50; + widget.height = 30; + widget.width = 96; + widget.name = "MyEditBox"; // id + widget.disabled = false; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::Button; + widget.posX = 12; + widget.posY = 88; + widget.name = "Disabled\nButton"; + widget.disabled = true; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::Editbox; + widget.posX = 12; + widget.posY = 132; + widget.height = 30; + widget.width = 96; + widget.name = "Inactive"; // id + widget.disabled = true; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::Label; + widget.posX = 150; + widget.posY = 12; + widget.height = 0; + widget.width = 0; + widget.name = "Active ListBox"; // id + widget.disabled = false; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::ListBoxActive; + widget.posX = 130; + widget.posY = 30; + widget.height = 150; + widget.width = 150; + widget.name = "MyListBox"; // id + widget.disabled = false; + widget.data.clear(); + for(int i = 0; i < 10; ++i) + widget.data.push_back("Item" + std::to_string(i)); + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::Label; + widget.posX = 300; + widget.posY = 12; + widget.height = 0; + widget.width = 0; + widget.name = "Passive ListBox"; // id + widget.disabled = false; + data.widgets.push_back(widget); + } + + { + widget.type = BasePlayer::GUIWindow::WidgetType::ListBoxPassive; + widget.posX = 288; + widget.posY = 30; + widget.height = 150; + widget.width = 150; + widget.name = "MyListBox"; // id + widget.disabled = false; + widget.data.clear(); + for(int i = 0; i < 10; ++i) + widget.data.push_back("Value" + std::to_string(i)); + data.widgets.push_back(widget); + } + + mCustomWindow = new GUICustomWindow(data); + + { + widget.type = BasePlayer::GUIWindow::WidgetType::ListBoxPassive; + widget.posX = 12; + widget.posY = 168; + widget.height = 14; + widget.width = 110; + widget.name = "MySlider"; // id + widget.disabled = false; + mCustomWindow->addSlider(widget); + } + + mCustomWindow->setVisible(true); + return true; + } return false; } -bool mwmp::GUIController::hasFocusedElement() +bool mwmp::GUIController:: hasFocusedElement() { return false; } diff --git a/apps/openmw/mwmp/GUIController.hpp b/apps/openmw/mwmp/GUIController.hpp index db42d692f..a3603d199 100644 --- a/apps/openmw/mwmp/GUIController.hpp +++ b/apps/openmw/mwmp/GUIController.hpp @@ -23,13 +23,15 @@ namespace mwmp { class GUIDialogList; class GUIChat; + class GUICustomWindow; class GUIController { public: enum GM { GM_TES3MP_InputBox = MWGui::GM_QuickKeysMenu + 1, - GM_TES3MP_ListBox + GM_TES3MP_ListBox, + GM_TES3MP_CustomWindow }; GUIController(); @@ -44,6 +46,8 @@ namespace mwmp void showCustomMessageBox(const BasePlayer::GUIMessageBox &guiMessageBox); void showInputBox(const BasePlayer::GUIMessageBox &guiMessageBox); + void showCustomWindow(const BasePlayer::GUIWindow &guiMessageBox); + void showDialogList(const BasePlayer::GUIMessageBox &guiMessageBox); /// Return true if any tes3mp gui element in active state @@ -72,6 +76,7 @@ namespace mwmp bool calledInteractiveMessage; TextInputDialog *mInputBox; GUIDialogList *mListBox; + GUICustomWindow *mCustomWindow; void onInputBoxDone(MWGui::WindowBase* parWindow); //MyGUI::Widget *oldFocusWidget, *currentFocusWidget; }; diff --git a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp index 537177970..08e5922f4 100644 --- a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp +++ b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp @@ -8,6 +8,7 @@ #include "player/ProcessorChatMessage.hpp" #include "player/ProcessorGUIMessageBox.hpp" +#include "player/ProcessorGUIWindow.hpp" #include "player/ProcessorHandshake.hpp" #include "player/ProcessorUserDisconnected.hpp" #include "player/ProcessorGameSettings.hpp" @@ -86,6 +87,7 @@ void ProcessorInitializer() { PlayerProcessor::AddProcessor(new ProcessorChatMessage()); PlayerProcessor::AddProcessor(new ProcessorGUIMessageBox()); + PlayerProcessor::AddProcessor(new ProcessorGUIWindow()); PlayerProcessor::AddProcessor(new ProcessorHandshake()); PlayerProcessor::AddProcessor(new ProcessorUserDisconnected()); PlayerProcessor::AddProcessor(new ProcessorGameSettings()); diff --git a/apps/openmw/mwmp/processors/player/ProcessorGUIWindow.hpp b/apps/openmw/mwmp/processors/player/ProcessorGUIWindow.hpp new file mode 100644 index 000000000..6bfb08917 --- /dev/null +++ b/apps/openmw/mwmp/processors/player/ProcessorGUIWindow.hpp @@ -0,0 +1,29 @@ +// +// Created by koncord on 24.11.17. +// + +#pragma once + +#include "../PlayerProcessor.hpp" + +namespace mwmp +{ + class ProcessorGUIWindow : public PlayerProcessor + { + public: + ProcessorGUIWindow() + { + BPP_INIT(ID_GUI_WINDOW) + } + + virtual void Do(PlayerPacket &packet, BasePlayer *player) + { + if (isLocal()) + { + LOG_MESSAGE_SIMPLE(Log::LOG_TRACE, "ID_GUI_WINDOW, ID %d", player->guiWindow.id); + + Main::get().getGUIController()->showCustomWindow(player->guiWindow); + } + } + }; +} diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 3ff8a1b2b..da1ac8a18 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -101,6 +101,7 @@ set(MYGUI_FILES tes3mp_chat.layout tes3mp_chat.skin.xml tes3mp_text_input.layout + tes3mp_custom.layout RussoOne-Regular.ttf ) diff --git a/files/mygui/tes3mp_custom.layout b/files/mygui/tes3mp_custom.layout new file mode 100644 index 000000000..479a79e91 --- /dev/null +++ b/files/mygui/tes3mp_custom.layout @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file