Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216#include "datadisplaydelegate.hpp"
#include "../../model/prefs/state.hpp"
#include <QApplication>#include <QIcon>#include <QPainter>#include <QRect>#include <QSize>#include <QString>#include <QStyle>
#include <memory>
#include <apps/opencs/model/prefs/category.hpp>#include <apps/opencs/model/prefs/setting.hpp>#include <apps/opencs/view/world/enumdelegate.hpp>#include <apps/opencs/view/world/util.hpp>
#include <components/misc/scalableicon.hpp>
class QModelIndex;class QObject;
namespace CSMDoc{ class Document;}
namespace CSMWorld{ class CommandDispatcher;}
CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList& values, const IconList& icons, CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, const std::string& pageName, const std::string& settingName, QObject* parent) : EnumDelegate(values, dispatcher, document, parent) , mDisplayMode(Mode_TextOnly) , mIcons(icons) , mIconSize(QSize(16, 16)) , mHorizontalMargin(QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) , mTextLeftOffset(8) , mPixmapsColor(QApplication::palette().text().color()) , mUiScale(static_cast<QGuiApplication*>(QGuiApplication::instance())->devicePixelRatio()) , mSettingKey(pageName + '/' + settingName){ if (parent) parent->installEventFilter(this);
buildPixmaps();
if (!pageName.empty()) updateDisplayMode(CSMPrefs::get()[pageName][settingName].toString());}
bool CSVWorld::DataDisplayDelegate::eventFilter(QObject* target, QEvent* event){ if (event->type() == QEvent::Resize) { auto uiScale = static_cast<QGuiApplication*>(QGuiApplication::instance())->devicePixelRatio(); if (mUiScale != uiScale) { mUiScale = uiScale;
buildPixmaps(); } } else if (event->type() == QEvent::PaletteChange) { QColor themeColor = QApplication::palette().text().color(); if (themeColor != mPixmapsColor) { mPixmapsColor = std::move(themeColor);
buildPixmaps(); } }
return false;}
void CSVWorld::DataDisplayDelegate::buildPixmaps(){ if (!mPixmaps.empty()) mPixmaps.clear();
IconList::iterator it = mIcons.begin();
while (it != mIcons.end()) { mPixmaps.emplace_back(it->mValue, it->mIcon.pixmap(mIconSize)); ++it; }}
void CSVWorld::DataDisplayDelegate::setIconSize(const QSize& size){ mIconSize = size; buildPixmaps();}
void CSVWorld::DataDisplayDelegate::setTextLeftOffset(int offset){ mTextLeftOffset = offset;}
QSize CSVWorld::DataDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const{ QSize size = EnumDelegate::sizeHint(option, index);
int valueIndex = getValueIndex(index); if (valueIndex != -1) { if (mDisplayMode == Mode_IconOnly) { size.setWidth(mIconSize.width() + 2 * mHorizontalMargin); } else if (mDisplayMode == Mode_IconAndText) { size.setWidth(size.width() + mIconSize.width() + mTextLeftOffset); }
if (mDisplayMode != Mode_TextOnly) { size.setHeight(qMax(size.height(), mIconSize.height())); } } return size;}
void CSVWorld::DataDisplayDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const{ painter->save();
// default to enum delegate's paint method for text-only conditions if (mDisplayMode == Mode_TextOnly) EnumDelegate::paint(painter, option, index); else { int valueIndex = getValueIndex(index); if (valueIndex != -1) { paintIcon(painter, option, valueIndex); } }
painter->restore();}
void CSVWorld::DataDisplayDelegate::paintIcon(QPainter* painter, const QStyleOptionViewItem& option, int index) const{ QRect iconRect = option.rect; QRect textRect = iconRect;
iconRect.setLeft(iconRect.left() + mHorizontalMargin); iconRect.setRight(option.rect.right() - mHorizontalMargin); if (mDisplayMode == Mode_IconAndText) { iconRect.setWidth(mIconSize.width()); textRect.setLeft(iconRect.right() + mTextLeftOffset); textRect.setRight(option.rect.right() - mHorizontalMargin);
QString text = option.fontMetrics.elidedText(mValues.at(index).second, option.textElideMode, textRect.width()); QApplication::style()->drawItemText( painter, textRect, Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text); } QApplication::style()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, mPixmaps.at(index).second);}
void CSVWorld::DataDisplayDelegate::updateDisplayMode(const std::string& mode){ if (mode == "Icon and Text") mDisplayMode = Mode_IconAndText;
else if (mode == "Icon Only") mDisplayMode = Mode_IconOnly;
else if (mode == "Text Only") mDisplayMode = Mode_TextOnly;}
void CSVWorld::DataDisplayDelegate::settingChanged(const CSMPrefs::Setting* setting){ if (*setting == mSettingKey) updateDisplayMode(setting->toString());}
void CSVWorld::DataDisplayDelegateFactory::add(int enumValue, const QString& enumName, const QString& iconFilename){ EnumDelegateFactory::add(enumValue, enumName);
Icon icon; icon.mValue = enumValue; icon.mName = enumName; icon.mIcon = Misc::ScalableIcon::load(iconFilename);
for (auto it = mIcons.begin(); it != mIcons.end(); ++it) { if (it->mName > enumName) { mIcons.insert(it, icon); return; } }
mIcons.push_back(icon);}
CSVWorld::CommandDelegate* CSVWorld::DataDisplayDelegateFactory::makeDelegate( CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const{ return new DataDisplayDelegate(mValues, mIcons, dispatcher, document, "", "", parent);}