1 #include "datadisplaydelegate.hpp"
2 
3 #include "../../model/prefs/state.hpp"
4 
5 #include <QApplication>
6 #include <QPainter>
7 
DataDisplayDelegate(const ValueList & values,const IconList & icons,CSMWorld::CommandDispatcher * dispatcher,CSMDoc::Document & document,const std::string & pageName,const std::string & settingName,QObject * parent)8 CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values,
9                                                    const IconList &icons,
10                                                    CSMWorld::CommandDispatcher *dispatcher,
11                                                    CSMDoc::Document& document,
12                                                    const std::string &pageName,
13                                                    const std::string &settingName,
14                                                    QObject *parent)
15     : EnumDelegate (values, dispatcher, document, parent), mDisplayMode (Mode_TextOnly),
16       mIcons (icons), mIconSize (QSize(16, 16)),
17       mHorizontalMargin(QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1),
18       mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName)
19 {
20     buildPixmaps();
21 
22     if (!pageName.empty())
23         updateDisplayMode (CSMPrefs::get()[pageName][settingName].toString());
24 }
25 
buildPixmaps()26 void CSVWorld::DataDisplayDelegate::buildPixmaps ()
27 {
28     if (!mPixmaps.empty())
29         mPixmaps.clear();
30 
31     IconList::iterator it = mIcons.begin();
32 
33     while (it != mIcons.end())
34     {
35         mPixmaps.emplace_back (it->mValue, it->mIcon.pixmap (mIconSize) );
36         ++it;
37     }
38 }
39 
setIconSize(const QSize & size)40 void CSVWorld::DataDisplayDelegate::setIconSize(const QSize& size)
41 {
42     mIconSize = size;
43     buildPixmaps();
44 }
45 
setTextLeftOffset(int offset)46 void CSVWorld::DataDisplayDelegate::setTextLeftOffset(int offset)
47 {
48     mTextLeftOffset = offset;
49 }
50 
sizeHint(const QStyleOptionViewItem & option,const QModelIndex & index) const51 QSize CSVWorld::DataDisplayDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
52 {
53     QSize size = EnumDelegate::sizeHint(option, index);
54 
55     int valueIndex = getValueIndex(index);
56     if (valueIndex != -1)
57     {
58         if (mDisplayMode == Mode_IconOnly)
59         {
60             size.setWidth(mIconSize.width() + 2 * mHorizontalMargin);
61         }
62         else if (mDisplayMode == Mode_IconAndText)
63         {
64             size.setWidth(size.width() + mIconSize.width() + mTextLeftOffset);
65         }
66 
67         if (mDisplayMode != Mode_TextOnly)
68         {
69             size.setHeight(qMax(size.height(), mIconSize.height()));
70         }
71     }
72     return size;
73 }
74 
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const75 void CSVWorld::DataDisplayDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
76 {
77     painter->save();
78 
79     //default to enum delegate's paint method for text-only conditions
80     if (mDisplayMode == Mode_TextOnly)
81         EnumDelegate::paint(painter, option, index);
82     else
83     {
84         int valueIndex = getValueIndex(index);
85         if (valueIndex != -1)
86         {
87             paintIcon(painter, option, valueIndex);
88         }
89     }
90 
91     painter->restore();
92 }
93 
paintIcon(QPainter * painter,const QStyleOptionViewItem & option,int index) const94 void CSVWorld::DataDisplayDelegate::paintIcon (QPainter *painter, const QStyleOptionViewItem &option, int index) const
95 {
96     QRect iconRect = option.rect;
97     QRect textRect = iconRect;
98 
99     iconRect.setLeft(iconRect.left() + mHorizontalMargin);
100     iconRect.setRight(option.rect.right() - mHorizontalMargin);
101     if (mDisplayMode == Mode_IconAndText)
102     {
103         iconRect.setWidth(mIconSize.width());
104         textRect.setLeft(iconRect.right() + mTextLeftOffset);
105         textRect.setRight(option.rect.right() - mHorizontalMargin);
106 
107         QString text = option.fontMetrics.elidedText(mValues.at(index).second,
108                                                      option.textElideMode,
109                                                      textRect.width());
110         QApplication::style()->drawItemText(painter,
111                                             textRect,
112                                             Qt::AlignLeft | Qt::AlignVCenter,
113                                             option.palette,
114                                             true,
115                                             text);
116     }
117     QApplication::style()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, mPixmaps.at(index).second);
118 }
119 
updateDisplayMode(const std::string & mode)120 void CSVWorld::DataDisplayDelegate::updateDisplayMode (const std::string &mode)
121 {
122     if (mode == "Icon and Text")
123         mDisplayMode = Mode_IconAndText;
124 
125     else if (mode == "Icon Only")
126         mDisplayMode = Mode_IconOnly;
127 
128     else if (mode == "Text Only")
129         mDisplayMode = Mode_TextOnly;
130 }
131 
~DataDisplayDelegate()132 CSVWorld::DataDisplayDelegate::~DataDisplayDelegate()
133 {
134 }
135 
settingChanged(const CSMPrefs::Setting * setting)136 void CSVWorld::DataDisplayDelegate::settingChanged (const CSMPrefs::Setting *setting)
137 {
138     if (*setting==mSettingKey)
139         updateDisplayMode (setting->toString());
140 }
141 
142 
add(int enumValue,const QString & enumName,const QString & iconFilename)143 void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, const QString& enumName, const QString& iconFilename)
144 {
145     EnumDelegateFactory::add(enumValue, enumName);
146 
147     Icon icon;
148     icon.mValue = enumValue;
149     icon.mName = enumName;
150     icon.mIcon = QIcon(iconFilename);
151 
152     for (auto it=mIcons.begin(); it!=mIcons.end(); ++it)
153     {
154         if (it->mName > enumName)
155         {
156             mIcons.insert(it, icon);
157             return;
158         }
159     }
160 
161     mIcons.push_back(icon);
162 }
163 
makeDelegate(CSMWorld::CommandDispatcher * dispatcher,CSMDoc::Document & document,QObject * parent) const164 CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate (
165     CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const
166 {
167     return new DataDisplayDelegate (mValues, mIcons, dispatcher, document, "", "", parent);
168 }
169