mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 02:56:39 +00:00 
			
		
		
		
	git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@138 ea6a568a-9f4f-0410-981a-c910a81bb256
		
			
				
	
	
		
			511 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
  OpenMW - The completely unofficial reimplementation of Morrowind
 | 
						|
  Copyright (C) 2008  Nicolay Korslund
 | 
						|
  Email: < korslund@gmail.com >
 | 
						|
  WWW: http://openmw.snaptoad.com/
 | 
						|
 | 
						|
  This file (cpp_mygui.cpp) is part of the OpenMW package.
 | 
						|
 | 
						|
  OpenMW is distributed as free software: you can redistribute it
 | 
						|
  and/or modify it under the terms of the GNU General Public License
 | 
						|
  version 3, as published by the Free Software Foundation.
 | 
						|
 | 
						|
  This program is distributed in the hope that it will be useful, but
 | 
						|
  WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
  General Public License for more details.
 | 
						|
 | 
						|
  You should have received a copy of the GNU General Public License
 | 
						|
  version 3 along with this program. If not, see
 | 
						|
  http://www.gnu.org/licenses/ .
 | 
						|
 | 
						|
 */
 | 
						|
 | 
						|
// TODO: KILLME
 | 
						|
std::string cellName;
 | 
						|
 | 
						|
extern "C" void gui_setCellName(char *str)
 | 
						|
{
 | 
						|
  cellName = str;
 | 
						|
}
 | 
						|
 | 
						|
// Get the widget type, as a string
 | 
						|
extern "C" const char *gui_widgetType(MyGUI::WidgetPtr p)
 | 
						|
{ return p->getTypeName().c_str(); }
 | 
						|
 | 
						|
extern "C" int32_t gui_getHeight(MyGUI::WidgetPtr p)
 | 
						|
{
 | 
						|
  if(p == NULL) mWindow->getHeight();
 | 
						|
  return p->getHeight();
 | 
						|
}
 | 
						|
 | 
						|
extern "C" int32_t gui_getWidth(MyGUI::WidgetPtr p)
 | 
						|
{
 | 
						|
  if(p == NULL) return mWindow->getWidth();
 | 
						|
  return p->getWidth();
 | 
						|
}
 | 
						|
 | 
						|
// Set various properties of a given widget
 | 
						|
