mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 14:56:44 +00:00 
			
		
		
		
	Implemented race dialog for character creation, it currently only contains hardcoded values.
This commit is contained in:
		
							parent
							
								
									0d100f7551
								
							
						
					
					
						commit
						beee17b36f
					
				
					 5 changed files with 322 additions and 2 deletions
				
			
		|  | @ -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}) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										231
									
								
								apps/openmw/mwgui/mw_chargen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								apps/openmw/mwgui/mw_chargen.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,231 @@ | |||
| #include "mw_chargen.hpp" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| 
 | ||||
| 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<MyGUI::WidgetPtr>::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<MyGUI::StaticText>("SandText", coord1, MyGUI::Align::Default, "SkillName0"); | ||||
| 		skillName->setCaption(inputList[i][0]); | ||||
| 		skillLevel = skillList->createWidget<MyGUI::StaticText>("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<MyGUI::WidgetPtr>::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<MyGUI::StaticText>("SandText", coord, MyGUI::Align::Default, name); | ||||
| 		specialsName->setCaption(inputList[i]); | ||||
| 
 | ||||
| 		specialsItems.push_back(specialsName); | ||||
| 
 | ||||
| 		coord.top += lineHeight; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										74
									
								
								apps/openmw/mwgui/mw_chargen.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								apps/openmw/mwgui/mw_chargen.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | |||
| #ifndef MWGUI_CHARGEN_H | ||||
| #define MWGUI_CHARGEN_H | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| #include <openengine/gui/layout.hpp> | ||||
| 
 | ||||
| #include <boost/array.hpp> | ||||
| 
 | ||||
| /*
 | ||||
|   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<MyGUI::WidgetPtr> skillItems; | ||||
| 
 | ||||
| 		MyGUI::WidgetPtr specialsList; | ||||
| 		std::vector<MyGUI::WidgetPtr> specialsItems; | ||||
| 
 | ||||
| 		int sexIndex, faceIndex, hairIndex; | ||||
| 		int faceCount, hairCount; | ||||
| 	}; | ||||
| } | ||||
| #endif | ||||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue