diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 288e0394c..c03cc3138 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -59,8 +59,17 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable + cellcreator referenceablecreator referencecreator scenesubview + infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable + ) + +opencs_units_noqt (view/world + subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate + scripthighlighter idvalidator dialoguecreator + ) + +opencs_units (view/widget + scenetoolbar scenetool scenetoolmode pushbutton ) opencs_units (view/render @@ -73,11 +82,6 @@ opencs_units_noqt (view/render lightingbright object cell ) -opencs_units_noqt (view/world - subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate - scripthighlighter idvalidator dialoguecreator - ) - opencs_units (view/tools reportsubview diff --git a/apps/opencs/model/world/resourcetable.cpp b/apps/opencs/model/world/resourcetable.cpp index 167b48436..86de0a6a6 100644 --- a/apps/opencs/model/world/resourcetable.cpp +++ b/apps/opencs/model/world/resourcetable.cpp @@ -75,8 +75,6 @@ QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orien break; } - // xxx - return QVariant(); } diff --git a/apps/opencs/view/doc/startup.cpp b/apps/opencs/view/doc/startup.cpp index 5d59492c6..799a07e14 100644 --- a/apps/opencs/view/doc/startup.cpp +++ b/apps/opencs/view/doc/startup.cpp @@ -81,6 +81,7 @@ QWidget *CSVDoc::StartupDialogue::createTools() config->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); config->setIcon (QIcon (":startup/configure")); + config->setToolTip ("Open user settings"); layout->addWidget (config); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 76f6db385..ebd3eb764 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -11,7 +12,7 @@ #include #include -#include "../world/scenetoolmode.hpp" +#include "../widget/scenetoolmode.hpp" #include "navigation.hpp" #include "lighting.hpp" @@ -51,16 +52,34 @@ namespace CSVRender QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), this, SLOT (update())); - timer->start (20); /// \todo make this configurable + timer->start (20); ///< \todo make this configurable + + /// \todo make shortcut configurable + QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut); + connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest())); } - CSVWorld::SceneToolMode *SceneWidget::makeLightingSelector (CSVWorld::SceneToolbar *parent) + CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent) { - CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent); - - tool->addButton (":door.png", "day"); /// \todo replace icons - tool->addButton (":GMST.png", "night"); - tool->addButton (":Info.png", "bright"); + CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Lighting Mode"); + + /// \todo replace icons + tool->addButton (":door.png", "day", + "Day" + "
  • Cell specific ambient in interiors
  • " + "
  • Low ambient in exteriors
  • " + "
  • Strong directional light source/lir>" + "
  • This mode closely resembles day time in-game
"); + tool->addButton (":GMST.png", "night", + "Night" + "
  • Cell specific ambient in interiors
  • " + "
  • Low ambient in exteriors
  • " + "
  • Weak directional light source
  • " + "
  • This mode closely resembles night time in-game
"); + tool->addButton (":Info.png", "bright", + "Bright" + "
  • Maximum ambient
  • " + "
  • Strong directional light source
"); connect (tool, SIGNAL (modeChanged (const std::string&)), this, SLOT (selectLightingMode (const std::string&))); @@ -347,6 +366,9 @@ namespace CSVRender mLighting = lighting; mLighting->activate (mSceneMgr, mHasDefaultAmbient ? &mDefaultAmbient : 0); + + if (mWindow) + mWindow->update(); } void SceneWidget::selectLightingMode (const std::string& mode) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index f6b41942f..8f548f483 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -16,7 +16,7 @@ namespace Ogre class RenderWindow; } -namespace CSVWorld +namespace CSVWidget { class SceneToolMode; class SceneToolbar; @@ -38,7 +38,7 @@ namespace CSVRender QPaintEngine* paintEngine() const; - CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent); + CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); ///< \attention The created tool is not added to the toolbar (via addTool). Doing that /// is the responsibility of the calling function. @@ -111,6 +111,10 @@ namespace CSVRender void update(); void selectLightingMode (const std::string& mode); + + signals: + + void focusToolbarRequest(); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index fee2f0a16..d3413a29d 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -7,8 +7,9 @@ #include -#include "../world/scenetoolmode.hpp" -#include +#include "../../model/world/universalid.hpp" + +#include "../widget/scenetoolmode.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (parent), mDocument(document) @@ -53,14 +54,39 @@ void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() setNavigation (&m1st); } -CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( - CSVWorld::SceneToolbar *parent) +CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( + CSVWidget::SceneToolbar *parent) { - CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent); - - tool->addButton (":door.png", "1st"); /// \todo replace icons - tool->addButton (":GMST.png", "free"); - tool->addButton (":Info.png", "orbit"); + CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Camera Mode"); + + /// \todo replace icons + /// \todo consider user-defined button-mapping + tool->addButton (":door.png", "1st", + "First Person" + "
  • Mouse-Look while holding the left button
  • " + "
  • WASD movement keys
  • " + "
  • Mouse wheel moves the camera forawrd/backward
  • " + "
  • Stafing (also vertically) by holding the left mouse button and control
  • " + "
  • Camera is held upright
  • " + "
  • Hold shift to speed up movement
  • " + "
