]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/YQBarGraph.cc
Duncan, for you
[duncan/yast2-qt4.git] / src / YQBarGraph.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQBarGraph.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #define y2log_component "qt-ui"
21 #include <ycp/y2log.h>
22
23 #include <algorithm>
24 #include <qpainter.h>
25 #include <qnamespace.h>
26
27 #include "utf8.h"
28 #include "YQUI.h"
29 #include "YQBarGraph.h"
30
31
32 #define YQBarGraphOuterMargin           YQWidgetMargin
33 #define YQBarGraphLabelHorizontalMargin 1
34 #define YQBarGraphLabelVerticalMargin   2
35 #define YQBarGraphMinWidth              80
36 #define YQBarGraphMinHeight             30
37
38
39
40 YQBarGraph::YQBarGraph( YWidget * parent )
41     : QFrame( (QWidget *) parent->widgetRep() )
42     , YBarGraph( parent )
43 {
44     setWidgetRep( this );
45 }
46
47
48 YQBarGraph::~YQBarGraph()
49 {
50     // NOP
51 }
52
53
54 void
55 YQBarGraph::doUpdate()
56 {
57     QFrame::update(); // triggers drawContents()
58 }
59
60
61 void
62 YQBarGraph::paintEvent( QPaintEvent* paintEvent )
63 {
64     QFrame::paintEvent( paintEvent );
65
66     QPainter painter( this );
67
68     unsigned nextDefaultColor = 0;
69     int totalWidth      = contentsRect().width()  - 2*YQBarGraphOuterMargin;
70     int segHeight       = contentsRect().height() - 2*YQBarGraphOuterMargin;
71     int x_off           = YQBarGraphOuterMargin;
72     int y_off           = YQBarGraphOuterMargin;
73     int valueTotal      = 0;
74
75     for ( int i=0; i < segments(); i++ )
76         valueTotal += segment(i).value();
77
78     if ( valueTotal == 0 ) // Avoid division by zero
79         return;
80
81     for ( int i=0; i < segments(); i++ )
82     {
83         const YBarGraphSegment & seg = segment(i);
84         int segWidth = ( (long) totalWidth * seg.value() ) / valueTotal;
85
86         if ( i == segments()-1 )
87         {
88             // Compensate for rounding errors:
89             // The last segment gets all leftover pixels from the previous ones.
90
91             segWidth = totalWidth - x_off + YQBarGraphOuterMargin;
92         }
93
94
95         //
96         // Fill the segment
97         //
98
99         YColor segmentColor = seg.segmentColor();
100         YColor textColor    = seg.textColor();
101
102         if ( segmentColor.isUndefined() || textColor.isUndefined() )
103         {
104             // If any of the colors is undefined, use the next default color
105             // for both so some contrast is ensured.
106
107             segmentColor = defaultSegmentColor( nextDefaultColor   );
108             textColor    = defaultTextColor   ( nextDefaultColor++ );
109         }
110
111         painter.setBrush( QColor( segmentColor.red(),
112                                    segmentColor.green(),
113                                    segmentColor.blue() ) );
114         painter.setPen( Qt::NoPen );
115         painter.drawRect( x_off, y_off, segWidth+2, segHeight+2 );
116
117
118         //
119         // Draw the label
120         //
121
122         painter.setPen( Qt::SolidLine );
123         painter.setPen( QColor( textColor.red(),
124                                  textColor.green(),
125                                  textColor.blue() ) );
126
127         QString txt = QString::fromStdString( seg.label() );
128
129         if ( txt.contains( "%1" ) )
130             txt = txt.arg( seg.value() );               // substitute variable
131
132         painter.drawText( x_off + YQBarGraphLabelHorizontalMargin,
133                            y_off + YQBarGraphLabelVerticalMargin,
134                            segWidth  - 2 * YQBarGraphLabelHorizontalMargin + 1,
135                            segHeight - 2 * YQBarGraphLabelVerticalMargin   + 1,
136                            Qt::AlignCenter, txt );
137
138         // Prepare for the next segment
139
140         x_off += segWidth;
141     }
142 }
143
144
145 YColor
146 YQBarGraph::defaultSegmentColor( unsigned index )
147 {
148     switch( index % 8 )
149     {
150         case 0: return YColor(   0,   0, 128 ); // dark blue
151         case 1: return YColor(  64, 200, 255 ); // medium blue
152         case 2: return YColor( 255, 255, 255 ); // white
153         case 3: return YColor(   0, 153, 153 ); // cadet blue
154         case 4: return YColor( 150, 255, 255 ); // cyan
155         case 5: return YColor( 100, 100, 100 ); // medium grey
156         case 6: return YColor(   0, 200, 100 ); // medium green
157         case 7: return YColor(   0, 100,  76 ); // dark green
158     }
159
160     return YColor( 255, 255, 255 ); // just to make gcc happy
161 }
162
163
164 YColor
165 YQBarGraph::defaultTextColor( unsigned index )
166 {
167     YColor black = YColor(   0,   0,   0 );
168     YColor white = YColor( 255, 255, 255 );
169
170     switch( index % 8 )
171     {
172         case 0: return white;
173         case 1: return black;
174         case 2: return black;
175         case 3: return black;
176         case 4: return black;
177         case 5: return white;
178         case 6: return black;
179         case 7: return white;
180     }
181
182     return black; // just to make gcc happy
183 }
184
185
186 void
187 YQBarGraph::setEnabled( bool enabled )
188 {
189     QFrame::setEnabled( enabled );
190     YWidget::setEnabled( enabled );
191 }
192
193
194 int
195 YQBarGraph::preferredWidth()
196 {
197     int width  = 0;
198     QFontMetrics metrics = fontMetrics();
199
200     for ( int i=0; i < segments(); i++ )
201     {
202         QString txt = QString::fromStdString( segment(i).label() );
203
204         if ( txt.contains( "%1" ) )
205             txt = txt.arg( segment(i).value() );
206
207         QSize segSize = metrics.size( 0, txt );
208         width += segSize.width();
209     }
210
211     width += 2 * YQBarGraphLabelHorizontalMargin;
212     width += frameWidth();
213     width += 2 * YQBarGraphOuterMargin;
214     width  = max( width, YQBarGraphMinWidth );
215
216     return width;
217 }
218
219
220 int
221 YQBarGraph::preferredHeight()
222 {
223     int height = YQBarGraphMinHeight;
224     QFontMetrics metrics = fontMetrics();
225
226     for ( int i=0; i < segments(); i++ )
227     {
228         QString txt = QString::fromStdString( segment(i).label() );
229
230         if ( txt.contains( "%1" ) )
231             txt = txt.arg( segment(i).value() );
232
233         QSize segSize = metrics.size( 0, txt );
234         height = max( height, segSize.height() );
235     }
236
237     height += 2 * YQBarGraphLabelVerticalMargin;
238     height += frameWidth();
239     height += 2 * YQBarGraphOuterMargin;
240     height  = max( height, YQBarGraphMinHeight );
241
242     return height;
243 }
244
245
246 void
247 YQBarGraph::setSize( int newWidth, int newHeight )
248 {
249     resize( newWidth, newHeight );
250 }
251
252
253
254 #include "YQBarGraph.moc"