From beee17b36faee18c5455fbeae30fbc71587c95ce Mon Sep 17 00:00:00 2001 From: Jan Borsodi Date: Sun, 12 Sep 2010 14:06:10 +0200 Subject: [PATCH] Implemented race dialog for character creation, it currently only contains hardcoded values. --- apps/openmw/CMakeLists.txt | 2 + apps/openmw/mwgui/mw_chargen.cpp | 231 +++++++++++++++++++++++++++ apps/openmw/mwgui/mw_chargen.hpp | 74 +++++++++ apps/openmw/mwgui/window_manager.cpp | 13 +- apps/openmw/mwgui/window_manager.hpp | 4 + 5 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 apps/openmw/mwgui/mw_chargen.cpp create mode 100644 apps/openmw/mwgui/mw_chargen.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 70979cca7..11b5a64d1 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -35,12 +35,14 @@ source_group(apps\\openmw\\mwinput FILES ${GAMEINPUT} ${GAMEINPUT_HEADER}) set(GAMEGUI_HEADER mwgui/mw_layouts.hpp + mwgui/mw_chargen.hpp mwgui/window_manager.hpp mwgui/console.hpp ) set(GAMEGUI mwgui/window_manager.cpp mwgui/console.cpp + mwgui/mw_chargen.cpp ) source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI}) diff --git a/apps/openmw/mwgui/mw_chargen.cpp b/apps/openmw/mwgui/mw_chargen.cpp new file mode 100644 index 000000000..2c02b0cf1 --- /dev/null +++ b/apps/openmw/mwgui/mw_chargen.cpp @@ -0,0 +1,231 @@ +#include "mw_chargen.hpp" + +#include +#include +#include + +using namespace MWGui; + +RaceDialog::RaceDialog() + : Layout("openmw_chargen_race_layout.xml") + , sexIndex(0) + , faceIndex(0) + , hairIndex(0) + , faceCount(10) + , hairCount(14) +{ + mMainWidget->setCoord(mMainWidget->getCoord() + MyGUI::IntPoint(0, 100)); + + // These are just demo values, you should replace these with + // real calls from outside the class later. + + setText("AppearanceT", "Appearance"); + getWidget(appearanceBox, "AppearanceBox"); + + getWidget(headRotate, "HeadRotate"); + headRotate->setScrollRange(50); + headRotate->setScrollPosition(20); + headRotate->setScrollViewPage(10); + headRotate->eventScrollChangePosition = MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); + + // Set up next/previous buttons + MyGUI::ButtonPtr prevButton, nextButton; + + getWidget(prevButton, "PrevSexButton"); + getWidget(nextButton, "NextSexButton"); + prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousSex); + nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextSex); + + getWidget(prevButton, "PrevFaceButton"); + getWidget(nextButton, "NextFaceButton"); + prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); + nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); + + getWidget(prevButton, "PrevHairButton"); + getWidget(nextButton, "NextHairButton"); + prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); + nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); + + setText("RaceT", "Race"); + getWidget(raceList, "RaceList"); + raceList->setScrollVisible(true); + raceList->eventListSelectAccept = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); + raceList->eventListMouseItemActivate = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); + + getWidget(skillList, "SkillList"); + getWidget(specialsList, "SpecialsList"); + + updateRaces(); + updateSkills(); + updateSpecials(); +} + +int wrap(int index, int max) +{ + if (index < 0) + return max - 1; + else if (index >= max) + return 0; + else + return index; +} + +void RaceDialog::selectPreviousSex() +{ + sexIndex = wrap(sexIndex - 1, 2); +} + +void RaceDialog::selectNextSex() +{ + sexIndex = wrap(sexIndex + 1, 2); +} + +void RaceDialog::selectPreviousFace() +{ + faceIndex = wrap(faceIndex - 1, faceCount); +} + +void RaceDialog::selectNextFace() +{ + faceIndex = wrap(faceIndex + 1, faceCount); +} + +void RaceDialog::selectPreviousHair() +{ + hairIndex = wrap(hairIndex - 1, hairCount); +} + +void RaceDialog::selectNextHair() +{ + hairIndex = wrap(hairIndex - 1, hairCount); +} + +// widget controls + +void RaceDialog::onHeadRotate(MyGUI::VScroll*, size_t _position) +{ + // TODO: Rotate head +} + +void RaceDialog::onSelectPreviousSex(MyGUI::Widget*) +{ + selectPreviousSex(); +} + +void RaceDialog::onSelectNextSex(MyGUI::Widget*) +{ + selectNextSex(); +} + +void RaceDialog::onSelectPreviousFace(MyGUI::Widget*) +{ + selectPreviousFace(); +} + +void RaceDialog::onSelectNextFace(MyGUI::Widget*) +{ + selectNextFace(); +} + +void RaceDialog::onSelectPreviousHair(MyGUI::Widget*) +{ + selectPreviousHair(); +} + +void RaceDialog::onSelectNextHair(MyGUI::Widget*) +{ + selectNextHair(); +} + +void RaceDialog::onSelectRace(MyGUI::List* _sender, size_t _index) +{ + // TODO: Select actual race + updateSkills(); + updateSpecials(); +} + +// update widget content + +void RaceDialog::updateRaces() +{ + raceList->removeAllItems(); + raceList->addItem("Argonian"); + raceList->addItem("Breton"); + raceList->addItem("Dark Elf"); + raceList->addItem("High Elf"); + raceList->addItem("Imperial"); + raceList->addItem("Khajiit"); + raceList->addItem("Nord"); + raceList->addItem("Orc"); +} + +void RaceDialog::updateSkills() +{ + for (std::vector::iterator it = skillItems.begin(); it != skillItems.end(); ++it) + { + MyGUI::Gui::getInstance().destroyWidget(*it); + } + skillItems.clear(); + + MyGUI::StaticTextPtr skillName, skillLevel; + const int lineHeight = 18; + MyGUI::IntCoord coord1(0, 0, skillList->getWidth() - (40 + 4), 18); + MyGUI::IntCoord coord2(coord1.left + coord1.width, 0, 40, 18); + + const char *inputList[][2] = { + {"Athletics", "5"}, + {"Destruction", "10"}, + {"Light Armor", "5"}, + {"Long Blade", "5"}, + {"Marksman", "5"}, + {"Mysticism", "5"}, + {"Short Blade", "10"}, + {0,0} + }; + + for (int i = 0; inputList[i][0]; ++i) + { + skillName = skillList->createWidget("SandText", coord1, MyGUI::Align::Default, "SkillName0"); + skillName->setCaption(inputList[i][0]); + skillLevel = skillList->createWidget("SandTextRight", coord2, MyGUI::Align::Default, "SkillLevel0"); + skillLevel->setCaption(inputList[i][1]); + + skillItems.push_back(skillName); + skillItems.push_back(skillLevel); + + coord1.top += lineHeight; + coord2.top += lineHeight; + } +} + +void RaceDialog::updateSpecials() +{ + for (std::vector::iterator it = specialsItems.begin(); it != specialsItems.end(); ++it) + { + MyGUI::Gui::getInstance().destroyWidget(*it); + } + specialsItems.clear(); + + MyGUI::StaticTextPtr specialsName; + const int lineHeight = 18; + MyGUI::IntCoord coord(0, 0, specialsList->getWidth(), 18); + + const char *inputList[] = { + "Depth Perception", + "Resist Fire", + "Ancestor Guardian", + 0 + }; + + for (int i = 0; inputList[i]; ++i) + { + std::string name = "specialsName"; + name += i; + specialsName = specialsList->createWidget("SandText", coord, MyGUI::Align::Default, name); + specialsName->setCaption(inputList[i]); + + specialsItems.push_back(specialsName); + + coord.top += lineHeight; + } +} diff --git a/apps/openmw/mwgui/mw_chargen.hpp b/apps/openmw/mwgui/mw_chargen.hpp new file mode 100644 index 000000000..726b0a022 --- /dev/null +++ b/apps/openmw/mwgui/mw_chargen.hpp @@ -0,0 +1,74 @@ +#ifndef MWGUI_CHARGEN_H +#define MWGUI_CHARGEN_H + +#include + +#include + +#include + +/* + This file contains classes corresponding to all the dialogs + for the character generation, layouts are defined in resources/mygui/ *.xml. + + Each class inherites GUI::Layout and loads the XML file, and + provides some helper functions to manipulate the elements of the + window. + + The windows are never created or destroyed (except at startup and + shutdown), they are only hid. You can control visibility with + setVisible(). + */ + +namespace MWGui +{ + using namespace MyGUI; + + class RaceDialog : public OEngine::GUI::Layout + { + public: + RaceDialog(); + + void selectPreviousSex(); + void selectNextSex(); + + void selectPreviousFace(); + void selectNextFace(); + + void selectPreviousHair(); + void selectNextHair(); + + protected: + void onHeadRotate(MyGUI::VScroll* _sender, size_t _position); + + void onSelectPreviousSex(MyGUI::Widget* _sender); + void onSelectNextSex(MyGUI::Widget* _sender); + + void onSelectPreviousFace(MyGUI::Widget* _sender); + void onSelectNextFace(MyGUI::Widget* _sender); + + void onSelectPreviousHair(MyGUI::Widget* _sender); + void onSelectNextHair(MyGUI::Widget* _sender); + + void onSelectRace(MyGUI::List* _sender, size_t _index); + + private: + void updateRaces(); + void updateSkills(); + void updateSpecials(); + + MyGUI::CanvasPtr appearanceBox; + MyGUI::ListPtr raceList; + MyGUI::HScrollPtr headRotate; + + MyGUI::WidgetPtr skillList; + std::vector skillItems; + + MyGUI::WidgetPtr specialsList; + std::vector specialsItems; + + int sexIndex, faceIndex, hairIndex; + int faceCount, hairCount; + }; +} +#endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 207a5bb8c..1642c66a5 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -1,5 +1,6 @@ #include "window_manager.hpp" #include "mw_layouts.hpp" +#include "mw_chargen.hpp" #include "console.hpp" @@ -25,6 +26,8 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment inventory = new InventoryWindow (); console = new Console(w,h, environment, extensions); + raceDialog = new RaceDialog (); + // The HUD is always on hud->setVisible(true); @@ -40,6 +43,8 @@ WindowManager::~WindowManager() delete menu; delete stats; delete inventory; + + delete raceDialog; } void WindowManager::updateVisible() @@ -50,6 +55,7 @@ void WindowManager::updateVisible() stats->setVisible(false); inventory->setVisible(false); console->disable(); + raceDialog->setVisible(false); // Mouse is visible whenever we're not in game mode gui->setVisiblePointer(isGuiMode()); @@ -84,8 +90,11 @@ void WindowManager::updateVisible() // Show the windows we want map -> setVisible( eff & GW_Map ); stats -> setVisible( eff & GW_Stats ); - inventory -> setVisible( eff & GW_Inventory ); - return; +// inventory -> setVisible( eff & GW_Inventory ); + + // Temporary, displays character generator dialogs when displaying inventory + raceDialog -> setVisible( true ); + return; } // All other modes are ignored diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 32f0d4944..0b6e89805 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -39,6 +39,8 @@ namespace MWGui class InventoryWindow; class Console; + class RaceDialog; + enum GuiMode { GM_Game, // Game mode, only HUD @@ -84,6 +86,8 @@ namespace MWGui InventoryWindow *inventory; Console *console; + RaceDialog *raceDialog; + MyGUI::Gui *gui; // Current gui mode