"); + tool->addButton (":GMST.png", "free", + "Free Camera" + "
  • Mouse-Look while holding the left button
  • " + "
  • Stafing (also vertically) via WASD or by holding the left mouse button and control
  • " + "
  • Mouse wheel moves the camera forawrd/backward
  • " + "
  • Roll camera with Q and E keys
  • " + "
  • Hold shift to speed up movement
  • " + "
"); + tool->addButton (":Info.png", "orbit", + "Orbiting Camera" + "
  • Always facing the centre point
  • " + "
  • Rotate around the centre point via WASD or by moving the mouse while holding the left button
  • " + "
  • Mouse wheel moves camera away or towards centre point but can not pass through it
  • " + "
  • Roll camera with Q and E keys
  • " + "
  • Stafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)
  • " + "
  • Hold shift to speed up movement
  • " + "
"); connect (tool, SIGNAL (modeChanged (const std::string&)), this, SLOT (selectNavigationMode (const std::string&))); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 2af90b0fe..3b96779a8 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -13,7 +13,7 @@ namespace CSMWorld { class UniversalId; } -namespace CSVWorld +namespace CSVWidget { class SceneToolMode; class SceneToolbar; @@ -49,7 +49,7 @@ namespace CSVRender WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0); - CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); + CSVWidget::SceneToolMode *makeNavigationSelector (CSVWidget::SceneToolbar *parent); ///< \attention The created tool is not added to the toolbar (via addTool). Doing that /// is the responsibility of the calling function. diff --git a/apps/opencs/view/widget/pushbutton.cpp b/apps/opencs/view/widget/pushbutton.cpp new file mode 100644 index 000000000..056e548fb --- /dev/null +++ b/apps/opencs/view/widget/pushbutton.cpp @@ -0,0 +1,83 @@ + +#include "pushbutton.hpp" + +#include +#include + +void CSVWidget::PushButton::setExtendedToolTip (const QString& text) +{ + QString tooltip = text; + + if (tooltip.isEmpty()) + tooltip = "(Tool tip not implemented yet)"; + + switch (mType) + { + case Type_TopMode: + + tooltip += + "

(left click to change mode)"; + + break; + + case Type_Mode: + + tooltip += + "

