Ticket #341: lcd-busy-520.patch

File lcd-busy-520.patch, 21.6 KB (added by eskil <myth@…>, 15 years ago)

busy spinner for LCD, plus fix for ticket 520

  • mythtv/libs/libmyth/lcddevice.cpp

    Patch to add a busy spinner to LCD and fix ticket#520.
    
    1) Added a flush when writing to the mythlcdserver. I might have been
    confused by the lag causes by the menus, but I'm fairly sure I
    observed lack of updates that the flush fixed. Anyway, it can't hurt.
    
    2) Fix for ticket#520. Add two new calls to LCD, setMusicShuffle and
    setMusicRepeat, used by MythMusic to set what the shuffle and repeat
    mode is.
    
    3) Changed the layout of the music screen :
        height == 2 :    Artist[-Album-]-Title
                            hh:mm / HH:MM
    
        height == 3 :    Artist[-Album-]-Title 
                            hh:mm / HH:MM
                          [shuffle] [repeat]
    
        height >  3 :    Artist[-Album-]-Title 
                            hh:mm / HH:MM
                         ====progress==-
                          [shuffle] [repeat]
    
    4) Added support for a busy spinner. Calling LCD::setGenericBusy will
    animate a busy spinner. Note, the busy spinner does *not* selfanimate
    (it could), but I've chosen to only animate when setGenericBusy is
    called. 
    
    5) when checking recording status, and failing to talk to the backend,
    only fallback to time screen if we're showing the recording
    status. Otherwise, if the backend is unreachable (ie. a machine used
    for mythmusic only) will constantly fallback to time screen.
    
    6) Moved all the LCD::switchToMusic calls in playbackbox to a single
    function (setTrackOnLCD).
    
    
    
     
    192192#endif
    193193        // Just stream the text out the socket
    194194
    195         os << someText << "\n";
     195        os << someText << "\n" << flush;
    196196    }
    197197    else
    198198    {
     
    387387    else if (value > 1.0)
    388388        value = 1.0;
    389389       
    390     sendToServer("SET_GENERIC_PROGRESS " + QString().setNum(value));   
     390    sendToServer("SET_GENERIC_PROGRESS " + QString().setNum (false) +
     391                 " " + QString().setNum(value));   
    391392}
    392393
     394void LCD::setGenericBusy ()
     395{
     396    if (!lcd_ready || !lcd_showgeneric)
     397        return;
     398
     399    sendToServer("SET_GENERIC_PROGRESS 1 0.0");
     400}
     401
    393402void LCD::setMusicProgress(QString time, float value)
    394403{
    395404    if (!lcd_ready || !lcd_showmusic)
     
    404413            QString().setNum(value));   
    405414}
    406415
     416void LCD::setMusicShuffle(int shuffle)
     417{
     418    if (!lcd_ready || !lcd_showmusic)
     419        return;
     420
     421    sendToServer("SET_MUSIC_PLAYER_PROP SHUFFLE "+ QString().setNum(shuffle));   
     422}
     423
     424void LCD::setMusicRepeat(int repeat)
     425{
     426    if (!lcd_ready || !lcd_showmusic)
     427        return;
     428
     429    sendToServer("SET_MUSIC_PLAYER_PROP REPEAT "+ QString().setNum(repeat));   
     430}
     431
    407432void LCD::setVolumeLevel(float value)
    408433{
    409434    if (!lcd_ready || !lcd_showvolume)
  • mythtv/libs/libmyth/lcddevice.h

     
    104104  public:
    105105   ~LCD();
    106106
     107    enum {
     108        MUSIC_REPEAT_NONE = 0,
     109        MUSIC_REPEAT_TRACK = 1,
     110        MUSIC_REPEAT_ALL = 2
     111    };
     112
     113    enum {
     114        MUSIC_SHUFFLE_NONE = 0,
     115        MUSIC_SHUFFLE_RAND = 1,
     116        MUSIC_SHUFFLE_SMART = 2
     117    };
     118
    107119    static class LCD * Get(void);
    108120    static void SetupLCD (void);
    109121
     
    147159    // define the screen, row, and alignment of the text
    148160    void switchToGeneric(QPtrList<LCDTextItem> *textItems);
    149161
    150     // Do a progress bar with the generic level between 0 and 1.0
     162    /** Update the generic progress bar.
     163        \param generic_progress a value between 0 and 1.0
     164    */
    151165    void setGenericProgress(float generic_progress);
    152166
     167    /** Update the generic screen to display a busy spinner.
     168
     169                \note The LCD busy spinner only 'moves' when this is called
     170                instead of the lcdserver just handling it itself.
     171    */
     172    void setGenericBusy();
     173
    153174    // Do a music progress bar with the generic level between 0 and 1.0
    154175    void setMusicProgress(QString time, float generic_progress);
    155176
     177        /** \brief Set music player's repeat properties         
     178        \param repeat the state of repeat
     179         */
     180    void setMusicRepeat (int repeat);
     181
     182        /** \brief Set music player's shuffle properties             
     183        \param repeat the state of repeat
     184    */
     185    void setMusicShuffle (int shuffle);
     186
    156187    // Show the Volume Level top_text scrolls
    157188    void switchToVolume(QString app_name);
    158189
  • mythtv/programs/mythlcdserver/lcdserver.h

     
    5555    void switchToMenu(const QStringList &tokens, QSocket *socket);
    5656    void setChannelProgress(const QStringList &tokens, QSocket *socket);
    5757    void setMusicProgress(const QStringList &tokens, QSocket *socket);
     58    void setMusicProp(const QStringList &tokens, QSocket *socket);
    5859    void setGenericProgress(const QStringList &tokens, QSocket *socket);
    5960    void setVolumeLevel(const QStringList &tokens, QSocket *socket);
    6061    void updateLEDs(const QStringList &tokens, QSocket *socket);
  • mythtv/programs/mythlcdserver/lcdprocclient.cpp

     
    470470    setPriority("Music", LOW);
    471471    sendToServer("widget_add Music topWidget string");
    472472    sendToServer("widget_add Music timeWidget string");
     473    sendToServer("widget_add Music infoWidget string");
    473474    sendToServer("widget_add Music progressBar hbar");
    474475   
    475476    // The Channel Screen
     
    959960void LCDProcClient::startMusic(QString artist, QString album, QString track)
    960961{
    961962    QString aString;
     963    music_progress = 0.0;
    962964    if (lcd_showmusic)
    963965      setPriority("Music", HIGH);
    964966    aString = artist;
     
    10161018    QString aString;
    10171019
    10181020    if (lcd_showgeneric)
    1019       setPriority("Generic", HIGH);
     1021      setPriority("Generic", TOP);
    10201022
    10211023    // Clear out the LCD.  Do this before checking if its empty incase the user
    10221024    //  wants to just clear the lcd
     
    10291031        return;
    10301032
    10311033    activeScreen = "Generic";
     1034
     1035    busy_progress = false;
     1036    busy_pos = 1;
     1037    busy_direction = 1;
     1038    busy_indicator_size = 2.0;
    10321039    generic_progress = 0.0;
    10331040
    10341041    // Return if there are no more items
     
    15051512    outputChannel();   
    15061513}
    15071514
    1508 void LCDProcClient::setGenericProgress(float value)
     1515void LCDProcClient::setGenericProgress(bool b, float value)
    15091516{
    15101517    if (!lcd_ready)
    15111518        return;
     
    15171524    else if (generic_progress > 1.0)
    15181525        generic_progress = 1.0;
    15191526
     1527    // Note, this will let us switch to/from busy indicator by alternating between
     1528    // being passed true or false for b.
     1529    busy_progress = b;
     1530    if (busy_progress) {
     1531        // If we're at either end of the line, switch direction
     1532        if (busy_pos + busy_direction > (signed int)lcdWidth - busy_indicator_size ||
     1533            busy_pos + busy_direction < 1) {
     1534            busy_direction = -busy_direction;
     1535        }
     1536        busy_pos += busy_direction;
     1537        generic_progress = busy_indicator_size / (float)lcdWidth;
     1538    } else {
     1539        busy_pos = 1;
     1540    }
     1541
    15201542    outputGeneric();
    15211543}
    15221544
     
    15361558    outputMusic();
    15371559}
    15381560
     1561void LCDProcClient::setMusicRepeat (int repeat)
     1562{
     1563    if (!lcd_ready)
     1564        return;
     1565
     1566    music_repeat = repeat;
     1567
     1568    outputMusic ();
     1569}
     1570
     1571void LCDProcClient::setMusicShuffle (int shuffle)
     1572{
     1573    if (!lcd_ready)
     1574        return;
     1575
     1576    music_shuffle = shuffle;
     1577
     1578    outputMusic ();
     1579}
     1580
    15391581void LCDProcClient::setVolumeLevel(float value)
    15401582{
    15411583    if (!lcd_ready)
     
    17671809
    17681810void LCDProcClient::outputMusic()
    17691811{
    1770     QString aString;
     1812    outputCenteredText("Music", music_time, "timeWidget", 2);
    17711813
    17721814    if (lcdHeight > 2) {
    1773       outputCenteredText("Music", music_time, "timeWidget", 2);
     1815      QString props;
     1816      QString shuffle = "      ";
     1817      QString repeat = "      ";
     1818
     1819      if (music_shuffle == 1) {
     1820          shuffle = "Shfl ?";
     1821      } else if (music_shuffle == 2) {
     1822          shuffle = "Shfl i";         
     1823      }
     1824
     1825      if (music_repeat == 1) {
     1826          repeat = "Rpt 1";
     1827      } else if (music_repeat == 2) {
     1828          repeat = "Rpt *";         
     1829      }
     1830
     1831      props.sprintf ("%s  %s", shuffle.ascii (), repeat.ascii ());
     1832
     1833      outputCenteredText("Music", props, "infoWidget", lcdHeight);
    17741834    }
    17751835
    1776     aString = "widget_set Music progressBar 1 ";
    1777     aString += QString::number(lcdHeight);
    1778     aString += " ";
    1779     aString += QString::number((int)rint(music_progress * lcdWidth *
     1836    if (lcdHeight > 3) {
     1837        QString aString;
     1838        aString = "widget_set Music progressBar 1 3 ";
     1839        aString += QString::number((int)rint(music_progress * lcdWidth *
    17801840                               cellWidth));
    1781     sendToServer(aString);
     1841        sendToServer(aString);
     1842    }
    17821843}
    17831844
    17841845void LCDProcClient::outputChannel()
     
    17941855void LCDProcClient::outputGeneric()
    17951856{
    17961857    QString aString;
    1797     aString = "widget_set Generic progressBar 1 ";
     1858    aString = "widget_set Generic progressBar ";
     1859    aString += QString::number (busy_pos);
     1860    aString += " ";
    17981861    aString += QString::number(lcdHeight);
    17991862    aString += " ";
    18001863    aString += QString::number((int)rint(generic_progress * lcdWidth *
     
    19351998    sendToServer("screen_del Menu menuWidget5");
    19361999
    19372000    sendToServer("widget_del Music progressBar");
     2001    sendToServer("widget_del Music infoWidget");
    19382002    sendToServer("widget_del Music timeWidget");
    19392003    sendToServer("widget_del Music topWidget");
    19402004    sendToServer("screen_del Music");
     
    20032067                                  "- is the master server running?\n\t\t\t"
    20042068                                  "Will retry in 30 seconds");
    20052069            QTimer::singleShot(30 * 1000, this, SLOT(updateRecordingList()));
    2006             switchToTime();
     2070
     2071            // If we can't get the recording status and we're showing
     2072            // it, switch back to time. Maybe it would be even better
     2073            // to show that the backend is unreachable ?
     2074            if  (activeScreen == "RecStatus")
     2075                switchToTime();
    20072076            return;
    20082077        }   
    20092078    }
  • mythtv/programs/mythlcdserver/lcdserver.cpp

     
    3939        time is a string
    4040        progress is a float between 0.0 and 1.0
    4141
    42     SET_GENERIC_PROGRESS <progress>
     42    SET_MUSIC_PLAYER_PROP <field> <val>
     43        field is a string, currently SHUFFLE or REPEAT
     44        val depends on field, currently integer
     45
     46    SET_GENERIC_PROGRESS <busy> <progress>
     47        busy is 0 for busy spinner, 0 for normal progess bar
    4348        progress is a float between 0.0 and 1.0
    4449   
    4550    UPDATE_LEDS
     
    213218    {
    214219        setMusicProgress(tokens, socket);
    215220    }
     221    else if (tokens[0] == "SET_MUSIC_PLAYER_PROP")
     222    {
     223        setMusicProp(tokens, socket);
     224    }
    216225    else if (tokens[0] == "SET_CHANNEL_PROGRESS")
    217226    {
    218227        setChannelProgress(tokens, socket);
     
    577586
    578587    QString flat = tokens.join(" ");
    579588   
    580     if (tokens.count() != 2)
     589    if (tokens.count() != 3)
    581590    {
    582591        VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_GENERIC_PROGRESS command: "
    583592                << flat);
     
    586595    }
    587596     
    588597    bool bOK;
    589     float progress = tokens[1].toFloat(&bOK);
     598    bool busy = tokens[1].toInt (&bOK);
    590599    if (!bOK)
    591600    {
     601        VERBOSE(VB_IMPORTANT, "LCDServer: bad bool value in "
     602                "SET_GENERIC_PROGRESS command: %1 %2" << tokens[1] << tokens[2]);
     603        sendMessage(socket, "HUH?");
     604        return;
     605    }
     606    float progress = tokens[2].toFloat(&bOK);
     607    if (!bOK)
     608    {
    592609        VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in "
    593610                "SET_GENERIC_PROGRESS command: %1" << tokens[1]);
    594611        sendMessage(socket, "HUH?");
     
    596613    }
    597614   
    598615    if (m_lcd)
    599         m_lcd->setGenericProgress(progress);
     616        m_lcd->setGenericProgress(busy, progress);
    600617       
    601618    sendMessage(socket, "OK");
    602619}
     
    632649    sendMessage(socket, "OK");
    633650}
    634651
     652void LCDServer::setMusicProp(const QStringList &tokens, QSocket *socket)
     653{
     654    if (debug_level > 0)
     655        VERBOSE(VB_GENERAL, "LCDServer: SET_MUSIC_PROP");
     656
     657    QString flat = tokens.join(" ");
     658   
     659    if (tokens.count() < 3)
     660    {
     661        VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_MUSIC_PROP command: "
     662                << flat);
     663        sendMessage(socket, "HUH?");
     664        return;
     665    }
     666     
     667    if (tokens[1] == "SHUFFLE") {
     668        if (tokens.count () != 3) {
     669            VERBOSE(VB_IMPORTANT, "LCDServer: missing argument for "
     670                    "SET_MUSIC_PROP SHUFFLE command: " << flat);
     671            sendMessage(socket, "HUH?");
     672            return;
     673        }
     674        bool bOk;
     675        int state = tokens[2].toInt (&bOk);
     676        if (!bOk) {
     677            VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
     678                    "SET_MUSIC_PROP SHUFFLE command: " << tokens[2]);
     679            sendMessage(socket, "HUH?");
     680        return;
     681        }
     682        if (m_lcd)
     683            m_lcd->setMusicShuffle (state);
     684    } else if (tokens[1] == "REPEAT") {
     685        if (tokens.count () != 3) {
     686            VERBOSE(VB_IMPORTANT, "LCDServer: missing argument for "
     687                    "SET_MUSIC_PROP REPEAT command: " << flat);
     688            sendMessage(socket, "HUH?");
     689            return;
     690        }
     691        bool bOk;
     692        int state = tokens[2].toInt (&bOk);
     693        if (!bOk) {
     694            VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
     695                    "SET_MUSIC_PROP REPEAT command: " << tokens[2]);
     696            sendMessage(socket, "HUH?");
     697            return;
     698        }
     699        if (m_lcd)
     700            m_lcd->setMusicRepeat (state);
     701    } else {
     702        VERBOSE(VB_IMPORTANT, "LCDServer: bad argument for "
     703                "SET_MUSIC_PROP command: " << tokens[1]);
     704        sendMessage(socket, "HUH?");
     705        return;
     706    }
     707       
     708    sendMessage(socket, "OK");
     709}
     710
    635711void LCDServer::setVolumeLevel(const QStringList &tokens, QSocket *socket)
    636712{
    637713    if (debug_level > 0)
  • mythtv/programs/mythlcdserver/lcdprocclient.h

     
    3939   
    4040    void switchToMusic(const QString &artist, const QString &album, const QString &track);
    4141    void setMusicProgress(QString time, float generic_progress);
     42    void setMusicRepeat (int repeat);
     43    void setMusicShuffle (int shuffle);
    4244    void setLevels(int numbLevels, float *values);
    4345   
    4446    void switchToChannel(QString channum = "", QString title = "",
     
    4951                      bool popMenu = true);
    5052   
    5153    void switchToGeneric(QPtrList<LCDTextItem> *textItems);
    52     void setGenericProgress(float generic_progress);
     54    void setGenericProgress(bool busy, float generic_progress);
    5355
    5456    void switchToVolume(QString app_name);
    5557    void setVolumeLevel(float volume_level);
     
    162164       
    163165    float EQlevels[10];
    164166    float progress;
     167    /** TRUE if the generic progress indicator is a busy (ie. doesn't have a known total steps */
     168    bool busy_progress;
     169    /** Current position of the busy indicator, used if @p busy_progress is true. */
     170    int busy_pos;
     171    /** How many "blocks" the busy indicator must be, used if @p busy_progress is true. */
     172    float busy_indicator_size;
     173    /** Dicrection of the busy indicator on the, -1 or 1, used if @p busy_progress is true. */
     174    int busy_direction;
    165175    float generic_progress;
    166176    float volume_level;
    167177
    168178    float music_progress;
    169179    QString music_time;
     180    int music_repeat;
     181    int music_shuffle;
    170182
    171183    QString scrollingText;
    172184    QString scrollScreen, scrollWidget;
  • mythplugins/mythmusic/mythmusic/playbackbox.cpp

     
    772772           
    773773            if (curMeta)
    774774            {
    775                 if (class LCD * lcd = LCD::Get())
    776                 {
    777                     // Set track info on the LCD
    778                     QPtrList<LCDTextItem> textItems;
    779                     textItems.setAutoDelete(true);
    780                     lcd->switchToMusic(curMeta->Artist (),
    781                                        curMeta->Album (),
    782                                        curMeta->Title ());
    783                 }
     775                setTrackOnLCD (curMeta);
    784776            }
    785777        }   
    786778        else
     
    850842
    851843                    if (curMeta)
    852844                    {
    853                         if (class LCD * lcd = LCD::Get())
    854                         {
    855                             //Show the artist stuff on the LCD
    856                             lcd->switchToMusic(curMeta->Artist (),
    857                                                curMeta->Album (),
    858                                                curMeta->Title ());
    859                             lcd_volume_visible = false;
    860                         }
     845                        setTrackOnLCD (curMeta);
    861846                    }
    862847                }
    863848            }
     
    10361021    }
    10371022}
    10381023
     1024void PlaybackBoxMusic::setTrackOnLCD (Metadata *mdata) {
     1025    if (class LCD * lcd = LCD::Get())
     1026    {
     1027        // Set the Artist and Tract on the LCD
     1028        lcd->switchToMusic(mdata->Artist (),
     1029                           mdata->Album (),
     1030                           mdata->Title ());
     1031    }
     1032}
    10391033
    10401034void PlaybackBoxMusic::pause(void)
    10411035{
     
    12471241                    shuffle_button->setText(tr("Shuffle: Smart"));
    12481242            }
    12491243            music_tree_list->scrambleParents(true);
     1244
     1245            if (class LCD * lcd = LCD::Get ())
     1246                lcd->setMusicShuffle (LCD::MUSIC_SHUFFLE_SMART);
    12501247            break;
    12511248        case SHUFFLE_RANDOM:
    12521249            if(shuffle_button)
     
    12571254                    shuffle_button->setText(tr("Shuffle: Rand"));
    12581255            }
    12591256            music_tree_list->scrambleParents(true);
     1257
     1258            if (class LCD * lcd = LCD::Get ())
     1259                lcd->setMusicShuffle (LCD::MUSIC_SHUFFLE_RAND);
    12601260            break;
    12611261        default:
    12621262            if(shuffle_button)
     
    12671267                    shuffle_button->setText(tr("Shuffle: None"));
    12681268            }
    12691269            music_tree_list->scrambleParents(false);
     1270
     1271            if (class LCD * lcd = LCD::Get ())
     1272                lcd->setMusicShuffle (LCD::MUSIC_SHUFFLE_NONE);
    12701273            break;
    12711274    }
    12721275    music_tree_list->setTreeOrdering(shufflemode + 1);
     
    12751278    else
    12761279        music_tree_list->setVisualOrdering(1);
    12771280    music_tree_list->refresh();
     1281   
     1282    if (isplaying) {
     1283        setTrackOnLCD (curMeta);
     1284    }   
    12781285}
    12791286
    12801287void PlaybackBoxMusic::toggleShuffle(void)
     
    13251332                repeat_button->setText(tr("2 Repeat: All"));
    13261333            else
    13271334                repeat_button->setText(tr("Repeat: All"));
     1335
     1336            if (class LCD * lcd = LCD::Get ())
     1337                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
    13281338            break;
    13291339        case REPEAT_TRACK:
    13301340            if (keyboard_accelerators)
    13311341                repeat_button->setText(tr("2 Repeat: Track"));
    13321342            else
    13331343                repeat_button->setText(tr("Repeat: Track"));
     1344
     1345            if (class LCD * lcd = LCD::Get ())
     1346                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
    13341347            break;
    13351348        default:
    13361349            if (keyboard_accelerators)
    13371350                repeat_button->setText(tr("2 Repeat: None"));
    13381351            else
    13391352                repeat_button->setText(tr("Repeat: None"));
     1353
     1354            if (class LCD * lcd = LCD::Get ())
     1355                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_NONE);
    13401356            break;
    13411357    }
    13421358}
     
    14371453    {
    14381454        case OutputEvent::Playing:
    14391455        {
    1440             if (class LCD * lcd = LCD::Get()) {
    1441                 // Set track info on the LCD
    1442                 QPtrList<LCDTextItem> textItems;
    1443                 textItems.setAutoDelete(true);
    1444                 lcd->switchToMusic(curMeta->Artist (),
    1445                                    curMeta->Album (),
    1446                                    curMeta->Title ());
    1447             }
     1456            setTrackOnLCD (curMeta);
    14481457            statusString = tr("Playing stream.");
    14491458            break;
    14501459        }
     
    16131622        if (album_text)
    16141623            album_text->SetText(curMeta->Album());
    16151624
    1616         if (class LCD * lcd = LCD::Get())
    1617         {
    1618             // Set the Artist and Tract on the LCD
    1619             lcd->switchToMusic(curMeta->Artist (),
    1620                                curMeta->Album (),
    1621                                curMeta->Title ());
    1622         }
     1625        setTrackOnLCD (curMeta);
    16231626
    16241627        maxTime = curMeta->Length() / 1000;
    16251628
  • mythplugins/mythmusic/mythmusic/playbackbox.h

     
    100100    void updatePlaylistFromSmartPlaylist(QString category, QString name);
    101101    void CycleVisualizer(void);
    102102    void updatePlaylistFromCD(void);
     103    void setTrackOnLCD (Metadata *mdata);
    103104
    104105    void postUpdate();
    105106