#ifndef MWGUI_LAYOUTS_H #define MWGUI_LAYOUTS_H #include #include #include #include #include #include #include #include "../mwmechanics/stat.hpp" #include "window_base.hpp" #include /* This file contains classes corresponding to window layouts 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 { class HUD : public OEngine::GUI::Layout { public: HUD(int width, int height, int fpsLevel); void setStats(int h, int hmax, int m, int mmax, int s, int smax); void setWeapIcon(const char *str); void setSpellIcon(const char *str); void setWeapStatus(int s, int smax); void setSpellStatus(int s, int smax); void setEffect(const char *img); void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setFPS(float fps); void setTriangleCount(size_t count); void setBatchCount(size_t count); MyGUI::ProgressPtr health, magicka, stamina; MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; MyGUI::WidgetPtr effectBox; MyGUI::ImageBox* effect1; MyGUI::ImageBox* minimap; MyGUI::ImageBox* compass; MyGUI::ImageBox* crosshair; MyGUI::WidgetPtr fpsbox; MyGUI::TextBox* fpscounter; MyGUI::TextBox* trianglecounter; MyGUI::TextBox* batchcounter; }; class MapWindow : public OEngine::GUI::Layout { public: MapWindow() : Layout("openmw_map_window_layout.xml"), mGlobal(false) { setCoord(500,0,320,300); setText("WorldButton", "World"); setImage("Compass", "textures\\compass.dds"); // Obviously you should override this later on setCellName("No Cell Loaded"); getWidget(mLocalMap, "LocalMap"); getWidget(mGlobalMap, "GlobalMap"); getWidget(mPlayerArrow, "Compass"); getWidget(mButton, "WorldButton"); mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); MyGUI::Button* eventbox; getWidget(eventbox, "EventBox"); eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); } void setVisible(bool b) { mMainWidget->setVisible(b); if (b) mVisible = true; else mVisible = false; } void setCellName(const std::string& cellName) { static_cast(mMainWidget)->setCaption(cellName); } // for interiors: cell name, for exteriors: "Cell" void setCellPrefix(const std::string& prefix) { mPrefix = prefix; } void setActiveCell(const int x, const int y, bool interior=false) { if (x==mCurX && y==mCurY && mInterior==interior) return; // don't do anything if we're still in the same cell for (int mx=0; mx<3; ++mx) { for (int my=0; my<3; ++my) { std::string name = "Map_" + boost::lexical_cast(mx) + "_" + boost::lexical_cast(my); std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) setImage(name, image); else setImage(name, "black.png"); if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) setImage(name+"_fog", image+"_fog"); else setImage(name+"_fog", "black.png"); } } mInterior = interior; mCurX = x; mCurY = y; } void setPlayerPos(const float x, const float y) { if (mGlobal || mVisible) return; MyGUI::IntSize size = mLocalMap->getCanvasSize(); MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); MyGUI::IntCoord viewsize = mLocalMap->getCoord(); MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); mLocalMap->setViewOffset(pos); mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); } void setPlayerDir(const float x, const float y) { if (!mVisible) return; MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); float angle = std::atan2(x,y); rotatingSubskin->setAngle(angle); } void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; if (!mGlobal) mLastDragPos = MyGUI::IntPoint(_left, _top); } void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { if (_id!=MyGUI::MouseButton::Left) return; if (!mGlobal) { MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); mLastDragPos = MyGUI::IntPoint(_left, _top); } } void onWorldButtonClicked(MyGUI::Widget* _sender) { mGlobal = !mGlobal; mGlobalMap->setVisible(mGlobal); mLocalMap->setVisible(!mGlobal); mButton->setCaption( mGlobal ? "Local" : "World" ); } private: std::string mPrefix; MyGUI::ScrollView* mLocalMap; MyGUI::ScrollView* mGlobalMap; MyGUI::ImageBox* mPlayerArrow; MyGUI::Button* mButton; MyGUI::IntPoint mLastDragPos; int mCurX, mCurY; bool mInterior; bool mVisible; bool mGlobal; }; class MainMenu : public OEngine::GUI::Layout { public: MainMenu(int w, int h) : Layout("openmw_mainmenu_layout.xml") { setCoord(0,0,w,h); } }; #if 0 class InventoryWindow : public OEngine::GUI::Layout { public: enum CategoryMode { CM_All = 0, // All items CM_Weapon = 1, // Only weapons CM_Apparel = 2, // Apparel CM_Magic = 3, // Magic CM_Misc = 4 // Misc }; InventoryWindow () : Layout("openmw_inventory_window_layout.xml") , categoryMode(CM_All) // color should be fetched from skin , activeColor(0, 0, 1) , inactiveColor(0.7, 0.7, 0.7) { setCoord(0, 200, 600, 400); // These are just demo values, you should replace these with // real calls from outside the class later. mMainWidget->setCaption("Glass Frostsword"); setText("EncumbranceBarT", "176/210"); MyGUI::ProgressPtr pt; getWidget(pt, "EncumbranceBar"); pt->setProgressRange(210); pt->setProgressPosition(176); MyGUI::WidgetPtr avatar; getWidget(avatar, "Avatar"); // Adjust armor rating text to bottom of avatar widget MyGUI::TextBox* armor_rating; getWidget(armor_rating, "ArmorRating"); armor_rating->setCaption("Armor: 11"); MyGUI::IntCoord coord = armor_rating->getCoord(); coord.top = avatar->getCoord().height - 4 - coord.height; armor_rating->setCoord(coord); names[0] = "All"; names[1] = "Weapon"; names[2] = "Apparel"; names[3] = "Magic"; names[4] = "Misc"; boost::array categories = { { CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc } }; // Initialize buttons with text and adjust sizes, also mark All as active button int margin = 2; int last_x = 0; for (int i = 0; i < categories.size(); ++i) { CategoryMode mode = categories[i]; std::string name = names[mode]; name += "Button"; setText(name, names[mode]); getWidget(buttons[mode], name); MyGUI::ButtonPtr &button_pt = buttons[mode]; if (mode == CM_All) button_pt->setTextColour(activeColor); else button_pt->setTextColour(inactiveColor); MyGUI::IntCoord coord = button_pt->getCoord(); coord.left = last_x; last_x += coord.width + margin; button_pt->setCoord(coord); button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected); } } void setCategory(CategoryMode mode) { MyGUI::ButtonPtr pt = getCategoryButton(categoryMode); pt->setTextColour(inactiveColor); pt = getCategoryButton(mode); pt->setTextColour(activeColor); categoryMode = mode; } MyGUI::ButtonPtr getCategoryButton(CategoryMode mode) { return buttons[mode]; } void onCategorySelected(MyGUI::Widget *widget) { boost::array categories = { { CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc } }; for (int i = 0; i < categories.size(); ++i) { CategoryMode mode = categories[i]; if (widget == buttons[mode]) { setCategory(mode); return; } } } CategoryMode categoryMode; // Current category filter MyGUI::ButtonPtr buttons[5]; // Button pointers std::string names[5]; // Names of category buttons MyGUI::Colour activeColor; MyGUI::Colour inactiveColor; }; #endif } #endif