(left click to activate," + "
shift-left click to activate and keep panel open)"; + + break; + } + + setToolTip (tooltip); +} + +void CSVWidget::PushButton::keyPressEvent (QKeyEvent *event) +{ + if (event->key()!=Qt::Key_Shift) + mKeepOpen = false; + + QPushButton::keyPressEvent (event); +} + +void CSVWidget::PushButton::keyReleaseEvent (QKeyEvent *event) +{ + if (event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) + { + mKeepOpen = event->modifiers() & Qt::ShiftModifier; + emit clicked(); + } + + QPushButton::keyReleaseEvent (event); +} + +void CSVWidget::PushButton::mouseReleaseEvent (QMouseEvent *event) +{ + mKeepOpen = event->button()==Qt::LeftButton && (event->modifiers() & Qt::ShiftModifier); + QPushButton::mouseReleaseEvent (event); +} + +CSVWidget::PushButton::PushButton (const QIcon& icon, Type type, const QString& tooltip, + QWidget *parent) +: QPushButton (icon, "", parent), mKeepOpen (false), mType (type), mToolTip (tooltip) +{ + setCheckable (type==Type_Mode); + setExtendedToolTip (tooltip); +} + +CSVWidget::PushButton::PushButton (Type type, const QString& tooltip, QWidget *parent) +: QPushButton (parent), mKeepOpen (false), mType (type), mToolTip (tooltip) +{ + setCheckable (type==Type_Mode); + setExtendedToolTip (tooltip); +} + +bool CSVWidget::PushButton::hasKeepOpen() const +{ + return mKeepOpen; +} + +QString CSVWidget::PushButton::getBaseToolTip() const +{ + return mToolTip; +} \ No newline at end of file diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp new file mode 100644 index 000000000..9b90bd0c6 --- /dev/null +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -0,0 +1,55 @@ +#ifndef CSV_WIDGET_PUSHBUTTON_H +#define CSV_WIDGET_PUSHBUTTON_H + +#include + +namespace CSVWidget +{ + class PushButton : public QPushButton + { + Q_OBJECT + + public: + + enum Type + { + Type_TopMode, // top level button for mode selector panel + Type_Mode // mode button + }; + + private: + + bool mKeepOpen; + Type mType; + QString mToolTip; + + private: + + void setExtendedToolTip (const QString& text); + + protected: + + virtual void keyPressEvent (QKeyEvent *event); + + virtual void keyReleaseEvent (QKeyEvent *event); + + virtual void mouseReleaseEvent (QMouseEvent *event); + + public: + + /// \param push Do not maintain a toggle state + PushButton (const QIcon& icon, Type type, const QString& tooltip = "", + QWidget *parent = 0); + + /// \param push Do not maintain a toggle state + PushButton (Type type, const QString& tooltip = "", + QWidget *parent = 0); + + bool hasKeepOpen() const; + + /// Return tooltip used at construction (without any button-specific modifications) + QString getBaseToolTip() const; + }; +} + +#endif diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/widget/scenetool.cpp similarity index 73% rename from apps/opencs/view/world/scenetool.cpp rename to apps/opencs/view/widget/scenetool.cpp index 612b4c6d3..e3f2dfd1c 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/widget/scenetool.cpp @@ -3,7 +3,8 @@ #include "scenetoolbar.hpp" -CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) +CSVWidget::SceneTool::SceneTool (SceneToolbar *parent) +: PushButton (PushButton::Type_TopMode, "", parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setIconSize (QSize (parent->getIconSize(), parent->getIconSize())); @@ -12,7 +13,7 @@ CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } -void CSVWorld::SceneTool::openRequest() +void CSVWidget::SceneTool::openRequest() { showPanel (parentWidget()->mapToGlobal (pos())); } diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/widget/scenetool.hpp similarity index 66% rename from apps/opencs/view/world/scenetool.hpp rename to apps/opencs/view/widget/scenetool.hpp index 07e8b58d7..24099683e 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/widget/scenetool.hpp @@ -1,14 +1,14 @@ -#ifndef CSV_WORLD_SCENETOOL_H -#define CSV_WORLD_SCENETOOL_H +#ifndef CSV_WIDGET_SCENETOOL_H +#define CSV_WIDGET_SCENETOOL_H -#include +#include "pushbutton.hpp" -namespace CSVWorld +namespace CSVWidget { class SceneToolbar; ///< \brief Tool base class - class SceneTool : public QPushButton + class SceneTool : public PushButton { Q_OBJECT diff --git a/apps/opencs/view/widget/scenetoolbar.cpp b/apps/opencs/view/widget/scenetoolbar.cpp new file mode 100644 index 000000000..eac9bcec3 --- /dev/null +++ b/apps/opencs/view/widget/scenetoolbar.cpp @@ -0,0 +1,47 @@ + +#include "scenetoolbar.hpp" + +#include +#include + +#include "scenetool.hpp" + +void CSVWidget::SceneToolbar::focusInEvent (QFocusEvent *event) +{ + QWidget::focusInEvent (event); + + if (mLayout->count()) + dynamic_cast (*mLayout->itemAt (0)).widget()->setFocus(); +} + +CSVWidget::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) +: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-6) +{ + setFixedWidth (mButtonSize); + + mLayout = new QVBoxLayout (this); + mLayout->setAlignment (Qt::AlignTop); + + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + setLayout (mLayout); + + /// \todo make shortcut configurable + QShortcut *focusScene = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut); + connect (focusScene, SIGNAL (activated()), this, SIGNAL (focusSceneRequest())); +} + +void CSVWidget::SceneToolbar::addTool (SceneTool *tool) +{ + mLayout->addWidget (tool, 0, Qt::AlignTop); +} + +int CSVWidget::SceneToolbar::getButtonSize() const +{ + return mButtonSize; +} + +int CSVWidget::SceneToolbar::getIconSize() const +{ + return mIconSize; +} diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/widget/scenetoolbar.hpp similarity index 66% rename from apps/opencs/view/world/scenetoolbar.hpp rename to apps/opencs/view/widget/scenetoolbar.hpp index 731806cc5..1902ba2be 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/widget/scenetoolbar.hpp @@ -1,11 +1,11 @@ -#ifndef CSV_WORLD_SCENETOOLBAR_H -#define CSV_WORLD_SCENETOOLBAR_H +#ifndef CSV_WIDGET_SCENETOOLBAR_H +#define CSV_WIDGET_SCENETOOLBAR_H #include class QVBoxLayout; -namespace CSVWorld +namespace CSVWidget { class SceneTool; @@ -17,6 +17,10 @@ namespace CSVWorld int mButtonSize; int mIconSize; + protected: + + virtual void focusInEvent (QFocusEvent *event); + public: SceneToolbar (int buttonSize, QWidget *parent = 0); @@ -26,6 +30,10 @@ namespace CSVWorld int getButtonSize() const; int getIconSize() const; + + signals: + + void focusSceneRequest(); }; } diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp new file mode 100644 index 000000000..caedfa3ee --- /dev/null +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -0,0 +1,86 @@ + +#include "scenetoolmode.hpp" + +#include +#include +#include + +#include "scenetoolbar.hpp" +#include "pushbutton.hpp" + +void CSVWidget::SceneToolMode::adjustToolTip (const PushButton *activeMode) +{ + QString toolTip = mToolTip; + + toolTip += "

