1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-07-21 03:44:05 +00:00

provide incremental update of SpellWindow (Fixes #2411)

When SpellWindow is visible, every 0.5 seconds update the cost/changes for spells/enchanted items shown.
Also, check to see if more substantial update of the window is required.
This commit is contained in:
dteviot 2015-04-03 17:59:13 +13:00
parent 6b6bed520d
commit 52de622e97
4 changed files with 113 additions and 19 deletions

View file

@ -10,6 +10,8 @@
namespace MWGui namespace MWGui
{ {
const char* SpellView::sSpellModelIndex = "SpellModelIndex";
SpellView::SpellView() SpellView::SpellView()
: mShowCostColumn(true) : mShowCostColumn(true)
, mHighlightSelected(true) , mHighlightSelected(true)
@ -113,10 +115,10 @@ namespace MWGui
group.push_back(costChance); group.push_back(costChance);
Gui::SharedStateButton::createButtonGroup(group); Gui::SharedStateButton::createButtonGroup(group);
mLines.push_back(std::make_pair(t, costChance)); mLines.push_back(boost::make_tuple(t, costChance, true));
} }
else else
mLines.push_back(std::make_pair(t, (MyGUI::Widget*)NULL)); mLines.push_back(boost::make_tuple(t, (MyGUI::Widget*)NULL, true));
t->setStateSelected(spell.mSelected); t->setStateSelected(spell.mSelected);
} }
@ -124,30 +126,85 @@ namespace MWGui
layoutWidgets(); layoutWidgets();
} }
void SpellView::incrementalUpdate()
{
if (!mModel.get())
{
return;
}
mModel->update();
bool fullUpdateRequired = false;
SpellModel::ModelIndex maxSpellIndexFound = -1;
for (std::vector< LineInfo >::iterator it = mLines.begin(); it != mLines.end(); ++it)
{
// only update the lines that are "updateable"
if (it->get<2>())
{
Gui::SharedStateButton* nameButton = reinterpret_cast<Gui::SharedStateButton*>(it->get<0>());
// match model against line
// if don't match, then major change has happened, so do a full update
SpellModel::ModelIndex spellIndex = getSpellModelIndex(nameButton);
if (mModel->getItemCount() <= static_cast<unsigned>(spellIndex))
{
fullUpdateRequired = true;
break;
}
// more checking for major change.
const Spell& spell = mModel->getItem(spellIndex);
if (nameButton->getCaption() != spell.mName)
{
fullUpdateRequired = true;
break;
}
else
{
maxSpellIndexFound = spellIndex;
Gui::SharedStateButton* costButton = reinterpret_cast<Gui::SharedStateButton*>(it->get<1>());
if ((costButton != NULL) && (costButton->getCaption() != spell.mCostColumn))
{
costButton->setCaption(spell.mCostColumn);
}
}
}
}
// special case, look for spells added to model that are beyond last updatable item
SpellModel::ModelIndex topSpellIndex = mModel->getItemCount() - 1;
if (fullUpdateRequired ||
((0 <= topSpellIndex) && (maxSpellIndexFound < topSpellIndex)))
{
update();
}
}
void SpellView::layoutWidgets() void SpellView::layoutWidgets()
{ {
int height = 0; int height = 0;
for (std::vector< std::pair<MyGUI::Widget*, MyGUI::Widget*> >::iterator it = mLines.begin(); for (std::vector< LineInfo >::iterator it = mLines.begin();
it != mLines.end(); ++it) it != mLines.end(); ++it)
{ {
height += (it->first)->getHeight(); height += (it->get<0>())->getHeight();
} }
bool scrollVisible = height > mScrollView->getHeight(); bool scrollVisible = height > mScrollView->getHeight();
int width = mScrollView->getWidth() - (scrollVisible ? 18 : 0); int width = mScrollView->getWidth() - (scrollVisible ? 18 : 0);
height = 0; height = 0;
for (std::vector< std::pair<MyGUI::Widget*, MyGUI::Widget*> >::iterator it = mLines.begin(); for (std::vector< LineInfo >::iterator it = mLines.begin();
it != mLines.end(); ++it) it != mLines.end(); ++it)
{ {
int lineHeight = (it->first)->getHeight(); int lineHeight = (it->get<0>())->getHeight();
(it->first)->setCoord(4, height, width-8, lineHeight); (it->get<0>())->setCoord(4, height, width - 8, lineHeight);
if (it->second) if (it->get<1>())
{ {
(it->second)->setCoord(4, height, width-8, lineHeight); (it->get<1>())->setCoord(4, height, width - 8, lineHeight);
MyGUI::TextBox* second = (it->second)->castType<MyGUI::TextBox>(false); MyGUI::TextBox* second = (it->get<1>())->castType<MyGUI::TextBox>(false);
if (second) if (second)
(it->first)->setSize(width-8-second->getTextSize().width, lineHeight); (it->get<0>())->setSize(width - 8 - second->getTextSize().width, lineHeight);
} }
height += lineHeight; height += lineHeight;
@ -167,7 +224,7 @@ namespace MWGui
MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18), MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18),
MyGUI::Align::Left | MyGUI::Align::Top); MyGUI::Align::Left | MyGUI::Align::Top);
separator->setNeedMouseFocus(false); separator->setNeedMouseFocus(false);
mLines.push_back(std::make_pair(separator, (MyGUI::Widget*)NULL)); mLines.push_back(boost::make_tuple(separator, (MyGUI::Widget*)NULL, false));
} }
MyGUI::TextBox* groupWidget = mScrollView->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::TextBox* groupWidget = mScrollView->createWidget<MyGUI::TextBox>("SandBrightText",
@ -186,10 +243,10 @@ namespace MWGui
groupWidget2->setTextAlign(MyGUI::Align::Right); groupWidget2->setTextAlign(MyGUI::Align::Right);
groupWidget2->setNeedMouseFocus(false); groupWidget2->setNeedMouseFocus(false);
mLines.push_back(std::make_pair(groupWidget, groupWidget2)); mLines.push_back(boost::make_tuple(groupWidget, groupWidget2, false));
} }
else else
mLines.push_back(std::make_pair(groupWidget, (MyGUI::Widget*)NULL)); mLines.push_back(boost::make_tuple(groupWidget, (MyGUI::Widget*)NULL, false));
} }
@ -222,16 +279,20 @@ namespace MWGui
widget->setUserString("Spell", spell.mId); widget->setUserString("Spell", spell.mId);
} }
widget->setUserString("SpellModelIndex", MyGUI::utility::toString(index)); widget->setUserString(sSpellModelIndex, MyGUI::utility::toString(index));
widget->eventMouseWheel += MyGUI::newDelegate(this, &SpellView::onMouseWheel); widget->eventMouseWheel += MyGUI::newDelegate(this, &SpellView::onMouseWheel);
widget->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellView::onSpellSelected); widget->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellView::onSpellSelected);
} }
SpellModel::ModelIndex SpellView::getSpellModelIndex(MyGUI::Widget* widget)
{
return MyGUI::utility::parseInt(widget->getUserString(sSpellModelIndex));
}
void SpellView::onSpellSelected(MyGUI::Widget* _sender) void SpellView::onSpellSelected(MyGUI::Widget* _sender)
{ {
SpellModel::ModelIndex i = MyGUI::utility::parseInt(_sender->getUserString("SpellModelIndex")); eventSpellClicked(getSpellModelIndex(_sender));
eventSpellClicked(i);
} }
void SpellView::onMouseWheel(MyGUI::Widget* _sender, int _rel) void SpellView::onMouseWheel(MyGUI::Widget* _sender, int _rel)

