new style for the progressbars, display more info
[case] / src / style.cpp
1 // case - file manager for N900
2 // Copyright (C) 2010 Lukas Hrazky <lukkash@email.cz>
3 // 
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 // 
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 // 
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18 #include "style.h"
19
20 #include <QPainter>
21
22 #include "progressbar.h"
23
24 #include <iostream>
25
26
27 void Style::drawControl(ControlElement element,
28     const QStyleOption *opt,
29     QPainter *p,
30     const QWidget *widget) const
31 {
32     switch (element) {
33     case CE_ProgressBarGroove:
34         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
35             p->setPen(opt->palette.color(QPalette::ButtonText).darker());
36             p->drawRoundedRect(pb->rect.adjusted(0, 0, -1, -1), 4, 4);
37         }
38         break;
39
40     case CE_ProgressBarLabel:
41         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
42             QRect rect = pb->rect;
43             int maximum = pb->maximum;
44             int minimum = pb->minimum;
45             int value = pb->progress;
46
47             const ProgressBar *w = qobject_cast<const ProgressBar*>(widget);
48
49             float perc = (maximum - minimum) ?  static_cast<float>(value - minimum) / (maximum - minimum) : 0;
50
51             rect.adjust(2, 2, -2, -2);
52             QRect filledRect = rect, emptyRect = rect;
53             filledRect.setWidth(filledRect.width() * perc);
54             emptyRect.setX(emptyRect.x() + filledRect.width());
55
56             rect.adjust(3, 0, -3, 0);
57             QPoint iconPoint;
58             QRect topRect = rect, mainTextRect, bottomLeftRect = rect, bottomRightRect;
59             topRect.setHeight(topRect.height() / 2);
60             bottomLeftRect.setY(bottomLeftRect.y() + topRect.height());
61
62             int topRightWidth = p->fontMetrics().size(Qt::TextSingleLine, pb->text).width();
63             QRect pauseRect1(topRect.x() + topRect.width() - topRightWidth,
64                 topRect.y() + topRect.height() / 2, 0, 0), pauseRect2;
65
66             if (w->paused) {
67                 pauseRect1.adjust(-24, -7, -19, 7);
68                 pauseRect2 = pauseRect1;
69                 pauseRect2.adjust(10, 0, 10, 0);
70             }
71
72             if (w->fromText.size() || w->toText.size()) {
73                 iconPoint = bottomLeftRect.center() - QPoint(10, 10);
74
75                 mainTextRect = topRect;
76                 mainTextRect.setRight(pauseRect1.x() - 10);
77
78                 bottomRightRect = bottomLeftRect;
79                 bottomLeftRect.setWidth(bottomLeftRect.width() / 2 - 13);
80                 bottomRightRect.setX(bottomRightRect.x() + bottomLeftRect.width() + 26);
81             } else {
82                 iconPoint = topRect.center() - QPoint(10, 8);
83
84                 mainTextRect = bottomLeftRect;
85             }
86
87             QString mainText = shortenTextPath(p, mainTextRect, w->mainText);
88             QString bottomLeftText = shortenTextPath(p, bottomLeftRect, w->fromText);
89             QString bottomRightText = shortenTextPath(p, bottomRightRect, w->toText);
90
91             if (filledRect.width()) {
92                 p->setClipRect(filledRect);
93                 p->setPen(opt->palette.text().color());
94                 p->setBrush(opt->palette.text());
95
96                 p->drawPixmap(iconPoint, w->fgIcon);
97
98                 p->drawText(mainTextRect, Qt::AlignCenter | Qt::TextSingleLine, mainText);
99                 p->drawText(topRect, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, pb->text);
100                 p->drawText(bottomLeftRect, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, bottomLeftText);
101                 p->drawText(bottomRightRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, bottomRightText);
102
103                 if (w->paused) {
104                     p->drawRect(pauseRect1);
105                     p->drawRect(pauseRect2);
106                 }
107             }
108
109             if (emptyRect.width()) {
110                 p->setClipRect(emptyRect);
111                 p->setPen(opt->palette.buttonText().color());
112                 p->setBrush(opt->palette.buttonText());
113
114                 p->drawPixmap(iconPoint, w->bgIcon);
115
116                 p->drawText(mainTextRect, Qt::AlignCenter | Qt::TextSingleLine, mainText);
117                 p->drawText(topRect, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, pb->text);
118                 p->drawText(bottomLeftRect, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, bottomLeftText);
119                 p->drawText(bottomRightRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, bottomRightText);
120
121                 if (w->paused) {
122                     p->drawRect(pauseRect1);
123                     p->drawRect(pauseRect2);
124                 }
125             }
126         }
127         break;
128
129     case CE_ProgressBarContents:
130         if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
131             QRect rect = pb->rect;
132             int maximum = pb->maximum;
133             int minimum = pb->minimum;
134             int value = pb->progress;
135
136             QPalette pal = pb->palette;
137             // Correct the highlight color if it is the same as the background
138             if (pal.highlight() == pal.background())
139                 pal.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
140                                                                      QPalette::Highlight));
141
142             float perc = (maximum - minimum) ?  static_cast<float>(value - minimum) / (maximum - minimum) : 0;
143
144             QRect filledRect = rect;
145             filledRect.adjust(2, 2, -2, -2);
146             filledRect.setWidth(filledRect.width() * perc);
147
148             QColor highlight = opt->palette.highlight().color();
149             QColor lighter = highlight.lighter(120);
150             QColor darker = highlight.darker(110);
151
152             QGradientStops stops;
153             stops << QGradientStop(0.00, lighter);
154             stops << QGradientStop(0.15, darker);
155             stops << QGradientStop(0.80, darker);
156             stops << QGradientStop(1.00, lighter);
157             QLinearGradient fillGrad(0, 0, 0, filledRect.height());
158             fillGrad.setStops(stops);
159             QBrush fillBrush(fillGrad);
160
161             p->setPen(lighter);
162             p->setBrush(fillBrush);
163             p->drawRoundedRect(filledRect.adjusted(0, 0, -1, -1), 2, 2);
164         }
165         break;
166         
167     default:
168         QMaemo5Style::drawControl(element, opt, p, widget);
169     }
170 }
171
172
173 QString Style::shortenTextPath(QPainter *p, const QRect &r, QString s) const {
174     QFontMetrics m = p->fontMetrics();
175     int width = r.width();
176     int start = -2, end = 1;
177
178     while (m.size(Qt::TextSingleLine, s).width() > width && s.size() > 7) {
179         if (end <= 0) {
180             start = end + 7;
181         } else {
182             // first pass only
183             if (start == -2) {
184                 start = s.lastIndexOf('/', -2);
185                 if (start <= 0) start += 4;
186                 end = s.lastIndexOf('/', start - 1);
187             } else {
188                 start = end + 4;
189                 end = s.lastIndexOf('/', end - 1);
190             }
191         }
192
193         s.replace(end + 1, start - end - 1, "...");
194     }
195
196     return s;
197 }