[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [parley/KDE/4.14] src: Part IIa of fixing the color issue: Make *one* function to draw the color bar
From:       Inge Wallin <inge () lysator ! liu ! se>
Date:       2015-02-05 0:07:52
Message-ID: E1YJ9z6-0002a5-Kh () scm ! kde ! org
[Download RAW message or body]

Git commit b9a2bfee36d6391e3017649e5117fc45a0503ad7 by Inge Wallin.
Committed on 04/02/2015 at 22:42.
Pushed by ingwa into branch 'KDE/4.14'.

Part IIa of fixing the color issue: Make *one* function to draw the color bars

This is now also used in the lesson statistics.

The next step, IIb, will be the last one.

M  +15   -11   src/statistics/lessonstatisticsview.cpp
M  +5    -3    src/statistics/statisticsmodel.cpp
M  +4    -1    src/statistics/statisticsmodel.h
M  +124  -10   src/utils.cpp
M  +13   -1    src/utils.h

http://commits.kde.org/parley/b9a2bfee36d6391e3017649e5117fc45a0503ad7

diff --git a/src/statistics/lessonstatisticsview.cpp \
b/src/statistics/lessonstatisticsview.cpp index 70abdaa..44094e9 100644
--- a/src/statistics/lessonstatisticsview.cpp
+++ b/src/statistics/lessonstatisticsview.cpp
@@ -33,9 +33,12 @@
 #include "statisticslegendwidget.h"
 #include "statisticsmodel.h"
 #include "keduvoclesson.h"
-#include "prefs.h"
+#include "utils.h"
 
 
+// GradeDelegate shows the graphic colored bar in the statistics,
+// showing how far the student has come on the way to enlightenment.
+
 class GradeDelegate: public QItemDelegate
 {
 public:
@@ -48,22 +51,23 @@ public:
     {
         QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, \
painter, 0);  
-        // empty lesson
+        // empty lesson? If so, paint nothing.
         if (!index.data(StatisticsModel::TotalCount).toInt()) {
             return;
         }
-        drawBackground(painter, option, index);
+
+        // Draw the colored bar.
+        KEduVocContainer *container = \
index.data(StatisticsModel::Container).value<KEduVocContainer*>(); +        WordCount \
wordCount; +        wordCount.fillFromContainer(*container, index.column() - \
ContainerModel::FirstDataColumn); +        ConfidenceColors  \
colors(ConfidenceColors::ProgressiveColorScheme); +
+        paintColorBar(*painter, option.rect, wordCount, colors); // in utils
+
+        // Draw the text telling the percentage on top of the bar.
         painter->drawText(option.rect, Qt::AlignCenter,
 			  QString("%1%").arg(index.data(StatisticsModel::TotalPercent).toInt()));
     }
-
-protected:
-    void drawBackground(QPainter *painter, const QStyleOptionViewItem &option,
-			const QModelIndex &index) const
-    {
-        QList<QVariant> fractions = \
                index.data(StatisticsModel::LegendFractions).toList();
-        StatisticsLegendWidget::paintStatisticsBar(*painter, option.rect, \
                fractions);
-    }
 };
 
 
