diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63db3f84a..c06f6732f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -202,6 +202,7 @@ set(SOURCES moodbar/moodbarloader.cpp moodbar/moodbarpipeline.cpp moodbar/moodbarproxystyle.cpp + moodbar/moodbarrenderer.cpp musicbrainz/acoustidclient.cpp musicbrainz/chromaprinter.cpp diff --git a/src/moodbar/moodbarproxystyle.cpp b/src/moodbar/moodbarproxystyle.cpp index 86fa27271..6d69f0ea4 100644 --- a/src/moodbar/moodbarproxystyle.cpp +++ b/src/moodbar/moodbarproxystyle.cpp @@ -25,7 +25,6 @@ #include #include -const int MoodbarProxyStyle::kNumHues = 12; const int MoodbarProxyStyle::kMarginSize = 3; const int MoodbarProxyStyle::kBorderSize = 1; const int MoodbarProxyStyle::kArrowWidth = 17; @@ -35,7 +34,7 @@ MoodbarProxyStyle::MoodbarProxyStyle(QSlider* slider) : QProxyStyle(slider->style()), slider_(slider), enabled_(true), - moodbar_style_(Style_SystemDefault), + moodbar_style_(MoodbarRenderer::Style_SystemDefault), state_(MoodbarOff), fade_timeline_(new QTimeLine(1000, this)), moodbar_colors_dirty_(true), @@ -174,7 +173,7 @@ void MoodbarProxyStyle::Render( void MoodbarProxyStyle::EnsureMoodbarRendered() { if (moodbar_colors_dirty_) { - moodbar_colors_ = MoodbarColors(data_, moodbar_style_, slider_->palette()); + moodbar_colors_ = MoodbarRenderer::Colors(data_, moodbar_style_, slider_->palette()); moodbar_colors_dirty_ = false; moodbar_pixmap_dirty_ = true; } @@ -185,150 +184,6 @@ void MoodbarProxyStyle::EnsureMoodbarRendered() { } } -MoodbarProxyStyle::ColorList MoodbarProxyStyle::MoodbarColors( - const QByteArray& data, MoodbarStyle style, const QPalette& palette) { - const int samples = data.size() / 3; - - // Set some parameters based on the moodbar style - StyleProperties properties; - switch(style) { - case Style_Angry: properties = StyleProperties(samples / 360 * 9, 45, -45, 200, 100); break; - case Style_Frozen: properties = StyleProperties(samples / 360 * 1, 140, 160, 50, 100); break; - case Style_Happy: properties = StyleProperties(samples / 360 * 2, 0, 359, 150, 250); break; - case Style_SystemDefault: - default: { - const QColor highlight_color(palette.color(QPalette::Active, QPalette::Highlight)); - - properties.threshold_ = samples / 360 * 3; - properties.range_start_ = (highlight_color.hsvHue() - 20 + 360) % 360; - properties.range_delta_ = 20; - properties.sat_ = highlight_color.hsvSaturation(); - properties.val_ = highlight_color.value() / 2; - } - } - - const unsigned char* data_p = - reinterpret_cast(data.constData()); - - int hue_distribution[360]; - int total = 0; - - memset(hue_distribution, 0, sizeof(hue_distribution)); - - ColorList colors; - - // Read the colors, keeping track of some histograms - for (int i=0; i properties.threshold_ ? n++ : n ) - * properties.range_delta_ / total + properties.range_start_) % 360; - } - - // Now huedist is a hue mapper: huedist[h] is the new hue value - // for a bar with hue h - for (ColorList::iterator it = colors.begin() ; it != colors.end() ; ++it) { - const int hue = qMax(0, it->hue()); - - *it = QColor::fromHsv( - qBound(0, hue_distribution[hue], 359), - qBound(0, it->saturation() * properties.sat_ / 100, 255), - qBound(0, it->value() * properties.val_ / 100, 255)); - } - - return colors; -} - -QPixmap MoodbarProxyStyle::MoodbarPixmap(const ColorList& colors, const QSize& size, - const QPalette& palette) { - QRect rect(QPoint(0, 0), size); - QRect border_rect(rect); - border_rect.adjust(kMarginSize, kMarginSize, -kMarginSize, -kMarginSize); - - QRect inner_rect(border_rect); - inner_rect.adjust(kBorderSize, kBorderSize, -kBorderSize, -kBorderSize); - - const QSize inner_size(inner_rect.size()); - - // Sample the colors and map them to screen pixels. - ColorList screen_colors; - for (int x=0; xrect.adjusted(kMarginSize, kMarginSize, -kMarginSize, kMarginSize); + return opt->rect.adjusted(kMarginSize, kMarginSize, + -kMarginSize, -kMarginSize); case SC_SliderHandle: { const QStyleOptionSlider* slider_opt = @@ -387,3 +243,34 @@ void MoodbarProxyStyle::DrawArrow(const QStyleOptionSlider* option, painter->drawPolygon(poly); painter->restore(); } + +QPixmap MoodbarProxyStyle::MoodbarPixmap( + const MoodbarRenderer::ColorList& colors, const QSize& size, + const QPalette& palette) { + QRect rect(QPoint(0, 0), size); + QRect border_rect(rect); + border_rect.adjust(kMarginSize, kMarginSize, -kMarginSize, -kMarginSize); + + QRect inner_rect(border_rect); + inner_rect.adjust(kBorderSize, kBorderSize, -kBorderSize, -kBorderSize); + + QPixmap ret(size); + QPainter p(&ret); + + // Draw the moodbar + MoodbarRenderer::Render(colors, &p, inner_rect); + + // Draw the border + p.setPen(QPen(palette.brush(QPalette::Active, QPalette::Highlight), + kBorderSize, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); + p.drawRect(border_rect.adjusted(0, 0, -1, -1)); + + // Draw the outer bit + p.setPen(QPen(palette.brush(QPalette::Active, QPalette::Background), + kMarginSize, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); + p.drawRect(rect.adjusted(1, 1, -2, -2)); + + p.end(); + + return ret; +} diff --git a/src/moodbar/moodbarproxystyle.h b/src/moodbar/moodbarproxystyle.h index c8585da0a..444aa5b32 100644 --- a/src/moodbar/moodbarproxystyle.h +++ b/src/moodbar/moodbarproxystyle.h @@ -18,6 +18,8 @@ #ifndef MOODBARPROXYSTYLE_H #define MOODBARPROXYSTYLE_H +#include "moodbarrenderer.h" + #include class QSlider; @@ -30,13 +32,6 @@ class MoodbarProxyStyle : public QProxyStyle { public: MoodbarProxyStyle(QSlider* slider); - enum MoodbarStyle { - Style_Angry, - Style_Frozen, - Style_Happy, - Style_SystemDefault - }; - // QProxyStyle void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const; @@ -54,7 +49,6 @@ public slots: void SetMoodbarEnabled(bool enabled); private: - static const int kNumHues; static const int kMarginSize; static const int kBorderSize; static const int kArrowWidth; @@ -67,21 +61,6 @@ private: FadingToOff }; - struct StyleProperties { - StyleProperties(int threshold = 0, int range_start = 0, int range_delta = 0, - int sat = 0, int val = 0) - : threshold_(threshold), range_start_(range_start), range_delta_(range_delta), - sat_(sat), val_(val) {} - - int threshold_; - int range_start_; - int range_delta_; - int sat_; - int val_; - }; - - typedef QVector ColorList; - private: void NextState(); @@ -90,10 +69,8 @@ private: void EnsureMoodbarRendered(); void DrawArrow(const QStyleOptionSlider* option, QPainter* painter) const; - static ColorList MoodbarColors(const QByteArray& data, MoodbarStyle style, - const QPalette& palette); - static QPixmap MoodbarPixmap(const ColorList& colors, const QSize& size, - const QPalette& palette); + static QPixmap MoodbarPixmap(const MoodbarRenderer::ColorList& colors, + const QSize& size, const QPalette& palette); private slots: void FaderValueChanged(qreal value); @@ -103,7 +80,7 @@ private: bool enabled_; QByteArray data_; - MoodbarStyle moodbar_style_; + MoodbarRenderer::MoodbarStyle moodbar_style_; State state_; QTimeLine* fade_timeline_; @@ -113,7 +90,7 @@ private: bool moodbar_colors_dirty_; bool moodbar_pixmap_dirty_; - ColorList moodbar_colors_; + MoodbarRenderer::ColorList moodbar_colors_; QPixmap moodbar_pixmap_; }; diff --git a/src/moodbar/moodbarrenderer.cpp b/src/moodbar/moodbarrenderer.cpp new file mode 100644 index 000000000..260fa4df3 --- /dev/null +++ b/src/moodbar/moodbarrenderer.cpp @@ -0,0 +1,140 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "moodbarrenderer.h" + +#include +#include + +const int MoodbarRenderer::kNumHues = 12; + +MoodbarRenderer::ColorList MoodbarRenderer::Colors( + const QByteArray& data, MoodbarStyle style, const QPalette& palette) { + const int samples = data.size() / 3; + + // Set some parameters based on the moodbar style + StyleProperties properties; + switch(style) { + case Style_Angry: properties = StyleProperties(samples / 360 * 9, 45, -45, 200, 100); break; + case Style_Frozen: properties = StyleProperties(samples / 360 * 1, 140, 160, 50, 100); break; + case Style_Happy: properties = StyleProperties(samples / 360 * 2, 0, 359, 150, 250); break; + case Style_SystemDefault: + default: { + const QColor highlight_color(palette.color(QPalette::Active, QPalette::Highlight)); + + properties.threshold_ = samples / 360 * 3; + properties.range_start_ = (highlight_color.hsvHue() - 20 + 360) % 360; + properties.range_delta_ = 20; + properties.sat_ = highlight_color.hsvSaturation(); + properties.val_ = highlight_color.value() / 2; + } + } + + const unsigned char* data_p = + reinterpret_cast(data.constData()); + + int hue_distribution[360]; + int total = 0; + + memset(hue_distribution, 0, sizeof(hue_distribution)); + + ColorList colors; + + // Read the colors, keeping track of some histograms + for (int i=0; i properties.threshold_ ? n++ : n ) + * properties.range_delta_ / total + properties.range_start_) % 360; + } + + // Now huedist is a hue mapper: huedist[h] is the new hue value + // for a bar with hue h + for (ColorList::iterator it = colors.begin() ; it != colors.end() ; ++it) { + const int hue = qMax(0, it->hue()); + + *it = QColor::fromHsv( + qBound(0, hue_distribution[hue], 359), + qBound(0, it->saturation() * properties.sat_ / 100, 255), + qBound(0, it->value() * properties.val_ / 100, 255)); + } + + return colors; +} + +void MoodbarRenderer::Render(const ColorList& colors, QPainter* p, const QRect& rect) { + // Sample the colors and map them to screen pixels. + ColorList screen_colors; + for (int x=0; xsetPen(QColor::fromHsv( + h, + qBound(0, int(float(s) * coeff), 255), + qBound(0, int(255.f - (255.f - float(v)) * coeff2), 255))); + + p->drawPoint(rect.left() + x, rect.top() + y); + p->drawPoint(rect.left() + x, rect.top() + rect.height() - 1 - y); + } + } +} diff --git a/src/moodbar/moodbarrenderer.h b/src/moodbar/moodbarrenderer.h new file mode 100644 index 000000000..da407fb52 --- /dev/null +++ b/src/moodbar/moodbarrenderer.h @@ -0,0 +1,61 @@ +/* This file is part of Clementine. + Copyright 2012, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef MOODBARRENDERER_H +#define MOODBARRENDERER_H + +#include +#include +#include + +class QPalette; + +class MoodbarRenderer { +public: + typedef QVector ColorList; + + enum MoodbarStyle { + Style_Angry, + Style_Frozen, + Style_Happy, + Style_SystemDefault + }; + + static const int kNumHues; + + static ColorList Colors(const QByteArray& data, MoodbarStyle style, + const QPalette& palette); + static void Render(const ColorList& colors, QPainter* p, const QRect& rect); + +private: + MoodbarRenderer(); + + struct StyleProperties { + StyleProperties(int threshold = 0, int range_start = 0, int range_delta = 0, + int sat = 0, int val = 0) + : threshold_(threshold), range_start_(range_start), range_delta_(range_delta), + sat_(sat), val_(val) {} + + int threshold_; + int range_start_; + int range_delta_; + int sat_; + int val_; + }; +}; + +#endif // MOODBARRENDERER_H