diff --git a/src/gui/upnpbrowser.cpp b/src/gui/upnpbrowser.cpp index 48ed0808c..7f266416f 100644 --- a/src/gui/upnpbrowser.cpp +++ b/src/gui/upnpbrowser.cpp @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -50,26 +49,23 @@ #include #include -#include - #include -#include #include -#include +#include #include #include #include -#include #include #include -#include -#include - #include +#include +#include #include + extern cVideo * videoDecoder; +extern CPictureViewer * g_PicViewer; const struct button_label RescanButton = {NEUTRINO_ICON_BUTTON_BLUE , LOCALE_UPNPBROWSER_RESCAN}; const struct button_label BrowseButtons[4] = @@ -80,51 +76,37 @@ const struct button_label BrowseButtons[4] = { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_AUDIOPLAYER_PLAY } }; -//------------------------------------------------------------------------ - CUpnpBrowserGui::CUpnpBrowserGui() { m_socket = new CUPnPSocket(); m_frameBuffer = CFrameBuffer::getInstance(); m_playing_entry_is_shown = false; + dline = NULL; } -//------------------------------------------------------------------------ - CUpnpBrowserGui::~CUpnpBrowserGui() { delete m_socket; + delete dline; } -//------------------------------------------------------------------------ - int CUpnpBrowserGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/) { - CAudioPlayer::getInstance()->init(); if (parent) - { parent->hide(); - } g_Zapit->stopPlayBack(); + //g_Zapit->lockPlayBack(); + CZapit::getInstance()->EnablePlayback(false); videoDecoder->ShowPicture(DATADIR "/neutrino/icons/mp3.jpg"); // tell neutrino we're in audio mode - CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , NeutrinoMessages::mode_audio ); + CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE , NeutrinoMessages::mode_audio); + // remember last mode -#if 0 - CZapitClient::responseGetLastChannel firstchannel; - g_Zapit->getLastChannel(firstchannel.channelNumber, firstchannel.mode); - if ((firstchannel.mode == 'r') ? - (CNeutrinoApp::getInstance()->zapto_radio_on_init_done) : - (CNeutrinoApp::getInstance()->zapto_tv_on_init_done)) - m_LastMode=(CNeutrinoApp::getInstance()->getLastMode() | NeutrinoMessages::norezap); - else - m_LastMode=(CNeutrinoApp::getInstance()->getLastMode()); -#endif m_LastMode=(CNeutrinoApp::getInstance()->getLastMode()); m_width = m_frameBuffer->getScreenWidthRel(); @@ -140,16 +122,17 @@ int CUpnpBrowserGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/ m_listmaxshow = (m_height - m_info_height - m_title_height - m_theight - 2*m_buttonHeight) / (m_fheight); m_height = m_theight + m_info_height + m_title_height + 2*m_buttonHeight + m_listmaxshow * m_fheight; // recalc height - m_x=getScreenStartX( m_width ); + m_x=getScreenStartX(m_width); if (m_x < ConnectLineBox_Width) m_x = ConnectLineBox_Width; - m_y=getScreenStartY( m_height ); + m_y=getScreenStartY(m_height); // Stop sectionsd g_Sectionsd->setPauseScanning(true); - m_indexdevice=0; + m_deviceliststart=0; m_selecteddevice=0; + timeout = 0; selectDevice(); @@ -162,14 +145,14 @@ int CUpnpBrowserGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/ g_Sectionsd->setPauseScanning(false); videoDecoder->StopPicture(); - CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , m_LastMode ); - g_RCInput->postMsg( NeutrinoMessages::SHOW_INFOBAR, 0 ); + //g_Zapit->unlockPlayBack(); + CZapit::getInstance()->EnablePlayback(true); + CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE , m_LastMode); + g_RCInput->postMsg(NeutrinoMessages::SHOW_INFOBAR, 0); - return menu_return::RETURN_EXIT_ALL; + return menu_return::RETURN_REPAINT; } -//------------------------------------------------------------------------ - void CUpnpBrowserGui::splitProtocol(std::string &protocol, std::string &prot, std::string &network, std::string &mime, std::string &additional) { std::string::size_type pos; @@ -204,7 +187,59 @@ void CUpnpBrowserGui::splitProtocol(std::string &protocol, std::string &prot, st //printf("%s -> %s - %s - %s - %s\n", protocol.c_str(), prot.c_str(), network.c_str(), mime.c_str(), additional.c_str()); } -//------------------------------------------------------------------------ +bool CUpnpBrowserGui::discoverDevices() +{ + if (!m_devices.empty()) + return true; + + CHintBox *scanBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_UPNPBROWSER_SCANNING)); // UTF-8 + scanBox->paint(); + + try { + m_devices = m_socket->Discover("urn:schemas-upnp-org:service:ContentDirectory:1"); + } + catch (std::runtime_error error) + { + delete scanBox; + ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + return false; + } + delete scanBox; + if (m_devices.empty()) + { + ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, LOCALE_UPNPBROWSER_NOSERVERS, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + return false; + } + return true; +} + +bool CUpnpBrowserGui::getResults(std::string id, unsigned int start, unsigned int count, std::list &results) +{ + std::listattribs; + std::stringstream sindex; + std::stringstream scount; + + sindex << start; + scount << count; + + attribs.push_back(UPnPAttribute("ObjectID", id)); + attribs.push_back(UPnPAttribute("BrowseFlag", "BrowseDirectChildren")); + attribs.push_back(UPnPAttribute("Filter", "*")); + attribs.push_back(UPnPAttribute("StartingIndex", sindex.str())); + attribs.push_back(UPnPAttribute("RequestedCount", scount.str())); + attribs.push_back(UPnPAttribute("SortCriteria", "")); + + try + { + results=m_devices[m_selecteddevice].SendSOAP("urn:schemas-upnp-org:service:ContentDirectory:1", "Browse", attribs); + } + catch (std::runtime_error error) + { + ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + return false; + } + return true; +} std::vector *CUpnpBrowserGui::decodeResult(std::string result) { @@ -323,7 +358,11 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) splitProtocol(protocol, prot, network, mime, additional); if (prot != "http-get") continue; -#if 0 + + if (mime.substr(0,6) == "image/" && pref < 1) + { + preferred=i; + } if (mime == "image/jpeg" && pref < 1) { preferred=i; @@ -334,7 +373,6 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) preferred=i; pref=2; } -#endif if (mime == "audio/mpeg" && pref < 3) { preferred=i; @@ -345,6 +383,26 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) preferred=i; pref=4; } + if (mime == "audio/x-flac" && pref < 5) + { + preferred=i; + pref=5; + } + if (mime.substr(0,6) == "video/" && pref < 6) + { + preferred=i; + pref=6; + } + if (mime == "video/x-flv" && pref < 7) + { + preferred=i; + pref=7; + } + if (mime == "video/mp4" && pref < 8) + { + preferred=i; + pref=8; + } } } p = node->GetAttributeValue("id"); @@ -366,109 +424,99 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) return entries; } -//------------------------------------------------------------------------ +void CUpnpBrowserGui::updateDeviceSelection(int newpos) +{ + if((int) m_selecteddevice != newpos) { + int prev_selected = m_selecteddevice; + unsigned int oldliststart = m_deviceliststart; + + m_selecteddevice = newpos; + m_deviceliststart = (m_selecteddevice/m_listmaxshow)*m_listmaxshow; + if (oldliststart != m_deviceliststart) + paintDevices(); + else { + paintDevice(prev_selected - m_deviceliststart); + paintDevice(m_selecteddevice - m_deviceliststart); + } + } +} void CUpnpBrowserGui::selectDevice() { bool loop = true; - bool changed = true; + bool refresh = true; neutrino_msg_t msg; neutrino_msg_data_t data; - CHintBox *scanBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_UPNPBROWSER_SCANNING)); // UTF-8 - scanBox->paint(); -#if 0 - try { - m_devices = m_socket->Discover("urn:schemas-upnp-org:service:ContentDirectory:1"); - } - catch (std::runtime_error error) - { - delete scanBox; - ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + if (!discoverDevices()) return; - } -#endif - m_devices = m_socket->Discover("urn:schemas-upnp-org:service:ContentDirectory:1"); - scanBox->hide(); - - if (m_devices.empty()) - { - ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, LOCALE_UPNPBROWSER_NOSERVERS, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); - delete scanBox; - return; - } CAudioMute::getInstance()->enableMuteIcon(false); while (loop) { - if (changed) + if (refresh) { - paintDevice(); - changed=false; + paintDevices(); + refresh=false; } g_RCInput->getMsg(&msg, &data, 10); // 1 sec timeout to update play/stop state display neutrino_msg_t msg_repeatok = msg & ~CRCInput::RC_Repeat; - if ( msg == CRCInput::RC_timeout) + if (msg == CRCInput::RC_timeout) { // nothing } - - else if ( msg == CRCInput::RC_home) + else if (msg == CRCInput::RC_home) { loop=false; } - - else if (msg_repeatok == CRCInput::RC_up && m_selecteddevice > 0) - { - m_selecteddevice--; - if (m_selecteddevice < m_indexdevice) - m_indexdevice-=m_listmaxshow; - changed=true; + else if (msg_repeatok == (neutrino_msg_t) g_settings.key_list_start) { + updateDeviceSelection(0); } - - else if (msg_repeatok == CRCInput::RC_down && m_selecteddevice + 1 < m_devices.size()) - { - m_selecteddevice++; - if (m_selecteddevice + 1 > m_indexdevice + m_listmaxshow) - m_indexdevice+=m_listmaxshow; - changed=true; + else if (msg_repeatok == (neutrino_msg_t) g_settings.key_list_end) { + updateDeviceSelection(m_devices.size()-1); } - - else if ( msg == CRCInput::RC_right || msg == CRCInput::RC_ok) + else if (msg_repeatok == CRCInput::RC_up || (int) msg == g_settings.key_channelList_pageup) + { + int step = ((int) msg == g_settings.key_channelList_pageup) ? m_listmaxshow : 1; // browse or step 1 + int new_selected = m_selecteddevice - step; + if (new_selected < 0) { + if (m_selecteddevice != 0 && step != 1) + new_selected = 0; + else + new_selected = m_devices.size() - 1; + } + updateDeviceSelection(new_selected); + } + else if (msg_repeatok == CRCInput::RC_down || (int) msg == g_settings.key_channelList_pagedown) + { + int step = ((int) msg == g_settings.key_channelList_pagedown) ? m_listmaxshow : 1; // browse or step 1 + int new_selected = m_selecteddevice + step; + if (new_selected >= (int) m_devices.size()) { + if ((m_devices.size() - m_listmaxshow -1 < m_selecteddevice) && (m_selecteddevice != (m_devices.size() - 1)) && (step != 1)) + new_selected = m_devices.size() - 1; + else if (((m_devices.size() / m_listmaxshow) + 1) * m_listmaxshow == m_devices.size() + m_listmaxshow) // last page has full entries + new_selected = 0; + else + new_selected = ((step == (int) m_listmaxshow) && (new_selected < (int) (((m_devices.size() / m_listmaxshow)+1) * m_listmaxshow))) ? (m_devices.size() - 1) : 0; + } + updateDeviceSelection(new_selected); + } + else if (msg == CRCInput::RC_right || msg == CRCInput::RC_ok) { m_folderplay = false; selectItem("0"); - changed=true; + refresh=true; } - - else if ( msg == CRCInput::RC_blue) + else if (msg == CRCInput::RC_blue) { - scanBox->paint(); -#if 0 - try { - m_devices = m_socket->Discover("urn:schemas-upnp-org:service:ContentDirectory:1"); - } - catch (std::runtime_error error) - { - delete scanBox; - ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + m_devices.clear(); + if (!discoverDevices()) return; - } -#endif - m_devices = m_socket->Discover("urn:schemas-upnp-org:service:ContentDirectory:1"); - scanBox->hide(); - if (m_devices.empty()) - { - ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, LOCALE_UPNPBROWSER_NOSERVERS, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); - delete scanBox; - return; - } - changed=true; + refresh=true; } - else if (msg == NeutrinoMessages::RECORD_START || msg == NeutrinoMessages::ZAPTO || msg == NeutrinoMessages::STANDBY_ON || @@ -478,57 +526,34 @@ void CUpnpBrowserGui::selectDevice() loop=false; g_RCInput->postMsg(msg, data); } - else if (msg == NeutrinoMessages::EVT_TIMER) { - CNeutrinoApp::getInstance()->handleMsg( msg, data ); + CNeutrinoApp::getInstance()->handleMsg(msg, data); } - - else + else if (msg > CRCInput::RC_MaxRC) { - if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) + if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::cancel_all) loop = false; - changed=true; } } - delete scanBox; - CAudioMute::getInstance()->enableMuteIcon(true); } -//------------------------------------------------------------------------ - void CUpnpBrowserGui::playnext(void) { + std::vector *entries = NULL; while (true) { - std::listattribs; + timeout = 0; + std::listresults; std::list::iterator i; - std::stringstream sindex; - std::vector *entries = NULL; - sindex << m_playid; - attribs.push_back(UPnPAttribute("ObjectID", m_playfolder)); - attribs.push_back(UPnPAttribute("BrowseFlag", "BrowseDirectChildren")); - attribs.push_back(UPnPAttribute("Filter", "*")); - attribs.push_back(UPnPAttribute("StartingIndex", sindex.str())); - attribs.push_back(UPnPAttribute("RequestedCount", "1")); - attribs.push_back(UPnPAttribute("SortCriteria", "")); - -#if 0 - try - { - results=m_devices[m_selecteddevice].SendSOAP("urn:schemas-upnp-org:service:ContentDirectory:1", "Browse", attribs); - } - catch (std::runtime_error error) - { - ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); + printf("playnext: getResults m_playfolder %s m_playid %d\n", m_playfolder.c_str(), m_playid); + if (!getResults(m_playfolder, m_playid, 1, results)) { m_folderplay = false; return; } -#endif - results=m_devices[m_selecteddevice].SendSOAP("urn:schemas-upnp-org:service:ContentDirectory:1", "Browse", attribs); for (i=results.begin(); i!=results.end(); ++i) { if (i->first=="NumberReturned") @@ -539,15 +564,12 @@ void CUpnpBrowserGui::playnext(void) return; } } - if (i->first=="TotalMatches") - { - } - if (i->first=="Result") + else if (i->first=="Result") { entries=decodeResult(i->second); } } - m_playid++; + //m_playid++; if ((entries != NULL) && (!(*entries)[0].isdir)) { int preferred=(*entries)[0].preferred; @@ -556,285 +578,252 @@ void CUpnpBrowserGui::playnext(void) std::string protocol, prot, network, mime, additional; protocol=(*entries)[0].resources[preferred].protocol; splitProtocol(protocol, prot, network, mime, additional); - if (mime == "audio/mpeg") - { + if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac") { m_playing_entry = (*entries)[0]; m_playing_entry_is_shown = false; - CAudiofile mp3((*entries)[0].resources[preferred].url, CFile::FILE_MP3); - CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); - return; + playAudio((*entries)[0].resources[preferred].url, mime); } - else if (mime == "audio/x-vorbis+ogg") - { - m_playing_entry = (*entries)[0]; - m_playing_entry_is_shown = false; - CAudiofile mp3((*entries)[0].resources[preferred].url, CFile::FILE_OGG); - CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); - return; + else if (mime.substr(0,6) == "video/") { + playVideo((*entries)[0].title, (*entries)[0].resources[preferred].url); + m_folderplay = false; // FIXME else no way to stop in video folder } + else if (mime.substr(0,6) == "image/") { + if (m_folderplay) + timeout = time(NULL) + atoi(g_settings.picviewer_slide_time); + showPicture((*entries)[0].resources[preferred].url); + } + return; } } else { neutrino_msg_t msg; neutrino_msg_data_t data; g_RCInput->getMsg(&msg, &data, 10); // 1 sec timeout to update play/stop state display - if ( msg == CRCInput::RC_home) + if (msg == CRCInput::RC_home) { m_folderplay = false; break; } } } + delete entries; + m_frameBuffer->Clear(); } -//------------------------------------------------------------------------ +bool CUpnpBrowserGui::getItems(std::string id, unsigned int index, std::vector * &entries, unsigned int &total) +{ + bool tfound = false; + bool rfound = false; + bool nfound = false; + unsigned int returned = 0; + std::listresults; + std::list::iterator i; + + delete entries; + entries = NULL; + + printf("getItems: getResults: index %d count %d\n", index, m_listmaxshow); + if (!getResults(id, index, m_listmaxshow, results)) + return false; + + for (i=results.begin(); i!=results.end(); ++i) { + if (i->first=="NumberReturned") { + returned=atoi(i->second.c_str()); + nfound=true; + } else if (i->first=="TotalMatches") { + total=atoi(i->second.c_str()); + tfound=true; + } else if (i->first=="Result") { + entries=decodeResult(i->second); + rfound=true; + } + } + if (!entries || !nfound || !tfound || !rfound || returned != entries->size() || returned == 0) + return false; + + return true; +} + +bool CUpnpBrowserGui::updateItemSelection(std::string id, std::vector * &entries, int newpos, unsigned int &selected, unsigned int &liststart) +{ + if((int) selected != newpos) { + int prev_selected = selected; + unsigned int oldliststart = liststart; + + selected = newpos; + liststart = (selected/m_listmaxshow)*m_listmaxshow; + printf("updateItemSelection: list start old %d new %d selected old %d new %d\n", oldliststart, liststart, prev_selected, selected); + if (oldliststart != liststart) { + unsigned int total; + if (!getItems(id, liststart, entries, total)) + return false; + paintItems(entries, selected - liststart, total - liststart, liststart); + } else { + paintItem(entries, prev_selected - liststart, selected - liststart); + paintItem(entries, selected - liststart, selected - liststart); + } + } + return true; +} bool CUpnpBrowserGui::selectItem(std::string id) { bool loop = true; bool endall = false; - bool changed = true; - bool rchanged = true; + bool refresh = true; neutrino_msg_t msg; neutrino_msg_data_t data; std::vector *entries = NULL; - unsigned int index, selected, dirnum; - index=0; - selected=0; - dirnum=0; - - while (loop) - { + unsigned int liststart = 0; + unsigned int selected = 0; + unsigned int total = 0; + + printf("selectItem: [%s]\n", id.c_str()); + if (!getItems(id, liststart, entries, total)) + return endall; + + while (loop) { updateTimes(); - if (rchanged) - { - std::listattribs; - std::listresults; - std::list::iterator i; - std::stringstream sindex; - std::stringstream scount; - unsigned int returned = 0; - bool rfound = false; - bool nfound = false; - bool tfound = false; - - sindex << index; - scount << m_listmaxshow; - - attribs.push_back(UPnPAttribute("ObjectID", id)); - attribs.push_back(UPnPAttribute("BrowseFlag", "BrowseDirectChildren")); - attribs.push_back(UPnPAttribute("Filter", "*")); - attribs.push_back(UPnPAttribute("StartingIndex", sindex.str())); - attribs.push_back(UPnPAttribute("RequestedCount", scount.str())); - attribs.push_back(UPnPAttribute("SortCriteria", "")); -#if 0 - try - { - results=m_devices[m_selecteddevice].SendSOAP("urn:schemas-upnp-org:service:ContentDirectory:1", "Browse", attribs); - } - catch (std::runtime_error error) - { - ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, error.what(), CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO); - if (entries) - delete entries; - return endall; - } -#endif - results=m_devices[m_selecteddevice].SendSOAP("urn:schemas-upnp-org:service:ContentDirectory:1", "Browse", attribs); - for (i=results.begin(); i!=results.end(); ++i) - { - if (i->first=="NumberReturned") - { - returned=atoi(i->second.c_str()); - nfound=true; - } - if (i->first=="TotalMatches") - { - dirnum=atoi(i->second.c_str()); - tfound=true; - } - if (i->first=="Result") - { - entries=decodeResult(i->second); - rfound=true; - } - } - if (!entries) - return endall; - if (!nfound || !tfound || !rfound) - { - delete entries; - return endall; - } - if (returned != entries->size()) - { - delete entries; - return endall; - } - - if (returned == 0) - { - delete entries; - return endall; - } - rchanged=false; - changed=true; - } - - if (changed) - { - paintItem(entries, selected - index, dirnum - index, index); - changed=false; + if (refresh) { + printf("selectItem: refresh, timeout = %d\n", (int) timeout); + if (!timeout) + paintItems(entries, selected - liststart, total - liststart, liststart); + refresh=false; } g_RCInput->getMsg(&msg, &data, 10); // 1 sec timeout to update play/stop state display neutrino_msg_t msg_repeatok = msg & ~CRCInput::RC_Repeat; - if ( msg == CRCInput::RC_timeout) - { + if (msg == CRCInput::RC_timeout) { // nothing } - else if (msg == CRCInput::RC_home) - { + else if (msg == CRCInput::RC_home) { loop=false; endall=true; } - else if (msg == CRCInput::RC_left) - { + else if (!timeout && (msg == CRCInput::RC_left)) { loop=false; } - - else if (msg_repeatok == CRCInput::RC_up && selected > 0) - { - selected--; - if (selected < index) - { - index-=m_listmaxshow; - rchanged=true; - } - changed=true; + else if (!timeout && (msg_repeatok == (neutrino_msg_t) g_settings.key_list_start)) { + updateItemSelection(id, entries, 0, selected, liststart); } - - else if (msg == CRCInput::RC_green && selected > 0) - { - if (index > 0) - { - index-=m_listmaxshow; - selected-=m_listmaxshow; - rchanged=true; - } - else - selected=0; - changed=true; + else if (!timeout && (msg_repeatok == (neutrino_msg_t) g_settings.key_list_end)) { + updateItemSelection(id, entries, total-1, selected, liststart); } - - else if (msg_repeatok == CRCInput::RC_down && selected + 1 < dirnum) - { - selected++; - if (selected + 1 > index + m_listmaxshow) - { - index+=m_listmaxshow; - rchanged=true; + else if (!timeout && (msg_repeatok == CRCInput::RC_up || (int) msg == g_settings.key_channelList_pageup)) { + int step = ((int) msg == g_settings.key_channelList_pageup) ? m_listmaxshow : 1; // browse or step 1 + int new_selected = selected - step; + if (new_selected < 0) { + if (selected != 0 && step != 1) + new_selected = 0; + else + new_selected = total - 1; } - changed=true; + updateItemSelection(id, entries, new_selected, selected, liststart); } - - else if (msg == CRCInput::RC_red && selected + 1 < dirnum) - { - if (index < ((dirnum - 1) / m_listmaxshow) * m_listmaxshow) - { - index+=m_listmaxshow; - selected+=m_listmaxshow; - if (selected + 1 >= dirnum) - selected=dirnum - 1; - rchanged=true; + else if (!timeout && (msg_repeatok == CRCInput::RC_down || (int) msg == g_settings.key_channelList_pagedown)) { + int step = ((int) msg == g_settings.key_channelList_pagedown) ? m_listmaxshow : 1; // browse or step 1 + int new_selected = selected + step; + if (new_selected >= (int) total) { + if ((total - m_listmaxshow -1 < selected) && (selected != (total - 1)) && (step != 1)) + new_selected = total - 1; + else if (((total / m_listmaxshow) + 1) * m_listmaxshow == total + m_listmaxshow) // last page has full entries + new_selected = 0; + else + new_selected = ((step == (int) m_listmaxshow) && (new_selected < (int) (((total / m_listmaxshow)+1) * m_listmaxshow))) ? (total - 1) : 0; } - else - selected=dirnum - 1; - changed=true; + updateItemSelection(id, entries, new_selected, selected, liststart); } - - else if (msg == CRCInput::RC_right) - { - if ((*entries)[selected - index].isdir) - { - endall=selectItem((*entries)[selected - index].id); + else if (!timeout && (msg == CRCInput::RC_ok || msg == CRCInput::RC_right)) { + if ((*entries)[selected - liststart].isdir) { + endall=selectItem((*entries)[selected - liststart].id); if (endall) loop=false; - } - changed=true; - } - else if (msg == CRCInput::RC_ok) - { - if (!(*entries)[selected - index].isdir) - { + refresh=true; + } else { m_folderplay = false; - int preferred=(*entries)[selected - index].preferred; + int preferred=(*entries)[selected - liststart].preferred; if (preferred != -1) { std::string protocol, prot, network, mime, additional; - protocol=(*entries)[selected - index].resources[preferred].protocol; + protocol=(*entries)[selected - liststart].resources[preferred].protocol; splitProtocol(protocol, prot, network, mime, additional); - if (mime == "audio/mpeg") + if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac") { - CAudiofile mp3((*entries)[selected - index].resources[preferred].url, CFile::FILE_MP3); - CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); + m_playing_entry = (*entries)[selected - liststart]; + m_playing_entry_is_shown = false; + playAudio((*entries)[selected - liststart].resources[preferred].url, mime); } - else if (mime == "audio/x-vorbis+ogg") + else if (mime.substr(0,6) == "video/") { - CAudiofile mp3((*entries)[selected - index].resources[preferred].url, CFile::FILE_OGG); - CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); - } - m_playing_entry = (*entries)[selected - index]; -#if 0 // TODO ! -// #ifdef ENABLE_PICTUREVIEWER - else if ((mime == "image/gif") || (mime == "image/jpeg")) - { - CPictureViewer *viewer = new CPictureViewer(); - bool loop=true; - viewer->SetScaling((CPictureViewer::ScalingMode)g_settings.picviewer_scaling); - viewer->SetVisible(g_settings.screen_StartX, g_settings.screen_EndX, g_settings.screen_StartY, g_settings.screen_EndY); - - if (g_settings.video_Format==1) - viewer->SetAspectRatio(16.0/9); - else - viewer->SetAspectRatio(4.0/3); - - m_frameBuffer->setMode(720, 576, 16); - m_frameBuffer->setTransparency(0); - viewer->ShowImage((*entries)[selected - index].resources[preferred].url, true); - while (loop) - { - g_RCInput->getMsg(&msg, &data, 10); // 1 sec timeout to update play/stop state display - - if ( msg == CRCInput::RC_home) - loop=false; - } - m_frameBuffer->setMode(720, 576, 8 * sizeof(fb_pixel_t)); m_frameBuffer->Clear(); - delete viewer; + playVideo((*entries)[selected - liststart].title, (*entries)[selected - liststart].resources[preferred].url); + videoDecoder->ShowPicture(DATADIR "/neutrino/icons/mp3.jpg"); + refresh = true; } -// #endif -#endif - } + else if (mime.substr(0,6) == "image/") + { + videoDecoder->setBlank(true); + showPicture((*entries)[selected - liststart].resources[preferred].url); + m_playid = selected; + while (true) + { + g_RCInput->getMsg(&msg, &data, 10); // 1 sec timeout - } else { - m_folderplay = true; - m_playfolder = (*entries)[selected - index].id; - m_playid = 0; - playnext(); + if (msg == CRCInput::RC_home || msg == CRCInput::RC_ok) + break; + else if (msg == CRCInput::RC_right || msg == CRCInput::RC_down) { + m_playfolder = id; + m_playid = (m_playid + 1)%total; + playnext(); + } + else if (msg == CRCInput::RC_left || msg == CRCInput::RC_up) { + m_playfolder = id; + m_playid--; + if (m_playid < 0) + m_playid = total - 1; + playnext(); + } else + CNeutrinoApp::getInstance()->handleMsg(msg, data); + } + m_frameBuffer->Clear(); + videoDecoder->setBlank(false); + refresh = true; + } + } } - changed=true; } - else if ( msg == CRCInput::RC_yellow) - { + else if (msg == CRCInput::RC_play) { + m_folderplay = true; + m_playfolder = (*entries)[selected - liststart].id; + m_playid = 0; + playnext(); + m_playid++; + } + else if (msg == CRCInput::RC_yellow) { if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) CAudioPlayer::getInstance()->stop(); m_folderplay = false; } - + else if (m_folderplay && msg == (neutrino_msg_t) CRCInput::RC_stop) { + timeout = 0; + m_folderplay = false; + m_frameBuffer->Clear(); + refresh = true; + } + else if (m_folderplay && msg == (neutrino_msg_t) CRCInput::RC_prev) { + timeout = 0; + m_playid -= 2; + if (m_playid < 0) + m_playid = 0; + } + else if (m_folderplay && msg == (neutrino_msg_t) CRCInput::RC_next) { + timeout = 0; + if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) + CAudioPlayer::getInstance()->stop(); + } else if (msg == NeutrinoMessages::RECORD_START || msg == NeutrinoMessages::ZAPTO || msg == NeutrinoMessages::STANDBY_ON || @@ -844,39 +833,80 @@ bool CUpnpBrowserGui::selectItem(std::string id) loop = false; g_RCInput->postMsg(msg, data); } - else if (msg == NeutrinoMessages::EVT_TIMER) { - CNeutrinoApp::getInstance()->handleMsg( msg, data ); + CNeutrinoApp::getInstance()->handleMsg(msg, data); } - - else + else if (msg > CRCInput::RC_MaxRC) { - if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) + if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::cancel_all) loop = false; - changed=true; + //refresh=true; } - if (m_folderplay && (CAudioPlayer::getInstance()->getState() == CBaseDec::STOP)) + if (m_folderplay && ((!timeout || (timeout <= time(NULL))) && (CAudioPlayer::getInstance()->getState() == CBaseDec::STOP))) { playnext(); + m_playid++; + } } - if (entries) - delete entries; + + delete entries; + timeout = 0; + m_frameBuffer->Clear(); + return endall; } -//------------------------------------------------------------------------ - -void CUpnpBrowserGui::paintDevicePos(unsigned int pos) +void CUpnpBrowserGui::paintDeviceInfo() { - int ypos = m_y + m_title_height + m_theight + pos*m_fheight; + std::string tmp; + int w, xstart; + + CVFD::getInstance()->showMenuText(0, m_devices[m_selecteddevice].friendlyname.c_str(), -1, true); + + // Info + m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6, RADIUS_MID); + m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, RADIUS_MID); + + // first line + tmp = m_devices[m_selecteddevice].manufacturer + " " + + m_devices[m_selecteddevice].manufacturerurl; + w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 + w = std::min(w, m_width - 20); + xstart = (m_width - w) / 2; + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 1*m_mheight, m_width - 20, + tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 + + // second line + tmp = m_devices[m_selecteddevice].modelname + " " + + m_devices[m_selecteddevice].modelnumber + " " + + m_devices[m_selecteddevice].modeldescription; + w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 + w = std::min(w, m_width - 20); + xstart = (m_width - w) / 2; + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 2*m_mheight, m_width - 20, + tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 + // third line + tmp = m_devices[m_selecteddevice].modelurl; + w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 + w = std::min(w, m_width - 20); + xstart = (m_width - w) / 2; + g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 3*m_mheight, m_width - 20, + tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 +} + +void CUpnpBrowserGui::paintDevice(unsigned int _pos) +{ + int ypos = m_y + m_title_height + m_theight + _pos*m_fheight; fb_pixel_t color; fb_pixel_t bgcolor; + unsigned int pos = m_deviceliststart + _pos; if (pos == m_selecteddevice) { color = COL_MENUCONTENT_TEXT_PLUS_2; bgcolor = COL_MENUCONTENT_PLUS_2; + paintDeviceInfo(); } else { @@ -885,14 +915,14 @@ void CUpnpBrowserGui::paintDevicePos(unsigned int pos) } m_frameBuffer->paintBoxRel(m_x, ypos, m_width - 15, m_fheight, bgcolor); - if (pos + m_indexdevice >= m_devices.size()) + if (pos >= m_devices.size()) return; char sNr[20]; sprintf(sNr, "%2d", pos + 1); std::string num = sNr; - std::string name = m_devices[pos + m_indexdevice].friendlyname; + std::string name = m_devices[pos].friendlyname; int w = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getRenderWidth(name) + 5; g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(m_x + 10, ypos + m_fheight, m_width - 30 - w, @@ -901,9 +931,44 @@ void CUpnpBrowserGui::paintDevicePos(unsigned int pos) w, name, color, m_fheight, true); // UTF-8 } -//------------------------------------------------------------------------ +void CUpnpBrowserGui::paintDevices() +{ + std::string tmp; + int ypos, top; -void CUpnpBrowserGui::paintItemPos(std::vector *entry, unsigned int pos, unsigned int selected) + // LCD + CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, "Select UPnP Device"); + + // Head + CComponentsHeader header(m_x, m_y + m_title_height, m_width, m_theight, LOCALE_UPNPBROWSER_HEAD, NEUTRINO_ICON_UPNP); + if (CNeutrinoApp::getInstance()->isMuted()) + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL); + header.paint(CC_SAVE_SCREEN_NO); + + // Items + for (unsigned int count=0; countpaintBoxRel(m_x + m_width - 15, ypos, 15, sb, COL_MENUCONTENT_PLUS_1); + + int sbc = ((m_devices.size() - 1) / m_listmaxshow) + 1; + int sbs = ((m_selecteddevice) / m_listmaxshow); + + m_frameBuffer->paintBoxRel(m_x + m_width - 13, ypos + 2 + sbs*(sb-4)/sbc, 11, (sb-4)/sbc, COL_MENUCONTENT_PLUS_3); + + // Foot + top = m_y + (m_height - m_info_height - 2 * m_buttonHeight); + + m_frameBuffer->paintBoxRel(m_x, top, m_width, m_buttonHeight+2, COL_INFOBAR_SHADOW_PLUS_1, RADIUS_LARGE, CORNER_BOTTOM); +// m_frameBuffer->paintHLine(m_x, m_x + m_width, top, COL_INFOBAR_SHADOW_PLUS_0); + ::paintButtons(m_x, top, 0, 1, &RescanButton, m_width, m_buttonHeight); + + paintItem2DetailsLine (-1); // clear it +} + +void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, unsigned int selected) { int ypos = m_y + m_title_height + m_theight + pos*m_fheight; fb_pixel_t color; @@ -913,11 +978,12 @@ void CUpnpBrowserGui::paintItemPos(std::vector *entry, unsigned int p { color = COL_MENUCONTENT_TEXT_PLUS_2; bgcolor = COL_MENUCONTENT_PLUS_2; + paintItemInfo(entry, selected); paintDetails(entry, pos); if ((*entry)[pos].isdir) - paintItem2DetailsLine (-1, pos); // clear it + paintItem2DetailsLine (-1); // clear it else - paintItem2DetailsLine (pos, pos); + paintItem2DetailsLine (pos); } else { @@ -960,100 +1026,21 @@ void CUpnpBrowserGui::paintItemPos(std::vector *entry, unsigned int p w, info, color, m_fheight); g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(m_x + 30, ypos + m_fheight, m_width - 50 - w, name, color, m_fheight, true); // UTF-8 - } -//------------------------------------------------------------------------ - -void CUpnpBrowserGui::paintDevice() -{ - std::string tmp; - int w, xstart, ypos, top; - int c_rad_mid = RADIUS_MID; - - // LCD - CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, "Select UPnP Device"); - CVFD::getInstance()->showMenuText(0, m_devices[m_selecteddevice].friendlyname.c_str(), -1, true); - - // Info - m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6, c_rad_mid); - m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, c_rad_mid); - - // first line - tmp = m_devices[m_selecteddevice].manufacturer + " " + - m_devices[m_selecteddevice].manufacturerurl; - w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 1*m_mheight, m_width - 20, - tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 - - // second line - tmp = m_devices[m_selecteddevice].modelname + " " + - m_devices[m_selecteddevice].modelnumber + " " + - m_devices[m_selecteddevice].modeldescription; - w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 2*m_mheight, m_width - 20, - tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 - // third line - tmp = m_devices[m_selecteddevice].modelurl; - w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 3*m_mheight, m_width - 20, - tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 - - // Head - CComponentsHeader header(m_x, m_y + m_title_height, m_width, m_theight, LOCALE_UPNPBROWSER_HEAD, NEUTRINO_ICON_UPNP, CComponentsHeader::CC_BTN_MENU); - if (CNeutrinoApp::getInstance()->isMuted()) - header.addButtonIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL); - header.paint(CC_SAVE_SCREEN_NO); - - // Items - for (unsigned int count=0; countpaintBoxRel(m_x + m_width - 15, ypos, 15, sb, COL_MENUCONTENT_PLUS_1); - - int sbc = ((m_devices.size() - 1) / m_listmaxshow) + 1; - int sbs = ((m_selecteddevice) / m_listmaxshow); - - m_frameBuffer->paintBoxRel(m_x + m_width - 13, ypos + 2 + sbs*(sb-4)/sbc, 11, (sb-4)/sbc, COL_MENUCONTENT_PLUS_3); - - // Foot - top = m_y + (m_height - m_info_height - 2 * m_buttonHeight); - - //int ButtonWidth = (m_width - 20) / 4; - m_frameBuffer->paintBoxRel(m_x, top, m_width, m_buttonHeight+2, COL_INFOBAR_SHADOW_PLUS_1, c_rad_mid, CORNER_BOTTOM); -// m_frameBuffer->paintHLine(m_x, m_x + m_width, top, COL_INFOBAR_SHADOW_PLUS_0); - ::paintButtons(m_x, top, 0, 1, &RescanButton, m_width, m_buttonHeight); - - clearItem2DetailsLine(); // clear it -} - -//------------------------------------------------------------------------ - -void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int selected, unsigned int max, unsigned int offset) +void CUpnpBrowserGui::paintItemInfo(std::vector *entry, unsigned int selected) { std::string tmp; std::stringstream ts; - int w, xstart, ypos, top; + int w, xstart; int preferred=(*entry)[selected].preferred; // LCD - CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, "Select UPnP Entry"); CVFD::getInstance()->showMenuText(0, (*entry)[selected].title.c_str(), -1, true); // Info - m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6); - m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0); + m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6, RADIUS_MID); + m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, RADIUS_MID); // first line ts << "Resources: " << (*entry)[selected].resources.size() << " Selected: " << preferred+1 << " "; @@ -1063,12 +1050,10 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int sele tmp = tmp + "Duration: " + (*entry)[selected].resources[preferred].duration; else tmp = tmp + "No resource for Item"; + w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - if (w > m_width - 20) - w = m_width - 20; + w = std::min(w, m_width - 20); xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 1*m_mheight, m_width - 20, tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 @@ -1084,61 +1069,45 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int sele splitProtocol((*entry)[selected].resources[preferred].protocol, proto, network, mime, info); tmp = "Protocol: " + proto + ", MIME-Type: " + mime; } - } w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - if (w > m_width - 20) - w = m_width - 20; + w = std::min(w, m_width - 20); xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 2*m_mheight, m_width - 20, tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 //third line tmp = ""; - if (!(*entry)[selected].isdir) - { - if (preferred != -1) - { - tmp = "URL: " + (*entry)[selected].resources[preferred].url; - } + if (!(*entry)[selected].isdir && preferred != -1) + tmp = "URL: " + (*entry)[selected].resources[preferred].url; - } w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 - if (w > m_width - 20) - w = m_width - 20; + w = std::min(w, m_width - 20); xstart = (m_width - w) / 2; - if (xstart < 10) - xstart = 10; g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 3*m_mheight, m_width - 20, tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 +} +void CUpnpBrowserGui::paintItems(std::vector *entry, unsigned int selected, unsigned int max, unsigned int offset) +{ +printf("CUpnpBrowserGui::paintItem:s selected %d max %d offset %d\n", selected, max, offset); + int ypos, top; + + // LCD + CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, "Select UPnP Entry"); // Head - tmp = g_Locale->getText(LOCALE_UPNPBROWSER_HEAD); - m_frameBuffer->paintBoxRel(m_x, m_y + m_title_height, m_width, m_theight, COL_MENUHEAD_PLUS_0); - m_frameBuffer->paintIcon(NEUTRINO_ICON_UPNP, m_x + 7, m_y + m_title_height + 6); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(m_x + 35, m_y + m_theight + m_title_height + 0, - m_width - 45, tmp, COL_MENUHEAD_TEXT, 0, true); // UTF-8 - ypos = m_y + m_title_height; - if (m_theight > 26) - ypos = (m_theight - 26) / 2 + m_y + m_title_height; - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MENU, m_x + m_width - 30, ypos); -#if 0 - if ( CNeutrinoApp::getInstance()->isMuted() ) - { - xpos = m_x + m_width - 75; - ypos = m_y + m_title_height; - if (m_theight > 32) - ypos = (m_theight - 32) / 2 + m_y + m_title_height; - m_frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_MUTE, xpos, ypos); - } -#endif + std::string name = g_Locale->getText(LOCALE_UPNPBROWSER_HEAD); + name += " : "; + name += m_devices[m_selecteddevice].friendlyname; + CComponentsHeader header(m_x, m_y + m_title_height, m_width, m_theight, name, NEUTRINO_ICON_UPNP); + if (CNeutrinoApp::getInstance()->isMuted()) + header.addButtonIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL); + header.paint(CC_SAVE_SCREEN_NO); // Items for (unsigned int count=0; count *entry, unsigned int sele ::paintButtons(m_x, top, 0, 4, BrowseButtons, m_width, m_buttonHeight); } - -//------------------------------------------------------------------------ - void CUpnpBrowserGui::paintDetails(std::vector *entry, unsigned int index, bool use_playing) { // Foot info int top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2; int text_start = m_x + 10; +printf("paintDetails: index %d use_playing %d shown %d\n", index, use_playing, m_playing_entry_is_shown); if ((!use_playing) && ((*entry)[index].isdir)) { - m_frameBuffer->paintBackgroundBoxRel(m_x+2, top + 2, m_width-4, 2 * m_buttonHeight+8); + m_frameBuffer->paintBackgroundBoxRel(m_x+2, top + 2, m_width-4, 2 * m_buttonHeight+8); + m_playing_entry_is_shown = false; } else { -// char cNoch[50]; // UTF-8 -// char cSeit[50]; // UTF-8 int ih = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getHeight(); - m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE); - if (use_playing) + //m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE); + if (use_playing) { - if (!m_playing_entry_is_shown) + if (!m_playing_entry_is_shown) { m_playing_entry_is_shown = true; + m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE); g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, top + 1 * m_buttonHeight + 4, m_x + m_width - 8, m_playing_entry.title + " - " + m_playing_entry.artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, top + 2 * m_buttonHeight + 4, m_x + m_width - 8, m_playing_entry.album, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 } - } - else + } + else { if (entry == NULL) return; m_playing_entry_is_shown = false; + m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE); g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, top + 1 * m_buttonHeight + 4, m_x + m_width - 8, (*entry)[index].title + " - " + (*entry)[index].artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, top + 2 * m_buttonHeight + 4, m_x + m_width - 8, (*entry)[index].album, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 } -//// printf("title = %s\n", (*entry)[selected].title.c_str()); -// printf("artist = %s\n", (*entry)[selected].artist.c_str()); -// printf("album = %s\n", (*entry)[selected].album.c_str()); -// printf("children = %s\n", (*entry)[selected].children.c_str()); -// printf("id = %s\n", (*entry)[selected].id.c_str()); -#if 0 - struct tm *pStartZeit = localtime(&chanlist[index]->currentEvent.startTime); - unsigned seit = ( time(NULL) - chanlist[index]->currentEvent.startTime ) / 60; - sprintf( cSeit, g_Locale->getText(LOCALE_CHANNELLIST_SINCE), pStartZeit->tm_hour, pStartZeit->tm_min); //, seit ); - int seit_len = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]->getRenderWidth(cSeit, true); // UTF-8 - - int noch = ( chanlist[index]->currentEvent.startTime + chanlist[index]->currentEvent.duration - time(NULL) ) / 60; - if ( (noch< 0) || (noch>=10000) ) - noch= 0; - sprintf( cNoch, "(%d / %d min)", seit, noch ); - int noch_len = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth(cNoch, true); // UTF-8 - - std::string text1= chanlist[index]->currentEvent.description; - std::string text2= chanlist[index]->currentEvent.text; - - int xstart = 10; - if (g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getRenderWidth(text1) > (width - 30 - seit_len) ) - { - // zu breit, Umbruch versuchen... - int pos; - do - { - pos = text1.find_last_of("[ -.]+"); - if ( pos!=-1 ) - text1 = text1.substr( 0, pos ); - } while ( ( pos != -1 ) && (g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getRenderWidth(text1) > (width - 30 - seit_len) ) ); - - std::string text3= chanlist[index]->currentEvent.description.substr(text1.length()+ 1); - if (!(text2.empty())) - text3 += " . "; - - xstart += g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getRenderWidth(text3); - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x+ 10, y+ height+ 5+ 2* fheight, width - 30- noch_len, text3, COL_MENUCONTENTDARK_TEXT); - } - - if (!(text2.empty())) - { - while ( text2.find_first_of("[ -.+*#?=!$%&/]+") == 0 ) - text2 = text2.substr( 1 ); - text2 = text2.substr( 0, text2.find('\n') ); - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]->RenderString(x+ xstart, y+ height+ 5+ 2* fheight, width- xstart- 20- noch_len, text2, COL_MENUCONTENTDARK_TEXT); - } - - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x+ 10, y+ height+ 5+ fheight, width - 30 - seit_len, text1, COL_MENUCONTENTDARK_TEXT); - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]->RenderString (x+ width- 10- seit_len, y+ height+ 5+ fheight , seit_len, cSeit, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->RenderString(x+ width- 10- noch_len, y+ height+ 5+ 2* fheight- 2, noch_len, cNoch, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 -#endif - } } -//------------------------------------------------------------------------ - -// -// -- Decoreline to connect ChannelDisplayLine with ChannelDetail display -// -- 2002-03-17 rasc -// - -void CUpnpBrowserGui::clearItem2DetailsLine () +void CUpnpBrowserGui::paintItem2DetailsLine (int pos) { - paintItem2DetailsLine (-1, 0); -} + if (dline) { + dline->kill(); + delete dline; + dline = NULL; + } -//------------------------------------------------------------------------ + if (pos < 0) + return; -void CUpnpBrowserGui::paintItem2DetailsLine (int pos, unsigned int /*ch_index*/) -{ int xpos = m_x - ConnectLineBox_Width; int ypos1 = m_y + m_title_height+0 + m_theight + pos*m_fheight; int ypos2 = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2; int ypos1a = ypos1 + (m_fheight/2); int ypos2a = ypos2 + (m_info_height/2)-4; - fb_pixel_t col1 = COL_MENUCONTENT_PLUS_6; - fb_pixel_t col2 = COL_MENUCONTENT_PLUS_1; - // Clear - m_frameBuffer->paintBackgroundBoxRel(xpos, m_y + m_title_height, ConnectLineBox_Width, m_height+m_info_height-(m_y + m_title_height)); - if (pos < 0) - m_frameBuffer->paintBackgroundBoxRel(m_x, m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2, m_width, m_info_height); - - // paint Line if detail info (and not valid list pos) - if (pos >= 0) - { - // 1. col thick line - // vertical - int mh = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getHeight() +2; - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-4, ypos1, 4, m_fheight, col1); //left from item - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-4, ypos2 + mh/2, 4, mh, col1); //left from detailbox - - // long vertical line - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-15, ypos1a, 4, ypos2a-ypos1a, col1); - - // short horizontal lines - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-15, ypos1a, 12, 4, col1); - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-15, ypos2a, 12, 4, col1); - - // 2. col small line - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-4, ypos1, 1, m_fheight, col2); - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-4, ypos2 + mh/2, 1, mh, col2); - - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-15, ypos1a, 1, ypos2a-ypos1a+4, col2); - - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-15, ypos1a, 12, 1, col2); - m_frameBuffer->paintBoxRel(xpos+ConnectLineBox_Width-12, ypos2a, 8, 1, col2); - - // small Frame around infobox - m_frameBuffer->paintBoxFrame(m_x, ypos2, m_width, mh*2-2, 2, col1, RADIUS_LARGE); - } + dline = new CComponentsDetailLine(xpos, ypos1a, ypos2a, m_fheight/2+1, m_info_height-RADIUS_LARGE*2); + dline->paint(CC_SAVE_SCREEN_NO); } -//------------------------------------------------------------------------ - void CUpnpBrowserGui::updateTimes(const bool force) { int top; @@ -1329,6 +1204,8 @@ void CUpnpBrowserGui::updateTimes(const bool force) m_time_played = CAudioPlayer::getInstance()->getTimePlayed(); updatePlayed = true; } + +printf("updateTimes: force %d updatePlayed %d\n", force, updatePlayed); char play_time[8]; snprintf(play_time, 7, "%ld:%02ld", m_time_played / 60, m_time_played % 60); char tmp_time[] = "000:00"; @@ -1344,3 +1221,33 @@ void CUpnpBrowserGui::updateTimes(const bool force) } } +void CUpnpBrowserGui::playAudio(std::string name, std::string mime) +{ + CFile::FileType type = mime == "audio/mpeg" ? CFile::FILE_MP3 : mime == "audio/x-vorbis+ogg" ? CFile::FILE_OGG : CFile::FILE_FLAC; + CAudiofile mp3(name, type); + CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); +} + +void CUpnpBrowserGui::showPicture(std::string name) +{ + g_PicViewer->SetScaling((CPictureViewer::ScalingMode)g_settings.picviewer_scaling); + g_PicViewer->SetVisible(g_settings.screen_StartX, g_settings.screen_EndX, g_settings.screen_StartY, g_settings.screen_EndY); + + if (g_settings.video_Format==3) + g_PicViewer->SetAspectRatio(16.0/9); + else + g_PicViewer->SetAspectRatio(4.0/3); + + g_PicViewer->ShowImage(name, false); + g_PicViewer->Cleanup(); +} + +void CUpnpBrowserGui::playVideo(std::string name, std::string url) +{ + if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) + CAudioPlayer::getInstance()->stop(); + + videoDecoder->StopPicture(); + CMoviePlayerGui::getInstance().SetFile(name, url); + CMoviePlayerGui::getInstance().exec(NULL, "upnp"); +} diff --git a/src/gui/upnpbrowser.h b/src/gui/upnpbrowser.h index c4495d5fc..4014ff6aa 100644 --- a/src/gui/upnpbrowser.h +++ b/src/gui/upnpbrowser.h @@ -81,7 +81,7 @@ class CUpnpBrowserGui : public CMenuTarget int m_x; int m_y; unsigned int m_listmaxshow; - unsigned int m_indexdevice; + unsigned int m_deviceliststart; unsigned int m_selecteddevice; int m_fheight; // Fonthoehe Inhalt int m_theight; // Fonthoehe Titel @@ -95,21 +95,34 @@ class CUpnpBrowserGui : public CMenuTarget int m_playid; time_t m_time_played; bool m_playing_entry_is_shown; + time_t timeout; + CComponentsDetailLine * dline; - void selectDevice(); - bool selectItem(std::string); - void paintItem(std::vector *entry, unsigned int selected, unsigned int max, unsigned int offset); - void paintDevice(); - std::vector *decodeResult(std::string); - void playnext(); + bool discoverDevices(); void splitProtocol(std::string &protocol, std::string &prot, std::string &network, std::string &mime, std::string &additional); - void paintItemPos (std::vector *entry, unsigned int pos, unsigned int selected); - void paintDevicePos(unsigned int pos); + bool getResults(std::string id, unsigned int start, unsigned int count, std::list &results); + std::vector *decodeResult(std::string); + + void updateDeviceSelection(int newpos); + void selectDevice(); + void paintDevices(); + void paintDevice(unsigned int pos); + void paintDeviceInfo(); + void playnext(); + + bool getItems(std::string id, unsigned int index, std::vector * &entries, unsigned int &total); + bool updateItemSelection(std::string id, std::vector * &entries, int newpos, unsigned int &selected, unsigned int &liststart); + bool selectItem(std::string); + void paintItems(std::vector *entry, unsigned int selected, unsigned int max, unsigned int offset); + void paintItem (std::vector *entry, unsigned int pos, unsigned int selected); + void paintItemInfo(std::vector *entry, unsigned int selected); void paintDetails(std::vector *entry, unsigned int index, bool use_playing = false); - void clearItem2DetailsLine (void); - void paintItem2DetailsLine (int pos,unsigned int ch_index); + void paintItem2DetailsLine (int pos); void updateTimes(const bool force = false); + void playAudio(std::string name, std::string mime); + void showPicture(std::string name); + void playVideo(std::string name, std::string url); }; #endif