extern "C" void gui_setCaption(MyGUI::WidgetPtr p, char* s)
 | 
						|
{
 | 
						|
  p->setCaption(s);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void gui_setNeedMouseFocus(MyGUI::WidgetPtr p, int32_t b)
 | 
						|
{ p->setNeedMouseFocus(b); }
 | 
						|
 | 
						|
extern "C" void gui_setTextColor(MyGUI::WidgetPtr p, float r,float g,float b)
 | 
						|
{
 | 
						|
  MyGUI::StaticText *st = dynamic_cast<MyGUI::StaticText*>(p);
 | 
						|
  if(st != NULL)
 | 
						|
    st->setTextColour(Ogre::ColourValue(b,g,r));
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void gui_setCoord(MyGUI::WidgetPtr p,
 | 
						|
                             int32_t x,int32_t y,int32_t w,int32_t h)
 | 
						|
{ p->setCoord(x,y,w,h); }
 | 
						|
 | 
						|
// Various ways to get or create widgets
 | 
						|
extern "C" MyGUI::WidgetPtr gui_loadLayout(char *file, char *prefix,
 | 
						|
                                           MyGUI::WidgetPtr parent)
 | 
						|
{
 | 
						|
  // Get the list of Widgets in this layout
 | 
						|
  MyGUI::VectorWidgetPtr wlist;
 | 
						|
  wlist = MyGUI::LayoutManager::getInstance().
 | 
						|
    loadLayout(file, prefix, parent);
 | 
						|
 | 
						|
  MyGUI::VectorWidgetPtr::iterator iter;
 | 
						|
  iter = wlist.begin();
 | 
						|
 | 
						|
  // Return null if the list is empty
 | 
						|
  if(wlist.end() == iter)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  MyGUI::WidgetPtr res = *iter;
 | 
						|
 | 
						|
  ++iter;
 | 
						|
 | 
						|
  if(iter != wlist.end())
 | 
						|
    std::cout << "WARNING: Layout '" << file
 | 
						|
              << "' has more than one root widget. Ignored.\n";
 | 
						|
 | 
						|
  return res;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" MyGUI::WidgetPtr gui_getChild(MyGUI::WidgetPtr p, char* name)
 | 
						|
{
 | 
						|
  return p->findWidget(name);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" MyGUI::WidgetPtr gui_createText(const char *skin,
 | 
						|
                                           int32_t x, int32_t y,
 | 
						|
                                           int32_t w, int32_t h,
 | 
						|
                                           const char *layer)
 | 
						|
{
 | 
						|
  return mGUI->createWidget<MyGUI::StaticText>
 | 
						|
    (skin,
 | 
						|
     x,y,w,h,
 | 
						|
     MyGUI::ALIGN_LEFT | MyGUI::ALIGN_TOP,
 | 
						|
     layer);
 | 
						|
}
 | 
						|
 | 
						|
// Copied from MyGUI demo code, with a few modifications
 | 
						|
class Layout
 | 
						|
{
 | 
						|
public:
 | 
						|
  Layout(const std::string & _layout, MyGUI::WidgetPtr _parent = nullptr)
 | 
						|
    : mMainWidget(nullptr)
 | 
						|
  {
 | 
						|
    initialise(_layout, _parent);
 | 
						|
  }
 | 
						|
 | 
						|
  template <typename T>
 | 
						|
  void getWidget(T * & _widget, const std::string & _name, bool _throw = true)
 | 
						|
  {
 | 
						|
    _widget = nullptr;
 | 
						|
    for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin();
 | 
						|
         iter!=mListWindowRoot.end(); ++iter)
 | 
						|
      {
 | 
						|
        MyGUI::WidgetPtr find = (*iter)->findWidget(mPrefix + _name);
 | 
						|
        if (nullptr != find)
 | 
						|
          {
 | 
						|
            T * cast = find->castType<T>(false);
 | 
						|
            if (nullptr != cast)
 | 
						|
              _widget = cast;
 | 
						|
            else if (_throw)
 | 
						|
              {
 | 
						|
                MYGUI_EXCEPT("Error cast : dest type = '" << T::getClassTypeName()
 | 
						|
                       << "' source name = '" << find->getName()
 | 
						|
                       << "' source type = '" << find->getTypeName() << "' in layout '" << mLayoutName << "'");
 | 
						|
              }
 | 
						|
            return;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' in layout '" << mLayoutName << "' not found.");
 | 
						|
  }
 | 
						|
 | 
						|
  void initialise(const std::string & _layout,
 | 
						|
                  MyGUI::WidgetPtr _parent = nullptr)
 | 
						|
  {
 | 
						|
    const std::string MAIN_WINDOW = "_Main";
 | 
						|
    mLayoutName = _layout;
 | 
						|
 | 
						|
    if (mLayoutName.empty())
 | 
						|
      mMainWidget = _parent;
 | 
						|
    else
 | 
						|
      {
 | 
						|
        mPrefix = MyGUI::utility::toString(this, "_");
 | 
						|
        mListWindowRoot = MyGUI::LayoutManager::getInstance().loadLayout(mLayoutName, mPrefix, _parent);
 | 
						|
 | 
						|
        const std::string main_name = mPrefix + MAIN_WINDOW;
 | 
						|
        for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); iter!=mListWindowRoot.end(); ++iter)
 | 
						|
          {
 | 
						|
            if ((*iter)->getName() == main_name)
 | 
						|
              {
 | 
						|
                mMainWidget = (*iter);
 | 
						|
                break;
 | 
						|
              }
 | 
						|
          }
 | 
						|
        MYGUI_ASSERT(mMainWidget, "root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found.");
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  void shutdown()
 | 
						|
  {
 | 
						|
    for (VectorBasePtr::iterator iter=mListBase.begin(); iter!=mListBase.end(); ++iter) {
 | 
						|
      delete (*iter);
 | 
						|
    }
 | 
						|
    mListBase.clear();
 | 
						|
 | 
						|
    MyGUI::LayoutManager::getInstance().unloadLayout(mListWindowRoot);
 | 
						|
    mListWindowRoot.clear();
 | 
						|
  }
 | 
						|
 | 
						|
  void setCoord(int x, int y, int w, int h)
 | 
						|
  {
 | 
						|
    mMainWidget->setCoord(x,y,w,h);
 | 
						|
  }
 | 
						|
 | 
						|
  void setVisible(bool b)
 | 
						|
  {
 | 
						|
    mMainWidget->setVisible(b);
 | 
						|
  }
 | 
						|
 | 
						|
  virtual ~Layout()
 | 
						|
  {
 | 
						|
    shutdown();
 | 
						|
  }
 | 
						|
 | 
						|
  void setText(const char* name, const char* caption)
 | 
						|
  {
 | 
						|
    MyGUI::WidgetPtr pt;
 | 
						|
    getWidget(pt, name);
 | 
						|
    pt->setCaption(caption);
 | 
						|
  }
 | 
						|
 | 
						|
  void setColor(const char* name, float r, float g, float b)
 | 
						|
  {
 | 
						|
    MyGUI::WidgetPtr pt;
 | 
						|
    getWidget(pt, name);
 | 
						|
    gui_setTextColor(pt,r,g,b);
 | 
						|
  }
 | 
						|
 | 
						|
  void setImage(const char* name, const char* imgName)
 | 
						|
  {
 | 
						|
    MyGUI::StaticImagePtr pt;
 | 
						|
    getWidget(pt, name);
 | 
						|
    pt->setImageTexture(imgName);
 | 
						|
  }
 | 
						|
 | 
						|
protected:
 | 
						|
 | 
						|
  MyGUI::WidgetPtr mMainWidget;
 | 
						|
 | 
						|
  std::string mPrefix;
 | 
						|
  std::string mLayoutName;
 | 
						|
  MyGUI::VectorWidgetPtr mListWindowRoot;
 | 
						|
  typedef std::vector<Layout*> VectorBasePtr;
 | 
						|
  VectorBasePtr mListBase;
 | 
						|
};
 | 
						|
 | 
						|
class HUD : public Layout
 | 
						|
{
 | 
						|
public:
 | 
						|
  HUD()
 | 
						|
    : Layout("openmw_hud_layout.xml")
 | 
						|
  {
 | 
						|
    setCoord(0,0,
 | 
						|
             mWindow->getWidth(),
 | 
						|
             mWindow->getHeight());
 | 
						|
 | 
						|
    // Energy bars
 | 
						|
    getWidget(health, "Health");
 | 
						|
    getWidget(magicka, "Magicka");
 | 
						|
    getWidget(stamina, "Stamina");
 | 
						|
 | 
						|
    // Item and spell images and status bars
 | 
						|
    getWidget(weapImage, "WeapImage");
 | 
						|
    getWidget(weapStatus, "WeapStatus");
 | 
						|
    getWidget(spellImage, "SpellImage");
 | 
						|
    getWidget(spellStatus, "SpellStatus");
 | 
						|
 | 
						|
    getWidget(effectBox, "EffectBox");
 | 
						|
    getWidget(effect1, "Effect1");
 | 
						|
 | 
						|
    getWidget(minimap, "MiniMap");
 | 
						|
    getWidget(compass, "Compass");
 | 
						|
 | 
						|
    getWidget(crosshair, "Crosshair");
 | 
						|
 | 
						|
    compass->setImageTexture("compass.dds");
 | 
						|
    crosshair->setImageTexture("target.dds");
 | 
						|
  }
 | 
						|
 | 
						|
  void setStats(int h, int hmax, int m, int mmax, int s, int smax)
 | 
						|
  {
 | 
						|
    health->setProgressRange(hmax);
 | 
						|
    health->setProgressPosition(h);
 | 
						|
    magicka->setProgressRange(mmax);
 | 
						|
    magicka->setProgressPosition(m);
 | 
						|
    stamina->setProgressRange(smax);
 | 
						|
    stamina->setProgressPosition(s);
 | 
						|
  }
 | 
						|
 | 
						|
  void setWeapIcon(const char *str)
 | 
						|
  { weapImage->setImageTexture(str); }
 | 
						|
  void setSpellIcon(const char *str)
 | 
						|
  { spellImage->setImageTexture(str); }
 | 
						|
 | 
						|
  void setWeapStatus(int s, int smax)
 | 
						|
  {
 | 
						|
    weapStatus->setProgressRange(smax);
 | 
						|
    weapStatus->setProgressPosition(s);
 | 
						|
  }
 | 
						|
  void setSpellStatus(int s, int smax)
 | 
						|
  {
 | 
						|
    spellStatus->setProgressRange(smax);
 | 
						|
    spellStatus->setProgressPosition(s);
 | 
						|
  }
 | 
						|
 | 
						|
  void setEffect(const char *img)
 | 
						|
  { effect1->setImageTexture(img); }
 | 
						|
 | 
						|
  MyGUI::ProgressPtr health, magicka, stamina;
 | 
						|
 | 
						|
  MyGUI::StaticImagePtr weapImage, spellImage;
 | 
						|
  MyGUI::ProgressPtr weapStatus, spellStatus;
 | 
						|
 | 
						|
  MyGUI::WidgetPtr effectBox;
 | 
						|
  MyGUI::StaticImagePtr effect1;
 | 
						|
 | 
						|
  MyGUI::StaticImagePtr minimap;
 | 
						|
  MyGUI::StaticImagePtr compass;
 | 
						|
 | 
						|
  MyGUI::StaticImagePtr crosshair;
 | 
						|
};
 | 
						|
 | 
						|
class MapWindow : public Layout
 | 
						|
{
 | 
						|
public:
 | 
						|
  MapWindow()
 | 
						|
    : Layout("openmw_map_window_layout.xml")
 | 
						|
  {
 | 
						|
    setCoord(500,0,320,300);
 | 
						|
    mMainWidget->setCaption(cellName);
 | 
						|
    setText("WorldButton", "World");
 | 
						|
    setImage("Compass", "compass.dds");
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
class MainMenu : public Layout
 | 
						|
{
 | 
						|
public:
 | 
						|
  MainMenu()
 | 
						|
    : Layout("openmw_mainmenu_layout.xml")
 | 
						|
  {
 | 
						|
    setCoord(0,0,
 | 
						|
             mWindow->getWidth(),
 | 
						|
             mWindow->getHeight());
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
class StatsWindow : public Layout
 | 
						|
{
 | 
						|
public:
 | 
						|
  void setBar(const char* name, const char* tname, int val, int max)
 | 
						|
  {
 | 
						|
    MyGUI::ProgressPtr pt;
 | 
						|
    getWidget(pt, name);
 | 
						|
    pt->setProgressRange(max);
 | 
						|
    pt->setProgressPosition(val);
 | 
						|
 | 
						|
    std::stringstream out;
 | 
						|
    out << val << "/" << max;
 | 
						|
    setText(tname, out.str().c_str());
 | 
						|
  }
 | 
						|
 | 
						|
  StatsWindow()
 | 
						|
    : Layout("openmw_stats_window_layout.xml")
 | 
						|
  {
 | 
						|
    setCoord(0,0,498, 342);
 | 
						|
    mMainWidget->setCaption("Playername");
 | 
						|
 | 
						|
    setText("Health_str", "Health");
 | 
						|
    setText("Magicka_str", "Magicka");
 | 
						|
    setText("Fatigue_str", "Fatigue");
 | 
						|
 | 
						|
    setText("Level_str", "Level");
 | 
						|
    setText("Race_str", "Race");
 | 
						|
    setText("Class_str", "Class");
 | 
						|
 | 
						|
    setText("LevelText", "5");
 | 
						|
    setText("RaceText", "Wood Elf");
 | 
						|
    setText("ClassText", "Pilgrim");
 | 
						|
 | 
						|
    setBar("HBar", "HBarT", 60, 100);
 | 
						|
    setBar("MBar", "MBarT", 30, 100);
 | 
						|
    setBar("FBar", "FBarT", 80, 100);
 | 
						|
 | 
						|
    setText("Attrib1", "Strength");
 | 
						|
    setText("Attrib2", "Intelligence");
 | 
						|
    setText("Attrib3", "Willpower");
 | 
						|
    setText("Attrib4", "Agility");
 | 
						|
    setText("Attrib5", "Speed");
 | 
						|
    setText("Attrib6", "Endurance");
 | 
						|
    setText("Attrib7", "Personality");
 | 
						|
    setText("Attrib8", "Luck");
 | 
						|
 | 
						|
    setText("AttribVal1", "30");
 | 
						|
    setText("AttribVal2", "40");
 | 
						|
    setText("AttribVal3", "30");
 | 
						|
    setText("AttribVal4", "75");
 | 
						|
    setText("AttribVal5", "50");
 | 
						|
    setText("AttribVal6", "40");
 | 
						|
    setText("AttribVal7", "50");
 | 
						|
    setText("AttribVal8", "40");
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
HUD *hud;
 | 
						|
StatsWindow *stats;
 | 
						|
MapWindow *map;
 | 
						|
MyGUI::WidgetPtr FPSText;
 | 
						|
OIS::MouseState state;
 | 
						|
bool consoleMode = false;
 | 
						|
bool inventoryMode = false;
 | 
						|
 | 
						|
void enterGui()
 | 
						|
{
 | 
						|
  guiMode++;
 | 
						|
 | 
						|
  if(guiMode == 1)
 | 
						|
    {
 | 
						|
      // If we just entered GUI mode, enable the pointer
 | 
						|
      mGUI->showPointer();
 | 
						|
 | 
						|
      // Restore the GUI mouse position. This is a hack because silly
 | 
						|
      // OIS doesn't allow us to set the mouse position ourselves.
 | 
						|
      *((OIS::MouseState*)&(mMouse->getMouseState())) = state;
 | 
						|
      mGUI->injectMouseMove(state.X.abs, state.Y.abs, 0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void leaveGui()
 | 
						|
{
 | 
						|
  guiMode--;
 | 
						|
 | 
						|
  if(guiMode < 0)
 | 
						|
    {
 | 
						|
      std::cout << "WARNING: guiMode is " << guiMode << "\n";
 | 
						|
      guiMode = 0;
 | 
						|
    }
 | 
						|
 | 
						|
  // Are we done with all GUI windows?
 | 
						|
  if(guiMode == 0)
 | 
						|
    {
 | 
						|
      // If so, hide the pointer and store the mouse state for later.
 | 
						|
      mGUI->hidePointer();
 | 
						|
      state = mMouse->getMouseState();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#include "cpp_console.cpp"
 | 
						|
 | 
						|
extern "C" void gui_toggleGui()
 | 
						|
{
 | 
						|
  if(inventoryMode)
 | 
						|
    {
 | 
						|
      leaveGui();
 | 
						|
      if(stats)
 | 
						|
        stats->setVisible(false);
 | 
						|
      if(map)
 | 
						|
        map->setVisible(false);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      enterGui();
 | 
						|
      if(stats)
 | 
						|
        stats->setVisible(true);
 | 
						|
      if(map)
 | 
						|
        map->setVisible(true);
 | 
						|
    }
 | 
						|
 | 
						|
  inventoryMode = !inventoryMode;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" int32_t* gui_getGuiModePtr() { return &guiMode; }
 | 
						|
 | 
						|
extern "C" void gui_showHUD()
 | 
						|
{
 | 
						|
  if(hud)
 | 
						|
    hud->setVisible(true);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void gui_setupGUI(int32_t debugOut)
 | 
						|
{
 | 
						|
  ResourceGroupManager::getSingleton().
 | 
						|
    addResourceLocation("media_mygui", "FileSystem", "General");
 | 
						|
 | 
						|
  // Enable/disable logging to stdout
 | 
						|
  MyGUI::LogManager::initialise();
 | 
						|
  MyGUI::LogManager::setSTDOutputEnabled(debugOut);
 | 
						|
 | 
						|
  mGUI = new MyGUI::Gui();
 | 
						|
  mGUI->initialise(mWindow);
 | 
						|
 | 
						|
  int mWidth = mWindow->getWidth();
 | 
						|
  int mHeight = mWindow->getHeight();
 | 
						|
 | 
						|
  stats = new StatsWindow();
 | 
						|
  map = new MapWindow();
 | 
						|
  cons = new Console();
 | 
						|
 | 
						|
  // Hide all the windows at startup
 | 
						|
  stats->setVisible(false);
 | 
						|
  map->setVisible(false);
 | 
						|
  cons->setVisible(false);
 | 
						|
  guiMode = 1;
 | 
						|
  leaveGui();
 | 
						|
 | 
						|
  // Start the mouse in the middle of the screen
 | 
						|
  state.X.abs = mWidth / 2;
 | 
						|
  state.Y.abs = mHeight / 2;
 | 
						|
 | 
						|
  // Set up the HUD
 | 
						|
  hud = new HUD();
 | 
						|
 | 
						|
  hud->setStats(60, 100,
 | 
						|
                30, 100,
 | 
						|
                80, 100);
 | 
						|
 | 
						|
  hud->setWeapIcon("icons\\w\\tx_knife_iron.dds");
 | 
						|
  hud->setWeapStatus(90, 100);
 | 
						|
  hud->setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds");
 | 
						|
  hud->setSpellStatus(65, 100);
 | 
						|
 | 
						|
  hud->setEffect("icons\\s\\tx_s_chameleon.dds");
 | 
						|
 | 
						|
  hud->setVisible(false);
 | 
						|
 | 
						|
  //new MainMenu();
 | 
						|
}
 |