506 lines
14 KiB
C++
506 lines
14 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// 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 Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include <nel/misc/types_nl.h>
|
|
#include "main_window.h"
|
|
|
|
// STL includes
|
|
|
|
// Qt includes
|
|
#include <QtGui/QtGui>
|
|
#include <QtGui/QTreeView>
|
|
#include <QtGui/QDirModel>
|
|
#include <QtGui/QUndoStack>
|
|
#include <QtGui/QScrollArea>
|
|
|
|
// NeL includes
|
|
// #include <nel/misc/debug.h>
|
|
#include <nel/misc/i18n.h>
|
|
#include <nel/3d/u_driver.h>
|
|
|
|
// Project includes
|
|
#include "command_log.h"
|
|
#include "graphics_viewport.h"
|
|
#include "graphics_config.h"
|
|
|
|
using namespace std;
|
|
using namespace NLMISC;
|
|
|
|
namespace NLQT {
|
|
|
|
namespace {
|
|
|
|
QString nli18n(const char *label)
|
|
{
|
|
return QString::fromUtf16(CI18N::get(label).c_str());
|
|
}
|
|
|
|
} /* anonymous namespace */
|
|
|
|
CMainWindow::CMainWindow(const QMap<QString, QSize> &customSizeHints, QWidget *parent, Qt::WindowFlags flags)
|
|
: QMainWindow(parent, flags),
|
|
m_UndoStack(NULL),
|
|
m_IsGraphicsInitialized(false), m_IsGraphicsEnabled(false),
|
|
m_IsSoundInitialized(false), m_IsSoundEnabled(false),
|
|
m_GraphicsViewport(NULL),
|
|
m_CommandLog(NULL), m_CommandLogDock(NULL),
|
|
m_GraphicsConfig(NULL), m_GraphicsConfigScroll(NULL), m_GraphicsConfigDock(NULL),
|
|
m_FileMenu(NULL), m_EditMenu(NULL), m_ViewportMenu(NULL), m_WidgetsMenu(NULL), m_HelpMenu(NULL),
|
|
m_FileToolBar(NULL), m_EditToolBar(NULL),
|
|
m_AboutAct(NULL), m_QuitAct(NULL), m_PrintDebugAct(NULL),
|
|
m_UndoAct(NULL), m_RedoAct(NULL), m_SaveScreenshotAct(NULL)
|
|
{
|
|
setObjectName("CMainWindow");
|
|
|
|
m_UndoStack = new QUndoStack(this);
|
|
|
|
m_Configuration.init();
|
|
|
|
m_OriginalPalette = QApplication::palette();
|
|
m_Configuration.setAndCallback("QtStyle", CConfigCallback(this, &CMainWindow::cfcbQtStyle));
|
|
m_Configuration.setAndCallback("QtPalette", CConfigCallback(this, &CMainWindow::cfcbQtPalette));
|
|
|
|
m_Internationalization.init(&m_Configuration);
|
|
m_Internationalization.enableCallback(CEmptyCallback(this, &CMainWindow::incbLanguageCode));
|
|
|
|
m_GraphicsViewport = new CGraphicsViewport(this);
|
|
setCentralWidget(m_GraphicsViewport);
|
|
|
|
createActions();
|
|
createMenus();
|
|
createToolBars();
|
|
createStatusBar();
|
|
createDockWindows();
|
|
|
|
incbLanguageCode();
|
|
|
|
recalculateMinimumWidth();
|
|
|
|
// As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed. This can be used to do heavy work while providing a snappy user interface.
|
|
QTimer *timer = new QTimer(this);
|
|
connect(timer, SIGNAL(timeout()), this, SLOT(updateRender()));
|
|
// timer->start(); // <- timeout 0
|
|
// it's heavy on cpu, though, when no 3d driver initialized :)
|
|
timer->start(40); // 25fps
|
|
|
|
m_IsGraphicsEnabled = m_GraphicsConfig->getGraphicsEnabled();
|
|
connect(m_GraphicsConfig, SIGNAL(applyGraphicsConfig()), this, SLOT(applyGraphicsConfig()));
|
|
m_Configuration.setAndCallback("SoundEnabled", CConfigCallback(this, &CMainWindow::cfcbSoundEnabled));
|
|
}
|
|
|
|
CMainWindow::~CMainWindow()
|
|
{
|
|
delete m_GraphicsConfig; m_GraphicsConfig = NULL;
|
|
|
|
m_Configuration.dropCallback("SoundEnabled");
|
|
updateInitialization(false);
|
|
m_Internationalization.disableCallback(CEmptyCallback(this, &CMainWindow::incbLanguageCode));
|
|
m_Internationalization.release();
|
|
m_Configuration.dropCallback("QtPalette");
|
|
m_Configuration.dropCallback("QtStyle");
|
|
m_Configuration.release();
|
|
}
|
|
|
|
void CMainWindow::setVisible(bool visible)
|
|
{
|
|
// called by show()
|
|
// code assuming visible window needed to init the 3d driver
|
|
if (visible != isVisible())
|
|
{
|
|
if (visible)
|
|
{
|
|
QMainWindow::setVisible(true);
|
|
updateInitialization(true);
|
|
}
|
|
else
|
|
{
|
|
updateInitialization(false);
|
|
QMainWindow::setVisible(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainWindow::updateInitialization(bool visible)
|
|
{
|
|
bool done;
|
|
do
|
|
{
|
|
done = true; // set false whenever change
|
|
bool wantSound = m_IsSoundEnabled && visible;
|
|
bool wantGraphics = m_IsGraphicsEnabled && visible;
|
|
// bool wantLandscape = wantGraphics && m_IsGraphicsInitialized && isLandscapeEnabled;
|
|
|
|
// .. stuff that depends on other stuff goes on top to prioritize deinitialization
|
|
|
|
// Landscape
|
|
// ...
|
|
|
|
// Graphics (Driver)
|
|
if (m_IsGraphicsInitialized)
|
|
{
|
|
if (!wantGraphics)
|
|
{
|
|
m_IsGraphicsInitialized = false;
|
|
if (m_IsSoundInitialized)
|
|
m_SoundUtilities.releaseGraphics();
|
|
m_GraphicsViewport->release();
|
|
done = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (wantGraphics)
|
|
{
|
|
m_GraphicsViewport->init(m_GraphicsConfig);
|
|
if (m_IsSoundInitialized)
|
|
m_SoundUtilities.initGraphics(m_GraphicsViewport);
|
|
m_IsGraphicsInitialized = true;
|
|
done = false;
|
|
}
|
|
}
|
|
|
|
// Sound (AudioMixer)
|
|
if (m_IsSoundInitialized)
|
|
{
|
|
if (!wantSound)
|
|
{
|
|
m_IsSoundInitialized = false;
|
|
if (m_IsGraphicsInitialized)
|
|
m_SoundUtilities.releaseGraphics();
|
|
m_SoundUtilities.release();
|
|
done = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (wantSound)
|
|
{
|
|
|
|
m_SoundUtilities.init(&m_Configuration, &m_Internationalization);
|
|
if (m_IsGraphicsInitialized)
|
|
m_SoundUtilities.initGraphics(m_GraphicsViewport);
|
|
m_IsSoundInitialized = true;
|
|
done = false;
|
|
}
|
|
}
|
|
|
|
} while (!done);
|
|
}
|
|
|
|
void CMainWindow::createActions()
|
|
{
|
|
m_QuitAct = new QAction(this);
|
|
m_QuitAct->setShortcuts(QKeySequence::Quit);
|
|
connect(m_QuitAct, SIGNAL(triggered()), this, SLOT(close()));
|
|
|
|
m_AboutAct = new QAction(this);
|
|
connect(m_AboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
|
|
|
m_PrintDebugAct = new QAction(this);
|
|
connect(m_PrintDebugAct, SIGNAL(triggered()), this, SLOT(printDebug()));
|
|
|
|
m_UndoAct = m_UndoStack->createUndoAction(this);
|
|
m_UndoAct->setShortcuts(QKeySequence::Undo);
|
|
m_RedoAct = m_UndoStack->createRedoAction(this);
|
|
m_RedoAct->setShortcuts(QKeySequence::Redo);
|
|
|
|
m_SaveScreenshotAct = m_GraphicsViewport->createSaveScreenshotAction(this);
|
|
}
|
|
|
|
void CMainWindow::translateActions()
|
|
{
|
|
m_QuitAct->setText(nli18n("ActionQuit"));
|
|
m_QuitAct->setStatusTip(nli18n("ActionQuitStatusTip"));
|
|
m_AboutAct->setText(nli18n("ActionAbout"));
|
|
m_AboutAct->setStatusTip(nli18n("ActionAboutStatusTip"));
|
|
m_PrintDebugAct->setText(nli18n("ActionPrintDebug"));
|
|
m_PrintDebugAct->setStatusTip(nli18n("ActionPrintDebugStatusTip"));
|
|
m_UndoAct->setText(nli18n("ActionUndo"));
|
|
m_UndoAct->setStatusTip(nli18n("ActionUndoStatusTip"));
|
|
m_RedoAct->setText(nli18n("ActionRedo"));
|
|
m_RedoAct->setStatusTip(nli18n("ActionRedoStatusTip"));
|
|
m_SaveScreenshotAct->setText(nli18n("ActionSaveScreenshot"));
|
|
m_SaveScreenshotAct->setStatusTip(nli18n("ActionSaveScreenshotStatusTip"));
|
|
}
|
|
|
|
void CMainWindow::createMenus()
|
|
{
|
|
m_FileMenu = menuBar()->addMenu(QString::null);
|
|
//m_FileMenu->addAction(saveAct);
|
|
//m_FileMenu->addSeparator();
|
|
m_FileMenu->addAction(m_QuitAct);
|
|
|
|
m_EditMenu = menuBar()->addMenu(QString::null);
|
|
m_EditMenu->addAction(m_UndoAct);
|
|
m_EditMenu->addAction(m_RedoAct);
|
|
|
|
m_ViewportMenu = menuBar()->addMenu(QString::null);
|
|
m_ViewportMenu->addAction(m_SaveScreenshotAct);
|
|
|
|
m_WidgetsMenu = menuBar()->addMenu(QString::null);
|
|
|
|
menuBar()->addSeparator();
|
|
|
|
m_HelpMenu = menuBar()->addMenu(QString::null);
|
|
m_HelpMenu->addAction(m_AboutAct);
|
|
}
|
|
|
|
void CMainWindow::translateMenus()
|
|
{
|
|
m_FileMenu->setTitle(nli18n("MenuFile"));
|
|
m_EditMenu->setTitle(nli18n("MenuEdit"));
|
|
m_ViewportMenu->setTitle(nli18n("MenuViewport"));
|
|
m_WidgetsMenu->setTitle(nli18n("MenuWidgets"));
|
|
m_HelpMenu->setTitle(nli18n("MenuHelp"));
|
|
}
|
|
|
|
void CMainWindow::createToolBars()
|
|
{
|
|
m_FileToolBar = addToolBar(QString::null);
|
|
m_FileToolBar->addAction(m_QuitAct);
|
|
m_FileToolBar->addAction(m_PrintDebugAct);
|
|
|
|
m_EditToolBar = addToolBar(QString::null);
|
|
m_EditToolBar->addAction(m_AboutAct);
|
|
}
|
|
|
|
void CMainWindow::translateToolBars()
|
|
{
|
|
m_FileToolBar->setWindowTitle(nli18n("BarFile"));
|
|
m_EditToolBar->setWindowTitle(nli18n("BarEdit"));
|
|
}
|
|
|
|
void CMainWindow::createStatusBar()
|
|
{
|
|
statusBar()->showMessage(nli18n("StatusReady"));
|
|
}
|
|
|
|
void CMainWindow::createDockWindows()
|
|
{
|
|
//QDockWidget *dock = new QDockWidget(tr("Test1"), this);
|
|
//dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
|
//customerList = new QListWidget(dock);
|
|
//dock->setWidget(customerList);
|
|
//addDockWidget(Qt::RightDockWidgetArea, dock);
|
|
//m_WidgetsMenu->addAction(dock->toggleViewAction());
|
|
|
|
//dock = new QDockWidget(tr("Test2"), this);
|
|
//paragraphsList = new QListWidget(dock);
|
|
//dock->setWidget(paragraphsList);
|
|
//addDockWidget(Qt::RightDockWidgetArea, dock);
|
|
//m_WidgetsMenu->addAction(dock->toggleViewAction());
|
|
|
|
//connect(customerList, SIGNAL(currentTextChanged(QString)),
|
|
// this, SLOT(insertCustomer(QString)));
|
|
//connect(paragraphsList, SIGNAL(currentTextChanged(QString)),
|
|
// this, SLOT(addParagraph(QString)));
|
|
|
|
//dock = new QDockWidget(
|
|
|
|
// CommandLog (Console)
|
|
{
|
|
m_CommandLogDock = new QDockWidget(this);
|
|
m_CommandLogDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
|
|
m_CommandLog = new CCommandLog(m_CommandLogDock);
|
|
m_CommandLogDock->setWidget(m_CommandLog);
|
|
addDockWidget(Qt::BottomDockWidgetArea, m_CommandLogDock);
|
|
m_WidgetsMenu->addAction(m_CommandLogDock->toggleViewAction());
|
|
}
|
|
|
|
// GraphicsConfig (Graphics Configuration)
|
|
{
|
|
m_GraphicsConfigDock = new QDockWidget(this);
|
|
m_GraphicsConfigDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
|
m_GraphicsConfigScroll = new QScrollArea();
|
|
m_GraphicsConfigScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
m_GraphicsConfigScroll->setWidgetResizable(true);
|
|
m_GraphicsConfig = new CGraphicsConfig(m_GraphicsConfigDock, &m_Configuration, &m_Internationalization, m_UndoStack);
|
|
m_GraphicsConfigScroll->setWidget(m_GraphicsConfig);
|
|
m_GraphicsConfigDock->setWidget(m_GraphicsConfigScroll);
|
|
addDockWidget(Qt::RightDockWidgetArea, m_GraphicsConfigDock);
|
|
m_WidgetsMenu->addAction(m_GraphicsConfigDock->toggleViewAction());
|
|
}
|
|
|
|
// AssetTree (Assets)
|
|
{
|
|
m_AssetTreeDock = new QDockWidget(this);
|
|
m_AssetTreeDock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
|
m_AssetTreeView = new QTreeView(m_AssetTreeDock);
|
|
m_AssetTreeModel = new QDirModel();
|
|
m_AssetTreeView->setModel(m_AssetTreeModel);
|
|
m_AssetTreeView->setSortingEnabled(true);
|
|
m_AssetTreeDock->setWidget(m_AssetTreeView);
|
|
addDockWidget(Qt::LeftDockWidgetArea, m_AssetTreeDock);
|
|
m_WidgetsMenu->addAction(m_AssetTreeDock->toggleViewAction());
|
|
}
|
|
}
|
|
|
|
void CMainWindow::translateDockWindows()
|
|
{
|
|
m_CommandLogDock->setWindowTitle(nli18n("WidgetCommandLog"));
|
|
m_GraphicsConfigDock->setWindowTitle(nli18n("WidgetGraphicsConfig"));
|
|
m_AssetTreeDock->setWindowTitle(nli18n("WidgetAssetTree"));
|
|
}
|
|
|
|
void CMainWindow::recalculateMinimumWidth()
|
|
{
|
|
if (m_GraphicsConfigScroll)
|
|
m_GraphicsConfigScroll->setMinimumWidth(m_GraphicsConfig->minimumSizeHint().width() + m_GraphicsConfigScroll->minimumSizeHint().width());
|
|
}
|
|
|
|
void CMainWindow::cfcbQtStyle(NLMISC::CConfigFile::CVar &var)
|
|
{
|
|
QApplication::setStyle(QStyleFactory::create(var.asString().c_str()));
|
|
recalculateMinimumWidth();
|
|
}
|
|
|
|
void CMainWindow::cfcbQtPalette(NLMISC::CConfigFile::CVar &var)
|
|
{
|
|
if (var.asBool()) QApplication::setPalette(QApplication::style()->standardPalette());
|
|
else QApplication::setPalette(m_OriginalPalette);
|
|
}
|
|
|
|
void CMainWindow::applyGraphicsConfig()
|
|
{
|
|
// reinitializes the graphics system completely
|
|
// heavy lifting is done in updateInitialization
|
|
m_IsGraphicsEnabled = false;
|
|
updateInitialization(isVisible());
|
|
m_IsGraphicsEnabled = m_GraphicsConfig->getGraphicsEnabled();
|
|
updateInitialization(isVisible());
|
|
}
|
|
|
|
void CMainWindow::cfcbSoundEnabled(NLMISC::CConfigFile::CVar &var)
|
|
{
|
|
// temp, todo as above
|
|
m_IsSoundEnabled = var.asBool(); // update loop inits
|
|
}
|
|
|
|
void CMainWindow::incbLanguageCode()
|
|
{
|
|
setWindowTitle(nli18n("WindowTitle"));
|
|
translateActions();
|
|
translateMenus();
|
|
translateToolBars();
|
|
translateDockWindows();
|
|
recalculateMinimumWidth();
|
|
}
|
|
|
|
void CMainWindow::about()
|
|
{
|
|
QMessageBox::about(this, nli18n("AboutTitle"), nli18n("AboutText"));
|
|
}
|
|
|
|
void CMainWindow::updateRender()
|
|
{
|
|
updateInitialization(isVisible());
|
|
|
|
if (isVisible())
|
|
{
|
|
|
|
// call all update functions
|
|
// 01. Update Utilities (configuration etc)
|
|
m_Configuration.updateUtilities();
|
|
|
|
// 02. Update Time (deltas)
|
|
// ...
|
|
|
|
// 03. Update Receive (network, servertime, receive messages)
|
|
// ...
|
|
|
|
// 04. Update Input (keyboard controls, etc)
|
|
if (m_IsGraphicsInitialized)
|
|
m_GraphicsViewport->updateInput();
|
|
|
|
// 05. Update Weather (sky, snow, wind, fog, sun)
|
|
// ...
|
|
|
|
// 06. Update Entities (movement, do after possible tp from incoming messages etc)
|
|
// - Move other entities
|
|
// - Update self entity
|
|
// - Move bullets
|
|
// ...
|
|
|
|
// 07. Update Landscape (async zone loading near entity)
|
|
// ...
|
|
|
|
// 08. Update Collisions (entities)
|
|
// - Update entities
|
|
// - Update move container (swap with Update entities? todo: check code!)
|
|
// - Update bullets
|
|
// ...
|
|
|
|
// 09. Update Animations (playlists)
|
|
// - Needs to be either before or after entities, not sure,
|
|
// there was a problem with wrong order a while ago!!!
|
|
// ...
|
|
|
|
// 10. Update Camera (depends on entities)
|
|
// ...
|
|
|
|
// 11. Update Interface (login, ui, etc)
|
|
// ...
|
|
|
|
// 12. Update Sound (sound driver)
|
|
if (m_IsSoundInitialized)
|
|
m_SoundUtilities.updateSound();
|
|
|
|
// 13. Update Send (network, send new position etc)
|
|
// ...
|
|
|
|
// 14. Update Debug (stuff for dev)
|
|
// ...
|
|
|
|
if (m_IsGraphicsInitialized && !m_GraphicsViewport->getDriver()->isLost())
|
|
{
|
|
// 01. Render Driver (background color)
|
|
m_GraphicsViewport->renderDriver(); // clear all buffers
|
|
|
|
// 02. Render Sky (sky scene)
|
|
// ...
|
|
|
|
// 04. Render Scene (entity scene)
|
|
// ...
|
|
|
|
// 05. Render Effects (flare)
|
|
// ...
|
|
|
|
// 06. Render Interface 3D (player names)
|
|
// ...
|
|
|
|
// 07. Render Debug 3D
|
|
// ...
|
|
|
|
// 08. Render Interface 2D (chatboxes etc, optionally does have 3d)
|
|
// ...
|
|
|
|
// 09. Render Debug 2D (stuff for dev)
|
|
m_GraphicsViewport->renderDebug2D();
|
|
|
|
// swap 3d buffers
|
|
m_GraphicsViewport->getDriver()->swapBuffers();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainWindow::printDebug()
|
|
{
|
|
nldebug("This is a debug message.");
|
|
}
|
|
|
|
} /* namespace NLQT */
|
|
|
|
/* end of file */
|