[kdevplatform] shell: Favour strongly distinct working set icons

Leon Pollak leonp at plris.com
Tue Dec 24 11:21:03 GMT 2013


Is it totally discarded to make icons with simple numbers 1,2,3...?


On Tuesday 24 December 2013 01:40:00 Sven Brauch wrote:
> Git commit 0b4e46220da82a6cc50bc8554bc9778632f7b51e by Sven Brauch.
> Committed on 24/12/2013 at 01:39.
> Pushed by brauch into branch 'master'.
> 
> Favour strongly distinct working set icons
> 
> When a new working set is created, the code will try to pick an icon
> which is sufficiently distinct from the existing icons. This should
> work nicely unless you have dozens of sets opened. Tell me if it does
> not. ;)
> 
> CCMAIL:kdevelop at kde.org
> 
> M  +27   -2    shell/workingsetcontroller.cpp
> M  +1    -0    shell/workingsetcontroller.h
> M  +11   -16   shell/workingsets/workingset.cpp
> M  +35   -0    shell/workingsets/workingset.h
> 
> http://commits.kde.org/kdevplatform/0b4e46220da82a6cc50bc8554bc9778632
> f7b51e
> 
> diff --git a/shell/workingsetcontroller.cpp
> b/shell/workingsetcontroller.cpp index 417a3b4..1b40750 100644
> --- a/shell/workingsetcontroller.cpp
> +++ b/shell/workingsetcontroller.cpp
> @@ -97,10 +97,35 @@ void WorkingSetController::cleanup()
>      m_emptyWorkingSet = 0;
>  }
> 
> +const QString WorkingSetController::makeSetId(const QString& prefix)
> const +{
> +    QString newId;
> +    const int maxRetries = 10;
> +    for(unsigned int retry = 2; retry <= maxRetries; retry++) {
> +        newId = QString("%1_%2").arg(prefix).arg(qrand() % 10000000);
> +        WorkingSetIconParameters params(newId);
> +        foreach(WorkingSet* set, m_workingSets) {
> +            if(set->isEmpty()) {
> +                continue;
> +            }
> +            // The last retry will always generate a valid set
> +            const int maxSimilarity = retry > maxRetries / 2 ? 55 :
> 35; +            if(retry != maxRetries &&
> WorkingSetIconParameters(set->id()).similarity(params) >= retry*8) {
> +                newId = QString();
> +                break;
> +            }
> +        }
> +        if(! newId.isEmpty()) {
> +            break;
> +        }
> +    }
> +    return newId;
> +}
> +
>  WorkingSet* WorkingSetController::newWorkingSet(const QString&
> prefix) {
> -    QString newId = QString("%1_%2").arg(prefix).arg(qrand() %
> 10000000); -    return getWorkingSet(newId);
> +
> +    return getWorkingSet(makeSetId(prefix));
>  }
> 
>  WorkingSet* WorkingSetController::getWorkingSet(const QString& id)
> diff --git a/shell/workingsetcontroller.h
> b/shell/workingsetcontroller.h index ea6985b..1bd2138 100644
> --- a/shell/workingsetcontroller.h
> +++ b/shell/workingsetcontroller.h
> @@ -103,6 +103,7 @@ private slots:
> 
>  private:
>      void setupActions();
> +    const QString makeSetId(const QString& prefix) const;
> 
>      QSet<QString> m_usedIcons;
>      QMap<QString, WorkingSet*> m_workingSets;
> diff --git a/shell/workingsets/workingset.cpp
> b/shell/workingsets/workingset.cpp index bfe93ca..bc4f430 100644
> --- a/shell/workingsets/workingset.cpp
> +++ b/shell/workingsets/workingset.cpp
> @@ -42,21 +42,16 @@ bool WorkingSet::m_loading = false;
> 
>  namespace {
> 
> -QIcon generateIcon(const QString& id)
> +QIcon generateIcon(const WorkingSetIconParameters& params)
>  {
>      QImage pixmap(16, 16, QImage::Format_ARGB32);
>      // fill the background with a transparent color
>      pixmap.fill(QColor::fromRgba(qRgba(0, 0, 0, 0)));
> -    // calculate layout and colors depending on the working set ID
> -    // modulo it so it's around 2^28, leaving some space before uint
> overflows -    const uint setId = qHash(id) % 268435459;
> -    // amount of colored squares in this icon (the rest is grey or
> whatever you set as default color) -    // use 4-6-4-1 weighting for
> 1, 2, 3, 4 squares, because that's the number of arrangements for
> each -    const uint coloredCount = (setId % 15 < 4) ? 1 : (setId %
> 15 < 10) ? 2 : (setId % 15 == 14) ? 4 : 3; +    const uint
> coloredCount = params.coloredCount;
>      // coordinates of the rectangles to draw, for 16x16 icons
> specifically QList<QRect> rects;
>      rects << QRect(1, 1, 5, 5) << QRect(1, 9, 5, 5) << QRect(9, 1, 5,
> 5) << QRect(9, 9, 5, 5); -    if ( setId % 31 < 16 ) {
> +    if ( params.swapDiagonal ) {
>          rects.swap(1, 2);
>      }
> 
> @@ -67,31 +62,31 @@ QIcon generateIcon(const QString& id)
>      // color for colored squares
>      // this code is not fragile, you can just tune the magic formulas
> at random and see what looks good. // just make sure to keep it
> within the 0-360 / 0-255 / 0-255 space of the HSV model -    QColor
> brightColor = QColor::fromHsv((setId % 273 * 81) % 360,
> qMin<uint>(255, 215 + (setId*5) % 150), -                            
>             205 + (setId*11) % 50); +    QColor brightColor =
> QColor::fromHsv(params.hue, qMin<uint>(255, 215 + (params.setId*5) %
> 150), +                                         205 +
> (params.setId*11) % 50); // Y'UV "Y" value, the approximate
> "lightness" of the color // If it is above 0.6, then making the color
> darker a bit is okay, // if it is below 0.35, then the color should
> be a bit brighter. float brightY = 0.299 * brightColor.redF() + 0.587
> * brightColor.greenF() + 0.114 * brightColor.blueF(); if ( brightY >
> 0.6 ) {
> -        if ( setId % 7 < 2 ) {
> +        if ( params.setId % 7 < 2 ) {
>              // 2/7 chance to make the color significantly darker
> -            brightColor = brightColor.darker(120 + (setId*7) % 35);
> +            brightColor = brightColor.darker(120 + (params.setId*7) %
> 35); }
> -        else if ( setId % 5 == 0 ) {
> +        else if ( params.setId % 5 == 0 ) {
>              // 1/5 chance to make it a bit darker
> -            brightColor = brightColor.darker(110 + (setId*3) % 10);
> +            brightColor = brightColor.darker(110 + (params.setId*3) %
> 10); }
>      }
>      if ( brightY < 0.35 ) {
>          // always make the color brighter to avoid very dark colors
> (like rgb(0, 0, 255)) -        brightColor = brightColor.lighter(120
> + (setId*13) % 55); +        brightColor = brightColor.lighter(120 +
> (params.setId*13) % 55); }
>      int at = 0;
>      foreach ( const QRect& rect, rects ) {
>          QColor currentColor;
>          // pick the colored squares; you can get different patterns
> by re-ordering the "rects" list -        if ( (at + setId*7) % 4 <
> coloredCount ) {
> +        if ( (at + params.setId*7) % 4 < coloredCount ) {
>              currentColor = brightColor;
>          }
>          else {
> diff --git a/shell/workingsets/workingset.h
> b/shell/workingsets/workingset.h index 047240f..98fbff3 100644
> --- a/shell/workingsets/workingset.h
> +++ b/shell/workingsets/workingset.h
> @@ -23,6 +23,7 @@
>  #include <QIcon>
>  #include <KConfigGroup>
>  #include <QPointer>
> +#include <QDebug>
> 
>  namespace Sublime {
>  class Area;
> @@ -32,6 +33,40 @@ class View;
> 
>  namespace KDevelop {
> 
> +/// Contains all significant parameters which control the appearance
> of a working set icon +struct WorkingSetIconParameters {
> +    WorkingSetIconParameters(const QString& id)
> +        : setId(qHash(id) % 268435459)
> +        , coloredCount((setId % 15 < 4) ? 1 : (setId % 15 < 10) ? 2 :
> (setId % 15 == 14) ? 4 : 3) +        , hue((setId % 273 * 83) % 360)
> +        , swapDiagonal(setId % 31 < 16)
> +    { };
> +    // calculate layout and colors depending on the working set ID
> +    // modulo it so it's around 2^28, leaving some space before uint
> overflows +    const uint setId;
> +    // amount of colored squares in this icon (the rest is grey or
> whatever you set as default color) +    // use 4-6-4-1 weighting for
> 1, 2, 3, 4 squares, because that's the number of arrangements for
> each +    const uint coloredCount;
> +    const uint hue;
> +    bool swapDiagonal;
> +    // between 0 and 100, 100 = very similar, 0 = very different
> +    // 20 points should make a significantly different icon.
> +    uint similarity(const WorkingSetIconParameters& other) const {
> +        int sim = 100;
> +        uint hueDiff = qAbs<int>(hue - other.hue);
> +        hueDiff = hueDiff > 180 ? 360 - hueDiff : hueDiff;
> +        sim -= hueDiff > 35 ? 50 : (hueDiff * 50) / 180;
> +        if ( coloredCount != other.coloredCount ) {
> +            sim -= 50;
> +        }
> +        else if ( coloredCount == 2 && swapDiagonal !=
> other.swapDiagonal ) { +            sim -= 35;
> +        }
> +        return sim;
> +    };
> +};
> +
> +
>  class WorkingSet : public QObject {
>      Q_OBJECT
> 
> _______________________________________________
> KDevelop mailing list
> KDevelop at kde.org
> https://mail.kde.org/mailman/listinfo/kdevelop

-- 
            Dr.Leon M.Pollak
                Director
       PLR Information Systems Ltd.
Tel.:+972-98657670  |  POB 8130, Giborei Israel 5a,
Fax.:+972-98657621  |  Poleg Industrial Zone,
Mob.:+972-544739246 |  Netanya, 42504, Israel.




More information about the KDevelop mailing list