picking up branches/tmp/sh/qt4-port/, merging it with trunk
[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::drawContents( QPainter * painter )
63 {
64     unsigned nextDefaultColor = 0;
65     int totalWidth      = contentsRect().width()  - 2*YQBarGraphOuterMargin;
66     int segHeight       = contentsRect().height() - 2*YQBarGraphOuterMargin;
67     int x_off           = YQBarGraphOuterMargin;
68     int y_off           = YQBarGraphOuterMargin;
69     int valueTotal      = 0;
70
71     for ( int i=0; i < segments(); i++ )
72         valueTotal += segment(i).value();
73
74     if ( valueTotal == 0 ) // Avoid division by zero
75         return;
76
77     for ( int i=0; i < segments(); i++ )
78     {
79         const YBarGraphSegment & seg = segment(i);
80         int segWidth = ( (long) totalWidth * seg.value() ) / valueTotal;
81
82         if ( i == segments()-1 )
83         {
84             // Compensate for rounding errors:
85             // The last segment gets all leftover pixels from the previous ones.
86
87             segWidth = totalWidth - x_off + YQBarGraphOuterMargin;
88         }
89
90
91         //
92         // Fill the segment
93         //
94
95         YColor segmentColor = seg.segmentColor();
96         YColor textColor    = seg.textColor();
97
98         if ( segmentColor.isUndefined() || textColor.isUndefined() )
99         {
100             // If any of the colors is undefined, use the next default color
101             // for both so some contrast is ensured.
102
103             segmentColor = defaultSegmentColor( nextDefaultColor   );
104             textColor    = defaultTextColor   ( nextDefaultColor++ );
105         }
106
107         painter->setBrush( QColor( segmentColor.red(),
108                                    segmentColor.green(),
109                                    segmentColor.blue() ) );
110         painter->setPen( Qt::NoPen );
111         painter->drawRect( x_off, y_off, segWidth+2, segHeight+2 );
112
113
114         //
115         // Draw the label
116         //
117
118         painter->setPen( Qt::SolidLine );
119         painter->setPen( QColor( textColor.red(),
120                                  textColor.green(),
121                                  textColor.blue() ) );
122
123         QString txt = QString::fromStdString( seg.label() );
124
125         if ( txt.contains( "%1" ) )
126             txt = txt.arg( seg.value() );               // substitute variable
127
128         painter->drawText( x_off + YQBarGraphLabelHorizontalMargin,
129                            y_off + YQBarGraphLabelVerticalMargin,
130                            segWidth  - 2 * YQBarGraphLabelHorizontalMargin + 1,
131                            segHeight - 2 * YQBarGraphLabelVerticalMargin   + 1,
132                            Qt::AlignCenter, txt );
133
134         // Prepare for the next segment
135
136         x_off += segWidth;
137     }
138 }
139
140
141 YColor
142 YQBarGraph::defaultSegmentColor( unsigned index )
143 {
144     switch( index % 8 )
145     {
146         case 0: return YColor(   0,   0, 128 ); // dark blue
147         case 1: return YColor(  64, 200, 255 ); // medium blue
148         case 2: return YColor( 255, 255, 255 ); // white
149         case 3: return YColor(   0, 153, 153 ); // cadet blue
150         case 4: return YColor( 150, 255, 255 ); // cyan
151         case 5: return YColor( 100, 100, 100 ); // medium grey
152         case 6: return YColor(   0, 200, 100 ); // medium green
153         case 7: return YColor(   0, 100,  76 ); // dark green
154     }
155
156     return YColor( 255, 255, 255 ); // just to make gcc happy
157 }
158
159
160 YColor
161 YQBarGraph::defaultTextColor( unsigned index )
162 {
163     YColor black = YColor(   0,   0,   0 );
164     YColor white = YColor( 255, 255, 255 );
165
166     switch( index % 8 )
167     {
168         case 0: return white;
169         case 1: return black;
170         case 2: return black;
171         case 3: return black;
172         case 4: return black;
173         case 5: return white;
174         case 6: return black;
175         case 7: return white;
176     }
177
178     return black; // just to make gcc happy
179 }
180
181
182 void
183 YQBarGraph::setEnabled( bool enabled )
184 {
185     QFrame::setEnabled( enabled );
186     YWidget::setEnabled( enabled );
187 }
188
189
190 int
191 YQBarGraph::preferredWidth()
192 {
193     int width  = 0;
194     QFontMetrics metrics = fontMetrics();
195
196     for ( int i=0; i < segments(); i++ )
197     {
198         QString txt = QString::fromStdString( segment(i).label() );
199
200         if ( txt.contains( "%1" ) )
201             txt = txt.arg( segment(i).value() );
202
203         QSize segSize = metrics.size( 0, txt );
204         width += segSize.width();
205     }
206
207     width += 2 * YQBarGraphLabelHorizontalMargin;
208     width += frameWidth();
209     width += 2 * YQBarGraphOuterMargin;
210     width  = max( width, YQBarGraphMinWidth );
211
212     return width;
213 }
214
215
216 int
217 YQBarGraph::preferredHeight()
218 {
219     int height = YQBarGraphMinHeight;
220     QFontMetrics metrics = fontMetrics();
221
222     for ( int i=0; i < segments(); i++ )
223     {
224         QString txt = QString::fromStdString( segment(i).label() );
225
226         if ( txt.contains( "%1" ) )
227             txt = txt.arg( segment(i).value() );
228
229         QSize segSize = metrics.size( 0, txt );
230         height = max( height, segSize.height() );
231     }
232
233     height += 2 * YQBarGraphLabelVerticalMargin;
234     height += frameWidth();
235     height += 2 * YQBarGraphOuterMargin;
236     height  = max( height, YQBarGraphMinHeight );
237
238     return height;
239 }
240
241
242 void
243 YQBarGraph::setSize( int newWidth, int newHeight )
244 {
245     resize( newWidth, newHeight );
246 }
247
248
249
250 #include "YQBarGraph.moc"