]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/imagedelegate.cpp
Various UI enhancements, like keyboard list searching in cart dialog.
[virtualjaguar] / src / gui / imagedelegate.cpp
1 //
2 // imagedelegate.cpp - Qt Model/View rendering class
3 //
4 // by James L. Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -------------------------------------------------------------
11 // JLH  02/04/2010  Created this file
12 //
13
14 // This class takes care of rendering items in our custom model in the ListView
15 // class utilized in FilePicker.
16
17 #include "imagedelegate.h"
18
19 #include "filedb.h"
20 #include "filelistmodel.h"
21
22 //ImageDelegate::ImageDelegate(QObject * parent): QAbstractItemDelegate(parent)//, pixelSize(12)
23 //{
24 //}
25
26 ImageDelegate::ImageDelegate()
27 {
28         QImage cartImg(":/res/cart-blank.png");
29         QPainter painter(&cartImg);
30         painter.drawPixmap(23, 87, QPixmap(":/res/label-blank.png"));
31         painter.end();
32         cartSmall = cartImg.scaled(488/4, 395/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
33 }
34
35 /*
36 Each item is rendered by the delegate's paint() function. The view calls this function with a ready-to-use QPainter object, style information that the delegate should use to correctly draw the item, and an index to the item in the model:
37 */
38
39 void ImageDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
40 {
41         if (option.state & QStyle::State_Selected)
42                 painter->fillRect(option.rect, option.palette.highlight());
43
44 /*
45 The first task the delegate has to perform is to draw the item's background correctly. Usually, selected items appear differently to non-selected items, so we begin by testing the state passed in the style option and filling the background if necessary.
46
47 The radius of each circle is calculated in the following lines of code:
48 */
49
50 #if 0
51         int size = qMin(option.rect.width(), option.rect.height());
52         int brightness = index.model()->data(index, Qt::DisplayRole).toInt();
53         double radius = (size/2.0) - (brightness/255.0 * size/2.0);
54         if (radius == 0.0)
55                 return;
56 #endif
57
58 /*
59 First, the largest possible radius of the circle is determined by taking the smallest dimension of the style option's rect attribute. Using the model index supplied, we obtain a value for the brightness of the relevant pixel in the image. The radius of the circle is calculated by scaling the brightness to fit within the item and subtracting it from the largest possible radius.
60 */
61
62         painter->save();
63 #if 0
64         painter->setRenderHint(QPainter::Antialiasing, true);
65         painter->setPen(Qt::NoPen);
66
67 /*
68 We save the painter's state, turn on antialiasing (to obtain smoother curves), and turn off the pen.
69 */
70
71         if (option.state & QStyle::State_Selected)
72                 painter->setBrush(option.palette.highlightedText());
73         else
74                 painter->setBrush(QBrush(Qt::black));
75
76 /*
77 The foreground of the item (the circle representing a pixel) must be rendered using an appropriate brush. For unselected items, we will use a solid black brush; selected items are drawn using a predefined brush from the style option's palette.
78 */
79
80         painter->drawEllipse(QRectF(option.rect.x() + option.rect.width()/2 - radius,
81                 option.rect.y() + option.rect.height()/2 - radius, 2*radius, 2*radius));
82 #else
83 //      painter->drawPixmap(option.rect.x()+8, option.rect.y()+8, 200, 94, QPixmap(":/res/labels/rayman.jpg"));
84 //      painter->drawPixmap(option.rect.x()+13, option.rect.y()+51, 433/2, 203/2, QPixmap(":/res/labels/rayman.jpg"));
85 //      painter->drawPixmap(option.rect.x(), option.rect.y(), 488/2, 395/2, QPixmap(":/res/cart-blank.png"));
86
87
88         // This is crappy. We really should have a properly scaled image ready to go so we
89         // don't get Qt's default ugly looking fast scaling...
90
91 #warning "!!! FIX !!! Need to create properly scaled down cart/label images!"
92 //We've got the carts, now just need to do the labels...
93
94 //      unsigned long i = index.model()->data(index, Qt::DisplayRole).toUInt();
95 #if 0
96         unsigned long i = index.model()->data(index, Qt::DisplayRole).toUInt();
97         QString filename = index.model()->data(index, Qt::EditRole).toString();
98         QImage label = index.model()->data(index, Qt::DecorationRole).value<QImage>();
99 #else
100         unsigned long i = index.model()->data(index, FLM_INDEX).toUInt();
101         QString filename = index.model()->data(index, FLM_FILENAME).toString();
102         QImage label = index.model()->data(index, FLM_LABEL).value<QImage>();
103 #endif
104         QString nameToDraw;
105
106         if (i == 0xFFFFFFFF)    // Not found...
107         {
108                 int lastSlashPos = filename.lastIndexOf('/');
109                 nameToDraw = "\"" + filename.mid(lastSlashPos + 1) + "\"";
110         }
111         else
112                 nameToDraw = romList[i].name;
113 #if 0
114         if (role == Qt::DecorationRole)
115                 return list.at(index.row()).label;
116         else if (role == Qt::DisplayRole)
117                 return (uint)list.at(index.row()).dbIndex;
118         else if (role == Qt::EditRole)
119                 return list.at(index.row()).filename;
120 #endif
121
122 //      if (romList[i].file[0] == 0)
123         if (label.isNull())
124         {
125 //      painter->drawPixmap(option.rect.x()+14, option.rect.y()+50, 433/2, 203/2, QPixmap(":/res/label-blank.png"));
126 //              painter->drawPixmap(option.rect.x()+7, option.rect.y()+25, 433/4, 203/4, QPixmap(":/res/label-blank.png"));
127                 painter->drawImage(option.rect.x() + 2, option.rect.y() + 2, cartSmall);
128 //Need to query the model for the data we're supposed to draw here...
129 //      painter->drawText(17, 73, QString(romList[i].name));
130 //      painter->setPen(Qt::white);
131                 painter->setPen(QColor(255, 128, 0, 255));
132 //      painter->drawText(QRect(option.rect.x()+20, option.rect.y()+73, 196, 70), Qt::TextWordWrap | Qt::AlignHCenter, QString(romList[i].name));
133                 painter->drawText(QRect(option.rect.x()+10, option.rect.y()+36, 196/2, 70/2),
134                         Qt::TextWordWrap | Qt::AlignHCenter, nameToDraw);
135         }
136         else
137         {
138 #if 0
139                 QString filename(romList[i].file);
140                 filename.prepend("./label/");
141                 QImage img(filename);
142                 painter->drawImage(QRect(option.rect.x()+7, option.rect.y()+25, 433/4, 203/4), img);
143 #else
144                 painter->drawPixmap(option.rect.x() + 2, option.rect.y() + 2, 488/4, 395/4, QPixmap(":/res/cart-blank.png"));
145                 painter->drawImage(QRect(option.rect.x()+2+7, option.rect.y()+2+25, 433/4, 203/4), label);
146 #endif
147         }
148 //26x100
149 #endif
150         painter->restore();
151 }
152
153 /*
154 Finally, we paint the circle within the rectangle specified by the style option and we call restore() on the painter.
155
156 The paint() function does not have to be particularly complicated; it is only necessary to ensure that the state of the painter when the function returns is the same as it was when it was called. This usually means that any transformations applied to the painter must be preceded by a call to QPainter::save() and followed by a call to QPainter::restore().
157
158 The delegate's sizeHint() function returns a size for the item based on the predefined pixel size, initially set up in the constructor:
159 */
160
161 QSize ImageDelegate::sizeHint(const QStyleOptionViewItem & /* option */, const QModelIndex & /* index */) const
162 {
163         // 488x395 --> blank cart (full size)
164         // 400x188 --> label (full size) 433x203 <-- (actually, it's this)
165
166         // 200x94 is shrunk dimension...
167 //      return QSize(100, 47);
168 //      return QSize(216, 110);
169 //      return QSize(488/2, 395/2);
170         return QSize((488/4) + 4, (395/4) + 4);
171 }
172
173 /*
174 The delegate's size is updated whenever the pixel size is changed. We provide a custom slot to do this:
175 */
176
177 //void ImageDelegate::setPixelSize(int size)
178 //{
179 //      pixelSize = size;
180 //}