View file

@ -1,6 +1,8 @@
#ifndef OPENMW_GUI_SPELLVIEW_H #ifndef OPENMW_GUI_SPELLVIEW_H
#define OPENMW_GUI_SPELLVIEW_H #define OPENMW_GUI_SPELLVIEW_H
#include <boost/tuple/tuple.hpp>
#include <MyGUI_Widget.h> #include <MyGUI_Widget.h>
#include "spellmodel.hpp" #include "spellmodel.hpp"
@ -37,6 +39,9 @@ namespace MWGui
void update(); void update();
/// simplified update called each frame
void incrementalUpdate();
typedef MyGUI::delegates::CMultiDelegate1<SpellModel::ModelIndex> EventHandle_ModelIndex; typedef MyGUI::delegates::CMultiDelegate1<SpellModel::ModelIndex> EventHandle_ModelIndex;
/// Fired when a spell was clicked /// Fired when a spell was clicked
EventHandle_ModelIndex eventSpellClicked; EventHandle_ModelIndex eventSpellClicked;
@ -51,7 +56,13 @@ namespace MWGui
std::auto_ptr<SpellModel> mModel; std::auto_ptr<SpellModel> mModel;
std::vector< std::pair<MyGUI::Widget*, MyGUI::Widget*> > mLines; /// tracks an item in the spell view
/// element<0> is the left column GUI object (usually holds the name)
/// element<1> is the right column (charge or cost info)
/// element<2> is if line needs to be checked during incremental update
typedef boost::tuple<MyGUI::Widget*, MyGUI::Widget*, bool> LineInfo;
std::vector< LineInfo > mLines;
bool mShowCostColumn; bool mShowCostColumn;
bool mHighlightSelected; bool mHighlightSelected;
@ -62,6 +73,10 @@ namespace MWGui
void onSpellSelected(MyGUI::Widget* _sender); void onSpellSelected(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel); void onMouseWheel(MyGUI::Widget* _sender, int _rel);
SpellModel::ModelIndex getSpellModelIndex(MyGUI::Widget* _sender);
static const char* sSpellModelIndex;
}; };
} }

View file

@ -28,6 +28,7 @@ namespace MWGui
: WindowPinnableBase("openmw_spell_window.layout") : WindowPinnableBase("openmw_spell_window.layout")
, NoDrop(drag, mMainWidget) , NoDrop(drag, mMainWidget)
, mSpellView(NULL) , mSpellView(NULL)
, mUpdateTimer(0.0f)
{ {
mSpellIcons = new SpellIcons(); mSpellIcons = new SpellIcons();
@ -60,6 +61,20 @@ namespace MWGui
updateSpells(); updateSpells();
} }
void SpellWindow::onFrame(float dt)
{
if (mMainWidget->getVisible())
{
NoDrop::onFrame(dt);
mUpdateTimer += dt;
if (0.5f < mUpdateTimer)
{
mUpdateTimer = 0;
mSpellView->incrementalUpdate();
}
}
}
void SpellWindow::updateSpells() void SpellWindow::updateSpells()
{ {
mSpellIcons->updateWidgets(mEffectBox, false); mSpellIcons->updateWidgets(mEffectBox, false);

View file

@ -19,7 +19,7 @@ namespace MWGui
void updateSpells(); void updateSpells();
void onFrame(float dt) { NoDrop::onFrame(dt); } void onFrame(float dt);
/// Cycle to next/previous spell /// Cycle to next/previous spell
void cycle(bool next); void cycle(bool next);
@ -41,6 +41,9 @@ namespace MWGui
SpellView* mSpellView; SpellView* mSpellView;
SpellIcons* mSpellIcons; SpellIcons* mSpellIcons;
private:
float mUpdateTimer;
}; };
} }