diff --git a/src/statistics/statisticsmodel.cpp b/src/statistics/statisticsmodel.cpp
index 6e67ba9..2fc8db1 100644
--- a/src/statistics/statisticsmodel.cpp
+++ b/src/statistics/statisticsmodel.cpp
@@ -42,10 +42,12 @@ QVariant StatisticsModel::data(const QModelIndex & index, int \
role) const  {
     if (index.column() >= FirstDataColumn) {
         KEduVocContainer *container = \
static_cast<KEduVocContainer*>(index.internalPointer()); +        QVariant var;
         switch (role) {
-        case LegendFractions:
-	    // Calculate the percent each grade and pregrade occupies.
-            return StatisticsLegendWidget::legendFractions(*container \
,index.column() - FirstDataColumn); +        case Container:
+	    // Return a pointer to the container we are working on.
+            var.setValue(container);
+            return var;
         case TotalPercent: // Average grade
             return container->averageGrade(index.column() - FirstDataColumn, \
KEduVocContainer::Recursive);  case TotalCount:
diff --git a/src/statistics/statisticsmodel.h b/src/statistics/statisticsmodel.h
index 5304c02..1e0511e 100644
--- a/src/statistics/statisticsmodel.h
+++ b/src/statistics/statisticsmodel.h
@@ -35,7 +35,7 @@ public:
         Grade5,
         Grade6,
         Grade7,
-        LegendFractions
+        Container
     };
 
     explicit StatisticsModel(QObject *parent = 0);
@@ -50,5 +50,8 @@ protected:
     KEduVocContainer * rootContainer() const;
 };
 
+// For index.data()
+Q_DECLARE_METATYPE(KEduVocContainer*)
+
 
 #endif
diff --git a/src/utils.cpp b/src/utils.cpp
index 13b0b33..2d24471 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -16,12 +16,15 @@
 #include "utils.h"
 
 // Qt
-//#include <QPaintEvent>
-//#include <QWidget>
+#include <QPainter>
+#include <QRect>
 
 // KEduVocDocument library
 #include <keduvocdocument.h>
+#include <keduvocexpression.h>
 
+// Parley
+#include "prefs.h"
 
 // ----------------------------------------------------------------
 //                         class WordCount
@@ -69,6 +72,29 @@ int WordCount::percentageCompleted() const
 }
 
 
+void WordCount::fillFromContainer(KEduVocContainer &container, int translationIndex,
+                                  KEduVocContainer::EnumEntriesRecursive recursive)
+{
+    clear();
+
+    foreach (KEduVocExpression *entry, container.entries(recursive)) {
+        KEduVocTranslation &translation(*entry->translation(translationIndex));
+
+        ++totalWords;
+        if (translation.isEmpty()) {
+            ++invalid;
+        } else if (translation.preGrade() > 0) {
+            // Initial phase (we assume correctness, i.e. if pregrade>0 then grade = \
0) +            ++initialWords;
+            ++pregrades[translation.preGrade()];
+        } else {
+            // Long term or unpracticed
+            ++grades[translation.grade()];
+        }
+    }
+}
+
+
 // ----------------------------------------------------------------
 //                         class confidenceColors
 
@@ -86,8 +112,8 @@ void ConfidenceColors::initColors(ColorScheme colorScheme)
     default: // Not default at the last line.  Hope this works...
 
         longTermColors[0] = QColor(25,38,41);
-        longTermColors[1] = QColor(Qt::yellow);
-        //longTermColors[1] = QColor(25,38,41,64);
+        //longTermColors[1] = QColor(Qt::yellow);
+        longTermColors[1] = QColor(25,38,41,64);
         longTermColors[2] = QColor(237,21,21);
         longTermColors[3] = QColor(246,116,0);
         longTermColors[4] = QColor(201,206,59);
@@ -95,15 +121,103 @@ void ConfidenceColors::initColors(ColorScheme colorScheme)
         longTermColors[6] = QColor(17,209,22);
         longTermColors[7] = QColor(61,174,253);
 
-        initialTermColor = QColor(25,38,41,64);
+        initialTermColor = QColor(25,38,41,64); // Find something else
 
-        // These two are placeholders for the wordcloud background color.
-        frontEndColors[0] = QColor(255,221,217);
-        frontEndColors[1] = QColor(238,232,213);
+        invalidColor = QColor(Qt::red);
         break;
 
     case ProgressiveColorScheme:
