diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index ab2f2b5..97fef9a --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ VERSIONSUFFIX = gen_version_suffix.h PLUGINOBJS = $(PLUGIN).o thread.o tntconfig.o setup.o i18n.o timers.o \ tools.o recman.o tasks.o status.o epg_events.o epgsearch.o \ grab.o md5.o filecache.o livefeatures.o preload.o timerconflict.o \ - users.o + users.o osd_status.o WEBLIBS = pages/libpages.a css/libcss.a javascript/libjavascript.a diff --git a/css/styles.css b/css/styles.css old mode 100644 new mode 100755 index cef24b3..d32e935 --- a/css/styles.css +++ b/css/styles.css @@ -1065,6 +1065,68 @@ div.screenshot img { height: 320px; } + +/* ############################## + # Remote page - OSD + ############################## +*/ + +#osd { + background-color:black; + color:white; + height: 320px; + width: 569px; +} +.osd { + padding: 5px 0px 5px 10px; + position:relative; +} +.osd div { + margin:0px; + tab-size:4; + font-family: "Courier New", Courier, monospace; +} +.osdMessage { + position:absolute; + overflow:auto; + top:250px; + max-height: 100px; + min-height:20px; + width: 510px; + background-color:yellow; + color:black; + padding:10px; + border:2px solid red; +} +.osdText, .osdItems { + overflow:auto; + overflow-x:hidden; + height: 267px; + width: 555px; + margin:5px 0px !important; +} +.osdItem, .osdTitle { + cursor:pointer; + white-space: nowrap; +} +.osdItem.selected { + background-color:#cccccc; + color:#000000; +} +.osdButtons {} +.osdButtons div { + float:left; + margin-right:5px; + padding:2px; + width:130px; + text-align: center; + cursor:pointer; +} +.osdButtonGreen {background-color:green} +.osdButtonYellow {background-color:yellow;color:black} +.osdButtonBlue {background-color:blue} +.osdButtonRed {background-color:red} + /* ############################## # Error widget diff --git a/osd_status.cpp b/osd_status.cpp new file mode 100755 index 0000000..a6791ab --- /dev/null +++ b/osd_status.cpp @@ -0,0 +1,167 @@ +#include +#include +#include "osd_status.h" + +namespace vdrlive { + +OsdStatusMonitor::OsdStatusMonitor():title(),message(),red(),green(),yellow(),blue(),text(),selected(-1),lastUpdate(0){ + memset(&tabs, 0, sizeof(tabs)); +} +OsdStatusMonitor::~OsdStatusMonitor() { + OsdClear(); +} + +void OsdStatusMonitor::OsdClear() { + title = message = text = ""; + red = green = yellow = blue = ""; + items.Clear(); + selected = -1; + memset(&tabs, 0, sizeof(tabs)); + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdTitle(const char *Title) { + title = Title ? Title : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdStatusMessage(const char *Message) { + message = Message ? Message : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) { + red = Red ? Red :""; + green = Green ? Green : ""; + yellow = Yellow ? Yellow : ""; + blue = Blue ? Blue : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdItem(const char *Text, int Index) { + const char* tab; + const char* colStart = Text; + for (int col = 0; col < MaxTabs && + (tab = strchr(colStart, '\t')); col++) { + int width = tab - colStart + 1; + if (width > tabs[col]) + tabs[col] = width; + colStart = colStart + width; + } + items.Add(new cLiveOsdItem(Text)); + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdCurrentItem(const char *Text) { + int i = -1; + int best = -1; + int dist = items.Count(); + cLiveOsdItem * currentItem = NULL; + cLiveOsdItem *bestItem = NULL; + for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { + if (++i == selected) + currentItem = item; + if ( item->Text().compare(Text) == 0) { + if (abs(i - selected) < dist) { + // best match is the one closest to previous position + best = i; + bestItem= item; + dist = abs(i - selected); + } + else if (selected < 0) { + // previous position unknown - take first match + best = i; + bestItem= item; + break; + } + else { + // we already have a better match, so we're done + break; + } + } + } + if (best >= 0) { + // found matching item + selected = best; + bestItem->Select(true); + if (currentItem && currentItem != bestItem){ + currentItem->Select(false); + lastUpdate= clock(); + } + } + else if (currentItem) { + // no match: the same item is still selected but its text changed + currentItem->Update(Text); + lastUpdate= clock(); + } +} + +void OsdStatusMonitor::OsdTextItem(const char *Text, bool Scroll) { + if (Text) { + text = Text; + //text= text.replace( text.begin(), text.end(), '\n', '|'); + } + else { + text = ""; + } + lastUpdate= clock(); +} +std::string const OsdStatusMonitor::GetTitleHtml() {return !title.empty() ? "
" + EncodeHtml(title) + "
" : "";} +std::string const OsdStatusMonitor::GetMessageHtml() {return !message.empty() ? "
" + EncodeHtml(message) + "
" : "";} +std::string const OsdStatusMonitor::GetRedHtml() {return !red.empty() ? "
" + EncodeHtml(red) + "
" : "";} +std::string const OsdStatusMonitor::GetGreenHtml() {return !green.empty() ? "
" + EncodeHtml(green) + "
" : "";} +std::string const OsdStatusMonitor::GetYellowHtml() {return !yellow.empty() ? "
" + EncodeHtml(yellow) + "
" : "";} +std::string const OsdStatusMonitor::GetBlueHtml() {return !blue.empty() ? "
" + EncodeHtml(blue) + "
" : "";} +std::string const OsdStatusMonitor::GetTextHtml() {return !text.empty() ? "
" + EncodeHtml(text) + "
" : "";} +std::string const OsdStatusMonitor::GetButtonsHtml() { + std::string buffer= GetRedHtml() + GetGreenHtml() + GetYellowHtml() + GetBlueHtml(); + return !buffer.empty() ? "
" + buffer + "
" : ""; +} + +std::string const OsdStatusMonitor::GetItemsHtml(void){ + std::string buffer= ""; + for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { + buffer += "
isSelected()) + buffer += " selected"; + buffer += "\">"; + buffer += EncodeHtml(item->Text()); + buffer += "
"; + } + return !buffer.empty() ? "
" + buffer + "
" : ""; +} +std::string const OsdStatusMonitor::GetHtml(){ + std::stringstream mystream; + mystream << lastUpdate; + return "
" + GetTitleHtml() + GetItemsHtml() + GetTextHtml() + GetMessageHtml() + GetButtonsHtml() + "
"; +} + +std::string const OsdStatusMonitor::EncodeHtml(const std::string& html) { + std::ostringstream result; + std::string::const_iterator i; + for (i = html.begin(); i != html.end(); ++i) { + if (*i >= 128) + result << "&#" << static_cast(*i) << ";"; + else if (*i == '<') + result << "<"; + else if (*i == '>') + result << ">"; + else if (*i == '&') + result << "&"; + else if (*i == '"') + result << """; + else + result << static_cast(*i); // Copy untranslated + } + return result.str(); +} + + + +OsdStatusMonitor& LiveOsdStatusMonitor() +{ + static OsdStatusMonitor instance; + return instance; +} + +} // namespace vdrlive diff --git a/osd_status.h b/osd_status.h new file mode 100755 index 0000000..f84b1ef --- /dev/null +++ b/osd_status.h @@ -0,0 +1,84 @@ +#ifndef VDR_LIVE_OSD_STATUS_H +#define VDR_LIVE_OSD_STATUS_H + +#include +#include +#include + +namespace vdrlive { + +class cLiveOsdItem: public cListObject { + private: + std::string text; + bool selected; + public: + std::string Text() const { return text; } + int isSelected() const {return selected;} + void Select(const bool doSelect) { selected= doSelect; }; + void Update(const char* Text) { text = Text ? Text : ""; }; + cLiveOsdItem(const char* Text):text(),selected(false) { text = Text ? Text : ""; }; + ~cLiveOsdItem() { } +}; + +class OsdStatusMonitor: public cStatus +{ + friend OsdStatusMonitor& LiveOsdStatusMonitor(); +public: + enum { MaxTabs = 6 }; +private: + OsdStatusMonitor(); + OsdStatusMonitor( OsdStatusMonitor const& ); + + std::string title; + std::string message; + std::string red; + std::string green; + std::string yellow; + std::string blue; + std::string text; + int selected; + cList items; + unsigned short tabs[MaxTabs]; + clock_t lastUpdate; + +protected: +// static void append(char *&tail, char type, const char *src, int max); +public: + + std::string const GetTitle() const {return title;} + std::string const GetMessage() const {return message;} + std::string const GetRed() const {return red;} + std::string const GetGreen() const {return green;} + std::string const GetYellow() const {return yellow;} + std::string const GetBlue() const {return blue;} + std::string const GetText() const {return text;} + + virtual std::string const GetHtml(); + virtual std::string const GetTitleHtml(); + virtual std::string const GetMessageHtml(); + virtual std::string const GetRedHtml(); + virtual std::string const GetGreenHtml(); + virtual std::string const GetYellowHtml(); + virtual std::string const GetBlueHtml(); + virtual std::string const GetTextHtml(); + virtual std::string const GetButtonsHtml(); + virtual std::string const GetItemsHtml(); + + virtual void OsdClear(); + virtual void OsdTitle(const char *Title); + virtual void OsdStatusMessage(const char *Message); + virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue); + virtual void OsdTextItem(const char *Text, bool Scroll); + virtual void OsdItem(const char *Text, int Index); + virtual void OsdCurrentItem(const char *Text); + + virtual ~OsdStatusMonitor(); + + std::string const EncodeHtml(const std::string& html); +}; + +OsdStatusMonitor& LiveOsdStatusMonitor(); + +} // namespace vdrlive + +#endif // VDR_LIVE_STATUS_H diff --git a/pages/Makefile b/pages/Makefile old mode 100644 new mode 100755 index 78a4a9c..2ca1b8d --- a/pages/Makefile +++ b/pages/Makefile @@ -41,7 +41,7 @@ OBJS = menu.o recordings.o schedule.o multischedule.o screenshot.o \ searchepg.o login.o ibox.o xmlresponse.o play_recording.o \ pause_recording.o stop_recording.o ffw_recording.o \ rwd_recording.o setup.o content.o epginfo.o timerconflicts.o \ - recstream.o users.o edit_user.o edit_recording.o + recstream.o users.o edit_user.o edit_recording.o osd.o ### Default rules: diff --git a/pages/osd.ecpp b/pages/osd.ecpp new file mode 100755 index 0000000..5318eed --- /dev/null +++ b/pages/osd.ecpp @@ -0,0 +1,26 @@ +<%pre> +#include +#include +#include +#include +#include "grab.h" +#include "setup.h" +#include "tools.h" +#include "users.h" +#include "osd_status.h" + +using namespace std; +using namespace vdrlive; + + +<%session scope="global"> +bool logged_in(false); + +<%request scope="page"> + +<%cpp> +if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); +reply.setContentType( "application/xml" ); + +reply.out() << LiveOsdStatusMonitor().GetHtml(); + diff --git a/pages/remote.ecpp b/pages/remote.ecpp old mode 100644 new mode 100755 index 0f2b195..6c75602 --- a/pages/remote.ecpp +++ b/pages/remote.ecpp @@ -58,12 +58,60 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <& pageelems.stylesheets &> <& pageelems.ajax_js &> % reply.sout().imbue(locale()); - + <& pageelems.logo &> <& menu active="remote" component=("remote.remote_actions")>
-
-<{ if (!LiveGrabImageManager().CanGrab()) { }> - bloek -<{ } else { }> -
+
+<{ if (LiveGrabImageManager().CanGrab()) { }> + <{ } }> +
" width="162" height="378" border="0" usemap="#remote" alt="" /> - Power - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 0 - Vol+ - Vol- - P+ - P- - Mute - Record - Menu - Exit - Subtitles - Audio - Up - Right - Down - Left - Ok - Red - Green - Yellow - Blue + Power + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + Vol+ + Vol- + P+ + P- + Mute + Record + Menu + Exit + Subtitles + Audio + Up + Right + Down + Left + Ok + Red + Green + Yellow + Blue
@@ -159,5 +271,10 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%include>page_exit.eh <%def remote_actions> -<$ tr("Snapshot interval") $>:           <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> +<$ tr("Selection") $>:  +<{ if ( LiveGrabImageManager().CanGrab()) { }> +             <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> - +<{ } }> +   - +