Currently selected: " + activeMode->getBaseToolTip(); + + toolTip += "

(left click to change mode)"; + + setToolTip (toolTip); +} + +CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip) +: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()), + mToolTip (toolTip), mFirst (0) +{ + mPanel = new QFrame (this, Qt::Popup); + + mLayout = new QHBoxLayout (mPanel); + + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + mPanel->setLayout (mLayout); +} + +void CSVWidget::SceneToolMode::showPanel (const QPoint& position) +{ + mPanel->move (position); + mPanel->show(); + + if (mFirst) + mFirst->setFocus (Qt::OtherFocusReason); +} + +void CSVWidget::SceneToolMode::addButton (const std::string& icon, const std::string& id, + const QString& tooltip) +{ + PushButton *button = new PushButton (QIcon (QPixmap (icon.c_str())), PushButton::Type_Mode, + tooltip, mPanel); + button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setIconSize (QSize (mIconSize, mIconSize)); + button->setFixedSize (mButtonSize, mButtonSize); + + mLayout->addWidget (button); + + mButtons.insert (std::make_pair (button, id)); + + connect (button, SIGNAL (clicked()), this, SLOT (selected())); + + if (mButtons.size()==1) + { + mFirst = button; + setIcon (button->icon()); + button->setChecked (true); + adjustToolTip (button); + } +} + +void CSVWidget::SceneToolMode::selected() +{ + std::map::const_iterator iter = + mButtons.find (dynamic_cast (sender())); + + if (iter!=mButtons.end()) + { + if (!iter->first->hasKeepOpen()) + mPanel->hide(); + + for (std::map::const_iterator iter2 = mButtons.begin(); + iter2!=mButtons.end(); ++iter2) + iter2->first->setChecked (iter2==iter); + + setIcon (iter->first->icon()); + adjustToolTip (iter->first); + emit modeChanged (iter->second); + } +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp similarity index 57% rename from apps/opencs/view/world/scenetoolmode.hpp rename to apps/opencs/view/widget/scenetoolmode.hpp index a156c0c95..9959f9835 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -1,5 +1,5 @@ -#ifndef CSV_WORLD_SCENETOOL_MODE_H -#define CSV_WORLD_SCENETOOL_MODE_H +#ifndef CSV_WIDGET_SCENETOOL_MODE_H +#define CSV_WIDGET_SCENETOOL_MODE_H #include "scenetool.hpp" @@ -7,9 +7,10 @@ class QHBoxLayout; -namespace CSVWorld +namespace CSVWidget { class SceneToolbar; + class PushButton; ///< \brief Mode selector tool class SceneToolMode : public SceneTool @@ -18,17 +19,22 @@ namespace CSVWorld QWidget *mPanel; QHBoxLayout *mLayout; - std::map mButtons; // widget, id + std::map mButtons; // widget, id int mButtonSize; int mIconSize; + QString mToolTip; + PushButton *mFirst; + + void adjustToolTip (const PushButton *activeMode); public: - SceneToolMode (SceneToolbar *parent); + SceneToolMode (SceneToolbar *parent, const QString& toolTip); virtual void showPanel (const QPoint& position); - void addButton (const std::string& icon, const std::string& id); + void addButton (const std::string& icon, const std::string& id, + const QString& tooltip = ""); signals: diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index ad2db8723..bcf108934 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -426,25 +426,32 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM QHBoxLayout *buttonsLayout = new QHBoxLayout; QToolButton* prevButton = new QToolButton(mainWidget); prevButton->setIcon(QIcon(":/go-previous.png")); + prevButton->setToolTip ("Switch to previous record"); QToolButton* nextButton = new QToolButton(mainWidget); nextButton->setIcon(QIcon(":/go-next.png")); + nextButton->setToolTip ("Switch to next record"); buttonsLayout->addWidget(prevButton, 0); buttonsLayout->addWidget(nextButton, 1); buttonsLayout->addStretch(2); QToolButton* cloneButton = new QToolButton(mainWidget); cloneButton->setIcon(QIcon(":/edit-clone.png")); + cloneButton->setToolTip ("Clone record"); QToolButton* addButton = new QToolButton(mainWidget); addButton->setIcon(QIcon(":/add.png")); + addButton->setToolTip ("Add new record"); QToolButton* deleteButton = new QToolButton(mainWidget); deleteButton->setIcon(QIcon(":/edit-delete.png")); + deleteButton->setToolTip ("Delete record"); QToolButton* revertButton = new QToolButton(mainWidget); revertButton->setIcon(QIcon(":/edit-undo.png")); + revertButton->setToolTip ("Revert record"); if (mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview) { QToolButton* previewButton = new QToolButton(mainWidget); previewButton->setIcon(QIcon(":/edit-preview.png")); + previewButton->setToolTip ("Open a preview of this record"); buttonsLayout->addWidget(previewButton); connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); } @@ -453,6 +460,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM { QToolButton* viewButton = new QToolButton(mainWidget); viewButton->setIcon(QIcon(":/cell.png")); + viewButton->setToolTip ("Open a scene view of the cell this record is located in"); buttonsLayout->addWidget(viewButton); connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord())); } diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 49e6d9361..1e106c69f 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -5,8 +5,8 @@ #include "../render/previewwidget.hpp" -#include "scenetoolbar.hpp" -#include "scenetoolmode.hpp" +#include "../widget/scenetoolbar.hpp" +#include "../widget/scenetoolmode.hpp" CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -28,9 +28,9 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo else mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), true, this); - SceneToolbar *toolbar = new SceneToolbar (48+6, this); + CSVWidget::SceneToolbar *toolbar = new CSVWidget::SceneToolbar (48+6, this); - SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); + CSVWidget::SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); layout->addWidget (toolbar, 0); @@ -46,6 +46,8 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); connect (mScene, SIGNAL (referenceableIdChanged (const std::string&)), this, SLOT (referenceableIdChanged (const std::string&))); + connect (mScene, SIGNAL (focusToolbarRequest()), toolbar, SLOT (setFocus())); + connect (toolbar, SIGNAL (focusSceneRequest()), mScene, SLOT (setFocus())); } void CSVWorld::PreviewSubView::setEditLock (bool locked) {} diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 36cce9ecd..dc1525b05 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -17,9 +17,11 @@ #include "../render/pagedworldspacewidget.hpp" #include "../render/unpagedworldspacewidget.hpp" +#include "../widget/scenetoolbar.hpp" +#include "../widget/scenetoolmode.hpp" + #include "tablebottombox.hpp" #include "creator.hpp" -#include "scenetoolmode.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mLayout(new QHBoxLayout), mDocument(document), mScene(NULL), mToolbar(NULL) @@ -95,18 +97,18 @@ void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); } -CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type) +CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type) { - CSVWorld::SceneToolbar* toolbar = new SceneToolbar (48+6, this); + CSVWidget::SceneToolbar* toolbar = new CSVWidget::SceneToolbar (48+6, this); - SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar); + CSVWidget::SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar); toolbar->addTool (navigationTool); - SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar); + CSVWidget::SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar); toolbar->addTool (lightingTool); /* Add buttons specific to the type. For now no need for it. - * + * switch (type) { case widget_Paged: @@ -188,7 +190,7 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI { CSVRender::PagedWorldspaceWidget* pagedNewWidget = NULL; CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = NULL; - SceneToolbar* toolbar = NULL; + CSVWidget::SceneToolbar* toolbar = NULL; switch (mScene->getDropRequirements(CSVRender::WorldspaceWidget::getDropType(data))) { @@ -217,7 +219,7 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI } } -void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceWidget* widget, CSVWorld::SceneToolbar* toolbar) +void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar) { assert(mLayout); @@ -236,8 +238,12 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW mScene = widget; mToolbar = toolbar; + connect (mScene, SIGNAL (focusToolbarRequest()), mToolbar, SLOT (setFocus())); + connect (mToolbar, SIGNAL (focusSceneRequest()), mScene, SLOT (setFocus())); + mLayout->addWidget (mToolbar, 0); mLayout->addWidget (mScene, 1); mScene->selectDefaultNavigationMode(); + setFocusProxy (mScene); } \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index b9ecbe931..b9dcdd6a3 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -4,7 +4,6 @@ #include #include "../doc/subview.hpp" -#include "scenetoolbar.hpp" class QModelIndex; @@ -25,6 +24,11 @@ namespace CSVRender class UnpagedWorldspaceWidget; } +namespace CSVWidget +{ + class SceneToolbar; +} + namespace CSVWorld { class Table; @@ -39,7 +43,7 @@ namespace CSVWorld CSVRender::WorldspaceWidget *mScene; QHBoxLayout* mLayout; CSMDoc::Document& mDocument; - SceneToolbar* mToolbar; + CSVWidget::SceneToolbar* mToolbar; public: @@ -59,14 +63,15 @@ namespace CSVWorld void makeConnections(CSVRender::UnpagedWorldspaceWidget* widget); - void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, SceneToolbar* toolbar); + void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar); enum widgetType { widget_Paged, widget_Unpaged }; - SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type); + + CSVWidget::SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type); private slots: diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp deleted file mode 100644 index d60240da7..000000000 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include "scenetoolbar.hpp" - -#include - -#include "scenetool.hpp" - -CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) -: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-6) -{ - setFixedWidth (mButtonSize); - - mLayout = new QVBoxLayout (this); - mLayout->setAlignment (Qt::AlignTop); - - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); - - setLayout (mLayout); -} - -void CSVWorld::SceneToolbar::addTool (SceneTool *tool) -{ - mLayout->addWidget (tool, 0, Qt::AlignTop); -} - -int CSVWorld::SceneToolbar::getButtonSize() const -{ - return mButtonSize; -} - -int CSVWorld::SceneToolbar::getIconSize() const -{ - return mIconSize; -} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp deleted file mode 100644 index 73b01ae3a..000000000 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -#include "scenetoolmode.hpp" - -#include -#include -#include - -#include "scenetoolbar.hpp" - -CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent) -: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()) -{ - mPanel = new QFrame (this, Qt::Popup); - - mLayout = new QHBoxLayout (mPanel); - - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); - - mPanel->setLayout (mLayout); -} - -void CSVWorld::SceneToolMode::showPanel (const QPoint& position) -{ - mPanel->move (position); - mPanel->show(); -} - -void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id) -{ - QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setIconSize (QSize (mIconSize, mIconSize)); - button->setFixedSize (mButtonSize, mButtonSize); - - mLayout->addWidget (button); - - mButtons.insert (std::make_pair (button, id)); - - connect (button, SIGNAL (clicked()), this, SLOT (selected())); - - if (mButtons.size()==1) - setIcon (button->icon()); -} - -void CSVWorld::SceneToolMode::selected() -{ - std::map::const_iterator iter = - mButtons.find (dynamic_cast (sender())); - - if (iter!=mButtons.end()) - { - mPanel->hide(); - - setIcon (iter->first->icon()); - emit modeChanged (iter->second); - } -} \ No newline at end of file diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 5c698258a..32aaa6e71 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -16,9 +16,10 @@ namespace MWGui { - + const unsigned int LevelupDialog::sMaxCoins = 3; LevelupDialog::LevelupDialog() - : WindowBase("openmw_levelup_dialog.layout") + : WindowBase("openmw_levelup_dialog.layout"), + mCoinCount(sMaxCoins) { getWidget(mOkButton, "OkButton"); getWidget(mClassImage, "ClassImage"); @@ -46,12 +47,10 @@ namespace MWGui mAttributeMultipliers.push_back(t); } - int curX = mMainWidget->getWidth()/2 - (16 + 2) * 1.5; - for (int i=0; i<3; ++i) + for (unsigned int i = 0; i < mCoinCount; ++i) { - MyGUI::ImageBox* image = mMainWidget->createWidget("ImageBox", MyGUI::IntCoord(curX,250,16,16), MyGUI::Align::Default); + MyGUI::ImageBox* image = mCoinBox->createWidget("ImageBox", MyGUI::IntCoord(0,0,16,16), MyGUI::Align::Default); image->setImageTexture ("icons\\tx_goldicon.dds"); - curX += 24+2; mCoins.push_back(image); } @@ -61,15 +60,15 @@ namespace MWGui void LevelupDialog::setAttributeValues() { MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats (player); + MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats(player); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); - for (int i=0; i<8; ++i) + for (int i = 0; i < 8; ++i) { - int val = creatureStats.getAttribute (i).getBase (); + int val = creatureStats.getAttribute(i).getBase(); if (std::find(mSpentAttributes.begin(), mSpentAttributes.end(), i) != mSpentAttributes.end()) { - val += pcStats.getLevelupAttributeMultiplier (i); + val += pcStats.getLevelupAttributeMultiplier(i); } if (val >= 100) @@ -80,20 +79,21 @@ namespace MWGui } - void LevelupDialog::resetCoins () + void LevelupDialog::resetCoins() { - int curX = 0; - for (int i=0; i<3; ++i) + const int coinSpacing = 10; + int curX = mCoinBox->getWidth()/2 - (coinSpacing*(mCoinCount - 1) + 16*mCoinCount)/2; + for (unsigned int i=0; idetachFromWidget(); image->attachToWidget(mCoinBox); image->setCoord(MyGUI::IntCoord(curX,0,16,16)); - curX += 24+2; + curX += 16+coinSpacing; } } - void LevelupDialog::assignCoins () + void LevelupDialog::assignCoins() { resetCoins(); for (unsigned int i=0; igetPlayerPtr(); - MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats (player); - MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); - - mSpentAttributes.clear(); - resetCoins(); - - setAttributeValues(); + MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats(player); + MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); const ESM::NPC *playerData = player.get()->mBase; @@ -154,61 +149,89 @@ namespace MWGui mLevelText->setCaptionWithReplacing("#{sLevelUpMenu1} " + boost::lexical_cast(level)); std::string levelupdescription; - if(level>20) + if(level > 20) levelupdescription=world->getFallback()->getFallbackString("Level_Up_Default"); else levelupdescription=world->getFallback()->getFallbackString("Level_Up_Level"+boost::lexical_cast(level)); mLevelDescription->setCaption (levelupdescription); - for (int i=0; i<8; ++i) + unsigned int availableAttributes = 0; + for (int i = 0; i < 8; ++i) { MyGUI::TextBox* text = mAttributeMultipliers[i]; - int mult = pcStats.getLevelupAttributeMultiplier (i); - text->setCaption(mult <= 1 ? "" : "x" + boost::lexical_cast(mult)); + if (pcStats.getAttribute(i).getBase() < 100) + { + mAttributes[i]->setEnabled(true); + availableAttributes++; + + int mult = pcStats.getLevelupAttributeMultiplier (i); + text->setCaption(mult <= 1 ? "" : "x" + boost::lexical_cast(mult)); + } + else + { + mAttributes[i]->setEnabled(false); + + text->setCaption(""); + } + } + + mCoinCount = std::min(sMaxCoins, availableAttributes); + + for (unsigned int i = 0; i < sMaxCoins; i++) + { + if (i < mCoinCount) + mCoins[i]->attachToWidget(mCoinBox); + else + mCoins[i]->detachFromWidget(); } + mSpentAttributes.clear(); + resetCoins(); + + setAttributeValues(); + center(); } - void LevelupDialog::onOkButtonClicked (MyGUI::Widget* sender) + void LevelupDialog::onOkButtonClicked(MyGUI::Widget* sender) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); - if (mSpentAttributes.size() < 3) - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}"); + if (mSpentAttributes.size() < mCoinCount) + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage36}"); else { // increase attributes - for (int i=0; i<3; ++i) + for (unsigned int i = 0; i < mCoinCount; ++i) { MWMechanics::AttributeValue attribute = pcStats.getAttribute(mSpentAttributes[i]); - attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i])); + attribute.setBase(attribute.getBase() + pcStats.getLevelupAttributeMultiplier(mSpentAttributes[i])); if (attribute.getBase() >= 100) attribute.setBase(100); pcStats.setAttribute(mSpentAttributes[i], attribute); } - pcStats.levelUp (); + pcStats.levelUp(); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Levelup); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Levelup); } } - void LevelupDialog::onAttributeClicked (MyGUI::Widget *sender) + void LevelupDialog::onAttributeClicked(MyGUI::Widget *sender) { int attribute = *sender->getUserData(); std::vector::iterator found = std::find(mSpentAttributes.begin(), mSpentAttributes.end(), attribute); if (found != mSpentAttributes.end()) - mSpentAttributes.erase (found); + mSpentAttributes.erase(found); else { - if (mSpentAttributes.size() == 3) - mSpentAttributes[2] = attribute; + if (mSpentAttributes.size() == mCoinCount) + mSpentAttributes[mCoinCount - 1] = attribute; else mSpentAttributes.push_back(attribute); } diff --git a/apps/openmw/mwgui/levelupdialog.hpp b/apps/openmw/mwgui/levelupdialog.hpp index 69afbf089..5ca9c8c75 100644 --- a/apps/openmw/mwgui/levelupdialog.hpp +++ b/apps/openmw/mwgui/levelupdialog.hpp @@ -28,8 +28,11 @@ namespace MWGui std::vector mSpentAttributes; - void onOkButtonClicked (MyGUI::Widget* sender); - void onAttributeClicked (MyGUI::Widget* sender); + unsigned int mCoinCount; + static const unsigned int sMaxCoins; + + void onOkButtonClicked(MyGUI::Widget* sender); + void onAttributeClicked(MyGUI::Widget* sender); void assignCoins(); void resetCoins(); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 6c4e00ae5..b11258f1c 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -321,6 +321,11 @@ namespace MWGui skillValueWidget->_setWidgetState(state); skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); + // resize dynamically according to text size + int textWidthPlusMargin = skillValueWidget->getTextSize().width + 12; + skillValueWidget->setCoord(coord2.left + coord2.width - textWidthPlusMargin, coord2.top, textWidthPlusMargin, coord2.height); + skillNameWidget->setSize(skillNameWidget->getSize() + MyGUI::IntSize(coord2.width - textWidthPlusMargin, 0)); + mSkillWidgets.push_back(skillNameWidget); mSkillWidgets.push_back(skillValueWidget); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 865ad1dca..668211db2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1529,6 +1529,8 @@ namespace MWGui mCompanionWindow->resetReference(); mConsole->resetReference(); + mSelectedSpell.clear(); + mGuiModes.clear(); MWBase::Environment::get().getInputManager()->changeInputMode(false); updateVisible(); diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 2606daa88..c0a97a1b1 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -265,7 +265,7 @@ namespace MWMechanics const ESM::Weapon *weapon = NULL; MWMechanics::WeaponType weaptype; - float weapRange; + float weapRange = 1.0f; actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); @@ -300,7 +300,7 @@ namespace MWMechanics else //is creature { weaptype = WeapType_HandToHand; //doesn't matter, should only reflect if it is melee or distant weapon - weapRange = 150; //TODO: use true attack range (the same problem in Creature::hit) + weapRange = 150.0f; //TODO: use true attack range (the same problem in Creature::hit) } float rangeAttack; diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 201393761..daad5b0e6 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -364,7 +364,7 @@ namespace MWWorld continue; // velocity updated, calculate nextpos again } - if(newPosition.squaredDistance(nextpos) > 0.00000001*0.00000001) + if(newPosition.squaredDistance(nextpos) > 0.0001) { // trace to where character would go if there were no obstructions tracer.doTrace(colobj, newPosition, nextpos, engine); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index fb520dae4..9b747582f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2320,15 +2320,10 @@ namespace MWWorld } // If this is a power, check if it was already used in the last 24h - if (!fail && spell->mData.mType == ESM::Spell::ST_Power) + if (!fail && spell->mData.mType == ESM::Spell::ST_Power && !stats.getSpells().canUsePower(spell->mId)) { - if (stats.getSpells().canUsePower(spell->mId)) - stats.getSpells().usePower(spell->mId); - else - { - message = "#{sPowerAlreadyUsed}"; - fail = true; - } + message = "#{sPowerAlreadyUsed}"; + fail = true; } // Reduce mana @@ -2361,6 +2356,10 @@ namespace MWWorld if (!selectedSpell.empty()) { const ESM::Spell* spell = getStore().get().search(selectedSpell); + + // A power can be used once per 24h + if (spell->mData.mType == ESM::Spell::ST_Power) + stats.getSpells().usePower(spell->mId); cast.cast(spell); } diff --git a/files/mygui/openmw_levelup_dialog.layout b/files/mygui/openmw_levelup_dialog.layout index 0b12d7a05..07e1e560b 100644 --- a/files/mygui/openmw_levelup_dialog.layout +++ b/files/mygui/openmw_levelup_dialog.layout @@ -23,7 +23,7 @@ - +