I made this patch for myself. Maybe someone else will find it useful it, too.
Screenshot:
Code:
Code: Select all
diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp
index 1877ef97d..455a67cd8 100644
--- a/apps/openmw/mwgui/inventorywindow.cpp
+++ b/apps/openmw/mwgui/inventorywindow.cpp
@@ -745,7 +745,7 @@ namespace MWGui
ItemModel::ModelIndex selected = -1;
// not using mSortFilterModel as we only need sorting, not filtering
SortFilterItemModel model(new InventoryItemModel(player));
- model.setSortByType(false);
+ model.setSort(SortFilterItemModel::Sort_None);
model.update();
if (model.getItemCount() == 0)
return;
diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp
index e8e348a8a..6c09007a6 100644
--- a/apps/openmw/mwgui/itemmodel.hpp
+++ b/apps/openmw/mwgui/itemmodel.hpp
@@ -78,6 +78,21 @@ namespace MWGui
virtual bool onDropItem(const MWWorld::Ptr &item, int count);
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
+ enum Sort
+ {
+ Sort_None,
+ Sort_Name,
+ Sort_Type,
+ Sort_Weight,
+ Sort_Value,
+ Sort_ValuePerWeight,
+ Sort_Last = Sort_ValuePerWeight,
+ };
+
+ virtual bool canSort() { return false; }
+ virtual Sort getSort() { return Sort_None; }
+ virtual void setSort(Sort sort) {}
+
private:
ItemModel(const ItemModel&);
ItemModel& operator=(const ItemModel&);
diff --git a/apps/openmw/mwgui/itemview.cpp b/apps/openmw/mwgui/itemview.cpp
index 94dcc77c5..fc4283b4a 100644
--- a/apps/openmw/mwgui/itemview.cpp
+++ b/apps/openmw/mwgui/itemview.cpp
@@ -13,6 +13,7 @@
#include "itemmodel.hpp"
#include "itemwidget.hpp"
+#include "sortfilteritemmodel.hpp"
namespace MWGui
{
@@ -20,6 +21,7 @@ namespace MWGui
ItemView::ItemView()
: mModel(nullptr)
, mScrollView(nullptr)
+ , mSortButton(nullptr)
{
}
@@ -48,6 +50,26 @@ void ItemView::initialiseOverride()
throw std::runtime_error("Item view needs a scroll view");
mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top);
+
+ {
+ static const int width = 60;
+ static const int height = 44;
+ MyGUI::IntCoord coord = MyGUI::IntCoord(
+ mScrollView->getLeft() + mScrollView->getWidth () - 5 - width,
+ mScrollView->getTop () + 5,
+ width,
+ height
+ );
+ mSortButton = createWidget<MyGUI::Button>(
+ MyGUI::WidgetStyle::Child,
+ "MW_Button",
+ coord,
+ MyGUI::Align::Top | MyGUI::Align::Right,
+ "");
+ mSortButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSort);
+ mSortButton->setNeedMouseFocus (true);
+ mSortButton->setNeedKeyFocus (false);
+ }
}
void ItemView::layoutWidgets()
@@ -130,6 +152,30 @@ void ItemView::update()
}
layoutWidgets();
+
+ mSortButton->setVisible(mModel->canSort());
+ if (mModel->canSort())
+ switch (mModel->getSort())
+ {
+ case MWGui::ItemModel::Sort_None:
+ mSortButton->setCaption("Sort\n[none]");
+ break;
+ case MWGui::ItemModel::Sort_Name:
+ mSortButton->setCaption("Sort\n[name]");
+ break;
+ case MWGui::ItemModel::Sort_Type:
+ mSortButton->setCaption("Sort\n[type]");
+ break;
+ case MWGui::ItemModel::Sort_Weight:
+ mSortButton->setCaption("Sort\n[wt]");
+ break;
+ case MWGui::ItemModel::Sort_Value:
+ mSortButton->setCaption("Sort\n[value]");
+ break;
+ case MWGui::ItemModel::Sort_ValuePerWeight:
+ mSortButton->setCaption("Sort\n[$/wt]");
+ break;
+ }
}
void ItemView::resetScrollBars()
@@ -156,6 +202,17 @@ void ItemView::onMouseWheelMoved(MyGUI::Widget *_sender, int _rel)
mScrollView->setViewOffset(MyGUI::IntPoint(static_cast<int>(mScrollView->getViewOffset().left + _rel*0.3f), 0));
}
+void ItemView::onSort(MyGUI::Widget *sender)
+{
+ if (!mModel || !mModel->canSort())
+ return;
+
+ MWGui::ItemModel::Sort sort = mModel->getSort();
+ sort = (MWGui::ItemModel::Sort)((sort + 1) % (MWGui::ItemModel::Sort_Last + 1));
+ mModel->setSort(sort);
+ update();
+}
+
void ItemView::setSize(const MyGUI::IntSize &_value)
{
bool changed = (_value.width != getWidth() || _value.height != getHeight());
diff --git a/apps/openmw/mwgui/itemview.hpp b/apps/openmw/mwgui/itemview.hpp
index fa6ef29f9..11af3001c 100644
--- a/apps/openmw/mwgui/itemview.hpp
+++ b/apps/openmw/mwgui/itemview.hpp
@@ -43,9 +43,11 @@ namespace MWGui
void onSelectedItem (MyGUI::Widget* sender);
void onSelectedBackground (MyGUI::Widget* sender);
void onMouseWheelMoved(MyGUI::Widget* _sender, int _rel);
+ void onSort(MyGUI::Widget* _sender);
ItemModel* mModel;
MyGUI::ScrollView* mScrollView;
+ MyGUI::Button* mSortButton;
};
diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp
index 23f8a121b..cb24692db 100644
--- a/apps/openmw/mwgui/sortfilteritemmodel.cpp
+++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp
@@ -48,17 +48,60 @@ namespace
return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
}
+ float stackWeight(const MWGui::ItemStack& stack)
+ {
+ return stack.mBase.getClass().getWeight(stack.mBase) * stack.mCount;
+ }
+
+ std::string stackName(const MWGui::ItemStack& stack)
+ {
+ return stack.mBase.getClass().getName(stack.mBase);
+ }
+
+ float stackValue(const MWGui::ItemStack& stack)
+ {
+ return stack.mBase.getClass().getValue(stack.mBase) * stack.mCount;
+ }
+
+ float stackValuePerWeight(const MWGui::ItemStack& stack)
+ {
+ float weight = stackWeight(stack);
+ if (weight < 1e-6f)
+ weight = 1e-6f;
+ return stackValue(stack) / weight;
+ }
+
struct Compare
{
- bool mSortByType;
- Compare() : mSortByType(true) {}
+ MWGui::SortFilterItemModel::Sort mSort;
+ Compare() : mSort(MWGui::SortFilterItemModel::Sort_Type) {}
bool operator() (const MWGui::ItemStack& left, const MWGui::ItemStack& right)
{
- if (mSortByType && left.mType != right.mType)
- return left.mType < right.mType;
-
float result = 0;
+ switch (mSort)
+ {
+ case MWGui::SortFilterItemModel::Sort_None:
+ break;
+ case MWGui::SortFilterItemModel::Sort_Name:
+ result = stackName(left).compare(stackName(right));
+ break;
+ case MWGui::SortFilterItemModel::Sort_Type:
+ result = left.mType - right.mType;
+ break;
+ case MWGui::SortFilterItemModel::Sort_Weight:
+ result = stackWeight(left) - stackWeight(right);
+ break;
+ case MWGui::SortFilterItemModel::Sort_Value:
+ result = stackValue(left) - stackValue(right);
+ break;
+ case MWGui::SortFilterItemModel::Sort_ValuePerWeight:
+ result = stackValuePerWeight(left) - stackValuePerWeight(right);
+ break;
+ }
+ if (result != 0)
+ return result < 0;
+
// compare items by type
std::string leftName = left.mBase.getTypeName();
std::string rightName = right.mBase.getTypeName();
@@ -150,7 +193,7 @@ namespace MWGui
SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel)
: mCategory(Category_All)
, mFilter(0)
- , mSortByType(true)
+ , mSort(Sort_Type)
{
mSourceModel = sourceModel;
}
@@ -303,7 +346,7 @@ namespace MWGui
}
Compare cmp;
- cmp.mSortByType = mSortByType;
+ cmp.mSort = mSort;
std::sort(mItems.begin(), mItems.end(), cmp);
}
diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp
index 98da8d8c9..c06bb63de 100644
--- a/apps/openmw/mwgui/sortfilteritemmodel.hpp
+++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp
@@ -27,7 +27,9 @@ namespace MWGui
void setFilter (int filter);
/// Use ItemStack::Type for sorting?
- void setSortByType(bool sort) { mSortByType = sort; }
+ bool canSort() { return true; }
+ Sort getSort() { return mSort; }
+ void setSort(Sort sort) { mSort = sort; }
void onClose();
bool onDropItem(const MWWorld::Ptr &item, int count);
@@ -56,7 +58,7 @@ namespace MWGui
int mCategory;
int mFilter;
- bool mSortByType;
+ Sort mSort;
};
}