"Fossies" - the Fresh Open Source Software Archive

Member "audacious-3.10.1/src/libaudqt/infopopup-qt.cc" (26 Dec 2018, 6252 Bytes) of package /linux/misc/audacious-3.10.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "infopopup-qt.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.10_vs_3.10.1.

    1 /*
    2  * infopopup-qt.cc
    3  * Copyright 2018 John Lindgren
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions, and the following disclaimer.
   10  *
   11  * 2. Redistributions in binary form must reproduce the above copyright notice,
   12  *    this list of conditions, and the following disclaimer in the documentation
   13  *    provided with the distribution.
   14  *
   15  * This software is provided "as is" and without any warranty, express or
   16  * implied. In no event shall the authors be liable for any damages arising from
   17  * the use of this software.
   18  */
   19 
   20 #include <libaudcore/audstrings.h>
   21 #include <libaudcore/hook.h>
   22 #include <libaudcore/i18n.h>
   23 #include <libaudcore/playlist.h>
   24 #include <libaudcore/tuple.h>
   25 
   26 #include "libaudqt.h"
   27 #include "libaudqt-internal.h"
   28 
   29 #include <QBoxLayout>
   30 #include <QGridLayout>
   31 #include <QLabel>
   32 #include <QPainter>
   33 
   34 namespace audqt {
   35 
   36 class InfoPopup : public PopupWidget
   37 {
   38 public:
   39     InfoPopup (const String & filename, const Tuple & tuple);
   40 
   41 private:
   42     void add_field (int row, const char * field, const char * value);
   43     void add_fields (const Tuple & tuple);
   44     void art_ready (const char * filename);
   45     void finish_loading ();
   46 
   47     void paintEvent (QPaintEvent *) override;
   48 
   49     HookReceiver<InfoPopup, const char *> art_ready_hook
   50         {"art ready", this, & InfoPopup::art_ready};
   51 
   52     const String m_filename;
   53     const QGradientStops m_stops;
   54 
   55     QHBoxLayout m_hbox;
   56     QGridLayout m_grid;
   57     bool m_queued = false;
   58 };
   59 
   60 static QGradientStops get_stops (const QColor & base)
   61 {
   62     QColor mid = QColor (64, 64, 64);
   63     QColor dark = QColor (38, 38, 38);
   64     QColor darker = QColor (26, 26, 26);
   65 
   66     /* In a dark theme, try to match the tone of the base color */
   67     int v = base.value ();
   68     if (v >= 10 && v < 80)
   69     {
   70         int r = base.red (), g = base.green (), b = base.blue ();
   71         mid = QColor (r * 64 / v, g * 64 / v, b * 64 / v);
   72         dark = QColor (r * 38 / v, g * 38 / v, b * 38 / v);
   73         darker = QColor (r * 26 / v, g * 26 / v, b * 26 / v);
   74     }
   75 
   76     return {
   77         {0, mid},
   78         {0.499, dark},
   79         {0.5, darker},
   80         {1, Qt::black}
   81     };
   82 }
   83 
   84 InfoPopup::InfoPopup (const String & filename, const Tuple & tuple) :
   85     m_filename (filename),
   86     m_stops (get_stops (palette ().color (QPalette::Window)))
   87 {
   88     setWindowFlags (Qt::ToolTip);
   89 
   90     m_hbox.setMargin (sizes.TwoPt);
   91     m_hbox.setSpacing (sizes.FourPt);
   92     setLayout (& m_hbox);
   93 
   94     m_grid.setMargin (0);
   95     m_grid.setHorizontalSpacing (sizes.FourPt);
   96     m_grid.setVerticalSpacing (0);
   97     m_hbox.addLayout (& m_grid);
   98 
   99     add_fields (tuple);
  100     finish_loading ();
  101 }
  102 
  103 void InfoPopup::add_fields (const Tuple & tuple)
  104 {
  105     String title = tuple.get_str (Tuple::Title);
  106     String artist = tuple.get_str (Tuple::Artist);
  107     String album = tuple.get_str (Tuple::Album);
  108     String genre = tuple.get_str (Tuple::Genre);
  109 
  110     int year = tuple.get_int (Tuple::Year);
  111     int track = tuple.get_int (Tuple::Track);
  112     int length = tuple.get_int (Tuple::Length);
  113     int row = 0;
  114 
  115     if (title)
  116         add_field (row ++, _("Title"), title);
  117     if (artist)
  118         add_field (row ++, _("Artist"), artist);
  119     if (album)
  120         add_field (row ++, _("Album"), album);
  121     if (genre)
  122         add_field (row ++, _("Genre"), genre);
  123     if (year > 0)
  124         add_field (row ++, _("Year"), int_to_str (year));
  125     if (track > 0)
  126         add_field (row ++, _("Track"), int_to_str (track));
  127     if (length > 0)
  128         add_field (row ++, _("Length"), str_format_time (length));
  129 }
  130 
  131 void InfoPopup::add_field (int row, const char * field, const char * value)
  132 {
  133     auto header = new QLabel (this);
  134     header->setTextFormat (Qt::RichText);
  135     header->setText (QString ("<i><font color=\"#a0a0a0\">%1</font></i>").arg (field));
  136     m_grid.addWidget (header, row, 0, Qt::AlignRight);
  137 
  138     auto label = new QLabel (this);
  139     header->setTextFormat (Qt::RichText);
  140     auto html = QString (value).toHtmlEscaped ();
  141     label->setText (QString ("<font color=\"#ffffff\">%1</font>").arg (html));
  142     m_grid.addWidget (label, row, 1, Qt::AlignLeft);
  143 }
  144 
  145 void InfoPopup::art_ready (const char * filename)
  146 {
  147     if (m_queued && strcmp (filename, m_filename) == 0)
  148         finish_loading ();
  149 }
  150 
  151 void InfoPopup::finish_loading ()
  152 {
  153     QImage image = art_request (m_filename, & m_queued);
  154 
  155     if (! image.isNull ())
  156     {
  157         auto label = new QLabel (this);
  158         label->setPixmap (art_scale (image, sizes.OneInch, sizes.OneInch));
  159         m_hbox.insertWidget (0, label);
  160     }
  161 
  162     if (! m_queued)
  163         show ();
  164 }
  165 
  166 void InfoPopup::paintEvent (QPaintEvent *)
  167 {
  168     QLinearGradient grad (0, 0, 0, height ());
  169     grad.setStops (m_stops);
  170 
  171     QPainter p (this);
  172     p.fillRect (rect (), grad);
  173 }
  174 
  175 static InfoPopup * s_infopopup;
  176 
  177 static void infopopup_show (const String & filename, const Tuple & tuple)
  178 {
  179     if (s_infopopup)
  180         s_infopopup->deleteLater ();
  181 
  182     s_infopopup = new InfoPopup (filename, tuple);
  183 
  184     QObject::connect (s_infopopup, & QObject::destroyed, [] () {
  185         s_infopopup = nullptr;
  186     });
  187 }
  188 
  189 EXPORT void infopopup_show (Playlist playlist, int entry)
  190 {
  191     String filename = playlist.entry_filename (entry);
  192     Tuple tuple = playlist.entry_tuple (entry);
  193 
  194     if (filename && tuple.valid ())
  195         infopopup_show (filename, tuple);
  196 }
  197 
  198 EXPORT void infopopup_show_current ()
  199 {
  200     auto playlist = Playlist::playing_playlist ();
  201     if (playlist == Playlist ())
  202         playlist = Playlist::active_playlist ();
  203 
  204     int position = playlist.get_position ();
  205     if (position >= 0)
  206         infopopup_show (playlist, position);
  207 }
  208 
  209 EXPORT void infopopup_hide ()
  210 {
  211     /* This function can be called from an enter/leave event, and Qt does not
  212      * like widgets being deleted from such events.  This is debatably a bug in
  213      * Qt, but deleteLater() is an effective workaround. */
  214     if (s_infopopup)
  215         s_infopopup->deleteLater ();
  216 }
  217 
  218 void infopopup_hide_now ()
  219 {
  220     /* On exit, we really do want to delete the widget immediately. */
  221     delete s_infopopup;
  222 }
  223 
  224 } // namespace audqt