-        // FIXME: NYI
-        break;
+        {
+            static const int AlphaMax = 255;
+            static const int AlphaStep = ((AlphaMax - 10) / KV_MAX_GRADE);
+            //static const int fractionsOffset = 3;
+
+            QColor color;
+
+            // Confidence 1..max
+            for (int grade = 1; grade <= KV_MAX_GRADE; ++grade) {
+                color = Prefs::gradeColor();
+                color.setAlpha(AlphaMax - (KV_MAX_GRADE - grade - 1) * AlphaStep);
+
+                longTermColors[grade] = color;
+            }
+
+            // Unpracticed (confidence 0)
+            color = QColor("#FFFFFF");
+            color.setAlpha(AlphaMax);
+            longTermColors[0] = color;
+
+            // Use one color for all initial phase values
+            color = Prefs::preGradeColor();
+            color.setAlpha(AlphaMax);
+            initialTermColor = color;
+
+            // Invalid
+            invalidColor = Prefs::invalidUnitColor();
+
+            break;
+        }
+    }
+
+    // These two are placeholders for the wordcloud background color.
+    frontEndColors[0] = QColor(255,221,217);
+    frontEndColors[1] = QColor(238,232,213);
+}
+
+
+// ----------------------------------------------------------------
+//                         Various utility functions
+
+
+void paintColorBar(QPainter &painter, const QRect &rect,
+                   const WordCount &wordCount, const ConfidenceColors &colors)
+{
+    // The outline of the total bar.
+    QRect roundedRect(rect);
+    roundedRect.adjust(1, 1, -1, -1);
+    QPainterPath roundedPath;
+    roundedPath.addRoundedRect(roundedRect, 2.0, 2.0);
+
+    int xPosition = 0;
+
+    // >0: grade, 0: initial, -1: untrained, -2: invalid
+    for (int i = KV_MAX_GRADE; i >= -2; --i) {
+        qreal fraction;
+        QColor color;
+
+        // Get the fraction and the color
+        if (i > 0) {
+            // long term
+            fraction = qreal(wordCount.grades[i]) / qreal(wordCount.totalWords);
+            color = colors.longTermColors[i];
+        } else if (i == 0) {
+            // initial term
+            fraction = qreal(wordCount.initialWords) / qreal(wordCount.totalWords);
+            color = colors.initialTermColor;
+        } else if (i == -1) {
+            // untrained (stored in longterm[0])
+            fraction = qreal(wordCount.grades[0]) / qreal(wordCount.totalWords);
+            color = colors.longTermColors[0];
+        } else {
+            fraction = qreal(wordCount.invalid) / qreal(wordCount.totalWords);
+            color = colors.invalidColor;
+        }
+
+        // Create a rect from the current fraction and 
+        // adjust the rect to the outer limits.
+        int barElementWidth = fraction * rect.width();
+        //int barElementWidth = fraction * roundedRect.width(); <-- Use this \
instead? +        QRectF barElement(rect.x() + xPosition, rect.y(), barElementWidth, \
rect.height()); +        QPainterPath barElementPath;
+        barElementPath.addRect(barElement);
+
+        // Intersect the QPainterPath of inner rectangle with outer,
+        // so that the inner rectangle takes the shape of the outer rounded \
rectangle. +        QPainterPath barElementIntersectedPath = \
roundedPath.intersected(barElementPath); +        xPosition += barElementWidth;
+
+        // Paint!
+        painter.setBrush(QBrush(color));
+        painter.drawPath(barElementIntersectedPath);
     }
 }
diff --git a/src/utils.h b/src/utils.h
index 5e00843..49d8d23 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -19,9 +19,12 @@
 #include <QtGui>
 
 // KEduVocDocument library
-#include <keduvocdocument.h>
+#include <keduvoccontainer.h>
 
 
+class QPainter;
+class QRect;
+
 // The WordCount struct contains the number of words in each category.
 // This could be used for number of words due, total number of words, etc.
 struct WordCount {
@@ -29,6 +32,10 @@ struct WordCount {
     void clear();
     int  percentageCompleted() const;
 
+    // Fill the WordCount data from the container.
+    void fillFromContainer(KEduVocContainer &container, int translationIndex,
+                           KEduVocContainer::EnumEntriesRecursive recursive = \
KEduVocContainer::Recursive); +
     int grades[KV_MAX_GRADE + 1]; // Number of entries in each grade including \
                grade=0, pregrade=0
     int pregrades[KV_MAX_GRADE + 1]; // Number of entries in each grade including \
                grade=0, pregrade=0
     int invalid;	          // Number of invalid entries (not always applicable);
@@ -52,8 +59,13 @@ struct ConfidenceColors {
 
     QColor longTermColors[KV_MAX_GRADE + 1];
     QColor initialTermColor;
+    QColor invalidColor;
     QColor frontEndColors[2]; // Placeholders for the wordcloud background colors
 };
 
 
+void paintColorBar(QPainter &painter, const QRect &rect,
+                   const WordCount &wordCount, const ConfidenceColors &colors);
+
+
 #endif // UTILS_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic